From 9d95f568dbd6b45c659909dc849eb0808c1f590b Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 28 Jul 2006 16:01:39 +0000 Subject: [PATCH 001/834] Initial checkin. --- plugins/org.eclipse.dd.dsf/.classpath | 7 + plugins/org.eclipse.dd.dsf/.cvsignore | 1 + plugins/org.eclipse.dd.dsf/.project | 28 ++ .../.settings/org.eclipse.jdt.core.prefs | 12 + .../org.eclipse.dd.dsf/META-INF/MANIFEST.MF | 14 + plugins/org.eclipse.dd.dsf/build.properties | 5 + plugins/org.eclipse.dd.dsf/plugin.xml | 5 + .../src/org/eclipse/dd/dsf/DsfPlugin.java | 68 +++ .../dd/dsf/concurrent/DefaultDsfExecutor.java | 60 +++ .../org/eclipse/dd/dsf/concurrent/Done.java | 48 +++ .../dd/dsf/concurrent/DoneTracker.java | 104 +++++ .../dd/dsf/concurrent/DsfExecutor.java | 31 ++ .../eclipse/dd/dsf/concurrent/DsfQuery.java | 161 +++++++ .../dd/dsf/concurrent/DsfRunnable.java | 21 + .../dd/dsf/concurrent/DsfSequence.java | 249 +++++++++++ .../dd/dsf/concurrent/GetDataDone.java | 33 ++ .../concurrent/GetDataDoneWithClientDone.java | 53 +++ .../org/eclipse/dd/dsf/model/AbstractDMC.java | 119 ++++++ .../src/org/eclipse/dd/dsf/model/DMCs.java | 44 ++ .../eclipse/dd/dsf/model/DataModelEvent.java | 29 ++ .../dd/dsf/model/IDataModelContext.java | 75 ++++ .../eclipse/dd/dsf/model/IDataModelData.java | 31 ++ .../eclipse/dd/dsf/model/IDataModelEvent.java | 21 + .../dd/dsf/model/IDataModelService.java | 29 ++ .../src/org/eclipse/dd/dsf/model/package.html | 26 ++ .../dd/dsf/service/AbstractDsfService.java | 139 ++++++ .../dsf/service/DsfServiceEventHandler.java | 45 ++ .../dd/dsf/service/DsfServicesTracker.java | 163 ++++++++ .../eclipse/dd/dsf/service/DsfSession.java | 395 ++++++++++++++++++ .../eclipse/dd/dsf/service/IDsfService.java | 88 ++++ 30 files changed, 2104 insertions(+) create mode 100644 plugins/org.eclipse.dd.dsf/.classpath create mode 100644 plugins/org.eclipse.dd.dsf/.cvsignore create mode 100644 plugins/org.eclipse.dd.dsf/.project create mode 100644 plugins/org.eclipse.dd.dsf/.settings/org.eclipse.jdt.core.prefs create mode 100644 plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF create mode 100644 plugins/org.eclipse.dd.dsf/build.properties create mode 100644 plugins/org.eclipse.dd.dsf/plugin.xml create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/DsfPlugin.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DoneTracker.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutor.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfQuery.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfRunnable.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/GetDataDone.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/GetDataDoneWithClientDone.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/AbstractDMC.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/DMCs.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/DataModelEvent.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelContext.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelData.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelEvent.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelService.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/package.html create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServiceEventHandler.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServicesTracker.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java diff --git a/plugins/org.eclipse.dd.dsf/.classpath b/plugins/org.eclipse.dd.dsf/.classpath new file mode 100644 index 00000000000..751c8f2e504 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/plugins/org.eclipse.dd.dsf/.cvsignore b/plugins/org.eclipse.dd.dsf/.cvsignore new file mode 100644 index 00000000000..ba077a4031a --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/.cvsignore @@ -0,0 +1 @@ +bin diff --git a/plugins/org.eclipse.dd.dsf/.project b/plugins/org.eclipse.dd.dsf/.project new file mode 100644 index 00000000000..63ae142e1be --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/.project @@ -0,0 +1,28 @@ + + + org.eclipse.dd.dsf + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/plugins/org.eclipse.dd.dsf/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.dd.dsf/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000000..93a2ad59b5e --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/.settings/org.eclipse.jdt.core.prefs @@ -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 diff --git a/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..300d22e0fe2 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF @@ -0,0 +1,14 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Riverbed Plug-in +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 +Eclipse-LazyStart: true +Export-Package: org.eclipse.dd.dsf.concurrent, + org.eclipse.dd.dsf.debug, + org.eclipse.dd.dsf.model, + org.eclipse.dd.dsf.service diff --git a/plugins/org.eclipse.dd.dsf/build.properties b/plugins/org.eclipse.dd.dsf/build.properties new file mode 100644 index 00000000000..e9863e281ea --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml diff --git a/plugins/org.eclipse.dd.dsf/plugin.xml b/plugins/org.eclipse.dd.dsf/plugin.xml new file mode 100644 index 00000000000..33ca93ceb1b --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/plugin.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/DsfPlugin.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/DsfPlugin.java new file mode 100644 index 00000000000..a87ce47e211 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/DsfPlugin.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * 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; + +import org.eclipse.core.runtime.Plugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class DsfPlugin extends Plugin { + + // The plug-in ID + public static final String PLUGIN_ID = "org.eclipse.dd.dsf"; + + // The shared instance + private static DsfPlugin fgPlugin; + + private static BundleContext fgBundleContext; + + /** + * The constructor + */ + public DsfPlugin() { + 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); + } + + /* + * (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 DsfPlugin getDefault() { + return fgPlugin; + } + + public static BundleContext getBundleContext() { + return fgBundleContext; + } + +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java new file mode 100644 index 00000000000..3bd4e996661 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.concurrent; + +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.ThreadFactory; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.DsfPlugin; + +/** + * Default implementation of a Riverbed executor interfaces, based on the + * standard java.util.concurrent.ThreadPoolExecutor. + */ + +public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor + implements DsfExecutor +{ + static class DsfThreadFactory implements ThreadFactory { + Thread fThread; + public Thread newThread(Runnable r) { + assert fThread == null; // Should be called only once. + fThread = new Thread(new ThreadGroup("Riverbed Thread Group"), r, "Riverbed Dispatch Thread", 0); + return fThread; + } + } + + + + public DefaultDsfExecutor() { + super(1, new DsfThreadFactory()); + } + + public boolean isInExecutorThread() { + return Thread.currentThread().equals( ((DsfThreadFactory)getThreadFactory()).fThread ); + } + + @Override + protected void afterExecute(Runnable r, Throwable t) { + // FIXME: Unfortunately this is not enough to catch runnable exceptions, because + // FutureTask implementation swallows exceptions when they're thrown by runnables. + // Need to override the FutureTask class, and the AbstractExecutorService.submit() + // methods in order to provide access to these exceptions. + + super.afterExecute(r, t); + if (t != null) { + DsfPlugin.getDefault().getLog().log(new Status( + IStatus.ERROR, DsfPlugin.PLUGIN_ID, -1, "Uncaught exception in dispatch thread.", t)); + } + } +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java new file mode 100644 index 00000000000..e36dbb23cee --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.concurrent; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.Status; + +/** + * Base class for Riverbed service method-completion callbacks. By default + * all callbacks that indicate a complition of a method contain the status + * of the result. + *
NOTE: Access to the status data is not synchronized, so + * clients have to make sure that access to this object is thread safe if + * it's used outside of the caller's dispatch thread. + */ +abstract public class Done extends DsfRunnable { + private IStatus fStatus = Status.OK_STATUS; + + /** Sets the status of the called method. */ + public void setStatus(IStatus status) { fStatus = status; } + + /** Returns the status of the completed method. */ + public IStatus getStatus() { return fStatus; } + + /** + * Convenience method for setting the status using a status object of a + * sub-command. + * @param pluginId plugin id of the invoked method + * @param code status code + * @param message message to include + * @param subStatus status object to base the Done status on + */ + public void setErrorStatus(String pluginId, int code, String message, final IStatus subStatus) { + MultiStatus status = new MultiStatus(pluginId, code, message, null); + status.merge(subStatus); + fStatus = status; + } + +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DoneTracker.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DoneTracker.java new file mode 100644 index 00000000000..3805a0e0b89 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DoneTracker.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.concurrent; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.dd.dsf.DsfPlugin; + +/** + * Utility class to track multiple done (callback) results of commands + * that are initiated simultaneously. The usage is as follows: + *
+ *     final DoneTracker doneTracker = new DoneTracker() { 
+ *         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() {
+ *             public void run() {
+ *                 System.out.println(Integer.toString(i) + " complete");
+ *                 doneTracker.doneDone(this);
+ *             }
+ *         }));
+ *     }
+ * 
+ */ +public abstract class DoneTracker extends Done { + private Map fDones = new HashMap(); + private int fDoneCounter; + + /** + * No-arg constructor. + *
+ * Note: this runnable will be executed following + * execution of the last done, and in the same dispatch loop. + * + */ + public DoneTracker() { + setStatus(new MultiStatus(DsfPlugin.PLUGIN_ID, 0, "Collective status for set of sub-operations.", null)); + } + + /** + * Adds a new Done callback to this tracker's list. + * @param Service-specific class of the Done callback, to avoid an + * unnecessary cast. + * @param done callback object to add to the tracker + * @return the done that was just added, it allows this method to be used + * inlined in service method calls + */ + public V add(V done) { + assert !fDones.containsKey(done); + fDones.put(done, false); + fDoneCounter++; + return done; + } + + /** + * Adds a Done which performs no actions. This is useful if all work + * is performed inside DoneTracker.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); + }}); + } + + /** + * Marks the given Done callback as completed. Client implementations of + * the Done callback have to call this method in order for the tracker + * to complete. + *
+ * Note: funniest method signature ever! + * @param done + */ + public void doneDone(Done done) { + ((MultiStatus)getStatus()).merge(done.getStatus()); + fDones.put(done, true); + fDoneCounter--; + if (fDoneCounter == 0) { + assert !fDones.containsValue(false); + run(); + } + } + + /** + * Returns the map of Done callbacks. Access to this data is provided + * in case overriding classes need access to the collected data in the + * done callbacks. + * @return map of the done callbacks. + */ + public Map getDones() { return fDones; } +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutor.java new file mode 100644 index 00000000000..a3243f4cbb8 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutor.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.concurrent; + +import java.util.concurrent.ScheduledExecutorService; + +/** + * DSF executor service. Implementations of this executor must ensure + * that all runnables and callables are executed in the same thread: the + * executor's single dispatch thread. + *
Note: A DSF executor dispatch thread does not necessarily have + * to be exclusive to the executor, it could be shared with + * another event dispatch service, such as the SWT display dispatch thread. + */ +public interface DsfExecutor extends ScheduledExecutorService +{ + /** + * Checks if the thread that this method is called in is the same as the + * executor's dispatch thread. + * @return true if in DSF executor's dispatch thread + */ + public boolean isInExecutorThread(); +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfQuery.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfQuery.java new file mode 100644 index 00000000000..0d58590c65a --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfQuery.java @@ -0,0 +1,161 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.concurrent; + +import java.util.concurrent.Future; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.DsfPlugin; + +/** + * A convenience class that allows a client to retrieve data from services + * synchronously from a non-dispatch thread. This class is different from + * a Callable in that it allows the implementation code to calculate + * the result in several dispatches, rather than requiring it to return the + * data at end of Callable#call method. + * + * @see java.util.concurrent.Callable + * FIXME: make this class implement the Future interface. + */ +abstract public class DsfQuery { + + private Object fResult; + private boolean fValid; + private DsfExecutor fExecutor; + private Future fFuture; + private boolean fWaiting; + private IStatus fStatus = Status.OK_STATUS; + + public DsfQuery(DsfExecutor executor) { + fExecutor = executor; + } + + /** + * Start data retrieval. + * Client must implement this method to do whatever is needed to retrieve data. + * Retrieval can be (but does not have to be) asynchronious - it meas this method can return + * before data is retrieved. When data is ready Proxy must be notified by calling done() method. + */ + protected abstract void execute(); + + /** + * Allows deriving classes to implement their own snipped additional + * cancellation code. + */ + protected void revokeChildren(Object result) {}; + + /** + * Get data associated with this proxy. This method is thread safe and + * it will block until data is ready. Because it's a blocking call and it waits + * for commands to be processed on the dispatch thread, this methods itself + * CANNOT be called on the dispatch thread. + */ + public synchronized Object get() { + assert !fExecutor.isInExecutorThread(); + if(!fValid) { + if (!fWaiting) { + fFuture = fExecutor.submit(new DsfRunnable() { + public void run() { + // TODO: not sure if this try-catch is desirable. It might encourage + // implementors to not catch its own exceptions. If the query code takes + // more than one dispatch, then this code will not be helpful anyway. + try { + DsfQuery.this.execute(); + } catch (Throwable t) { + doneException(t); + } + } + }); + } + + fWaiting = true; + try { + while(fWaiting) { + wait(); + } + } catch (InterruptedException e) { + fStatus = new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, -1, + "Interrupted exception while waiting for result.", e); + fValid = true; + } + assert fValid; + } + return fResult; + } + + /** + * Same as get(), but with code to automatically re-threw the exception if one + * was reported by the run() method. + */ + public Object getWithThrows() throws CoreException { + Object retVal = get(); + if (!getStatus().isOK()) { + throw new CoreException(getStatus()); + } + return retVal; + } + + public IStatus getStatus() { return fStatus; } + + /** Abort current operation and keep old proxy data */ + public synchronized void cancel() { + assert fExecutor.isInExecutorThread(); + assert !fWaiting || !fValid; + if (fWaiting) { + fFuture.cancel(false); + fWaiting = false; + notifyAll(); + } else if (fValid) { + revokeChildren(fResult); + } + fValid = true; + } + + /** Abort current operation and set proxy data to 'result' */ + public synchronized void cancel(Object newResult) { + fResult = newResult; + cancel(); + } + + public Object getCachedResult() { + return fResult; + } + + public boolean isValid() { return fValid; } + + public synchronized void done(Object result) { + // Valid could be true if request was cancelled while data was + // being retrieved, and then done() was called. + if (fValid) return; + + fResult = result; + fValid = true; + if (fWaiting) { + fWaiting = false; + notifyAll(); + } + } + + public synchronized void doneError(IStatus errorStatus) { + if (fValid) return; + fStatus = errorStatus; + done(null); + } + + public synchronized void doneException(Throwable t) { + if (fValid) return; + doneError(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, -1, + "Exception while computing result.", t)); + } +} + diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfRunnable.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfRunnable.java new file mode 100644 index 00000000000..caf610210ae --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfRunnable.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.concurrent; + +/** + * A DSF-instrumented alternative to the Runnable interface. + *

+ * While it is perfectly fine for clients to call the Riverbed executor with + * an object only implementing the Runnable interface, the RbRunnable is a + * place holder for future tracing enhancments for Riverbed. + */ +abstract public class DsfRunnable implements Runnable { +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java new file mode 100644 index 00000000000..b8f852585b2 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java @@ -0,0 +1,249 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.concurrent; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.DsfPlugin; + +/** + * Convenience class for implementing a series of commands that need to be + * executed asynchronously. + *

+ * Certain complex tasks require multiple commands to be executed in a chain, + * because for example result of one command is used as input into another + * command. The typical Riverbed pattern of solving this problem is the following: + *

  • + *
    1. original caller passes a Done callback to a method and invokes it + *
    2. the method is executed by a subsystem + *
    3. when the method is finished it calls another method and passes + * the original callback to it + *
    4. steps 2-3 are repeated number of times + *
    5. when the last method in a chain is executed, it submits the original + * Done callback + *
  • + *

    + * This pattern is very useful in itself, but it proves very difficult to follow + * because the methods can be scattered accross many classes and systems. Also + * if progress reporting, cancellability, and roll-back ability is required, it + * has to be re-implemented every time. The Sequence class tries to address + * this problem by containing this pattern in a single class. + * + *
    TODO: should a sequence be re-entrant. I.e. should the arguments be + * passed in through a map, and the return values returned back in the done? + *
    FIXME: convert to implement Future interface + */ +abstract public class DsfSequence { + + /** + * The abstract class that each step has to implement + *
    FIXME: convert execute() and rollBacl() to take "done" as an argument. + * This way we can make step a static class, and make its paradigm + * more consistent with rest of Riverbed. + */ + abstract public class Step { + public void execute() { stepFinished(); } + public void rollBack() { stepRolledBack(); } + public int getTicks() { return 1; } + } + + private DsfExecutor fExecutor; + private Step[] fSteps; + private Done fDoneQC; + private String fTaskName; + private String fRollbackTaskName; + private IProgressMonitor fProgressMonitor = new NullProgressMonitor(); + private int fCurrentStepIdx = 0; + boolean fCancelled = false; + + /** + * Default constructor. If this constructor is used, the steps need to be initialized + * before the sequence can be invoked. + * @param executor the Riverbed executor which will be used to invoke all steps + */ + public DsfSequence(DsfExecutor executor) { + this(executor, null); + } + + /** + * Constructor that initialized the steps. + * @param executor the Riverbed executor which will be used to invoke all steps + * @param steps sequence steps + */ + public DsfSequence(DsfExecutor executor, Step[] steps) { + fExecutor = executor; + fSteps = steps; + } + + /** Returns the riverbed executor for this sequence */ + public DsfExecutor getExecutor() { return fExecutor; } + + /** + * Sets the done callback to be submitted when the sequence is finished. + * If the sequence is submitted by a caller in the dispatch thread, this is + * the way that the original caller can be notified of the sequence + * completion. If the caller blocks and waits for the sequence + * completion, the Done callback is not necessary. + * @param doneQC callback to submit when sequence completes, can be null + */ + public void setDone(Done doneQC) { + fDoneQC = doneQC; + } + + /** + * Returns the Done callback that is registered with the Sequence + * @param doneQC callback that will be submitted when sequence completes, + * null if there is no callback configured + */ + public Done getDone() { return fDoneQC; } + + /** Sets the steps to be executed. */ + public void setSteps(Step[] steps) { + assert fCurrentStepIdx == 0; + fSteps = steps; + } + + /** Returns the steps to be executed. */ + public Step[] getSteps() { return fSteps; } + + /** + * Returns index of the step that is currently being executed. + *
    NOTE: After sequence is invoked, this method should be called + * only in the Riverbed executor thread. + * @return + */ + public int getCurrentIdx() { return fCurrentStepIdx; } + + /** + * Sets the progress monitor that will be called by the sequence with udpates. + * @param pm + */ + public void setProgressMonitor(IProgressMonitor pm) { fProgressMonitor = pm; } + + /** + * Sets the task name for this sequence. To be used with progress monitor; + * @param taskName + */ + public void setTaskName(String taskName) { fTaskName = taskName; } + + /** + * Sets the task name to be used with progress monitor, if this sequence needs + * to be rolled back as result of cancellation or error. + * @param taskName + */ + public void setRollBackTaskName(String n) { fRollbackTaskName = n; } + + + /** Submits this sequence to the executor. */ + public void invokeLater() { + getExecutor().submit( new DsfRunnable() { public void run() { doInvoke(); } }); + } + + /** + * Submits this sequence to the Riverbed executor, and blocks waiting for the + * sequence to complete. + *
    NOTE: This method is NOT to be called on the Riverbed executor thread. + */ + public synchronized void invoke() { + assert !fExecutor.isInExecutorThread() : + "Cannot be called on dispatch thread: " + this; + setDone(new Done() { + public void run() { + synchronized(DsfSequence.this) { DsfSequence.this.notifyAll(); } + } + }); + invokeLater(); + try { + wait(); + } catch (InterruptedException e) { + // TODO: error handling? + } + } + + private void doInvoke() { + assert fCurrentStepIdx == 0; + if (fTaskName != null) { + fProgressMonitor.subTask(fTaskName); + } + fSteps[fCurrentStepIdx].execute(); + } + + /** + * Cancells the execution of this sequence. The roll-back will start when + * the current step completes. + * + */ + public void cancel() { + fCancelled = true; + } + + /** + * To be called only by the step implementation, Tells the sequence to + * submit the next step. + */ + public void stepFinished() { + getExecutor().submit(new DsfRunnable() { public void run() { + fProgressMonitor.worked(getSteps()[fCurrentStepIdx].getTicks()); + fCurrentStepIdx++; + if (fCurrentStepIdx < fSteps.length) { + if (fCancelled) { + abort(new Status( + IStatus.CANCEL, DsfPlugin.PLUGIN_ID, -1, + "Cancelled" + fTaskName != null ? ": " + fTaskName : "", + null)); + } + fSteps[fCurrentStepIdx].execute(); + } else { + if (fDoneQC != null) getExecutor().submit(fDoneQC); + } + }}); + } + + /** + * To be called only by the step implementation. Tells the sequence to + * roll back next step. + */ + public void stepRolledBack() { + getExecutor().submit(new DsfRunnable() { public void run() { + fProgressMonitor.worked(getSteps()[fCurrentStepIdx].getTicks()); + fCurrentStepIdx--; + if (fCurrentStepIdx >= 0) { + fSteps[fCurrentStepIdx].rollBack(); + } else { + if (fDoneQC != null) getExecutor().submit(fDoneQC); + } + }}); + } + + /** + * To be called only by step implementation. Tells the sequence + * that its execution is to be aborted and it should start rolling back + * the sequence as if it was cancelled by user. + * @param error + */ + public void abort(final IStatus error) { + getExecutor().submit(new DsfRunnable() { public void run() { + if (fRollbackTaskName != null) { + fProgressMonitor.subTask(fRollbackTaskName); + } + fDoneQC.setStatus(error); + fCurrentStepIdx--; + if (fCurrentStepIdx >= 0) { + fSteps[fCurrentStepIdx].rollBack(); + } else { + if (fDoneQC != null) getExecutor().submit(fDoneQC); + } + }}); + } + +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/GetDataDone.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/GetDataDone.java new file mode 100644 index 00000000000..3a8784d10ee --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/GetDataDone.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.concurrent; + +/** + * Asynchronous method callback which returns a data object (in addition to + * the base class's getStatus(). + * @param + */ +public abstract class GetDataDone extends Done { + /** Data object reference */ + private V fData; + + /** + * Sets the data object to specified value. To be called by the + * asynchronous method implementor. + * @param data Data value to set. + */ + public void setData(V data) { fData = data; } + + /** + * Returns the data value, null if not set. + */ + public V getData() { return fData; } +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/GetDataDoneWithClientDone.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/GetDataDoneWithClientDone.java new file mode 100644 index 00000000000..0affa1ff7ae --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/GetDataDoneWithClientDone.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.concurrent; + +import org.eclipse.core.runtime.IStatus; + +/** + * Convenience extension to GetDataDone, which handles posting of the client's + * Done upon the completion of this GetDataDone. + * @param Class type of data. + */ +public abstract class GetDataDoneWithClientDone extends GetDataDone { + private DsfExecutor fExecutor; + private Done fClientDone; + + /** + * Constructor requires the Done to be posted as well as the executor to + * post it with. + */ + public GetDataDoneWithClientDone(DsfExecutor executor, Done clientDone) { + fExecutor = executor; + fClientDone = clientDone; + } + + /** + * The run method checks the client done for cancellation, and this done + * for errors. It calls doRun() for the sub-class execution, and posts + * the client done when finished. + */ + public final void run() { + if (fClientDone.getStatus().getSeverity() == IStatus.CANCEL) return; + if (!getStatus().isOK()) { + fClientDone.setStatus(getStatus()); + } else { + doRun(); + } + fExecutor.execute(fClientDone); + } + + /** + * Method to perform the actual work. It should not post the client done + * because it will be posted by this class in run(). + */ + protected abstract void doRun(); +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/AbstractDMC.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/AbstractDMC.java new file mode 100644 index 00000000000..08e03569c18 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/AbstractDMC.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * 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.model; + +import org.eclipse.core.runtime.PlatformObject; +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 Data model data that this context is for. + */ +public class AbstractDMC extends PlatformObject + implements IDataModelContext +{ + private final String fSessionId; + private final String fServiceFilter; + private final IDataModelContext[] fParents; + + /** + * Main constructor provides all data needed to implement the IModelContext + * interface. + */ + public AbstractDMC(String sessionId, String filter, IDataModelContext[] parents) { + fSessionId = sessionId; + fServiceFilter = filter; + fParents = parents; + } + + /** Convenience constructor */ + public AbstractDMC(AbstractDsfService service, IDataModelContext parent) { + this(service.getSession().getId(), + service.getServiceFilter(), + parent == null ? new IDataModelContext[] {} : new IDataModelContext[] { parent }); + } + + /** + * Should be used by the deriving class to compare the basic context object + * information. + * @param other the other service to compare to + * @return true if contexts are equal + */ + protected boolean baseEquals(Object other) { + if (other == null) return false; + if ( !(other.getClass().equals(getClass()))) return false; + IDataModelContext otherCtx = (IDataModelContext)other; + return getSessionId().equals(otherCtx.getSessionId()) && + getServiceFilter().equals(otherCtx.getServiceFilter()) && + areParentsEqual(otherCtx.getParents()); + } + + private boolean areParentsEqual(IDataModelContext[] otherParents) { + if ( !(fParents.length == otherParents.length) ) return false; + for (int i = 0; i < fParents.length; i++) { + if (!fParents[i].equals(otherParents[i])) { + return false; + } + } + return true; + } + + protected int baseHashCode() { + int parentsHash = 0; + for (Object parent : getParents()) { + parentsHash += parent.hashCode(); + } + return getSessionId().hashCode() + getServiceFilter().hashCode() + parentsHash; + } + + protected String baseToString() { + StringBuffer retVal = new StringBuffer(); + for (IDataModelContext parent : fParents) { + retVal.append(parent); + } + return retVal.toString(); + } + + public String getSessionId() { return fSessionId; } + public String getServiceFilter() { return fServiceFilter; } + public IDataModelContext[] getParents() { return fParents; } + + /** + * Overrides the standard platform getAdapter to provide session-specific + * adapters. + *

    + * ModelContext is intended to be used in views, which call the + * contexts.getAdapter() method to retrieve model-specific content and + * label providers. But since many different sessions could be active + * at the same time, each requiring different content providers, the + * standard platform IAdapterManager is not sufficient in + * handling adapters for the model context object. This is because + * IAdapterManager uses only the class of the adaptable to + * select the correct adapter factoru, while for model context, the + * session is equally important. + * @see org.eclipse.runtime.IAdapterManager + */ + public Object getAdapter(Class adapterType) { + Object retVal = null; + DsfSession session = DsfSession.getSession(fSessionId); + if (session != null) { + retVal = session.getModelAdapter(adapterType); + } + if (retVal == null) { + retVal = super.getAdapter(adapterType); + } + return retVal; + } + +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/DMCs.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/DMCs.java new file mode 100644 index 00000000000..5aa60ef4d2b --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/DMCs.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.model; + + +/** + * Holder for utility static methods for manipulating IDataModelContext + * objects. + */ +public class DMCs { + + /** + * Finds a data model context of given type among ancestors of the + * specified context. + * @param ctx DMC to search. + * @param ancestorType Class type of the desired DMC ancestor. + * @return Returns the ancestor if found, null otherwise. + */ + @SuppressWarnings("unchecked") + public static V getAncestorOfType(IDataModelContext ctx, Class ancestorType) { + for (IDataModelContext parent : ctx.getParents()) { + if (parent.getClass().equals(ancestorType)) { + return (V)parent; + } + } + + for (IDataModelContext parent : ctx.getParents()) { + if (parent.getClass().equals(ancestorType)) { + V ancestor = getAncestorOfType(parent, ancestorType); + if (ancestor != null) return ancestor; + } + } + return null; + } + +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/DataModelEvent.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/DataModelEvent.java new file mode 100644 index 00000000000..7a41740ea07 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/DataModelEvent.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * 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.model; + +/** + * Base implementation of the IDataModelContext interface. + *

    + * TODO: consider merging the event interface with this class. + */ +public class DataModelEvent implements IDataModelEvent { + + private V fModelContext; + public DataModelEvent(V context) { + fModelContext = context; + } + + public V getDMC() { + return fModelContext; + } + +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelContext.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelContext.java new file mode 100644 index 00000000000..362182961ab --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelContext.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.model; + +import org.eclipse.core.runtime.IAdaptable; + +/** + * The base class for data model objects. + *

    + * DSF services need to return objects to clients which can be used as + * handles to track data stored in the service. Clients such as lazy-loading + * tree and table views retrieve a list of handles, then as needed, they + * 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 + * to represent the handle objects that are to be referenced by view model. + *

    + * Note: DMC objects 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. + *

    + * Note #2: DMCs 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 + * a lot of resources tied up. + * + * @param For each context object there is a corresponding data object + * which will contain information about that context. This template argument + * allows the clients to avoid casting the data class when retrieving data + * for a context object. + * + * @see IDataModelData + */ +public interface IDataModelContext extends IAdaptable +{ + /** + * Each model context object needs to track the session from which it + * originated. The session ID allows clients to choose the correct + * dispatch thread with which to access the service, and it allows the + * service to be uniquely identified among other sessions. + * @return Session ID of the service that originated the cotnext. + */ + public String getSessionId(); + + /** + * Returns the service filter object which can be used to uniquely identify + * a service. For most services, it's sufficient to know the service class + * and the session-id to find the service, but some services may have + * multiple instances running in the same session. For those services, this + * filter string can be used to find the correct service instance. + * @see org.osgi.framework.BundleContext#getServiceReferences + * @return + */ + public String getServiceFilter(); + + /** + * Returns the parent context of this context. ModelContext objects can be + * chained this way to allow methods that require context from multiple + * services to retrieve this context from a single handle that comes from + * the client. + * @return parent context of this context. + */ + public IDataModelContext[] getParents(); +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelData.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelData.java new file mode 100644 index 00000000000..5d3df186db0 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelData.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * 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.model; + +/** + * Data object containing information regarding a model context. Unlike the + * 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. + *

    + * This interface is intended primarily to allow for future development of + * a generic API to parametrize data model data. + * + */ +public interface IDataModelData { + + /** + * Returns true if the data represented by this object is still valid. + * Data may become invalid if, for example the cache object backing this + * data was cleared. + */ + public boolean isValid(); +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelEvent.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelEvent.java new file mode 100644 index 00000000000..1806112cac9 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelEvent.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * 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.model; + +/** + * 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 DMC that is affected by this event. + */ +public interface IDataModelEvent { + V getDMC(); +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelService.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelService.java new file mode 100644 index 00000000000..da587a61fe2 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelService.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * 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.model; + +import org.eclipse.dd.dsf.service.IDsfService; + +/** + * Interface for Riverbed services that provide model data to clients. + *

    + * For completeness this service interface derives from IDataModelData + * and has a method which allows clients to retrieve the DMC that represents the + * service data. + */ +public interface IDataModelService extends IDsfService, IDataModelData { + /** + * 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(); +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/package.html b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/package.html new file mode 100644 index 00000000000..2ea664a1ee4 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/package.html @@ -0,0 +1,26 @@ + + + + + Eclipse Device Debug - Debugger Services Framework - Data Model + + +Provides a base API and utilities for expoding data model through DSF +services.
    +
    +

    Package Specification

    +Practically speaking, all state data held by the DSF services makes up +the "data mode" of the service session.  However, to make it easy +to present this data in standard debug views, as well as customizable +views, it is useful to present the data using a consisten pattern and +with a set of published APIs and utilities.  This package aims to +provide these APIs and utilities.
    +

    Development Plans

    +This package is a work in progress and it is missing a major +feature.  This feature is being able to automatically parametrize +the contents of the data model in order to generically traverse it, and +to write data-driven framework for populating views with model data.
    +
    + + diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java new file mode 100644 index 00000000000..3c4d6b95487 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java @@ -0,0 +1,139 @@ +/******************************************************************************* + * 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.service; + +import java.util.Dictionary; +import java.util.Enumeration; + +import org.eclipse.dd.dsf.concurrent.Done; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; +import org.osgi.framework.ServiceRegistration; + + +/** + * Standard base implementation of the Riverbed service. This is a convinience + * class that provides the basic functionality that all Riverbed services have + * to implement. + */ +abstract public class AbstractDsfService + implements IDsfService +{ + /** Reference to the session that this service belongs to. */ + private DsfSession fSession; + + /** Startup order number of this service. */ + private int fStartupNumber; + + /** Registration object for this service. */ + private ServiceRegistration fRegistration; + + /** Tracker for services that this service depends on. */ + private DsfServicesTracker fTracker; + + /** Properties that this service was registered with */ + private Dictionary fProperties; + + /** Properties that this service was registered with */ + private String fFilter; + + + /** + * Only constructor, requires a reference to the session that this + * service belongs to. + * @param session + */ + public AbstractDsfService(DsfSession session) { + fSession = session; + } + + public DsfExecutor getExecutor() { return fSession.getExecutor(); } + public Dictionary getProperties() { return fProperties; } + public String getServiceFilter() { return fFilter; } + public int getStartupNumber() { return fStartupNumber; } + public void initialize(Done done) { + fTracker = new DsfServicesTracker(getBundleContext(), fSession.getId()); + fStartupNumber = fSession.getAndIncrementServiceStartupCounter(); + getExecutor().submit(done); + } + + public void shutdown(Done done) { + fTracker.dispose(); + fTracker = null; + getExecutor().submit(done); + } + + /** Returns the session object for this service */ + public DsfSession getSession() { return fSession; } + + /** + * Sub-classes should return the bundle context of the plugin, which the + * service belongs to. + */ + abstract protected BundleContext getBundleContext(); + + /** Returns the tracker for the services that this service depends on. */ + protected DsfServicesTracker getServicesTracker() { return fTracker; } + + /** + * Registers this service. + *
    FIXME: Move registering call to default initialize()/shutdown(). Add a new + * protected method calcProperties() to get the initial list of properties. + */ + @SuppressWarnings("unchecked") + protected void register(String[] classes, Dictionary properties) { + String[] newClasses = new String[classes.length + 2]; + System.arraycopy(classes, 0, newClasses, 2, classes.length); + newClasses[0] = IDsfService.class.getName(); + newClasses[1] = getClass().getName(); + properties.put(PROP_SESSION_ID, getSession().getId()); + fProperties = properties; + fRegistration = getBundleContext().registerService(newClasses, this, properties); + fRegistration.getReference().getProperty(Constants.OBJECTCLASS); + fFilter = generateFilter(fProperties); + fProperties.put(Constants.OBJECTCLASS, fRegistration.getReference().getProperty(Constants.OBJECTCLASS)); + } + + 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(')'); + } + filter.append(')'); + return filter.toString(); + } + + /** + * De-registers this service. + * + */ + protected void unregister() { + fRegistration.unregister(); + } + + /** Returns the registration object that was obtained when this service was registered */ + protected ServiceRegistration getServiceRegistration() { return fRegistration; } +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServiceEventHandler.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServiceEventHandler.java new file mode 100644 index 00000000000..d82886fae2f --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServiceEventHandler.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * 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.service; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation for service event handler methods. The name of the event + * handler method is irrelevant, only the annotation is checked. + *

    + * Each service event handler method should have one or two parameters: + *

  • + *
    First argument is required and it should be the event object, with + * type with the event class desired. + *
    Second argument is optional, and it has to be of type Dictionary. + * If this parameter is declared, the handler will be passed the properties + * dictionary of the service that submitted the event. + *
  • + *

    + * It is expected that service event classes are hierarchical. So that if a + * handler is registered for a super-class of another event, this handler + * will be called every time one of the sub-class events is invoked. + * If a listener declares a handler for an event AND a superclass of that event, + * both handlers will be invoked when the event is dispatched. + * + *
    TODO: Handling of second argument is not yet implemented. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +@Documented +public @interface DsfServiceEventHandler { + +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServicesTracker.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServicesTracker.java new file mode 100644 index 00000000000..5821e8796a6 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServicesTracker.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * 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.service; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.osgi.framework.BundleContext; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; + +/** + * Convenience class to help track Riverbed services that a given + * client needs to use. This class is similar to the standard OSGI + * org.osgi.util.tracker.ServiceTracker class, with a few differences: + *
    1. This class is assumed to be accessed by a single thread hence it + * has no synchronization built in, while OSGI ServiceTracker synchronized + * access to its data. + *
    2. This class is primarily designed to track multiple services of + * different type (class), while OSGI ServiceTracker is designed to work with + * single class type, with optional filtering options. + *
    3. This class uses knowledge of Riverbed sessions to help narrow down + * service references. + *
    4. OSGI Service tracker explicitly listens to OSGI service + * startup/shutdown events and it will clear a reference to a service as + * soon as it's shut down. This class leaves it up to the client to make + * sure that it doesn't access a service once that service has been shut down. + *

    + * That said, it might be more convenient for certain types of clients to use + * OSGI Service tracker for the additional features it provides. + * + * @see org.osgi.util.tracker.ServiceTracker + */ +public class DsfServicesTracker { + + private static String getServiceFilter(String sessionId) { + return ("(" + IDsfService.PROP_SESSION_ID + "=" + sessionId + ")").intern(); + } + + private static class ServiceKey + { + String fClassString; + String fFilter; + public ServiceKey(String classString, String filter) { + fClassString = classString; + fFilter = filter; + } + + public boolean equals(Object other) { + // I guess this doesn't have to assume fFilter can be null, but oh well. + return other instanceof ServiceKey && + ((ServiceKey)other).fClassString.equals(fClassString) && + ((fFilter == null && ((ServiceKey)other).fFilter == null) || + (fFilter != null && fFilter.equals(((ServiceKey)other).fFilter))); + } + + public int hashCode() { + return fClassString.hashCode() + (fFilter == null ? 0 : fFilter.hashCode()); + } + } + + private BundleContext fBundleContext; + private Map fServiceReferences = new HashMap(); + private Map fServices = new HashMap(); + private String fServiceFilter; + + /** + * Only constructor. + * @param bundleContext Context of the plugin that the client lives in. + * @param sessionId The Riverbed session that this tracker will be used for. + */ + public DsfServicesTracker(BundleContext bundleContext, String sessionId) { + fBundleContext = bundleContext; + fServiceFilter = getServiceFilter(sessionId); + } + + /** + * Retrieves a service reference for given service class and optional filter. + * Filter should be used if there are multiple instances of the desired service + * running within the same session. + * @param serviceClass class of the desired service + * @param custom filter to use when searching for the service, this filter will + * be used instead of the standard filter so it should also specify the desired + * session-ID + * @return OSGI service reference object to the desired service, null if not found + */ + public ServiceReference getServiceReference(Class serviceClass, String filter) { + ServiceKey key = new ServiceKey(serviceClass.getName().intern(), filter != null ? filter : fServiceFilter); + if (fServiceReferences.containsKey(key)) { + return fServiceReferences.get(key); + } + + try { + ServiceReference[] references = fBundleContext.getServiceReferences(key.fClassString, key.fFilter); + assert references == null || references.length <= 1; + if (references == null || references.length == 0) { + return null; + } else { + fServiceReferences.put(key, references[0]); + return references[0]; + } + } catch(InvalidSyntaxException e) { + assert false : "Invalid session ID syntax"; + } + return null; + } + + /** + * Convenience class to retrieve a service based on class name only. + * @param serviceClass class of the desired service + * @return instance of the desired service, null if not found + */ + public V getService(Class serviceClass) { + return getService(serviceClass, null); + } + + /** + * Retrieves the service given service class and optional filter. + * Filter should be used if there are multiple instances of the desired service + * running within the same session. + * @param serviceClass class of the desired service + * @param custom filter to use when searching for the service, this filter will + * be used instead of the standard filter so it should also specify the desired + * session-ID + * @return instance of the desired service, null if not found + */ + @SuppressWarnings("unchecked") + public V getService(Class serviceClass, String filter) { + ServiceReference serviceRef = getServiceReference(serviceClass, filter); + if (serviceRef == null) { + return null; + } else { + if (fServices.containsKey(serviceRef)) { + return (V)fServices.get(serviceRef); + } else { + V service = (V)fBundleContext.getService(serviceRef); + fServices.put(serviceRef, service); + return service; + } + } + } + + /** + * Un-gets all the serferences held by this tracker. Must be called + * to avoid leaking OSGI service references. + */ + public void dispose() { + for (Iterator itr = fServices.keySet().iterator(); itr.hasNext();) { + fBundleContext.ungetService((ServiceReference)itr.next()); + itr.remove(); + } + } + +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java new file mode 100644 index 00000000000..aa273865fa9 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java @@ -0,0 +1,395 @@ +/******************************************************************************* + * 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.service; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Dictionary; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.SortedMap; +import java.util.TreeMap; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.DsfPlugin; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.osgi.framework.Filter; + +/** + * Class to manage Riverbed sessions. A Riverbed session is a way to + * associate a set of Riverbed services that are running simultaneously and + * are interacting with each other to provide a complete set of functionality. + *

    + * Properties of a session are following: + *
    1. Each session is associated with a single Riverbed executor, although there + * could be multiple sessions using the same executor. + *
    2. Each session has a unique String identifier, which has to be used by + * the services belonging to this session when registering with OSGI services. + *
    3. Each session has its set of service event listeners. + *
    4. Start and end of each session is announced by events, which are always + * sent on that session's executor dispatch thread. + * + * @see org.eclipse.dd.dsf.concurrent.DsfExecutor + */ +public class DsfSession +{ + + /** + * Listener for session started events. This listener is always going to be + * called in the dispatch thread of the session's executor. + * + */ + public static interface SessionStartedListener { + /** + * Called when a new session is started. It is always called in the + * dispatch thread of the new session. + */ + public void sessionStarted(DsfSession session); + } + + /** + * Listener for session ended events. This listener is always going to be + * called in the dispatch thread of the session's executor. + */ + public static interface SessionEndedListener { + /** + * Called when a session is ended. It is always called in the + * dispatch thread of the session. + */ + public void sessionEnded(DsfSession session); + } + + private static int fgSessionIdCounter = 0; + private static Set fgActiveSessions = Collections.synchronizedSet(new HashSet()); + private static List fSessionStartedListeners = Collections.synchronizedList(new ArrayList()); + private static List fSessionEndedListeners = Collections.synchronizedList(new ArrayList()); + + /** Returns true if given session is currently active */ + public static boolean isSessionActive(String sessionId) { + return getSession(sessionId) != null; + } + + /** Returns a session instance for given session identifier */ + public static DsfSession getSession(String sessionId) { + for (DsfSession session : fgActiveSessions) { + if (session.getId().equals(sessionId)) { + return session; + } + } + return null; + } + + /** + * Registers a listener for session started events. + * Can be called on any thread. + */ + public static void addSessionStartedListener(SessionStartedListener listener) { + assert !fSessionStartedListeners.contains(listener); + fSessionStartedListeners.add(listener); + } + + /** + * Un-registers a listener for session started events. + * Can be called on any thread. + */ + public static void removeSessionStartedListener(SessionStartedListener listener) { + assert fSessionStartedListeners.contains(listener); + fSessionStartedListeners.remove(listener); + } + + /** + * Registers a listener for session ended events. + * Can be called on any thread. + */ + public static void addSessionEndedListener(SessionEndedListener listener) { + assert !fSessionEndedListeners.contains(listener); + fSessionEndedListeners.add(listener); + } + + /** + * Un-registers a listener for session ended events. + * Can be called on any thread. + */ + public static void removeSessionEndedListener(SessionEndedListener listener) { + assert fSessionEndedListeners.contains(listener); + fSessionEndedListeners.remove(listener); + } + + /** + * Starts and returns a new session instance. This method can be called on any + * thread, but the session-started listeners will be called using the session's + * executor. + * @param executor The Riverbed executor to use for this session. + * @return instance object of the new session + */ + public static DsfSession startSession(DsfExecutor executor) { + synchronized(fgActiveSessions) { + final DsfSession newSession = new DsfSession(executor, Integer.toString(fgSessionIdCounter++)); + fgActiveSessions.add(newSession); + executor.submit( new DsfRunnable() { public void run() { + SessionStartedListener[] listeners = fSessionStartedListeners.toArray( + new SessionStartedListener[fSessionStartedListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + listeners[i].sessionStarted(newSession); + } + }}); + return newSession; + } + } + + /** + * Terminates the given session. This method can be also called on any + * thread, but the session-ended listeners will be called using the session's + * executor. + * @param session session to terminate + */ + public static void endSession(final DsfSession session) { + synchronized(fgActiveSessions) { + if (!fgActiveSessions.contains(session)) { + throw new IllegalArgumentException(); + } + fgActiveSessions.remove(session); + session.getExecutor().submit( new DsfRunnable() { public void run() { + SessionEndedListener[] listeners = fSessionEndedListeners.toArray( + new SessionEndedListener[fSessionEndedListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + listeners[i].sessionEnded(session); + } + }}); + } + } + + private static class ListenerEntry { + Object fListener; + Filter fFilter; + + ListenerEntry(Object listener, Filter filter) { + fListener = listener; + fFilter = filter; + } + + public boolean equals(Object other) { + return other instanceof ListenerEntry && fListener.equals(((ListenerEntry)other).fListener); + } + + public int hashCode() { return fListener.hashCode(); } + } + + /** Session ID of this session. */ + private String fId; + + /** Dispatch-thread executor for this session */ + private DsfExecutor fExecutor; + + /** Service start-up counter for this session */ + private int fServiceInstanceCounter; + + /** Map of registered event listeners. */ + private Map fListeners = new HashMap(); + + /** + * Map of registered adapters, for implementing the + * IModelContext.getAdapter() method. + * @see org.eclipse.dd.dsf.model.AbstractDMC#getAdapter + */ + private Map fAdapters = Collections.synchronizedMap(new HashMap()); + + + /** Returns the ID of this session */ + public String getId() { return fId; } + + /** Returns the Riverbed executor of this session */ + public DsfExecutor getExecutor() { return fExecutor; } + + /** + * Adds a new listener for service events in this session. + * @param listener the listener that will receive service events + * @param filter optional filter to restrict the services that the + * listener will receive events from + */ + public void addServiceEventListener(Object listener, Filter filter) { + ListenerEntry entry = new ListenerEntry(listener, filter); + assert !fListeners.containsKey(entry); + fListeners.put(entry, getEventHandlerMethods(listener)); + } + + /** + * Removes the given listener. + * @param listener listener to remove + */ + public void removeServiceEventListener(Object listener) { + ListenerEntry entry = new ListenerEntry(listener, null); + assert fListeners.containsKey(entry); + fListeners.remove(entry); + } + + /** + * Retrieves and increments the startup counter for services in this session. + * Riverbed services should retrieve this counter when they are initialized, + * and should return it through IService.getStartupNumber(). This number is then + * used to prioritize service events. + * @return current startup counter value + */ + public int getAndIncrementServiceStartupCounter() { return fServiceInstanceCounter++; } + + /** + * Dispatches the given event to service event listeners. The event is submitted to + * the executor to be dispatched. + * @param event to be sent out + * @param serviceProperties properties of the service requesting the event to be dispatched + */ + public void dispatchEvent(final Object event, final Dictionary serviceProperties) { + getExecutor().submit(new DsfRunnable() { public void run() { + // TED added FIXME otherwise no way to detect!!! + try { + doDispatchEvent(event, serviceProperties); + } catch(Throwable e) { e.printStackTrace(); } + }}); + } + + /** + * 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 + */ + public void registerModelAdapter(Class adapterType, Object adapter) { + fAdapters.put(adapterType, adapter); + } + + /** + * Un-registers a IModelContext adapter of given type. + * @param adapterType adapter type to unregister + * @see org.eclipse.dsdp.model.AbstractDMC#getAdapter + */ + public void unregisterModelAdapter(Class adapterType) { + fAdapters.remove(adapterType); + } + + /** + * 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 + */ + public Object getModelAdapter(Class adapterType) { + return fAdapters.get(adapterType); + } + + public boolean equals(Object other) { + return other instanceof DsfSession && fId.equals(((DsfSession)other).fId); + } + + public int hashCode() { return fId.hashCode(); } + + private void doDispatchEvent(Object event, Dictionary serviceProperties) { + // Build a list of listeners; + SortedMap> listeners = new TreeMap>(new Comparator() { + public int compare(ListenerEntry o1, ListenerEntry o2) { + if (o1.fListener == o2.fListener) { + return 0; + } if (o1.fListener instanceof IDsfService && !(o2.fListener instanceof IDsfService)) { + return Integer.MAX_VALUE; + } else if (o2.fListener instanceof IDsfService && !(o1.fListener instanceof IDsfService)) { + return Integer.MIN_VALUE; + } else if ( (o1.fListener instanceof IDsfService) && (o2.fListener instanceof IDsfService) ) { + return ((IDsfService)o1.fListener).getStartupNumber() - ((IDsfService)o2.fListener).getStartupNumber(); + } + return 1; + }; + + public boolean equals(Object obj) { + return obj == this; + }; + }); + + // Build a list of listeners and methods that are registered for this event class. + Class eventClass = event.getClass(); + for (Map.Entry entry : fListeners.entrySet()) { + if (entry.getKey().fFilter != null && !entry.getKey().fFilter.match(serviceProperties)) { + // Dispatching service doesn't match the listener's filter, skip it. + continue; + } + Method[] allMethods = entry.getValue(); + List matchingMethods = new ArrayList(); + for (Method method : allMethods) { + assert method.getParameterTypes().length > 0 : eventClass.getName() + "." + method.getName() + + " signature contains zero parameters"; + if ( method.getParameterTypes()[0].isAssignableFrom(eventClass) ) { + matchingMethods.add(method); + } + } + if (!matchingMethods.isEmpty()) { + listeners.put(entry.getKey(), matchingMethods); + } + } + + // Call the listeners + for (Map.Entry> entry : listeners.entrySet()) { + for (Method method : entry.getValue()) { + try { + method.invoke(entry.getKey().fListener, new Object[] { event } ); + } + catch (IllegalAccessException e) { + DsfPlugin.getDefault().getLog().log(new Status( + IStatus.ERROR, DsfPlugin.PLUGIN_ID, -1, "Security exception when calling a service event handler method", e)); + assert false : "IServiceEventListener.ServiceHandlerMethod method not accessible, is listener declared public?"; + } + catch (InvocationTargetException e) { + DsfPlugin.getDefault().getLog().log(new Status( + IStatus.ERROR, DsfPlugin.PLUGIN_ID, -1, "Invocation exception when calling a service event handler method", e)); + assert false : "Exception thrown by a IServiceEventListener.ServiceHandlerMethod method"; + } + } + } + } + + private Method[] getEventHandlerMethods(Object listener) + { + List retVal = new ArrayList(); + try { + Method[] methods = listener.getClass().getMethods(); + for (Method method : methods) { + if (method.isAnnotationPresent(DsfServiceEventHandler.class)) { + Class[] paramTypes = method.getParameterTypes(); + if (paramTypes.length > 2) { + throw new IllegalArgumentException("ServiceEventHandler method has incorrect number of parameters"); + } + retVal.add(method); + } + } + } catch(SecurityException e) { + throw new IllegalArgumentException("No permission to access ServiceEventHandler method"); + } + + if (retVal.isEmpty()) { + throw new IllegalArgumentException("No methods marked with @ServiceEventHandler in listener, is listener declared public?"); + } + return retVal.toArray(new Method[retVal.size()]); + } + + /** + * Class to be instanciated only using startSession() + */ + private DsfSession(DsfExecutor executor, String id) { + fId = id; + fExecutor = executor; + } + +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java new file mode 100644 index 00000000000..82e5c310e32 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * 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.service; + +import java.util.Dictionary; + +import org.eclipse.dd.dsf.concurrent.Done; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; + +/** + * The inteface that all Riverbed services must implement. It only privides a + * few features to help manage and identify the servies using the OSGI services + * framework. + *

    + * Each service should register itself with OSGI services framework using + * the BundleContext.registerService() method. And each service should use the + * session ID that it is registering with as one of the service properties. If there + * is more than one instance of the service to be instanciated for a given session, + * additional properties should be used when registering the service to allow clients + * to uniquely identify the services. + *

    + * By convention, all methods of Riverbed services can be called only on the dispatch + * thread of the Riverbed executor that is associated with the service. If a + * service exposes a method that is to be called on non-dispatch thread, it should + * be documented so. + * + * TODO: Add IStatus error code constants for common service related failures. + * + * @see org.osgi.framework.BundleContext#registerService(String[], Object, Dictionary) + */ +public interface IDsfService { + + /** + * Property name for the session-id of this service. This property should be set by + * all Riverbed services when they are registered with OSGI service framework. + */ + static String PROP_SESSION_ID = "org.eclipse.dd.dsf.service.IService.session_id"; + + /** + * Returns the executor that should be used to call methods of this service. + * @return + */ + DsfExecutor getExecutor(); + + /** + * Returns a filter string that can be used to uniquely identify this + * service. This filter string should be based on the properties and class + * name, which were used to register this service. + * @see org.osgi.framework.BundleContext#getServiceReferences + */ + String getServiceFilter(); + + /** + * Performs initialization and registration of the given service. Implementation + * should initialize the service, so that all methods and events belonging to this + * service can be used following the initialization. + *
    Note: Since service initializaiton should be performed by an external + * logic, if this service depends on other services, the implementaion should + * assume that these services are already present, and if they are not, the + * initializaiton should fail. + * @param done callback to be submitted when the initialization is complete + */ + void initialize(Done done); + + /** + * Performs shutdown and de-registration of the given service. + * @param done callback to be submitted when shutdown is complete + */ + void shutdown(Done done); + + /** + * Returns the startup order number of this service among services in the same session. + * Implementations should get this number during initialization by calling + * Session.getAndIncrementServiceStartupCounter(). This counter is used to Session + * objects to prioritize the listeners of service events. + * @return startup order number of this service + * @see org.eclipse.dd.dsf.service.DsfSession#getAndIncrementServiceStartupCounter() + */ + int getStartupNumber(); +} From 550466b139102fdefcef8b3caf47775551f7c378 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 28 Jul 2006 16:07:11 +0000 Subject: [PATCH 002/834] Initial checkin. --- plugins/org.eclipse.dd.dsf.ui/.classpath | 7 + plugins/org.eclipse.dd.dsf.ui/.project | 28 ++ .../.settings/org.eclipse.jdt.core.prefs | 12 + .../META-INF/MANIFEST.MF | 13 + .../org.eclipse.dd.dsf.ui/build.properties | 4 + .../org/eclipse/dd/dsf/ui/DsfUIPlugin.java | 68 +++++ .../dsf/ui/model/DataViewModelSchemaNode.java | 231 ++++++++++++++++ .../model/GetDataDoneWithRequestMonitor.java | 51 ++++ .../dd/dsf/ui/model/IViewModelContext.java | 30 ++ .../dd/dsf/ui/model/IViewModelSchemaNode.java | 86 ++++++ .../dd/dsf/ui/model/ViewModelDelta.java | 259 ++++++++++++++++++ .../dd/dsf/ui/model/ViewModelProvider.java | 256 +++++++++++++++++ .../org/eclipse/dd/dsf/ui/model/package.html | 32 +++ 13 files changed, 1077 insertions(+) create mode 100644 plugins/org.eclipse.dd.dsf.ui/.classpath create mode 100644 plugins/org.eclipse.dd.dsf.ui/.project create mode 100644 plugins/org.eclipse.dd.dsf.ui/.settings/org.eclipse.jdt.core.prefs create mode 100644 plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF create mode 100644 plugins/org.eclipse.dd.dsf.ui/build.properties create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/DsfUIPlugin.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/DataViewModelSchemaNode.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/GetDataDoneWithRequestMonitor.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/IViewModelContext.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/IViewModelSchemaNode.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/ViewModelDelta.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/ViewModelProvider.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/package.html diff --git a/plugins/org.eclipse.dd.dsf.ui/.classpath b/plugins/org.eclipse.dd.dsf.ui/.classpath new file mode 100644 index 00000000000..751c8f2e504 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/plugins/org.eclipse.dd.dsf.ui/.project b/plugins/org.eclipse.dd.dsf.ui/.project new file mode 100644 index 00000000000..2ae0cefded6 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/.project @@ -0,0 +1,28 @@ + + + org.eclipse.dd.dsf.ui + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/plugins/org.eclipse.dd.dsf.ui/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.dd.dsf.ui/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000000..5e43d7eeaec --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,12 @@ +#Thu Jul 27 15:22:36 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 diff --git a/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..c9cd81ee3cf --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF @@ -0,0 +1,13 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Ui Plug-in +Bundle-SymbolicName: org.eclipse.dd.dsf.ui +Bundle-Version: 1.0.0 +Bundle-Activator: org.eclipse.dd.dsf.ui.DsfUIPlugin +Bundle-Localization: plugin +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.dd.dsf, + org.eclipse.debug.ui +Eclipse-LazyStart: true +Export-Package: org.eclipse.dd.dsf.ui.model diff --git a/plugins/org.eclipse.dd.dsf.ui/build.properties b/plugins/org.eclipse.dd.dsf.ui/build.properties new file mode 100644 index 00000000000..34d2e4d2dad --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/DsfUIPlugin.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/DsfUIPlugin.java new file mode 100644 index 00000000000..9b2c7cb05b7 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/DsfUIPlugin.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * 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; + +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class DsfUIPlugin extends AbstractUIPlugin { + + // The plug-in ID + public static final String PLUGIN_ID = "org.eclipse.dd.dsf.ui"; + + // The shared instance + private static DsfUIPlugin fgPlugin; + + private static BundleContext fgBundleContext; + + /** + * The constructor + */ + public DsfUIPlugin() { + fgPlugin = this; + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext context) throws Exception { + fgBundleContext = context; + super.start(context); + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#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 DsfUIPlugin getDefault() { + return fgPlugin; + } + + public static BundleContext getBundleContext() { + return fgBundleContext; + } + +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/DataViewModelSchemaNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/DataViewModelSchemaNode.java new file mode 100644 index 00000000000..94fced13b5a --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/DataViewModelSchemaNode.java @@ -0,0 +1,231 @@ +/******************************************************************************* + * 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.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. + */ + public class DataVMC implements IViewModelContext { + IViewModelContext fParent; + 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() + "\n" + 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 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 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); + }}; + + // TODO: 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( + (IViewModelContext)parent.getElement(), + new GetDataDone() { 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 findDMContext(IViewModelContext vmc, Class 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() { + // FIXME: should track when disposed and avoid issuing model deltas + fServices.dispose(); + for (IViewModelSchemaNode childNode : getChildNodes()) { + childNode.sessionDispose(); + } + } +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/GetDataDoneWithRequestMonitor.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/GetDataDoneWithRequestMonitor.java new file mode 100644 index 00000000000..50cf3712582 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/GetDataDoneWithRequestMonitor.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * 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.GetDataDone; +import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousRequestMonitor; + +/** + * Convenience extension to GetDataDone, which handles notifying the + * IAsynchronousRequestMonitor when the done is executed. + * @param Class type of data. + */ +@SuppressWarnings("restriction") +public abstract class GetDataDoneWithRequestMonitor extends GetDataDone { + /** Monitor to be posted when this done is executed. */ + private IAsynchronousRequestMonitor fMonitor; + + /** Constructor requires the monitor */ + public GetDataDoneWithRequestMonitor(IAsynchronousRequestMonitor monitor) { + fMonitor = monitor; + } + + /** + * Run method checks the request monitor for cancellation and checks this + * done's status before calling doRun(). Finally it takes care of + * notifying the request montior that request is finished. + */ + public final void run() { + if (fMonitor.isCanceled()) return; + if (!getStatus().isOK()) { + fMonitor.setStatus(getStatus()); + } else { + doRun(); + } + fMonitor.done(); + } + + /** + * Method to perform the actual work. It should not call monitor.done(), + * because it will be called by this class in run(). + */ + protected abstract void doRun(); +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/IViewModelContext.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/IViewModelContext.java new file mode 100644 index 00000000000..02dbf460d6d --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/IViewModelContext.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * 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.IAdaptable; + +/** + * View model element which is stored as the data object of nodes in the viewer. + */ +public interface IViewModelContext extends IAdaptable { + + /** + * Returns the schema node that originated this element. + */ + public IViewModelSchemaNode getSchemaNode(); + + /** + * Returns the parent of this element in the viewer layout. + * @return + */ + public IViewModelContext getParent(); +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/IViewModelSchemaNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/IViewModelSchemaNode.java new file mode 100644 index 00000000000..37beb9413ce --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/IViewModelSchemaNode.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * 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.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. + *

    + * Besides the standard data model context (DMC) 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 + */ +@SuppressWarnings("restriction") +public interface IViewModelSchemaNode { + + /** + * Retrieves information whether for the given parent node, there are any elements + * available. + * @param parentVmc Parent node, for which to calculate elements at the + * current level. + * @param done The data return token. + */ + public void hasElements(IViewModelContext parentVmc, GetDataDone done); + + /** + * Retrieves the list of elements. + * @param parentVmc Parent node, for which to calculate elements at the + * current level. + * @param done The data return token. + */ + public void getElements(final IViewModelContext parentVmc, GetDataDone 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, final ILabelRequestMonitor result); + + /** + * Returns the list of child schema nodes which are configured for this node. + */ + public IViewModelSchemaNode[] getChildNodes(); + + /** + * 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. + * @return True if this node (or its children) would generate delta data + * due to this event. + * @see IModelDelta + */ + public boolean hasDeltaFlags(IDataModelEvent e); + + /** + * Builds model delta information based on the given event. + * @param e Data model 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); + + /** + * Disposes the resources held by this node. + */ + public void sessionDispose(); +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/ViewModelDelta.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/ViewModelDelta.java new file mode 100644 index 00000000000..d1802b98d00 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/ViewModelDelta.java @@ -0,0 +1,259 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Wind River Systems - adapted to use in DSF + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.model; + +import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.provisional.ModelDelta; + +/** + * This delta class mostly just duplicates the ModelDelta implemention, but + * it allows clients to modify the flags after the original object is + * constructed. + *

    + * TODO: This class derives from ModelDelta as opposed to just implementing IModelDelta + * because of a reference in IModelDelta to ModelDelta. Need to file a bug on it. + * @see IModelDelta#getNodes() + */ +@SuppressWarnings("restriction") +public class ViewModelDelta extends ModelDelta { + + private ViewModelDelta fParent; + private IViewModelContext fVmcElement; + private Object fElement; + private int fFlags; + private ViewModelDelta[] fNodes = EMPTY_NODES; + private Object fReplacement; + private int fIndex; + private static final ViewModelDelta[] EMPTY_NODES = new ViewModelDelta[0]; + + /** + * Constructs a new delta for the given element. + * + * @param vmcElement model element + * @param flags change flags + */ + public ViewModelDelta(IViewModelContext vmcElement, int flags) { + super(vmcElement, flags); + fVmcElement = vmcElement; + fFlags = flags; + } + + /** + * Constructs a new delta for the given element to be replaced + * with the specified replacement element. + * + * @param vmcElement model element + * @param replacement replacement element + * @param flags change flags + */ + public ViewModelDelta(IViewModelContext vmcElement, Object replacement, int flags) { + super(vmcElement, replacement, flags); + fVmcElement = vmcElement; + fReplacement = replacement; + fFlags = flags; + } + + /** + * Constructs a new delta for the given element to be inserted at + * the specified index. + * + * @param vmcElement model element + * @param index insertion position + * @param flags change flags + */ + public ViewModelDelta(IViewModelContext vmcElement, int index, int flags) { + super(vmcElement, index, flags); + fVmcElement = vmcElement; + fIndex = index; + fFlags = flags; + } + + /** + * Constructor for model delta based on non-VMC element. This delta is + * only needed for creating delta nodes for parent elements in the tree + * if the VMC elements are not at the root of the tree. + * @param element Element to create the delta for. + */ + public ViewModelDelta(Object element) { + super(element, IModelDelta.NO_CHANGE); + fElement = element; + } + + + /** + * Returns the non-VMC element if one is set, otherwise returns the VMC + * element of this delta node. + * @see org.eclipse.debug.internal.ui.viewers.IModelDelta#getElement() + */ + public Object getElement() { + return fElement != null ? fElement : fVmcElement; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.IModelDelta#getFlags() + */ + public int getFlags() { + return fFlags; + } + + public void addFlags(int flags) { + fFlags |= flags; + } + + + public IViewModelContext getVMC() { return fVmcElement; } + + /** + * Adds a child node to this delta with the given element and change flags, + * and returns the child delta. + * + * @param element child element to add + * @param flags change flags for child + * @return newly created child delta + */ + public ViewModelDelta addNode(IViewModelContext element, int flags) { + ViewModelDelta node = new ViewModelDelta(element, flags); + node.setParent(this); + addDelta(node); + return node; + } + + /** + * Adds a child node to this delta to replace the given element with the + * specified replacement element and change flags, and returns the + * newly created child delta. + * + * @param element child element to add to this delta + * @param replacement replacement element for the child element + * @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); + node.setParent(this); + addDelta(node); + return node; + } + + /** + * Adds a child delta to this delta to insert the specified element at + * the given index, and returns the newly created child delta. + * + * @param element child element in insert + * @param index index of insertion + * @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); + node.setParent(this); + addDelta(node); + return node; + } + + /** + * Sets the parent delta of this delta + * + * @param node parent delta + */ + void setParent(ViewModelDelta node) { + fParent = node; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.IModelDelta#getParent() + */ + public IModelDelta getParent() { + return fParent; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.IModelDelta#getReplacementElement() + */ + public Object getReplacementElement() { + return fReplacement; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.IModelDelta#getIndex() + */ + public int getIndex() { + return fIndex; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.IModelDelta#getNodes() + */ + public ViewModelDelta[] getNodes() { + return fNodes; + } + + private void addDelta(ViewModelDelta delta) { + if (fNodes.length == 0) { + fNodes = new ViewModelDelta[]{delta}; + } else { + ViewModelDelta[] nodes = new ViewModelDelta[fNodes.length + 1]; + System.arraycopy(fNodes, 0, nodes, 0, fNodes.length); + nodes[fNodes.length] = delta; + fNodes = nodes; + } + } + + public String toString() { + StringBuffer buf = new StringBuffer(); + buf.append("Model Delta Start\n"); //$NON-NLS-1$ + appendDetail(buf, this); + buf.append("Model Delta End\n"); //$NON-NLS-1$ + return buf.toString(); + } + + private void appendDetail(StringBuffer buf, ViewModelDelta delta) { + buf.append("\tElement: "); //$NON-NLS-1$ + buf.append(delta.getElement()); + buf.append('\n'); + buf.append("\t\tFlags: "); //$NON-NLS-1$ + int flags = delta.getFlags(); + if (flags == 0) { + buf.append("NO_CHANGE"); //$NON-NLS-1$ + } else { + if ((flags & IModelDelta.ADDED) > 0) { + buf.append("ADDED | "); //$NON-NLS-1$ + } + if ((flags & IModelDelta.CONTENT) > 0) { + buf.append("CONTENT | "); //$NON-NLS-1$ + } + if ((flags & IModelDelta.EXPAND) > 0) { + buf.append("EXPAND | "); //$NON-NLS-1$ + } + if ((flags & IModelDelta.INSERTED) > 0) { + buf.append("INSERTED | "); //$NON-NLS-1$ + } + if ((flags & IModelDelta.REMOVED) > 0) { + buf.append("REMOVED | "); //$NON-NLS-1$ + } + if ((flags & IModelDelta.REPLACED) > 0) { + buf.append("REPLACED | "); //$NON-NLS-1$ + } + if ((flags & IModelDelta.SELECT) > 0) { + buf.append("SELECT | "); //$NON-NLS-1$ + } + if ((flags & IModelDelta.STATE) > 0) { + buf.append("STATE | "); //$NON-NLS-1$ + } + } + buf.append('\n'); + ViewModelDelta[] nodes = delta.getNodes(); + for (int i = 0; i < nodes.length; i++) { + appendDetail(buf, nodes[i]); + } + } +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/ViewModelProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/ViewModelProvider.java new file mode 100644 index 00000000000..40473f2b181 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/ViewModelProvider.java @@ -0,0 +1,256 @@ +/******************************************************************************* + * 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.Done; +import org.eclipse.dd.dsf.concurrent.DoneTracker; +import org.eclipse.dd.dsf.concurrent.GetDataDone; +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. + *

    + * 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 + */ +@SuppressWarnings("restriction") +public class ViewModelProvider extends AbstractModelProxy +{ + private 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(); + } + } + + /** + * 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) { + 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)hasElementsDone).getData().booleanValue(); + } + monitor.setIsContainer(isContainer); + monitor.done(); + }}; + for (IViewModelSchemaNode childNode : childSchemaNodes) { + childNode.hasElements( + vmc, + doneTracker.add( new GetDataDone() { 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) { + 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() { public void run() { + 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; } + }; + + public void installed() { + fProxyActive++; + } + + public void dipose() { + 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(); + } +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/package.html b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/package.html new file mode 100644 index 00000000000..166d66ee39c --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/package.html @@ -0,0 +1,32 @@ + + + + + Eclipse Device Debug - Debugger Services Framework - View Model + + +Provides a set of  utilities and interfaces for defining the +conent and layout of views based on Debugger Services Framework (DSF).
    +
    +

    Package Specification

    +

    The DSF data model is designed in a way to make it easy to achieve +modularity in the services that collectively make-up its +contents.  This design goal makes it difficult to display the data +in a view, because its layout of the data needs to depend on the type +of view.  This package is used to make it simpler to take the +contents of a data model and display them in various debug views, using +the platform debug flexible-hierarchy asynchronous debug +views.  
    +

    +

    Development Plans

    +This package is also a work in progress and it is missing a major +feature.  +This feature is to be able to create a complete view schema using a +simple data specification (XML or other format).  Still further, a +feature to build on this, should allow users to modify the view schema +using GUI tools and to apply the modified layout at runtime.
    +


    +

    + + From 83096c458bc7224acfe47777199e0a6c59907d54 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 28 Jul 2006 23:11:55 +0000 Subject: [PATCH 003/834] Initial checkin. --- .../org/eclipse/dd/dsf/debug/IAddress.java | 9 ++ .../eclipse/dd/dsf/debug/IBackEndProcess.java | 37 +++++ .../eclipse/dd/dsf/debug/IBreakpoints.java | 65 ++++++++ .../eclipse/dd/dsf/debug/IExpressions.java | 82 ++++++++++ .../src/org/eclipse/dd/dsf/debug/IMemory.java | 45 ++++++ .../org/eclipse/dd/dsf/debug/IModules.java | 141 ++++++++++++++++++ .../dd/dsf/debug/INativeProcesses.java | 71 +++++++++ .../src/org/eclipse/dd/dsf/debug/IOS.java | 93 ++++++++++++ .../org/eclipse/dd/dsf/debug/IRegisters.java | 104 +++++++++++++ .../org/eclipse/dd/dsf/debug/IRunControl.java | 87 +++++++++++ .../eclipse/dd/dsf/debug/ISourceLookup.java | 48 ++++++ .../src/org/eclipse/dd/dsf/debug/IStack.java | 62 ++++++++ .../dd/dsf/debug/IStepQueueManager.java | 43 ++++++ .../org/eclipse/dd/dsf/debug/ISymbols.java | 46 ++++++ .../org/eclipse/dd/dsf/debug/ITargets.java | 42 ++++++ 15 files changed, 975 insertions(+) create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IAddress.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IBackEndProcess.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IBreakpoints.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IExpressions.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IMemory.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IModules.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/INativeProcesses.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IOS.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IRegisters.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IRunControl.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ISourceLookup.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStack.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStepQueueManager.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ISymbols.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ITargets.java diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IAddress.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IAddress.java new file mode 100644 index 00000000000..4175ec51a21 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IAddress.java @@ -0,0 +1,9 @@ +package org.eclipse.dd.dsf.debug; + +/** + * I was told that BigInteger was not sufficient to represent an address, so + * I created this interface as a place holder for representing an address. + */ +public interface IAddress { + +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IBackEndProcess.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IBackEndProcess.java new file mode 100644 index 00000000000..49fcf560b4e --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IBackEndProcess.java @@ -0,0 +1,37 @@ +package org.eclipse.dd.dsf.debug; + +import org.eclipse.dd.dsf.service.IDsfService; + + +/** + * Service representing an external process that is part of the debugger back + * end implementation. Having this service allows UI and other clients + * access to the java.lang.Process object for monitoring. E.g. for displaying + * in Debug view and channeling I/O to the console view. + */ +public interface IBackEndProcess extends IDsfService { + /** + * Optional property identifying the process among other services. + * Since there could be multiple instances of this service running at the + * same time, a service property is needed to allow clients to distinguish + * between them. + */ + static final String PROCESS_ID = "org.eclipse.dsdp.riverbed.debug.BackendProcess.PROCESS_ID"; + + /** + * Event indicating that the back end process has terminated. + */ + public interface ExitedEvent {} + + /** + * Returns the instance of the java process object representing the back + * end process. + * @return + */ + Process getProcess(); + + /** + * Returns true if back-end process has exited. + */ + boolean isExited(); +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IBreakpoints.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IBreakpoints.java new file mode 100644 index 00000000000..01ee465b7ab --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IBreakpoints.java @@ -0,0 +1,65 @@ +package org.eclipse.dd.dsf.debug; + +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.debug.core.model.IBreakpoint; + +/** + * Breakpoint service provides access to information about breakpoints that + * are planted on a target. It's the reposnsibility of the debugger + * implementation to retrieve static breakpoint data from platform APIs and to + * install them on the target. + */ +public interface IBreakpoints extends IDataModelService { + /** + * Data Model Context for a breakpoint objects. Breakpoints service only + * with respect to running processes/threads, therefore the breakpoint + * context will always have an IExecutionDMC as one of its ancestors. + */ + public interface IBreakpointDMC extends IDataModelContext {} + + /** Indicates that the state of given breakpoint has changed. */ + public interface BreakpointChangedEvent extends IDataModelEvent {} + + /** Indicates that given breakpoint was hit, by the given execution context. */ + public interface BreakpointHitEvent extends BreakpointChangedEvent { + IRunControl.IExecutionDMC getExecutionDMC(); + } + + /** Common breakpoint state data. */ + public interface BreakpointData extends IDataModelData { + /** Installed status values of a breakpoint. */ + public enum Status { FILTERED_OUT, INSTALLED, FAILED_TO_INSTALL, PENDING_INSTALL, PENDING_UNINSTALL } + + /** Returns the corresponding platform debug model breakpoint object. */ + IBreakpoint getBreakpoint(); + + /** Returns current installed status of this breakpoint */ + Status getStatus(); + + /** + * Returns error message (if any) with respect to current status of + * the breakpoint. + */ + String getErrorMessage(); + + /** + * Returns a warning message (if any) with respect to current status of + * the breakpoint. + */ + String getWarningMessage(); + } + + /** + * Retrieves all breakpoints for given execution context. + */ + void getBreakpoints(IRunControl.IExecutionDMC execCtx, GetDataDone done); + + /** + * Retrieves all breakpoints for given platform breakpoint object. + */ + void getBreakpoints(IBreakpoint bp, GetDataDone done); +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IExpressions.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IExpressions.java new file mode 100644 index 00000000000..228912b498c --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IExpressions.java @@ -0,0 +1,82 @@ +package org.eclipse.dd.dsf.debug; + +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; + +/** + * Expressions service provides access to the debugger's expression evaluator. + * This service has dependencies on the Modules service, RunControl service, and + * Stack service, as all may be used to provide context for an expression to be + * evaluated. + */ +public interface IExpressions extends IDataModelService { + + /** + * 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 { + String getExpression(); + } + + /** + * Expression data. It is based pretty closely on what DFW's info-retrieve + * node for expressions. + */ + public interface IExpressionData extends IDataModelData { + String getName(); + public enum BasicType { basic, pointer, array, composite, enumeration, function } + BasicType getBasicType(); + String getTypeName(); + String getEncoding(); + String getTypeId(); + int getBitCount(); + String getNaturalValue(); + String getHexValue(); + String getOctalValue(); + String getBinaryValue(); + String getStringValue(); + IAddress getAddress(); + IRegisters.RegisterDMC getRegister(); + Map getEnumerations(); + } + + /** + * Event indicating that a given expression is changed. If an expression + * is changed, it's implied that all the children of that expression are + * changed too. + */ + public interface IExpressionChangedEvent extends IDataModelEvent {} + + /** + * Returns the context for the specified expression. + * @param symCtx Symbol context in which to evaluate the expression. This parameter is required and cannot be null. + * @param execCtx Optional execution context for the evaluation. Can be null. + * @param frameCtx Optional stack frame context for the evaluation. Can be null. + * @param expression Expression to evaluate. + * @return Expression context. + */ + IExpressionDMC getExpressionContext(IModules.ISymbolDMC symCtx, IRunControl.IExecutionDMC execCtx, IStack.IFrameDMC frameCtx, String expression); + + /** + * Retrieves the sub-expressions of the given expression. + * @param exprCtx Expression context to evaluate. + * @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> done); + + /** + * For object oriented languages, this method returns the expressions + * representing base types of the given expression type. + * @param exprContext + * @param done + */ + void getBaseExpressions(IExpressionDMC exprContext, GetDataDone done); +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IMemory.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IMemory.java new file mode 100644 index 00000000000..eff0c6f1b14 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IMemory.java @@ -0,0 +1,45 @@ +package org.eclipse.dd.dsf.debug; + +import org.eclipse.dd.dsf.concurrent.Done; +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. + */ +public interface IMemory extends IDsfService { + + /** + * A context for memory is still needed, for debuggers that can debug + * multiple processes/targets at the same time. + */ + public interface IMemoryContext {} + + /** + * I was told that BigInteger is also too restrictive to represent an + * address, but I'm not really sure what is appropriate for this interface. + */ + public interface IAddress { + /** Returns the memory context that this address belongs to. */ + public IMemoryContext getContext(); + } + + /** Writes the given value to the given memory location. */ + public void setMemory(IMemoryContext memCtx, IAddress addr, + int word_size, byte[] buf, int offs, int size, int mode, Done done); + + /** Reads memory at the given location */ + public void getMemory(IMemoryContext memCtx, IAddress addr, + int word_size, byte[] buf, int offs, int size, int mode, Done done); + + /** + * Fill target memory with given pattern. + * 'size' is number of bytes to fill. + * Parameter 0 of sequent 'done' is assigned with Throwable if + * there was an error. + */ + public void fillMemory(IMemoryContext memCtx, IAddress addr, + int word_size, byte[] value, int size, int mode, Done done); + +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IModules.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IModules.java new file mode 100644 index 00000000000..737ff7a54eb --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IModules.java @@ -0,0 +1,141 @@ +package org.eclipse.dd.dsf.debug; + +import java.math.BigInteger; + +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; + +/** + * Debugger service representing module handling logic of a debugger. + *
    + * TODO: I meant this as a replacement for Application service as well as the + * registry API in Riverbed 1. But I still don't fully understand the format + * of the symbol data that is stored in the registry, so that needs to be added + * to this interface. + */ +public interface IModules extends IDataModelService { + + /** + * Symbol context represents the space into which module symbols are loaded. + * Traditionally symbols are loaded in context of a process, but for other + * 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 {} + + /** + * Module context represents a single module that is loaded. + */ + public interface IModuleDMC extends IDataModelContext {} + + /** + * Event indicating a change in the symbol information for given context. + */ + public interface ModulesChangedEvent extends IDataModelEvent {} + + /** + * Specific event identifying that a new module was loaded into a + * symbol context. + */ + public interface ModuleLoadedEvent extends ModulesChangedEvent { + /** Returns context of the module that was loaded */ + IModuleDMC getLoadedModuleContext(); + } + + public interface ModuleUnloadedEvent extends ModulesChangedEvent { + /** Returns context of the module that was un-loaded */ + IModuleDMC getUnloadedModuleContext(); + } + + /** + * Object representing a unuqie location in a symbol context, based on + * a module, section, and address offset within the seciton. + */ + public final class ModuleSectionOffset { + private final IModuleDMC fModule; + private final Section fSection; + private final BigInteger fOffset; + + public IModuleDMC getModule() { return fModule; } + public Section getSection() { return fSection; } + public BigInteger getOffset() { return fOffset; } + + public ModuleSectionOffset(IModuleDMC module, Section section, BigInteger offset) { + this.fModule = module; + this.fSection = section; + this.fOffset = offset; + } + + public int hashCode() { + return fModule.hashCode() + fSection.hashCode() + fOffset.intValue(); + } + + public boolean equals(Object o) { + if (!(o instanceof ModuleSectionOffset)) return false; + ModuleSectionOffset mso = (ModuleSectionOffset)o; + return fModule.equals(mso.fModule) && fSection.equals(mso.fSection) && fOffset.equals(mso.fOffset); + } + } + + /** + * Symbol context data includes a mapping between run-time addresses and + * module-section-offset coordinates. + */ + public interface SymbolData extends IDataModelData { + /** Convert link-time address 'addr' to run-time address */ + public long convertToRT(ModuleSectionOffset mso); + + /** Convert run-time address 'addr' to link-time address */ + public ModuleSectionOffset convertFromRT(IAddress addr); + } + + /** Module information. */ + public interface ModuleData extends IDataModelData { + String getName(); + String getFile(); + long getTimeStamp(); + Section[] getSections(); + } + + /** Section information */ + public interface Section { + String getName(); + IAddress getStartAddress(); + BigInteger getCount(); + } + + /** Line information about a particular address */ + public interface LineInfo { + IAddress getAddress(); + String getSourceFile(); + int getStartLine(); + int getStartColumn(); + int getEndLine(); + int getEndColumn(); + } + + /** Address information about a particular file/line */ + public interface AddressRange { + IAddress getStartAddress(); + IAddress getEndAddress(); + } + + /** + * Retreives the list of modules loaded in given symbol context. + */ + void getModules(ISymbolDMC symCtx, GetDataDone done); + + /** + * Calculates the line numbers corresponding to the given address. + */ + void calcLineInfo(ISymbolDMC symCtx, IAddress address, GetDataDone done); + + /** + * Calculates the addresses corresponding to the given source file location. + */ + void calcAddressInfo(ISymbolDMC symCtx, String file, int line, int col, GetDataDone done); + +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/INativeProcesses.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/INativeProcesses.java new file mode 100644 index 00000000000..54081096a7b --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/INativeProcesses.java @@ -0,0 +1,71 @@ +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 interface provides access to the native OS's process + * information, manipulation methods, and debugging methods. + * This service provides a relatively simple interface for + * manipulating processes as compared with a full-blown + * remote target debugger. + */ +public interface INativeProcesses extends IDataModelService { + + public interface IThreadDMC extends IDataModelContext {} + public interface IProcessDMC extends IThreadDMC {} + + /** + * 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 { + String getName(); + String getId(); + boolean isDebuggerAttached(); + IRunControl.IExecutionDMC getExecutionContext(); + IMemory.IMemoryContext getMemoryContext(); + IModules.ISymbolDMC getSymbolContext(); + } + + /** + * Event indicating that process data has changed. + */ + public interface ProcessChangedEvent extends IDataModelEvent {} + + /** + * Retrieves the current list of processes running on target. + */ + void getRunningProcesses(GetDataDone done); + + /** + * Attaches debugger to the given process. + */ + void attachDebuggerToProcess(IProcessDMC 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 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 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); +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IOS.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IOS.java new file mode 100644 index 00000000000..21c153ab2d7 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IOS.java @@ -0,0 +1,93 @@ +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.IDataModelService; + +/** + * Provides generic access to operating system objects and methods to + * manipulate those objects. This is a much more extensive interface than + * the NativeProcesses service but for simple debugging, it serves the same + * purpose: to list/create/terminate processes and attach debugger to them. + *

    + * TODO: need methods for performing actions on objects (create, terminate, + * etc). + * @see INativeProcesses + */ +public interface IOS extends IDataModelService { + + /** + * Context object for the whole OS, for debuggers that support + * debugging multiple targets/cores simultaneously. + */ + public interface IOSDMC extends IDataModelContext {} + + /** + * Data object describing OS info + */ + public interface IOSData extends IDataModelData { + String getName(); + String getDescription(); + String getVersion(); + } + + /** + * Context for a OS object type, such as process, kernel task, semaphore, etc. + */ + public interface IObjectTypeDMC extends IDataModelContext {} + + /** + * Description data for a OS object type. + */ + public interface IObjectTypeData extends IDataModelData { + String getName(); + String getDescription(); + String getSingularName(); + String getPluralName(); + boolean hasExecutionContext(); + boolean hasModulesContext(); + boolean hasMemoryContext(); + } + + /** + * OS object context. + */ + public interface IObjectDMC extends IDataModelContext {} + + /** + * Description data for an OS object. + */ + public interface IObjectData extends IDataModelData { + String getName(); + String getID(); + boolean canAttachDebugger(); + boolean isDebuggerAttached(); + IRunControl.IExecutionDMC getExecutionDMC(); + IModules.ISymbolDMC getSymbolDMC(); + IMemory.IMemoryContext getMemoryContext(); + } + + /** + * Retrieves list of OS object types. + * @param os OS context. + * @param parent Optional parent type. + * @param done Return token. + */ + public void getObjectTypes(IOSDMC os, IObjectTypeDMC parent, GetDataDone done); + + /** + * Retrieves list of OS objects for given type. + * @param os OS context. + * @param type The object type. + * @param parent Optional parent of the requested objects. + * @param done Return token. + */ + public void getObjects(IOSDMC os, IObjectTypeDMC type, IObjectDMC parent, GetDataDone done); + + /** + * Attaches the debugger to given OS object context. + */ + public void attachDebuggerToObject(IObjectDMC objectDmc, Done done); +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IRegisters.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IRegisters.java new file mode 100644 index 00000000000..ab41ad41ecc --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IRegisters.java @@ -0,0 +1,104 @@ +package org.eclipse.dd.dsf.debug; + +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; + +/** + * Service for accessing register data. + */ +public interface IRegisters extends IDataModelService { + + /** Register group context */ + public interface RegisterGroupDMC extends IDataModelContext {} + + /** + * Register groups only have a name. Sub groups and registered are retrieved + * through the service interface. + */ + public interface RegisterGroupData extends IDataModelData { + public String getName(); + } + + /** Register context */ + public interface RegisterDMC extends IDataModelContext {} + + /** Event indicating register value changed. */ + public interface RegisterChangedEvent extends IDataModelEvent {} + + /** Register information */ + public interface RegisterData extends IDataModelData, NumericalValue { + String getName(); + String getDescription(); + boolean isReadable(); + boolean isReadOnce(); + boolean isWriteable(); + boolean isWriteOnce(); + boolean hasSideEffects(); + boolean isVolatile(); + boolean isFloat(); + } + + /** Bit field context */ + public interface BitFieldDMC extends IDataModelContext {} + + /** + * Bitfield data, big groups and mnemonics are retrieved at the same + * time as rest of bit field data + */ + public interface BitFieldData extends IDataModelData, NumericalValue { + String getName(); + String getDescription(); + boolean isReadable(); + boolean isReadOnce(); + boolean isWriteable(); + boolean isWriteOnce(); + boolean hasSideEffects(); + boolean isZeroBasedNumbering(); + boolean isZeroBitLeftMost(); + BitGroup[] getBitGroup(); + Mnemonic[] getMnemonics(); + } + + /** Bit group definition */ + public interface BitGroup { + int startBit(); + int bitCount(); + } + + /** Bit field mnemonic */ + public interface Mnemonic extends NumericalValue { + String getShortName(); + String getLongName(); + } + + /** + * Common interface for describing a number value for various register + * data objects + */ + public interface NumericalValue { + String getNaturalValue(); + String getHexValue(); + String getOctalValue(); + String getBinaryValue(); + } + + /** + * Retrieves the list of register groups. + * @param execCtx Execution DMC, this is required. + * @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 done); + + /** Retrieves list of sub-groups of given register group. */ + void getRegisterSubGroups(RegisterGroupDMC groupCtx, GetDataDone done); + + /** Retrieves registers in given register group. */ + void getRegisters(RegisterGroupDMC groupCtx, GetDataDone done); + + /** Retrieves bit fields for given register */ + void getBitFields(RegisterDMC regCtx, GetDataDone done); +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IRunControl.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IRunControl.java new file mode 100644 index 00000000000..e68ed472007 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IRunControl.java @@ -0,0 +1,87 @@ +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 interface provides access to controlling and monitoring the execution + * state of a process being debugged. This interface does not actually + * provide methods for creating or destroying execution contexts, it doesn't + * even have methods for getting labels. That's because it is expected that + * higher level services, ones that deal with processes, kernels, or target + * features will provide that functionality. + */ +public interface IRunControl extends IDataModelService +{ + + /** + * 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 {} + + /** + * 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 {} + + /** Flag indicating reason context state change. */ + public enum StateChangeReason { USER_REQUEST, STEP, BREAKPOINT, EXCEPTION, CONTAINER }; + + /** + * Events signaling a state changes. + */ + public interface SuspendedEvent extends IDataModelEvent { + StateChangeReason getReason(); + } + public interface ResumedEvent extends IDataModelEvent { + StateChangeReason getReason(); + } + public interface ContainerSuspendedEvent extends IDataModelEvent { + StateChangeReason getReason(); + } + public interface ContainerResumedEvent extends IDataModelEvent { + StateChangeReason getReason(); + } + public interface IStartedEvent extends IDataModelEvent { + IExecutionDMC getExecutionContext(); + } + public interface IExitedEvent extends IDataModelEvent { + IExecutionDMC getExecutionContext(); + } + + /** + * Display information for an execution context. + */ + public interface IExecutionData extends IDataModelData { + boolean isSuspended(); + StateChangeReason getStateChangeReason(); + } + + /** + * Returns execution contexts belonging to the given container context. + */ + public void getExecutionContexts(IContainerDMC c, GetDataDone 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); + public enum StepType { STEP_OVER, STEP_INTO, STEP_RETURN }; + boolean isStepping(IExecutionDMC context); + void canStep(IExecutionDMC context); + void step(IExecutionDMC context, StepType stepType, Done done); + void instructionStep(IExecutionDMC context, StepType stepType, Done done); +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ISourceLookup.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ISourceLookup.java new file mode 100644 index 00000000000..8e37f7b4767 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ISourceLookup.java @@ -0,0 +1,48 @@ +package org.eclipse.dd.dsf.debug; + +import org.eclipse.dd.dsf.concurrent.GetDataDone; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.debug.core.sourcelookup.ISourceContainer; + +/** + * Service for mapping debugger paths to host paths. This service is needed + * primarily by other services that need to access source-path mappings, such + * as the breakpoints service. For UI components, the platform source lookup + * interfaces could be sufficient. + */ +public interface ISourceLookup extends IDsfService { + + /** + * Context needed for debuggers that debug multiple processes. + */ + public interface ISourceLookupContext {} + + public interface ISourceLookupResult { + Object getSourceObject(); + ISourceContainer getMatchingContainer(); + } + + public interface IDebuggerPathLookupResult { + String getDebuggerPath(); + ISourceContainer getMatchingContainer(); + } + + /** Returns the source lookup context for the given modules context. */ + ISourceLookupContext getContextForSymbolContext(IModules.ISymbolDMC symCtx); + + /** + * Initializes the given context with the given list of source lookup + * containers. + */ + void initializeSourceContainers(ISourceLookupContext ctx, ISourceContainer[] containers); + + /** + * Retrieves the host source object for given debugger path string. + */ + void getSource(ISourceLookupContext srcCtx, String debuggerPath, boolean searchDuplicates, GetDataDone done); + + /** + * Retrieves the debugger path string(s) for given host source object. + */ + void getDebuggerPath(ISourceLookupContext srcCtx, Object source, boolean searchDuplicates, GetDataDone done); +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStack.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStack.java new file mode 100644 index 00000000000..34c0d56ecee --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStack.java @@ -0,0 +1,62 @@ +package org.eclipse.dd.dsf.debug; + +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; + +/** + * Stack service provides access to stack information for a + * given execution context. + */ +public interface IStack extends IDataModelService { + + /** + * 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 {} + + /** + * Stack frame information. + */ + public interface IFrameData extends IDataModelData { + IAddress getAddress(); + String getFile(); + int getLine(); + int getColumn(); + } + + /** + * Variable context. This context only provides access to limited + * expression information. For displaying complete information, + * Expressions service should be used. + */ + public interface IVariableDMC extends IDataModelContext {} + + /** + * Stack frame variable information. + */ + public interface VariableData extends IDataModelData { + String getName(); + String getTypeName(); + String getValue(); + } + + /** + * 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 done); + + /** + * Retrieves variables which were arguments to the stack frame's function. + */ + void getArguments(IFrameDMC frameCtx, GetDataDone done); + + /** + * Retrieves variables local to the stack frame. + */ + void getLocals(IFrameDMC frameCtx, GetDataDone done); +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStepQueueManager.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStepQueueManager.java new file mode 100644 index 00000000000..5c5f04e4ddf --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStepQueueManager.java @@ -0,0 +1,43 @@ +package org.eclipse.dd.dsf.debug; + +import org.eclipse.dd.dsf.service.IDsfService; + +/** + * This service builds on top of standard run control service to provide + * step queuing functionality. Step queuing essentially allows user to press + * and hold the step key and achieve maximum stepping speed. If this service + * is used, other service implementations, such as stack and expressions, can + * use it to avoid requesting data from debugger back end if another step is + * about to be executed. + */ +public interface IStepQueueManager extends IDsfService { + + void setStepQueueDepth(int depth); + int getStepQueueDepth(); + + /** + * Returns the number of step commands that are queued for given execution + * context. + */ + int getPendingStepCount(IRunControl.IExecutionDMC execCtx); + + /** + * Checks whether a step command can be queued up for given context. + */ + void canEnqueueStep(IRunControl.IExecutionDMC 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); + + /** + * Adds an instruction 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 enqueueInstructionStep(IRunControl.IExecutionDMC execCtx, IRunControl.StepType stepType); +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ISymbols.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ISymbols.java new file mode 100644 index 00000000000..c3863dd259a --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ISymbols.java @@ -0,0 +1,46 @@ +package org.eclipse.dd.dsf.debug; + +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; + +/** + * Service for accessing debugger symbols. This service builds on the Modules + * service, but not all debuggers provide access for parsing symbols so this + * service is separated. + * @see IModules + */ +public interface ISymbols extends IDataModelService { + public interface SymbolObjectDMC extends IDataModelContext {} + + /** + * Data about a debug symbol. + */ + public interface SymbolObjectData extends IDataModelData { + String getName(); + String getTypeName(); + String getFilepath(); + } + + /** + * Indicates that the list of symbol objects is changed. Parsing debug + * symbols can be a long running operation (order of 10's of seconds or + * minues), so it is useful for the service to provide access to the data + * even while it's still parsing. This event may be issued periodically + * by the service to indicate that a section of debug symbols has been + * parsed. + * TODO: This is not an IModelEvent because the context of this event is + * the whole service. This needs to be fixed. + */ + public interface SymbolDataChanged extends IDataModelEvent {} + + /** + * Retrieves the list of symbols. + * @param symCtx Symbols context to retrieve symbols for. + * @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> done); +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ITargets.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ITargets.java new file mode 100644 index 00000000000..a90c2f68fbc --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ITargets.java @@ -0,0 +1,42 @@ +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 {} + + public interface ITargetData extends IDataModelData { + String getName(); + boolean isConnected(); + } + + public interface ITargetStateChanged extends IDataModelEvent {} + + public interface ICoreDMC extends IDataModelContext {} + + public interface ICoreData extends IDataModelData { + String getName(); + boolean isConnected(); + IOS.IOSDMC getOSDMC(); + } + + public interface ICoreStateChanged extends IDataModelEvent {} + + public void getTargets(GetDataDone done); + public void getCores(ITargetDMC target, GetDataDone 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); + +} From a1c17ecdcf0306e5e2c172670651b5a4045adbe0 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 3 Aug 2006 23:26:02 +0000 Subject: [PATCH 004/834] Framework changed based on MI prototype fixes. --- .../dsf/ui/model/DataViewModelSchemaNode.java | 2 +- .../dd/dsf/ui/model/ViewModelDelta.java | 22 ++++- .../dd/dsf/ui/model/ViewModelProvider.java | 6 +- .../org/eclipse/dd/dsf/concurrent/Done.java | 20 ++++- .../eclipse/dd/dsf/debug/IBackEndProcess.java | 2 +- .../eclipse/dd/dsf/debug/IBreakpoints.java | 80 +++++-------------- .../org/eclipse/dd/dsf/debug/IModules.java | 1 + .../dd/dsf/debug/INativeProcesses.java | 20 +++++ .../org/eclipse/dd/dsf/debug/IRunControl.java | 13 +-- .../src/org/eclipse/dd/dsf/debug/IStack.java | 11 +++ .../org/eclipse/dd/dsf/model/AbstractDMC.java | 2 +- .../src/org/eclipse/dd/dsf/model/DMCs.java | 12 +-- .../dd/dsf/model/IDataModelService.java | 8 ++ .../dd/dsf/service/AbstractDsfService.java | 19 +++-- 14 files changed, 135 insertions(+), 83 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/DataViewModelSchemaNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/DataViewModelSchemaNode.java index 94fced13b5a..61a8355957c 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/DataViewModelSchemaNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/DataViewModelSchemaNode.java @@ -149,7 +149,7 @@ abstract public class DataViewModelSchemaNode implements IViewModelSchemaNode { childNodeDone); } else { getElements( - (IViewModelContext)parent.getElement(), + parent.getVMC(), new GetDataDone() { public void run() { if (!getStatus().isOK()) { fExecutor.execute(done); diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/ViewModelDelta.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/ViewModelDelta.java index d1802b98d00..eb0dbf87004 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/ViewModelDelta.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/ViewModelDelta.java @@ -82,10 +82,13 @@ public class ViewModelDelta extends ModelDelta { * only needed for creating delta nodes for parent elements in the tree * if the VMC elements are not at the root of the tree. * @param element Element to create the delta for. + * @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) { + public ViewModelDelta(Object element, IViewModelContext vmcElement) { super(element, IModelDelta.NO_CHANGE); fElement = element; + fVmcElement = vmcElement; } @@ -109,7 +112,6 @@ public class ViewModelDelta extends ModelDelta { fFlags |= flags; } - public IViewModelContext getVMC() { return fVmcElement; } /** @@ -160,6 +162,22 @@ public class ViewModelDelta extends ModelDelta { return node; } + /** + * Adds a node to the delta for a non-VMC element. This is used to + * construct the root branch of the delta before it is handed off to + * ViewModelProvider.handleDataModelEvent() + * @param element Element in the asynchronous view to create the new node for. + * @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. + * @return Returns the added delta node. + */ + public ViewModelDelta addNode(Object element, IViewModelContext vmcElement) { + ViewModelDelta node = new ViewModelDelta(element, vmcElement); + node.setParent(this); + addDelta(node); + return node; + } + /** * Sets the parent delta of this delta * diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/ViewModelProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/ViewModelProvider.java index 40473f2b181..7a054a3457a 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/ViewModelProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/ViewModelProvider.java @@ -175,7 +175,9 @@ public class ViewModelProvider extends AbstractModelProxy childNode.getElements( vmc, doneTracker.add( new GetDataDone() { public void run() { - monitor.addChildren(getData()); + if (getStatus().isOK()) { + monitor.addChildren(getData()); + } doneTracker.doneDone(this); }})); } @@ -203,7 +205,7 @@ public class ViewModelProvider extends AbstractModelProxy fProxyActive++; } - public void dipose() { + public void dispose() { fProxyActive--; super.dispose(); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java index e36dbb23cee..74d9cc58df8 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java @@ -13,6 +13,7 @@ package org.eclipse.dd.dsf.concurrent; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.DsfPlugin; /** * Base class for Riverbed service method-completion callbacks. By default @@ -44,5 +45,22 @@ abstract public class Done extends DsfRunnable { status.merge(subStatus); fStatus = status; } - + + /** + * Convenience method which checks for error in done, and propagates it + * to caller's client done. + * @return Returns true if there was an error that was propagated and + * the caller can stop processing result. + */ + protected boolean propagateErrorToClient(DsfExecutor executor, Done clientDone, int code, String message) { + if (clientDone.getStatus().getSeverity() == IStatus.CANCEL) { + return true; + } + if (!getStatus().isOK()) { + clientDone.setErrorStatus(DsfPlugin.PLUGIN_ID, code, message, getStatus()); + executor.execute(clientDone); + return true; + } + return false; + } } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IBackEndProcess.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IBackEndProcess.java index 49fcf560b4e..f8dae4b15df 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IBackEndProcess.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IBackEndProcess.java @@ -21,7 +21,7 @@ public interface IBackEndProcess extends IDsfService { /** * Event indicating that the back end process has terminated. */ - public interface ExitedEvent {} + public interface IExitedEvent {} /** * Returns the instance of the java process object representing the back diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IBreakpoints.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IBreakpoints.java index 01ee465b7ab..68d8dbf9bd5 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IBreakpoints.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IBreakpoints.java @@ -1,65 +1,27 @@ +/******************************************************************************* + * 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.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.debug.core.model.IBreakpoint; +import org.eclipse.dd.dsf.service.IDsfService; /** - * Breakpoint service provides access to information about breakpoints that - * are planted on a target. It's the reposnsibility of the debugger - * implementation to retrieve static breakpoint data from platform APIs and to - * install them on the target. + * Note: This interface is just a place-holder. */ -public interface IBreakpoints extends IDataModelService { - /** - * Data Model Context for a breakpoint objects. Breakpoints service only - * with respect to running processes/threads, therefore the breakpoint - * context will always have an IExecutionDMC as one of its ancestors. - */ - public interface IBreakpointDMC extends IDataModelContext {} - - /** Indicates that the state of given breakpoint has changed. */ - public interface BreakpointChangedEvent extends IDataModelEvent {} - - /** Indicates that given breakpoint was hit, by the given execution context. */ - public interface BreakpointHitEvent extends BreakpointChangedEvent { - IRunControl.IExecutionDMC getExecutionDMC(); - } - - /** Common breakpoint state data. */ - public interface BreakpointData extends IDataModelData { - /** Installed status values of a breakpoint. */ - public enum Status { FILTERED_OUT, INSTALLED, FAILED_TO_INSTALL, PENDING_INSTALL, PENDING_UNINSTALL } - - /** Returns the corresponding platform debug model breakpoint object. */ - IBreakpoint getBreakpoint(); - - /** Returns current installed status of this breakpoint */ - Status getStatus(); - - /** - * Returns error message (if any) with respect to current status of - * the breakpoint. - */ - String getErrorMessage(); - - /** - * Returns a warning message (if any) with respect to current status of - * the breakpoint. - */ - String getWarningMessage(); - } - - /** - * Retrieves all breakpoints for given execution context. - */ - void getBreakpoints(IRunControl.IExecutionDMC execCtx, GetDataDone done); - - /** - * Retrieves all breakpoints for given platform breakpoint object. - */ - void getBreakpoints(IBreakpoint bp, GetDataDone done); +public interface IBreakpoints extends IDsfService { + + public class BreakpointEvent { + public final int fLineNumber; + public BreakpointEvent(int line) { + fLineNumber = line; + } + } } + diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IModules.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IModules.java index 737ff7a54eb..803dd2f0558 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IModules.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IModules.java @@ -3,6 +3,7 @@ package org.eclipse.dd.dsf.debug; 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; diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/INativeProcesses.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/INativeProcesses.java index 54081096a7b..e2eae52fca2 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/INativeProcesses.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/INativeProcesses.java @@ -61,6 +61,12 @@ public interface INativeProcesses extends IDataModelService { * @param done Return token with the process context. */ void debugNewProcess(String file, GetDataDone done); + + /** + * Retrieves the list of processes which are currently under + * debugger control. + */ + void getProcessesBeingDebugged(GetDataDone done); /** * Returns a thread context for given run control execution context. @@ -68,4 +74,18 @@ public interface INativeProcesses extends IDataModelService { * @return Corresponding thread context. */ IThreadDMC getThreadForExecutionContext(IRunControl.IExecutionDMC 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 done); + + /** + * Terminates the selected process or thread. + * @param thread Thread or process to terminate. + * @param done Return token. + */ + void terminate(IThreadDMC thread, Done done); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IRunControl.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IRunControl.java index e68ed472007..6b0d9d20df6 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IRunControl.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IRunControl.java @@ -33,21 +33,21 @@ public interface IRunControl extends IDataModelService public interface IContainerDMC extends IExecutionDMC {} /** Flag indicating reason context state change. */ - public enum StateChangeReason { USER_REQUEST, STEP, BREAKPOINT, EXCEPTION, CONTAINER }; + public enum StateChangeReason { UNKNOWN, USER_REQUEST, STEP, BREAKPOINT, EXCEPTION, CONTAINER }; /** * Events signaling a state changes. */ - public interface SuspendedEvent extends IDataModelEvent { + public interface ISuspendedEvent extends IDataModelEvent { StateChangeReason getReason(); } - public interface ResumedEvent extends IDataModelEvent { + public interface IResumedEvent extends IDataModelEvent { StateChangeReason getReason(); } - public interface ContainerSuspendedEvent extends IDataModelEvent { + public interface IContainerSuspendedEvent extends IDataModelEvent { StateChangeReason getReason(); } - public interface ContainerResumedEvent extends IDataModelEvent { + public interface IContainerResumedEvent extends IDataModelEvent { StateChangeReason getReason(); } public interface IStartedEvent extends IDataModelEvent { @@ -81,7 +81,8 @@ public interface IRunControl extends IDataModelService void suspend(IExecutionDMC context, Done done); public enum StepType { STEP_OVER, STEP_INTO, STEP_RETURN }; boolean isStepping(IExecutionDMC context); - void canStep(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); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStack.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStack.java index 34c0d56ecee..0275dc5d7f0 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStack.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStack.java @@ -1,6 +1,7 @@ package org.eclipse.dd.dsf.debug; 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; @@ -24,6 +25,7 @@ public interface IStack extends IDataModelService { public interface IFrameData extends IDataModelData { IAddress getAddress(); String getFile(); + String getFunction(); int getLine(); int getColumn(); } @@ -44,6 +46,15 @@ public interface IStack extends IDataModelService { String getValue(); } + /** + * Returns whether the stack frames can be retrieved for given thread. + *
    + * TODO: I'm not sure if this method should be async. It assumes that the + * implementation can determine if stack is available based on process + * state information. + */ + boolean isStackAvailable(IRunControl.IExecutionDMC execContext); + /** * Retrieves list of stack frames for the given execution context. Request * will fail if the stack frame data is not available. diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/AbstractDMC.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/AbstractDMC.java index 08e03569c18..ecc291300e0 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/AbstractDMC.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/AbstractDMC.java @@ -21,7 +21,7 @@ import org.eclipse.dd.dsf.service.DsfSession; * @param Data model data that this context is for. */ public class AbstractDMC extends PlatformObject - implements IDataModelContext + implements IDataModelContext { private final String fSessionId; private final String fServiceFilter; diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/DMCs.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/DMCs.java index 5aa60ef4d2b..14d77050f14 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/DMCs.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/DMCs.java @@ -26,17 +26,19 @@ public class DMCs { */ @SuppressWarnings("unchecked") public static V getAncestorOfType(IDataModelContext ctx, Class ancestorType) { + if (ancestorType.isAssignableFrom(ctx.getClass())) { + return (V)ctx; + } + for (IDataModelContext parent : ctx.getParents()) { - if (parent.getClass().equals(ancestorType)) { + if (ancestorType.isAssignableFrom(parent.getClass())) { return (V)parent; } } for (IDataModelContext parent : ctx.getParents()) { - if (parent.getClass().equals(ancestorType)) { - V ancestor = getAncestorOfType(parent, ancestorType); - if (ancestor != null) return ancestor; - } + V ancestor = getAncestorOfType(parent, ancestorType); + if (ancestor != null) return ancestor; } return null; } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelService.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelService.java index da587a61fe2..dd39a162707 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelService.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelService.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.dsf.model; +import org.eclipse.dd.dsf.concurrent.GetDataDone; import org.eclipse.dd.dsf.service.IDsfService; /** @@ -26,4 +27,11 @@ public interface IDataModelService extends IDsfService, IDataModelData { * service are changed. */ IDataModelContext 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. + */ + void getModelData(IDataModelContext dmc, GetDataDone done); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java index 3c4d6b95487..196e66c1bed 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.dsf.service; +import java.util.Arrays; import java.util.Dictionary; import java.util.Enumeration; @@ -91,13 +92,21 @@ abstract public class AbstractDsfService */ @SuppressWarnings("unchecked") protected void register(String[] classes, Dictionary properties) { - String[] newClasses = new String[classes.length + 2]; - System.arraycopy(classes, 0, newClasses, 2, classes.length); - newClasses[0] = IDsfService.class.getName(); - newClasses[1] = getClass().getName(); + if (!Arrays.asList(classes).contains(IDsfService.class.getName())) { + String[] newClasses = new String[classes.length + 1]; + System.arraycopy(classes, 0, newClasses, 1, classes.length); + newClasses[0] = IDsfService.class.getName(); + classes = newClasses; + } + if (!Arrays.asList(classes).contains(getClass().getName())) { + String[] newClasses = new String[classes.length + 1]; + System.arraycopy(classes, 0, newClasses, 1, classes.length); + newClasses[0] = getClass().getName(); + classes = newClasses; + } properties.put(PROP_SESSION_ID, getSession().getId()); fProperties = properties; - fRegistration = getBundleContext().registerService(newClasses, this, properties); + fRegistration = getBundleContext().registerService(classes, this, properties); fRegistration.getReference().getProperty(Constants.OBJECTCLASS); fFilter = generateFilter(fProperties); fProperties.put(Constants.OBJECTCLASS, fRegistration.getReference().getProperty(Constants.OBJECTCLASS)); From 43c8135378197e4e3a6cd58c8560183ffd9adca9 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Mon, 7 Aug 2006 00:33:28 +0000 Subject: [PATCH 005/834] created feature --- .../org.eclipse.dd.dsf.sdk-feature/.project | 17 ++++++ .../build.properties | 1 + .../feature.xml | 54 +++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 features/org.eclipse.dd.dsf.sdk-feature/.project create mode 100644 features/org.eclipse.dd.dsf.sdk-feature/build.properties create mode 100644 features/org.eclipse.dd.dsf.sdk-feature/feature.xml diff --git a/features/org.eclipse.dd.dsf.sdk-feature/.project b/features/org.eclipse.dd.dsf.sdk-feature/.project new file mode 100644 index 00000000000..591437f01c1 --- /dev/null +++ b/features/org.eclipse.dd.dsf.sdk-feature/.project @@ -0,0 +1,17 @@ + + + org.eclipse.dd.dsf.sdk-feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/features/org.eclipse.dd.dsf.sdk-feature/build.properties b/features/org.eclipse.dd.dsf.sdk-feature/build.properties new file mode 100644 index 00000000000..64f93a9f0b7 --- /dev/null +++ b/features/org.eclipse.dd.dsf.sdk-feature/build.properties @@ -0,0 +1 @@ +bin.includes = feature.xml diff --git a/features/org.eclipse.dd.dsf.sdk-feature/feature.xml b/features/org.eclipse.dd.dsf.sdk-feature/feature.xml new file mode 100644 index 00000000000..7564cb5a78a --- /dev/null +++ b/features/org.eclipse.dd.dsf.sdk-feature/feature.xml @@ -0,0 +1,54 @@ + + + + + [Enter Feature Description here.] + + + + [Enter Copyright Description here.] + + + + [Enter License Description here.] + + + + + + + + + + + + + + + + + + From 05aac6962b8846563526d4884d42ddc8ecbbc582 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Mon, 7 Aug 2006 01:03:51 +0000 Subject: [PATCH 006/834] renamed --- features/org.eclipse.dd.dsf.sdk-feature/.project | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/org.eclipse.dd.dsf.sdk-feature/.project b/features/org.eclipse.dd.dsf.sdk-feature/.project index 591437f01c1..f03529db932 100644 --- a/features/org.eclipse.dd.dsf.sdk-feature/.project +++ b/features/org.eclipse.dd.dsf.sdk-feature/.project @@ -1,6 +1,6 @@ - org.eclipse.dd.dsf.sdk-feature + org.eclipse.dd.dsf.sdk From efdfe21c0d1c009d1f872316a5786b3ba07f64da Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Mon, 7 Aug 2006 01:04:26 +0000 Subject: [PATCH 007/834] renamed id --- features/org.eclipse.dd.dsf.sdk-feature/feature.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/org.eclipse.dd.dsf.sdk-feature/feature.xml b/features/org.eclipse.dd.dsf.sdk-feature/feature.xml index 7564cb5a78a..f1252d48e8e 100644 --- a/features/org.eclipse.dd.dsf.sdk-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.sdk-feature/feature.xml @@ -1,6 +1,6 @@ From 0b17595f4e4b9abedbb1dfcdc9ec25b147abacae Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Mon, 7 Aug 2006 01:11:44 +0000 Subject: [PATCH 008/834] removed .sdk-feature --- features/.project | 11 ++++ .../org.eclipse.dd.dsf.sdk-feature/.project | 17 ------ .../build.properties | 1 - .../feature.xml | 54 ------------------- 4 files changed, 11 insertions(+), 72 deletions(-) create mode 100644 features/.project delete mode 100644 features/org.eclipse.dd.dsf.sdk-feature/.project delete mode 100644 features/org.eclipse.dd.dsf.sdk-feature/build.properties delete mode 100644 features/org.eclipse.dd.dsf.sdk-feature/feature.xml diff --git a/features/.project b/features/.project new file mode 100644 index 00000000000..cf8899cb3fa --- /dev/null +++ b/features/.project @@ -0,0 +1,11 @@ + + + features + + + + + + + + diff --git a/features/org.eclipse.dd.dsf.sdk-feature/.project b/features/org.eclipse.dd.dsf.sdk-feature/.project deleted file mode 100644 index f03529db932..00000000000 --- a/features/org.eclipse.dd.dsf.sdk-feature/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - org.eclipse.dd.dsf.sdk - - - - - - org.eclipse.pde.FeatureBuilder - - - - - - org.eclipse.pde.FeatureNature - - diff --git a/features/org.eclipse.dd.dsf.sdk-feature/build.properties b/features/org.eclipse.dd.dsf.sdk-feature/build.properties deleted file mode 100644 index 64f93a9f0b7..00000000000 --- a/features/org.eclipse.dd.dsf.sdk-feature/build.properties +++ /dev/null @@ -1 +0,0 @@ -bin.includes = feature.xml diff --git a/features/org.eclipse.dd.dsf.sdk-feature/feature.xml b/features/org.eclipse.dd.dsf.sdk-feature/feature.xml deleted file mode 100644 index f1252d48e8e..00000000000 --- a/features/org.eclipse.dd.dsf.sdk-feature/feature.xml +++ /dev/null @@ -1,54 +0,0 @@ - - - - - [Enter Feature Description here.] - - - - [Enter Copyright Description here.] - - - - [Enter License Description here.] - - - - - - - - - - - - - - - - - - From 98268e210107e85b74e2c068baf80a9cd04fac4d Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 16 Aug 2006 16:23:10 +0000 Subject: [PATCH 009/834] Converted DsfQuery to use generics. --- .../org/eclipse/dd/dsf/concurrent/DsfQuery.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfQuery.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfQuery.java index 0d58590c65a..71e9d7ef9dd 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfQuery.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfQuery.java @@ -27,9 +27,9 @@ import org.eclipse.dd.dsf.DsfPlugin; * @see java.util.concurrent.Callable * FIXME: make this class implement the Future interface. */ -abstract public class DsfQuery { +abstract public class DsfQuery { - private Object fResult; + private V fResult; private boolean fValid; private DsfExecutor fExecutor; private Future fFuture; @@ -52,7 +52,7 @@ abstract public class DsfQuery { * Allows deriving classes to implement their own snipped additional * cancellation code. */ - protected void revokeChildren(Object result) {}; + protected void revokeChildren(V result) {}; /** * Get data associated with this proxy. This method is thread safe and @@ -60,7 +60,7 @@ abstract public class DsfQuery { * for commands to be processed on the dispatch thread, this methods itself * CANNOT be called on the dispatch thread. */ - public synchronized Object get() { + public synchronized V get() { assert !fExecutor.isInExecutorThread(); if(!fValid) { if (!fWaiting) { @@ -97,8 +97,8 @@ abstract public class DsfQuery { * Same as get(), but with code to automatically re-threw the exception if one * was reported by the run() method. */ - public Object getWithThrows() throws CoreException { - Object retVal = get(); + public V getWithThrows() throws CoreException { + V retVal = get(); if (!getStatus().isOK()) { throw new CoreException(getStatus()); } @@ -122,7 +122,7 @@ abstract public class DsfQuery { } /** Abort current operation and set proxy data to 'result' */ - public synchronized void cancel(Object newResult) { + public synchronized void cancel(V newResult) { fResult = newResult; cancel(); } @@ -133,7 +133,7 @@ abstract public class DsfQuery { public boolean isValid() { return fValid; } - public synchronized void done(Object result) { + public synchronized void done(V result) { // Valid could be true if request was cancelled while data was // being retrieved, and then done() was called. if (fValid) return; From ec84c5494b71d4c9602ed5692c44740c60583980 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 16 Aug 2006 16:38:12 +0000 Subject: [PATCH 010/834] Explicitly set the execution enviroment for plugins to java 1.5. --- plugins/org.eclipse.dd.dsf.ui/.classpath | 2 +- plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF | 1 + plugins/org.eclipse.dd.dsf/.classpath | 2 +- plugins/org.eclipse.dd.dsf/.settings/org.eclipse.jdt.ui.prefs | 3 +++ plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF | 1 + 5 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf/.settings/org.eclipse.jdt.ui.prefs diff --git a/plugins/org.eclipse.dd.dsf.ui/.classpath b/plugins/org.eclipse.dd.dsf.ui/.classpath index 751c8f2e504..304e86186aa 100644 --- a/plugins/org.eclipse.dd.dsf.ui/.classpath +++ b/plugins/org.eclipse.dd.dsf.ui/.classpath @@ -1,7 +1,7 @@ - + diff --git a/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF index c9cd81ee3cf..753bd6411e2 100644 --- a/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF @@ -11,3 +11,4 @@ Require-Bundle: org.eclipse.ui, org.eclipse.debug.ui Eclipse-LazyStart: true Export-Package: org.eclipse.dd.dsf.ui.model +Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/plugins/org.eclipse.dd.dsf/.classpath b/plugins/org.eclipse.dd.dsf/.classpath index 751c8f2e504..304e86186aa 100644 --- a/plugins/org.eclipse.dd.dsf/.classpath +++ b/plugins/org.eclipse.dd.dsf/.classpath @@ -1,7 +1,7 @@ - + diff --git a/plugins/org.eclipse.dd.dsf/.settings/org.eclipse.jdt.ui.prefs b/plugins/org.eclipse.dd.dsf/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 00000000000..087537fe3fb --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,3 @@ +#Sun Aug 06 18:10:27 CEST 2006 +eclipse.preferences.version=1 +internal.default.compliance=default diff --git a/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF index 300d22e0fe2..5f065af667f 100644 --- a/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF @@ -12,3 +12,4 @@ Export-Package: org.eclipse.dd.dsf.concurrent, org.eclipse.dd.dsf.debug, org.eclipse.dd.dsf.model, org.eclipse.dd.dsf.service +Bundle-RequiredExecutionEnvironment: J2SE-1.5 From fb0fd74800776c7f628c26787f43d9bc11ebdcb2 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 16 Aug 2006 16:48:25 +0000 Subject: [PATCH 011/834] Renamed remaining "Riverbed"s to "DSF"s. --- plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF | 2 +- .../dd/dsf/concurrent/DefaultDsfExecutor.java | 4 ++-- .../src/org/eclipse/dd/dsf/concurrent/Done.java | 2 +- .../eclipse/dd/dsf/concurrent/DsfRunnable.java | 6 +++--- .../eclipse/dd/dsf/concurrent/DsfSequence.java | 16 ++++++++-------- .../eclipse/dd/dsf/debug/IBackEndProcess.java | 2 +- .../src/org/eclipse/dd/dsf/debug/IModules.java | 2 +- .../eclipse/dd/dsf/model/IDataModelService.java | 2 +- .../dd/dsf/service/AbstractDsfService.java | 4 ++-- .../dd/dsf/service/DsfServicesTracker.java | 6 +++--- .../org/eclipse/dd/dsf/service/DsfSession.java | 12 ++++++------ .../org/eclipse/dd/dsf/service/IDsfService.java | 8 ++++---- 12 files changed, 33 insertions(+), 33 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF index 5f065af667f..b9ae36656fd 100644 --- a/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF @@ -1,6 +1,6 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 -Bundle-Name: Riverbed Plug-in +Bundle-Name: DSF Plug-in Bundle-SymbolicName: org.eclipse.dd.dsf Bundle-Version: 1.0.0 Bundle-Activator: org.eclipse.dd.dsf.DsfPlugin diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java index 3bd4e996661..5247c800a17 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java @@ -18,7 +18,7 @@ import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.DsfPlugin; /** - * Default implementation of a Riverbed executor interfaces, based on the + * Default implementation of a DSF executor interfaces, based on the * standard java.util.concurrent.ThreadPoolExecutor. */ @@ -29,7 +29,7 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor Thread fThread; public Thread newThread(Runnable r) { assert fThread == null; // Should be called only once. - fThread = new Thread(new ThreadGroup("Riverbed Thread Group"), r, "Riverbed Dispatch Thread", 0); + fThread = new Thread(new ThreadGroup("DSF Thread Group"), r, "DSF Dispatch Thread", 0); return fThread; } } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java index 74d9cc58df8..1c7632d546b 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java @@ -16,7 +16,7 @@ import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.DsfPlugin; /** - * Base class for Riverbed service method-completion callbacks. By default + * Base class for DSF service method-completion callbacks. By default * all callbacks that indicate a complition of a method contain the status * of the result. *
    NOTE: Access to the status data is not synchronized, so diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfRunnable.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfRunnable.java index caf610210ae..65bc577c7df 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfRunnable.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfRunnable.java @@ -13,9 +13,9 @@ package org.eclipse.dd.dsf.concurrent; /** * A DSF-instrumented alternative to the Runnable interface. *

    - * While it is perfectly fine for clients to call the Riverbed executor with - * an object only implementing the Runnable interface, the RbRunnable is a - * place holder for future tracing enhancments for Riverbed. + * While it is perfectly fine for clients to call the DSF executor with + * an object only implementing the Runnable interface, the DsfRunnable is a + * place holder for future tracing enhancments for DSF. */ abstract public class DsfRunnable implements Runnable { } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java index b8f852585b2..47c752d0af7 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java @@ -22,7 +22,7 @@ import org.eclipse.dd.dsf.DsfPlugin; *

    * Certain complex tasks require multiple commands to be executed in a chain, * because for example result of one command is used as input into another - * command. The typical Riverbed pattern of solving this problem is the following: + * command. The typical DSF pattern of solving this problem is the following: *

  • *
    1. original caller passes a Done callback to a method and invokes it *
    2. the method is executed by a subsystem @@ -49,7 +49,7 @@ abstract public class DsfSequence { * The abstract class that each step has to implement *
    FIXME: convert execute() and rollBacl() to take "done" as an argument. * This way we can make step a static class, and make its paradigm - * more consistent with rest of Riverbed. + * more consistent with rest of DSF. */ abstract public class Step { public void execute() { stepFinished(); } @@ -69,7 +69,7 @@ abstract public class DsfSequence { /** * Default constructor. If this constructor is used, the steps need to be initialized * before the sequence can be invoked. - * @param executor the Riverbed executor which will be used to invoke all steps + * @param executor the DSF executor which will be used to invoke all steps */ public DsfSequence(DsfExecutor executor) { this(executor, null); @@ -77,7 +77,7 @@ abstract public class DsfSequence { /** * Constructor that initialized the steps. - * @param executor the Riverbed executor which will be used to invoke all steps + * @param executor the DSF executor which will be used to invoke all steps * @param steps sequence steps */ public DsfSequence(DsfExecutor executor, Step[] steps) { @@ -85,7 +85,7 @@ abstract public class DsfSequence { fSteps = steps; } - /** Returns the riverbed executor for this sequence */ + /** Returns the DSF executor for this sequence */ public DsfExecutor getExecutor() { return fExecutor; } /** @@ -119,7 +119,7 @@ abstract public class DsfSequence { /** * Returns index of the step that is currently being executed. *
    NOTE: After sequence is invoked, this method should be called - * only in the Riverbed executor thread. + * only in the DSF executor thread. * @return */ public int getCurrentIdx() { return fCurrentStepIdx; } @@ -150,9 +150,9 @@ abstract public class DsfSequence { } /** - * Submits this sequence to the Riverbed executor, and blocks waiting for the + * Submits this sequence to the DSF executor, and blocks waiting for the * sequence to complete. - *
    NOTE: This method is NOT to be called on the Riverbed executor thread. + *
    NOTE: This method is NOT to be called on the DSF executor thread. */ public synchronized void invoke() { assert !fExecutor.isInExecutorThread() : diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IBackEndProcess.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IBackEndProcess.java index f8dae4b15df..094e63d0d2c 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IBackEndProcess.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IBackEndProcess.java @@ -16,7 +16,7 @@ public interface IBackEndProcess extends IDsfService { * same time, a service property is needed to allow clients to distinguish * between them. */ - static final String PROCESS_ID = "org.eclipse.dsdp.riverbed.debug.BackendProcess.PROCESS_ID"; + static final String PROCESS_ID = "org.eclipse.dsdp.DSF.debug.BackendProcess.PROCESS_ID"; /** * Event indicating that the back end process has terminated. diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IModules.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IModules.java index 803dd2f0558..d15b2939322 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IModules.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IModules.java @@ -13,7 +13,7 @@ import org.eclipse.dd.dsf.model.IDataModelService; * Debugger service representing module handling logic of a debugger. *
    * TODO: I meant this as a replacement for Application service as well as the - * registry API in Riverbed 1. But I still don't fully understand the format + * registry API in DSF 1. But I still don't fully understand the format * of the symbol data that is stored in the registry, so that needs to be added * to this interface. */ diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelService.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelService.java index dd39a162707..9ce857005fe 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelService.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelService.java @@ -14,7 +14,7 @@ import org.eclipse.dd.dsf.concurrent.GetDataDone; import org.eclipse.dd.dsf.service.IDsfService; /** - * Interface for Riverbed services that provide model data to clients. + * Interface for DSF services that provide model data to clients. *

    * For completeness this service interface derives from IDataModelData * and has a method which allows clients to retrieve the DMC that represents the diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java index 196e66c1bed..98c674b9f39 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java @@ -22,8 +22,8 @@ import org.osgi.framework.ServiceRegistration; /** - * Standard base implementation of the Riverbed service. This is a convinience - * class that provides the basic functionality that all Riverbed services have + * Standard base implementation of the DSF service. This is a convinience + * class that provides the basic functionality that all DSF services have * to implement. */ abstract public class AbstractDsfService diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServicesTracker.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServicesTracker.java index 5821e8796a6..6c9b440e31c 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServicesTracker.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServicesTracker.java @@ -19,7 +19,7 @@ import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceReference; /** - * Convenience class to help track Riverbed services that a given + * Convenience class to help track DSF services that a given * client needs to use. This class is similar to the standard OSGI * org.osgi.util.tracker.ServiceTracker class, with a few differences: *
    1. This class is assumed to be accessed by a single thread hence it @@ -28,7 +28,7 @@ import org.osgi.framework.ServiceReference; *
    2. This class is primarily designed to track multiple services of * different type (class), while OSGI ServiceTracker is designed to work with * single class type, with optional filtering options. - *
    3. This class uses knowledge of Riverbed sessions to help narrow down + *
    3. This class uses knowledge of DSF sessions to help narrow down * service references. *
    4. OSGI Service tracker explicitly listens to OSGI service * startup/shutdown events and it will clear a reference to a service as @@ -76,7 +76,7 @@ public class DsfServicesTracker { /** * Only constructor. * @param bundleContext Context of the plugin that the client lives in. - * @param sessionId The Riverbed session that this tracker will be used for. + * @param sessionId The DSF session that this tracker will be used for. */ public DsfServicesTracker(BundleContext bundleContext, String sessionId) { fBundleContext = bundleContext; diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java index aa273865fa9..33820e7114b 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java @@ -32,12 +32,12 @@ import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.osgi.framework.Filter; /** - * Class to manage Riverbed sessions. A Riverbed session is a way to - * associate a set of Riverbed services that are running simultaneously and + * Class to manage DSF sessions. A DSF session is a way to + * associate a set of DSF services that are running simultaneously and * are interacting with each other to provide a complete set of functionality. *

    * Properties of a session are following: - *
    1. Each session is associated with a single Riverbed executor, although there + *
    1. Each session is associated with a single DSF executor, although there * could be multiple sessions using the same executor. *
    2. Each session has a unique String identifier, which has to be used by * the services belonging to this session when registering with OSGI services. @@ -135,7 +135,7 @@ public class DsfSession * Starts and returns a new session instance. This method can be called on any * thread, but the session-started listeners will be called using the session's * executor. - * @param executor The Riverbed executor to use for this session. + * @param executor The DSF executor to use for this session. * @return instance object of the new session */ public static DsfSession startSession(DsfExecutor executor) { @@ -214,7 +214,7 @@ public class DsfSession /** Returns the ID of this session */ public String getId() { return fId; } - /** Returns the Riverbed executor of this session */ + /** Returns the DSF executor of this session */ public DsfExecutor getExecutor() { return fExecutor; } /** @@ -241,7 +241,7 @@ public class DsfSession /** * Retrieves and increments the startup counter for services in this session. - * Riverbed services should retrieve this counter when they are initialized, + * DSF services should retrieve this counter when they are initialized, * and should return it through IService.getStartupNumber(). This number is then * used to prioritize service events. * @return current startup counter value diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java index 82e5c310e32..26f72fec26e 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java @@ -16,7 +16,7 @@ import org.eclipse.dd.dsf.concurrent.Done; import org.eclipse.dd.dsf.concurrent.DsfExecutor; /** - * The inteface that all Riverbed services must implement. It only privides a + * The inteface that all DSF services must implement. It only privides a * few features to help manage and identify the servies using the OSGI services * framework. *

    @@ -27,8 +27,8 @@ import org.eclipse.dd.dsf.concurrent.DsfExecutor; * additional properties should be used when registering the service to allow clients * to uniquely identify the services. *

    - * By convention, all methods of Riverbed services can be called only on the dispatch - * thread of the Riverbed executor that is associated with the service. If a + * By convention, all methods of DSF services can be called only on the dispatch + * thread of the DSF executor that is associated with the service. If a * service exposes a method that is to be called on non-dispatch thread, it should * be documented so. * @@ -40,7 +40,7 @@ public interface IDsfService { /** * Property name for the session-id of this service. This property should be set by - * all Riverbed services when they are registered with OSGI service framework. + * all DSF services when they are registered with OSGI service framework. */ static String PROP_SESSION_ID = "org.eclipse.dd.dsf.service.IService.session_id"; From 32b8c9157f940143e470bc7eb9947d1ee74fcf90 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Sat, 19 Aug 2006 17:52:42 +0000 Subject: [PATCH 012/834] Started work on optimizing stepping. --- .../org/eclipse/dd/dsf/debug/IRunControl.java | 39 +++++++++++++++---- .../src/org/eclipse/dd/dsf/debug/IStack.java | 11 ++++++ 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IRunControl.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IRunControl.java index 6b0d9d20df6..25fc30a7926 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IRunControl.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IRunControl.java @@ -17,7 +17,13 @@ import org.eclipse.dd.dsf.model.IDataModelService; */ public interface IRunControl extends IDataModelService { - + /** + * Amount of time in seconds, that it takes the ISteppingTimedOutEvent event to + * be issued after a step is started. + * @see ISteppingTimedOutEvent + */ + public final static int STEPPING_TIMEOUT = 5; + /** * Execution context is the object on which run control operations can be * performed. A lot of higher-level services reference this context to build @@ -50,18 +56,34 @@ public interface IRunControl extends IDataModelService public interface IContainerResumedEvent extends IDataModelEvent { StateChangeReason getReason(); } - public interface IStartedEvent extends IDataModelEvent { - IExecutionDMC getExecutionContext(); - } - public interface IExitedEvent extends IDataModelEvent { - IExecutionDMC getExecutionContext(); - } + /** + * 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 { + IExecutionDMC 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 { + IExecutionDMC getExecutionContext(); + } + + /** + * 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 { + } + /** * Display information for an execution context. */ public interface IExecutionData extends IDataModelData { - boolean isSuspended(); StateChangeReason getStateChangeReason(); } @@ -81,6 +103,7 @@ public interface IRunControl extends IDataModelService void suspend(IExecutionDMC context, Done done); public enum StepType { STEP_OVER, STEP_INTO, STEP_RETURN }; boolean isStepping(IExecutionDMC context); + boolean isSteppingTimedOut(IExecutionDMC context); boolean canStep(IExecutionDMC context); void step(IExecutionDMC context, StepType stepType, Done done); boolean canInstructionStep(IExecutionDMC context); diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStack.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStack.java index 0275dc5d7f0..faf8933c487 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStack.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStack.java @@ -61,6 +61,17 @@ public interface IStack extends IDataModelService { */ void getFrames(IRunControl.IExecutionDMC execContext, GetDataDone done); + /** + * Retrieves the top stack frame for the given execution context. + * Retrieving just the top frame DMC and corresponding data can be much + * more efficient than just retrieving the whole stack, before the data + * is often included in the stopped event. Also for some UI functionality, + * such as setpping, only top stack frame is often needed. + * @param execContext + * @param done + */ + void getTopFrame(IRunControl.IExecutionDMC execContext, GetDataDone done); + /** * Retrieves variables which were arguments to the stack frame's function. */ From 71db7fdfe2fe2096a9628007d1952575459e68fb Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 22 Aug 2006 15:04:41 +0000 Subject: [PATCH 013/834] Optimized stepping performance. --- .../eclipse/dd/dsf/debug/IBackEndProcess.java | 10 ++++++ .../eclipse/dd/dsf/debug/IExpressions.java | 10 ++++++ .../src/org/eclipse/dd/dsf/debug/IMemory.java | 10 ++++++ .../org/eclipse/dd/dsf/debug/IModules.java | 10 ++++++ .../dd/dsf/debug/INativeProcesses.java | 10 ++++++ .../src/org/eclipse/dd/dsf/debug/IOS.java | 10 ++++++ .../org/eclipse/dd/dsf/debug/IRegisters.java | 10 ++++++ .../org/eclipse/dd/dsf/debug/IRunControl.java | 25 ++++++-------- .../eclipse/dd/dsf/debug/ISourceLookup.java | 10 ++++++ .../src/org/eclipse/dd/dsf/debug/IStack.java | 10 ++++++ .../dd/dsf/debug/IStepQueueManager.java | 34 +++++++++++++++++-- .../org/eclipse/dd/dsf/debug/ISymbols.java | 10 ++++++ .../org/eclipse/dd/dsf/debug/ITargets.java | 10 ++++++ .../eclipse/dd/dsf/service/DsfSession.java | 4 +-- .../eclipse/dd/dsf/service/IDsfService.java | 9 +++++ 15 files changed, 163 insertions(+), 19 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IBackEndProcess.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IBackEndProcess.java index 094e63d0d2c..d255acbff0a 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IBackEndProcess.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IBackEndProcess.java @@ -1,3 +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 + *******************************************************************************/ package org.eclipse.dd.dsf.debug; import org.eclipse.dd.dsf.service.IDsfService; diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IExpressions.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IExpressions.java index 228912b498c..6d32378f8b9 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IExpressions.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IExpressions.java @@ -1,3 +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 + *******************************************************************************/ package org.eclipse.dd.dsf.debug; import java.util.Map; diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IMemory.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IMemory.java index eff0c6f1b14..c87fe7ccec0 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IMemory.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IMemory.java @@ -1,3 +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 + *******************************************************************************/ package org.eclipse.dd.dsf.debug; import org.eclipse.dd.dsf.concurrent.Done; diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IModules.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IModules.java index d15b2939322..9d30a3e7f46 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IModules.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IModules.java @@ -1,3 +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 + *******************************************************************************/ package org.eclipse.dd.dsf.debug; import java.math.BigInteger; diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/INativeProcesses.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/INativeProcesses.java index e2eae52fca2..22476de3980 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/INativeProcesses.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/INativeProcesses.java @@ -1,3 +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 + *******************************************************************************/ package org.eclipse.dd.dsf.debug; import org.eclipse.dd.dsf.concurrent.Done; diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IOS.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IOS.java index 21c153ab2d7..2e3af9bd707 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IOS.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IOS.java @@ -1,3 +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 + *******************************************************************************/ package org.eclipse.dd.dsf.debug; import org.eclipse.dd.dsf.concurrent.Done; diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IRegisters.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IRegisters.java index ab41ad41ecc..586add23540 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IRegisters.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IRegisters.java @@ -1,3 +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 + *******************************************************************************/ package org.eclipse.dd.dsf.debug; import org.eclipse.dd.dsf.concurrent.GetDataDone; diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IRunControl.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IRunControl.java index 25fc30a7926..48b78e8783a 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IRunControl.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IRunControl.java @@ -1,3 +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 + *******************************************************************************/ package org.eclipse.dd.dsf.debug; import org.eclipse.dd.dsf.concurrent.Done; @@ -17,13 +27,6 @@ import org.eclipse.dd.dsf.model.IDataModelService; */ public interface IRunControl extends IDataModelService { - /** - * Amount of time in seconds, that it takes the ISteppingTimedOutEvent event to - * be issued after a step is started. - * @see ISteppingTimedOutEvent - */ - public final static int STEPPING_TIMEOUT = 5; - /** * Execution context is the object on which run control operations can be * performed. A lot of higher-level services reference this context to build @@ -73,13 +76,6 @@ public interface IRunControl extends IDataModelService IExecutionDMC getExecutionContext(); } - /** - * 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 { - } - /** * Display information for an execution context. */ @@ -103,7 +99,6 @@ public interface IRunControl extends IDataModelService void suspend(IExecutionDMC context, Done done); public enum StepType { STEP_OVER, STEP_INTO, STEP_RETURN }; boolean isStepping(IExecutionDMC context); - boolean isSteppingTimedOut(IExecutionDMC context); boolean canStep(IExecutionDMC context); void step(IExecutionDMC context, StepType stepType, Done done); boolean canInstructionStep(IExecutionDMC context); diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ISourceLookup.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ISourceLookup.java index 8e37f7b4767..54f1341a1e5 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ISourceLookup.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ISourceLookup.java @@ -1,3 +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 + *******************************************************************************/ package org.eclipse.dd.dsf.debug; import org.eclipse.dd.dsf.concurrent.GetDataDone; diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStack.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStack.java index faf8933c487..7d26f13928f 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStack.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStack.java @@ -1,3 +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 + *******************************************************************************/ package org.eclipse.dd.dsf.debug; import org.eclipse.dd.dsf.concurrent.GetDataDone; diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStepQueueManager.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStepQueueManager.java index 5c5f04e4ddf..aa92242269f 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStepQueueManager.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStepQueueManager.java @@ -1,5 +1,17 @@ +/******************************************************************************* + * 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.debug.IRunControl.IExecutionDMC; +import org.eclipse.dd.dsf.model.IDataModelEvent; import org.eclipse.dd.dsf.service.IDsfService; /** @@ -11,7 +23,21 @@ import org.eclipse.dd.dsf.service.IDsfService; * about to be executed. */ public interface IStepQueueManager extends IDsfService { + /** + * Amount of time in miliseconds, that it takes the ISteppingTimedOutEvent + * event to be issued after a step is started. + * @see ISteppingTimedOutEvent + */ + public final static int STEPPING_TIMEOUT = 500; + /** + * 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 { + } + + void setStepQueueDepth(int depth); int getStepQueueDepth(); @@ -24,8 +50,10 @@ public interface IStepQueueManager extends IDsfService { /** * Checks whether a step command can be queued up for given context. */ - void canEnqueueStep(IRunControl.IExecutionDMC execCtx); - + boolean canEnqueueStep(IRunControl.IExecutionDMC execCtx); + + boolean canEnqueueInstructionStep(IRunControl.IExecutionDMC execCtx); + /** * Adds a step command to the execution queue for given context. * @param execCtx Execution context that should perform the step. @@ -40,4 +68,6 @@ public interface IStepQueueManager extends IDsfService { * @param stepType Type of step to execute. */ void enqueueInstructionStep(IRunControl.IExecutionDMC execCtx, IRunControl.StepType stepType); + + boolean isSteppingTimedOut(IExecutionDMC context); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ISymbols.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ISymbols.java index c3863dd259a..95c82ca6e06 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ISymbols.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ISymbols.java @@ -1,3 +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 + *******************************************************************************/ package org.eclipse.dd.dsf.debug; import org.eclipse.dd.dsf.concurrent.GetDataDone; diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ITargets.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ITargets.java index a90c2f68fbc..f142efe9393 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ITargets.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ITargets.java @@ -1,3 +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 + *******************************************************************************/ package org.eclipse.dd.dsf.debug; import org.eclipse.dd.dsf.concurrent.Done; diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java index 33820e7114b..019cb5b8b2e 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java @@ -305,9 +305,9 @@ public class DsfSession if (o1.fListener == o2.fListener) { return 0; } if (o1.fListener instanceof IDsfService && !(o2.fListener instanceof IDsfService)) { - return Integer.MAX_VALUE; - } else if (o2.fListener instanceof IDsfService && !(o1.fListener instanceof IDsfService)) { return Integer.MIN_VALUE; + } else if (o2.fListener instanceof IDsfService && !(o1.fListener instanceof IDsfService)) { + return Integer.MAX_VALUE; } else if ( (o1.fListener instanceof IDsfService) && (o2.fListener instanceof IDsfService) ) { return ((IDsfService)o1.fListener).getStartupNumber() - ((IDsfService)o2.fListener).getStartupNumber(); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java index 26f72fec26e..b834d757dba 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java @@ -50,6 +50,15 @@ public interface IDsfService { */ DsfExecutor getExecutor(); + /** + * Returns the map of properties that this service was registered with. + *
    + * TODO: is returning the properties and service filter redundant? Should + * getServiceFilter() be removed from the interface since it can be generated + * from the properties? + */ + Dictionary getProperties(); + /** * Returns a filter string that can be used to uniquely identify this * service. This filter string should be based on the properties and class From 2adca3eb1d8693a96c5d29029af70a072c4fcc8d Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 25 Aug 2006 16:59:16 +0000 Subject: [PATCH 014/834] Added Paining of IP in editor, and finished optimizing stepping. --- .../src/org/eclipse/dd/dsf/debug/IStack.java | 1 + .../src/org/eclipse/dd/dsf/model/DMCs.java | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStack.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStack.java index 7d26f13928f..107b0fdabec 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStack.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStack.java @@ -33,6 +33,7 @@ public interface IStack extends IDataModelService { * Stack frame information. */ public interface IFrameData extends IDataModelData { + int getLevel(); IAddress getAddress(); String getFile(); String getFunction(); diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/DMCs.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/DMCs.java index 14d77050f14..923621244b6 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/DMCs.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/DMCs.java @@ -43,4 +43,29 @@ public class DMCs { return null; } + /** + * Checks all ancestors for a given DMC 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. + * @return true if a match is found. + */ + public static boolean isAncestorOf(IDataModelContext dmc, IDataModelContext potentialAncestor) { + // Check the direct parents for a match. + for (IDataModelContext parentDmc : dmc.getParents()) { + if (potentialAncestor.equals(parentDmc)) { + return true; + } + } + + // Recursively check the parents' parents for a match. + for (IDataModelContext parentDmc : dmc.getParents()) { + if (isAncestorOf(parentDmc, potentialAncestor)) { + return true; + } + } + + // No match. + return false; + } } From 9a2e04c09ad4450ffa0ba62bc733a5145841dcf2 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 25 Aug 2006 21:52:40 +0000 Subject: [PATCH 015/834] Added provider name to plugins (Bug 154346). Added a stack trace collecting mechanism to DsfRunnable. --- .../META-INF/MANIFEST.MF | 3 ++- .../org.eclipse.dd.dsf.ui/plugin.properties | 13 ++++++++++ .../org.eclipse.dd.dsf/META-INF/MANIFEST.MF | 3 ++- plugins/org.eclipse.dd.dsf/plugin.properties | 13 ++++++++++ .../dd/dsf/concurrent/DsfRunnable.java | 24 +++++++++++++++++++ 5 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf.ui/plugin.properties create mode 100644 plugins/org.eclipse.dd.dsf/plugin.properties diff --git a/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF index 753bd6411e2..7e3baf87e0e 100644 --- a/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF @@ -1,6 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 -Bundle-Name: Ui Plug-in +Bundle-Name: %pluginName +Bundle-Vendor: %providerName Bundle-SymbolicName: org.eclipse.dd.dsf.ui Bundle-Version: 1.0.0 Bundle-Activator: org.eclipse.dd.dsf.ui.DsfUIPlugin diff --git a/plugins/org.eclipse.dd.dsf.ui/plugin.properties b/plugins/org.eclipse.dd.dsf.ui/plugin.properties new file mode 100644 index 00000000000..67ffce67f7c --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/plugin.properties @@ -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), UI +providerName=Eclipse.org + diff --git a/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF index b9ae36656fd..5b33ce3d3d5 100644 --- a/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF @@ -1,6 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 -Bundle-Name: DSF Plug-in +Bundle-Name: %pluginName +Bundle-Vendor: %providerName Bundle-SymbolicName: org.eclipse.dd.dsf Bundle-Version: 1.0.0 Bundle-Activator: org.eclipse.dd.dsf.DsfPlugin diff --git a/plugins/org.eclipse.dd.dsf/plugin.properties b/plugins/org.eclipse.dd.dsf/plugin.properties new file mode 100644 index 00000000000..7152bf0a89d --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/plugin.properties @@ -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) +providerName=Eclipse.org + diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfRunnable.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfRunnable.java index 65bc577c7df..6318b8a9dcb 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfRunnable.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfRunnable.java @@ -18,4 +18,28 @@ package org.eclipse.dd.dsf.concurrent; * place holder for future tracing enhancments for DSF. */ abstract public class DsfRunnable implements Runnable { + private StackTraceElement [] fStackTrace = null; + + public DsfRunnable() { + // Use assertion flag (-ea) to jre to avoid affecting performance when not debugging. + boolean assertsEnabled = false; + assert assertsEnabled = true; + if (assertsEnabled) { + fStackTrace = Thread.currentThread().getStackTrace(); + } + } + + public String toString () { + // If assertions are not turned on. + if (fStackTrace == null) return super.toString(); + + StringBuilder builder = new StringBuilder() ; + // ommit the first elements in the stack trace + for ( int i= 3 ; i < fStackTrace.length; i++ ) { + builder.append ( "\tat " ) ; + builder.append ( fStackTrace [ i ] .toString ()) ; + builder.append ( "\n" ) ; + } + return builder.toString () ; + } } From 5516763481bec42b6075646195ebd5808e473be2 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 1 Sep 2006 16:41:08 +0000 Subject: [PATCH 016/834] Added basic breakpoint support. Other cosmetic changes. --- .../eclipse/dd/dsf/debug/IBreakpoints.java | 37 +++++++++++++++---- .../src/org/eclipse/dd/dsf/debug/IStack.java | 5 +-- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IBreakpoints.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IBreakpoints.java index 68d8dbf9bd5..dab9151288f 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IBreakpoints.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IBreakpoints.java @@ -10,18 +10,41 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug; +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.service.IDsfService; +import org.eclipse.debug.core.model.IBreakpoint; /** - * Note: This interface is just a place-holder. + * Breakpoint service interface. The breakpoint service tracks platform breakpoint + * objects, and based on those, it manages breakpoints in the debugger back end. + * The purpose of the service model interface is to allow UI clients to display + * breakpoint status in more detail and more dynamically than it it possible with + * just the marker-based breakpoint object. */ public interface IBreakpoints extends IDsfService { - public class BreakpointEvent { - public final int fLineNumber; - public BreakpointEvent(int line) { - fLineNumber = line; - } - } + public enum BreakpointStatus { INSTALLED, FAILED_TO_INSTALL, FILTERED_OUT } + + public interface IBreakpointDMC extends IDataModelContext {} + + public interface IBreakpointData extends IDataModelData { + IBreakpoint getPlatformBreakpoint(); + BreakpointStatus getStatus(); + } + + public interface IBreakpointEvent extends IDataModelEvent {} + + public interface IBreakpointInstalledEvent extends IBreakpointEvent {} + public interface IBreakpointUninstalledEvent extends IBreakpointEvent {} + public interface IBreakpointInstallFailedEvent extends IBreakpointEvent {} + + public interface IBreakpointHitEvent extends IBreakpointEvent {} + + public void getAllBreakpoints(IExecutionDMC execDmc, GetDataDone done); + public void getBreakpoints(IExecutionDMC execDmc, IBreakpoint platformBp, GetDataDone done); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStack.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStack.java index 107b0fdabec..b2598629896 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStack.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStack.java @@ -46,14 +46,13 @@ public interface IStack extends IDataModelService { * expression information. For displaying complete information, * Expressions service should be used. */ - public interface IVariableDMC extends IDataModelContext {} + public interface IVariableDMC extends IDataModelContext {} /** * Stack frame variable information. */ - public interface VariableData extends IDataModelData { + public interface IVariableData extends IDataModelData { String getName(); - String getTypeName(); String getValue(); } From 5fa8b64ad62d7733e92dca898d321e6d53d7a2e9 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 28 Sep 2006 18:14:14 +0000 Subject: [PATCH 017/834] DSF Updates related to adding registers view. --- .../dsf/ui/model/DataViewModelSchemaNode.java | 5 +- .../dd/dsf/ui/model/IViewModelSchemaNode.java | 4 +- .../dd/dsf/ui/model/ViewModelDelta.java | 4 +- .../dd/dsf/ui/model/ViewModelProvider.java | 12 +++- plugins/org.eclipse.dd.dsf/.options | 2 + .../src/org/eclipse/dd/dsf/DsfPlugin.java | 15 ++++- .../dd/dsf/concurrent/DefaultDsfExecutor.java | 55 +++++++++++++++---- .../eclipse/dd/dsf/concurrent/DsfQuery.java | 3 +- .../dd/dsf/concurrent/DsfRunnable.java | 41 ++++++++++---- .../dd/dsf/concurrent/DsfSequence.java | 11 +--- .../concurrent/GetDataDoneWithClientDone.java | 3 + .../eclipse/dd/dsf/debug/IExpressions.java | 2 +- .../org/eclipse/dd/dsf/debug/IModules.java | 5 -- .../src/org/eclipse/dd/dsf/debug/IOS.java | 4 +- .../org/eclipse/dd/dsf/debug/IRegisters.java | 33 +++++------ .../src/org/eclipse/dd/dsf/debug/IStack.java | 4 -- .../org/eclipse/dd/dsf/debug/ISymbols.java | 10 ++-- .../eclipse/dd/dsf/model/DataModelEvent.java | 2 - .../dd/dsf/service/AbstractDsfService.java | 2 - .../dsf/service/DsfServiceEventHandler.java | 2 - .../eclipse/dd/dsf/service/DsfSession.java | 16 ++++-- .../eclipse/dd/dsf/service/IDsfService.java | 6 -- 22 files changed, 142 insertions(+), 99 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf/.options diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/DataViewModelSchemaNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/DataViewModelSchemaNode.java index 61a8355957c..04a7fed2faf 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/DataViewModelSchemaNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/DataViewModelSchemaNode.java @@ -65,7 +65,7 @@ abstract public class DataViewModelSchemaNode implements IViewModelSchemaNode { } public String toString() { - return fParent.toString() + "\n" + fDmc.toString(); + return fParent.toString() + "->" + fDmc.toString(); } } @@ -127,7 +127,7 @@ abstract public class DataViewModelSchemaNode implements IViewModelSchemaNode { fExecutor.execute(done); }}; - // TODO: Note this is pretty inefficient: for one the below loop could + // 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. @@ -222,7 +222,6 @@ abstract public class DataViewModelSchemaNode implements IViewModelSchemaNode { } public void sessionDispose() { - // FIXME: should track when disposed and avoid issuing model deltas fServices.dispose(); for (IViewModelSchemaNode childNode : getChildNodes()) { childNode.sessionDispose(); diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/IViewModelSchemaNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/IViewModelSchemaNode.java index 37beb9413ce..3e6679e1b12 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/IViewModelSchemaNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/IViewModelSchemaNode.java @@ -45,14 +45,14 @@ public interface IViewModelSchemaNode { * current level. * @param done The data return token. */ - public void getElements(final IViewModelContext parentVmc, GetDataDone done); + public void getElements(IViewModelContext parentVmc, GetDataDone 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, final ILabelRequestMonitor result); + public void retrieveLabel(IViewModelContext vmc, ILabelRequestMonitor result); /** * Returns the list of child schema nodes which are configured for this node. diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/ViewModelDelta.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/ViewModelDelta.java index eb0dbf87004..9451da2e594 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/ViewModelDelta.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/ViewModelDelta.java @@ -18,9 +18,7 @@ import org.eclipse.debug.internal.ui.viewers.provisional.ModelDelta; * This delta class mostly just duplicates the ModelDelta implemention, but * it allows clients to modify the flags after the original object is * constructed. - *

    - * TODO: This class derives from ModelDelta as opposed to just implementing IModelDelta - * because of a reference in IModelDelta to ModelDelta. Need to file a bug on it. + * * @see IModelDelta#getNodes() */ @SuppressWarnings("restriction") diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/ViewModelProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/ViewModelProvider.java index 7a054a3457a..a36fccca031 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/ViewModelProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/ViewModelProvider.java @@ -108,6 +108,14 @@ public class ViewModelProvider extends AbstractModelProxy } } + 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. @@ -122,7 +130,7 @@ public class ViewModelProvider extends AbstractModelProxy // collect the list of children. Otherwise, get the child schema nodes // out of VMC's schema node. IViewModelSchemaNode[] childSchemaNodes; - if (vmc == fRootVMC) { + if (vmc == fRootVMC || !isOurSchemaNode(vmc.getSchemaNode(), fRootSchemaNodes)) { childSchemaNodes = fRootSchemaNodes; } else { childSchemaNodes = vmc.getSchemaNode().getChildNodes(); @@ -161,7 +169,7 @@ public class ViewModelProvider extends AbstractModelProxy // Get the child nodes as in isContainer(). IViewModelSchemaNode[] childSchemaNodes; - if (vmc == fRootVMC) { + if (vmc == fRootVMC || !isOurSchemaNode(vmc.getSchemaNode(), fRootSchemaNodes)) { childSchemaNodes = fRootSchemaNodes; } else { childSchemaNodes = vmc.getSchemaNode().getChildNodes(); diff --git a/plugins/org.eclipse.dd.dsf/.options b/plugins/org.eclipse.dd.dsf/.options new file mode 100644 index 00000000000..54b07bac112 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/.options @@ -0,0 +1,2 @@ +org.eclipse.dd.dsf/debug = false +org.eclipse.dd.dsf/debug/executor = false diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/DsfPlugin.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/DsfPlugin.java index a87ce47e211..7582eb85e83 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/DsfPlugin.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/DsfPlugin.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.dsf; +import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Plugin; import org.osgi.framework.BundleContext; @@ -24,8 +25,12 @@ public class DsfPlugin extends Plugin { // The shared instance private static DsfPlugin fgPlugin; + // BundleContext of this plugin private static BundleContext fgBundleContext; + // Debugging flag + public static boolean DEBUG = false; + /** * The constructor */ @@ -40,7 +45,8 @@ public class DsfPlugin extends Plugin { public void start(BundleContext context) throws Exception { fgBundleContext = context; super.start(context); - } + DEBUG = "true".equals(Platform.getDebugOption("org.eclipse.debug.ui/debug")); //$NON-NLS-1$//$NON-NLS-2$ + } /* * (non-Javadoc) @@ -64,5 +70,12 @@ public class DsfPlugin extends Plugin { public static BundleContext getBundleContext() { return fgBundleContext; } + + public static void debug(String message) { + if (DEBUG) { + System.out.println(message); + } + } + } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java index 5247c800a17..fd739eaf8fe 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java @@ -10,10 +10,17 @@ *******************************************************************************/ package org.eclipse.dd.dsf.concurrent; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ThreadFactory; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.DsfPlugin; @@ -25,6 +32,14 @@ import org.eclipse.dd.dsf.DsfPlugin; public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor implements DsfExecutor { + // debug tracing flags + public static boolean DEBUG_EXECUTOR = false; + static { + DEBUG_EXECUTOR = DsfPlugin.DEBUG && "true".equals( //$NON-NLS-1$ + Platform.getDebugOption("org.eclipse.dd.dsf/debug/executor")); //$NON-NLS-1$ + } + + static class DsfThreadFactory implements ThreadFactory { Thread fThread; public Thread newThread(Runnable r) { @@ -34,8 +49,6 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor } } - - public DefaultDsfExecutor() { super(1, new DsfThreadFactory()); } @@ -45,16 +58,36 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor } @Override - protected void afterExecute(Runnable r, Throwable t) { - // FIXME: Unfortunately this is not enough to catch runnable exceptions, because - // FutureTask implementation swallows exceptions when they're thrown by runnables. - // Need to override the FutureTask class, and the AbstractExecutorService.submit() - // methods in order to provide access to these exceptions. + protected void beforeExecute(Thread t, Runnable r) { + System.out.println(""); + + + } - super.afterExecute(r, t); - if (t != null) { - DsfPlugin.getDefault().getLog().log(new Status( - IStatus.ERROR, DsfPlugin.PLUGIN_ID, -1, "Uncaught exception in dispatch thread.", t)); + @Override + protected void afterExecute(Runnable r, Throwable t) { + if (r instanceof Future) { + Future future = (Future)r; + try { + future.get(); + } catch (InterruptedException e) { // Ignore + } catch (CancellationException e) { // Ignore also + } catch (ExecutionException e) { + if (e.getCause() != null) { + DsfPlugin.getDefault().getLog().log(new Status( + IStatus.ERROR, DsfPlugin.PLUGIN_ID, -1, "Uncaught exception in DSF executor thread", e.getCause())); + if (DEBUG_EXECUTOR) { + ByteArrayOutputStream outStream = new ByteArrayOutputStream(512); + PrintStream printStream = new PrintStream(outStream); + try { + printStream.write("Uncaught exception in session executor thread: ".getBytes()); + } catch (IOException e2) {} + e.getCause().printStackTrace(new PrintStream(outStream)); + DsfPlugin.debug(outStream.toString()); + } + } + } } } + } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfQuery.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfQuery.java index 71e9d7ef9dd..bf26e3f77d4 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfQuery.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfQuery.java @@ -25,7 +25,6 @@ import org.eclipse.dd.dsf.DsfPlugin; * data at end of Callable#call method. * * @see java.util.concurrent.Callable - * FIXME: make this class implement the Future interface. */ abstract public class DsfQuery { @@ -66,7 +65,7 @@ abstract public class DsfQuery { if (!fWaiting) { fFuture = fExecutor.submit(new DsfRunnable() { public void run() { - // TODO: not sure if this try-catch is desirable. It might encourage + // Note: not sure if this try-catch is desirable. It might encourage // implementors to not catch its own exceptions. If the query code takes // more than one dispatch, then this code will not be helpful anyway. try { diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfRunnable.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfRunnable.java index 6318b8a9dcb..47efc51d75b 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfRunnable.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfRunnable.java @@ -14,32 +14,49 @@ package org.eclipse.dd.dsf.concurrent; * A DSF-instrumented alternative to the Runnable interface. *

    * While it is perfectly fine for clients to call the DSF executor with - * an object only implementing the Runnable interface, the DsfRunnable is a - * place holder for future tracing enhancments for DSF. + * an object only implementing the Runnable interface, the DsfRunnable + * contains fields and methods that used for debugging and tracing when + * tracing is enabled. */ abstract public class DsfRunnable implements Runnable { private StackTraceElement [] fStackTrace = null; + private Runnable fSubmittedBy = null; public DsfRunnable() { // Use assertion flag (-ea) to jre to avoid affecting performance when not debugging. boolean assertsEnabled = false; assert assertsEnabled = true; - if (assertsEnabled) { + if (assertsEnabled || DefaultDsfExecutor.DEBUG_EXECUTOR) { fStackTrace = Thread.currentThread().getStackTrace(); } } public String toString () { - // If assertions are not turned on. - if (fStackTrace == null) return super.toString(); - StringBuilder builder = new StringBuilder() ; - // ommit the first elements in the stack trace - for ( int i= 3 ; i < fStackTrace.length; i++ ) { - builder.append ( "\tat " ) ; - builder.append ( fStackTrace [ i ] .toString ()) ; - builder.append ( "\n" ) ; + // If assertions are not turned on. + builder.append(super.toString()); + if (fStackTrace != null) { + builder.append ( "\n\tCreated at" ) ; + + // ommit the first elements in the stack trace + for (int i = 3; i < fStackTrace.length && i < 13; i++) { + if (i > 3) builder.append ( "\tat " ) ; + builder.append( fStackTrace [ i ] .toString ()) ; + builder.append( "\n" ) ; + } + if (fStackTrace.length > 13) { + builder.append("\t at ..."); + } } - return builder.toString () ; + if (fSubmittedBy != null) { + builder.append("Submitted by \n"); + builder.append(fSubmittedBy.toString()); + } + + return builder.toString(); } + + void setSubmittedBy(Runnable runnable) { + fSubmittedBy = runnable; + } } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java index 47c752d0af7..3de19cd88ae 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java @@ -38,18 +38,11 @@ import org.eclipse.dd.dsf.DsfPlugin; * if progress reporting, cancellability, and roll-back ability is required, it * has to be re-implemented every time. The Sequence class tries to address * this problem by containing this pattern in a single class. - * - *
    TODO: should a sequence be re-entrant. I.e. should the arguments be - * passed in through a map, and the return values returned back in the done? - *
    FIXME: convert to implement Future interface */ abstract public class DsfSequence { /** * The abstract class that each step has to implement - *
    FIXME: convert execute() and rollBacl() to take "done" as an argument. - * This way we can make step a static class, and make its paradigm - * more consistent with rest of DSF. */ abstract public class Step { public void execute() { stepFinished(); } @@ -165,9 +158,7 @@ abstract public class DsfSequence { invokeLater(); try { wait(); - } catch (InterruptedException e) { - // TODO: error handling? - } + } catch (InterruptedException e) {} } private void doInvoke() { diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/GetDataDoneWithClientDone.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/GetDataDoneWithClientDone.java index 0affa1ff7ae..a05877f1168 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/GetDataDoneWithClientDone.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/GetDataDoneWithClientDone.java @@ -16,6 +16,9 @@ import org.eclipse.core.runtime.IStatus; * Convenience extension to GetDataDone, which handles posting of the client's * Done upon the completion of this GetDataDone. * @param Class type of data. + * @deprecated This class has been replaced with the + * {@link Done#propagateErrorToClient(DsfExecutor, Done, int, String)} + * method. */ public abstract class GetDataDoneWithClientDone extends GetDataDone { private DsfExecutor fExecutor; diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IExpressions.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IExpressions.java index 6d32378f8b9..74969e81202 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IExpressions.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IExpressions.java @@ -53,7 +53,7 @@ public interface IExpressions extends IDataModelService { String getBinaryValue(); String getStringValue(); IAddress getAddress(); - IRegisters.RegisterDMC getRegister(); + IRegisters.IRegisterDMC getRegister(); Map getEnumerations(); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IModules.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IModules.java index 9d30a3e7f46..caa2cb80667 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IModules.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IModules.java @@ -21,11 +21,6 @@ import org.eclipse.dd.dsf.model.IDataModelService; /** * Debugger service representing module handling logic of a debugger. - *
    - * TODO: I meant this as a replacement for Application service as well as the - * registry API in DSF 1. But I still don't fully understand the format - * of the symbol data that is stored in the registry, so that needs to be added - * to this interface. */ public interface IModules extends IDataModelService { diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IOS.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IOS.java index 2e3af9bd707..4862e922375 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IOS.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IOS.java @@ -21,9 +21,7 @@ import org.eclipse.dd.dsf.model.IDataModelService; * manipulate those objects. This is a much more extensive interface than * the NativeProcesses service but for simple debugging, it serves the same * purpose: to list/create/terminate processes and attach debugger to them. - *

    - * TODO: need methods for performing actions on objects (create, terminate, - * etc). + * * @see INativeProcesses */ public interface IOS extends IDataModelService { diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IRegisters.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IRegisters.java index 586add23540..de9409a5260 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IRegisters.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IRegisters.java @@ -22,24 +22,25 @@ import org.eclipse.dd.dsf.model.IDataModelService; public interface IRegisters extends IDataModelService { /** Register group context */ - public interface RegisterGroupDMC extends IDataModelContext {} + public interface IRegisterGroupDMC extends IDataModelContext {} /** * Register groups only have a name. Sub groups and registered are retrieved * through the service interface. */ - public interface RegisterGroupData extends IDataModelData { + public interface IRegisterGroupData extends IDataModelData { public String getName(); + public String getDescription(); } /** Register context */ - public interface RegisterDMC extends IDataModelContext {} + public interface IRegisterDMC extends IDataModelContext {} /** Event indicating register value changed. */ - public interface RegisterChangedEvent extends IDataModelEvent {} + public interface IRegisterChangedEvent extends IDataModelEvent {} /** Register information */ - public interface RegisterData extends IDataModelData, NumericalValue { + public interface IRegisterData extends IDataModelData, INumericalValue { String getName(); String getDescription(); boolean isReadable(); @@ -52,13 +53,13 @@ public interface IRegisters extends IDataModelService { } /** Bit field context */ - public interface BitFieldDMC extends IDataModelContext {} + public interface IBitFieldDMC extends IDataModelContext {} /** * Bitfield data, big groups and mnemonics are retrieved at the same * time as rest of bit field data */ - public interface BitFieldData extends IDataModelData, NumericalValue { + public interface IBitFieldData extends IDataModelData, INumericalValue { String getName(); String getDescription(); boolean isReadable(); @@ -68,18 +69,18 @@ public interface IRegisters extends IDataModelService { boolean hasSideEffects(); boolean isZeroBasedNumbering(); boolean isZeroBitLeftMost(); - BitGroup[] getBitGroup(); - Mnemonic[] getMnemonics(); + IBitGroup[] getBitGroup(); + IMnemonic[] getMnemonics(); } /** Bit group definition */ - public interface BitGroup { + public interface IBitGroup { int startBit(); int bitCount(); } /** Bit field mnemonic */ - public interface Mnemonic extends NumericalValue { + public interface IMnemonic extends INumericalValue { String getShortName(); String getLongName(); } @@ -88,7 +89,7 @@ public interface IRegisters extends IDataModelService { * Common interface for describing a number value for various register * data objects */ - public interface NumericalValue { + public interface INumericalValue { String getNaturalValue(); String getHexValue(); String getOctalValue(); @@ -101,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 done); + void getRegisterGroups(IRunControl.IExecutionDMC execCtx, IStack.IFrameDMC frameCtx, GetDataDone done); /** Retrieves list of sub-groups of given register group. */ - void getRegisterSubGroups(RegisterGroupDMC groupCtx, GetDataDone done); + void getRegisterSubGroups(IRegisterGroupDMC groupCtx, GetDataDone done); /** Retrieves registers in given register group. */ - void getRegisters(RegisterGroupDMC groupCtx, GetDataDone done); + void getRegisters(IRegisterGroupDMC groupCtx, GetDataDone done); /** Retrieves bit fields for given register */ - void getBitFields(RegisterDMC regCtx, GetDataDone done); + void getBitFields(IRegisterDMC regCtx, GetDataDone done); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStack.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStack.java index b2598629896..13936f96425 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStack.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStack.java @@ -58,10 +58,6 @@ public interface IStack extends IDataModelService { /** * Returns whether the stack frames can be retrieved for given thread. - *
    - * TODO: I'm not sure if this method should be async. It assumes that the - * implementation can determine if stack is available based on process - * state information. */ boolean isStackAvailable(IRunControl.IExecutionDMC execContext); diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ISymbols.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ISymbols.java index 95c82ca6e06..be5d03437a4 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ISymbols.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ISymbols.java @@ -23,12 +23,12 @@ import org.eclipse.dd.dsf.model.IDataModelService; * @see IModules */ public interface ISymbols extends IDataModelService { - public interface SymbolObjectDMC extends IDataModelContext {} + public interface ISymbolObjectDMC extends IDataModelContext {} /** * Data about a debug symbol. */ - public interface SymbolObjectData extends IDataModelData { + public interface ISymbolObjectData extends IDataModelData { String getName(); String getTypeName(); String getFilepath(); @@ -41,10 +41,8 @@ public interface ISymbols extends IDataModelService { * even while it's still parsing. This event may be issued periodically * by the service to indicate that a section of debug symbols has been * parsed. - * TODO: This is not an IModelEvent because the context of this event is - * the whole service. This needs to be fixed. */ - public interface SymbolDataChanged extends IDataModelEvent {} + public interface ISymbolDataChanged extends IDataModelEvent {} /** * Retrieves the list of symbols. @@ -52,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> done); + public void getSymbols(IModules.ISymbolDMC symCtx, GetDataDone> done); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/DataModelEvent.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/DataModelEvent.java index 7a41740ea07..681b62defae 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/DataModelEvent.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/DataModelEvent.java @@ -12,8 +12,6 @@ package org.eclipse.dd.dsf.model; /** * Base implementation of the IDataModelContext interface. - *

    - * TODO: consider merging the event interface with this class. */ public class DataModelEvent implements IDataModelEvent { diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java index 98c674b9f39..90bdc508b5a 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java @@ -87,8 +87,6 @@ abstract public class AbstractDsfService /** * Registers this service. - *
    FIXME: Move registering call to default initialize()/shutdown(). Add a new - * protected method calcProperties() to get the initial list of properties. */ @SuppressWarnings("unchecked") protected void register(String[] classes, Dictionary properties) { diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServiceEventHandler.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServiceEventHandler.java index d82886fae2f..c66f71c29c5 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServiceEventHandler.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServiceEventHandler.java @@ -34,8 +34,6 @@ import java.lang.annotation.Target; * will be called every time one of the sub-class events is invoked. * If a listener declares a handler for an event AND a superclass of that event, * both handlers will be invoked when the event is dispatched. - * - *
    TODO: Handling of second argument is not yet implemented. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java index 019cb5b8b2e..7f5b867504d 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java @@ -136,11 +136,12 @@ public class DsfSession * thread, but the session-started listeners will be called using the session's * executor. * @param executor The DSF executor to use for this session. + * @param ownerId ID (plugin ID preferably) of the owner of this session * @return instance object of the new session */ - public static DsfSession startSession(DsfExecutor executor) { + public static DsfSession startSession(DsfExecutor executor, String ownerId) { synchronized(fgActiveSessions) { - final DsfSession newSession = new DsfSession(executor, Integer.toString(fgSessionIdCounter++)); + final DsfSession newSession = new DsfSession(executor, ownerId, Integer.toString(fgSessionIdCounter++)); fgActiveSessions.add(newSession); executor.submit( new DsfRunnable() { public void run() { SessionStartedListener[] listeners = fSessionStartedListeners.toArray( @@ -191,6 +192,9 @@ public class DsfSession public int hashCode() { return fListener.hashCode(); } } + /** ID (plugin ID preferably) of the owner of this session */ + private String fOwnerId; + /** Session ID of this session. */ private String fId; @@ -210,6 +214,8 @@ public class DsfSession */ private Map fAdapters = Collections.synchronizedMap(new HashMap()); + /** Returns the owner ID of this session */ + public String getOwnerId() { return fOwnerId; } /** Returns the ID of this session */ public String getId() { return fId; } @@ -256,10 +262,7 @@ public class DsfSession */ public void dispatchEvent(final Object event, final Dictionary serviceProperties) { getExecutor().submit(new DsfRunnable() { public void run() { - // TED added FIXME otherwise no way to detect!!! - try { doDispatchEvent(event, serviceProperties); - } catch(Throwable e) { e.printStackTrace(); } }}); } @@ -387,8 +390,9 @@ public class DsfSession /** * Class to be instanciated only using startSession() */ - private DsfSession(DsfExecutor executor, String id) { + private DsfSession(DsfExecutor executor, String ownerId, String id) { fId = id; + fOwnerId = ownerId; fExecutor = executor; } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java index b834d757dba..b7f06f75db7 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java @@ -32,8 +32,6 @@ import org.eclipse.dd.dsf.concurrent.DsfExecutor; * service exposes a method that is to be called on non-dispatch thread, it should * be documented so. * - * TODO: Add IStatus error code constants for common service related failures. - * * @see org.osgi.framework.BundleContext#registerService(String[], Object, Dictionary) */ public interface IDsfService { @@ -52,10 +50,6 @@ public interface IDsfService { /** * Returns the map of properties that this service was registered with. - *
    - * TODO: is returning the properties and service filter redundant? Should - * getServiceFilter() be removed from the interface since it can be generated - * from the properties? */ Dictionary getProperties(); From 97edaeb59d1d395413dceb6186aec8e1a6782dba Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 28 Sep 2006 21:40:28 +0000 Subject: [PATCH 018/834] Got rid of an erronous System.out.println(). --- .../org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java index fd739eaf8fe..f24b8932804 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java @@ -57,13 +57,6 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor return Thread.currentThread().equals( ((DsfThreadFactory)getThreadFactory()).fThread ); } - @Override - protected void beforeExecute(Thread t, Runnable r) { - System.out.println(""); - - - } - @Override protected void afterExecute(Runnable r, Throwable t) { if (r instanceof Future) { From 60ce7f8c100db5e4e084c6857ef69203a1d9b2ea Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 3 Oct 2006 00:54:57 +0000 Subject: [PATCH 019/834] Added generic tracing to the executor (bug# 159052). --- .../src/org/eclipse/dd/dsf/DsfPlugin.java | 2 +- .../dd/dsf/concurrent/DefaultDsfExecutor.java | 243 +++++++++++++++++- .../org/eclipse/dd/dsf/concurrent/Done.java | 4 + .../dd/dsf/concurrent/DsfExecutable.java | 62 +++++ .../dd/dsf/concurrent/DsfRunnable.java | 43 +--- .../dd/dsf/concurrent/GetDataDone.java | 8 + 6 files changed, 310 insertions(+), 52 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/DsfPlugin.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/DsfPlugin.java index 7582eb85e83..abcae5d1d16 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/DsfPlugin.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/DsfPlugin.java @@ -45,7 +45,7 @@ public class DsfPlugin extends Plugin { public void start(BundleContext context) throws Exception { fgBundleContext = context; super.start(context); - DEBUG = "true".equals(Platform.getDebugOption("org.eclipse.debug.ui/debug")); //$NON-NLS-1$//$NON-NLS-2$ + DEBUG = "true".equals(Platform.getDebugOption("org.eclipse.dd.dsf/debug")); //$NON-NLS-1$//$NON-NLS-2$ } /* diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java index f24b8932804..bae93caaf90 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java @@ -13,11 +13,16 @@ package org.eclipse.dd.dsf.concurrent; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.PrintStream; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.Callable; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; +import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; @@ -32,14 +37,7 @@ import org.eclipse.dd.dsf.DsfPlugin; public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor implements DsfExecutor { - // debug tracing flags - public static boolean DEBUG_EXECUTOR = false; - static { - DEBUG_EXECUTOR = DsfPlugin.DEBUG && "true".equals( //$NON-NLS-1$ - Platform.getDebugOption("org.eclipse.dd.dsf/debug/executor")); //$NON-NLS-1$ - } - - + /** Thread factory that creates the single thread to be used for this executor */ static class DsfThreadFactory implements ThreadFactory { Thread fThread; public Thread newThread(Runnable r) { @@ -51,6 +49,11 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor public DefaultDsfExecutor() { super(1, new DsfThreadFactory()); + if(DEBUG_EXECUTOR || ASSERTIONS_ENABLED) { + // If tracing, pre-start the dispatch thread, and add it to the map. + prestartAllCoreThreads(); + fThreadToExecutorMap.put(((DsfThreadFactory)getThreadFactory()).fThread, DefaultDsfExecutor.this); + } } public boolean isInExecutorThread() { @@ -69,18 +72,238 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor if (e.getCause() != null) { DsfPlugin.getDefault().getLog().log(new Status( IStatus.ERROR, DsfPlugin.PLUGIN_ID, -1, "Uncaught exception in DSF executor thread", e.getCause())); - if (DEBUG_EXECUTOR) { + + // Print out the stack trace to console if assertions are enabled. + if(ASSERTIONS_ENABLED) { ByteArrayOutputStream outStream = new ByteArrayOutputStream(512); PrintStream printStream = new PrintStream(outStream); try { printStream.write("Uncaught exception in session executor thread: ".getBytes()); } catch (IOException e2) {} e.getCause().printStackTrace(new PrintStream(outStream)); - DsfPlugin.debug(outStream.toString()); + System.err.println(outStream.toString()); } } } } } + + // + // Utilities used for tracing. + // + static boolean DEBUG_EXECUTOR = false; + static boolean ASSERTIONS_ENABLED = false; + static { + DEBUG_EXECUTOR = DsfPlugin.DEBUG && "true".equals( //$NON-NLS-1$ + Platform.getDebugOption("org.eclipse.dd.dsf/debug/executor")); //$NON-NLS-1$ + assert ASSERTIONS_ENABLED = true; + } + + /** + * This map is used by DsfRunnable/DsfQuery/DsfCallable to track by which executor + * an executable object was created. + *
    Note: Only used when tracing. + */ + static Map fThreadToExecutorMap = new HashMap(); + + /** + * Currently executing runnable/callable. + *
    Note: Only used when tracing. + */ + TracingWrapper fCurrentlyExecuting; + + /** + * Counter number saved by each tracing runnable when executed + *
    Note: Only used when tracing. + */ + int fSequenceCounter; + + /** + * Wrapper for runnables/callables, is used to store tracing information + *
    Note: Only used when tracing. + */ + abstract class TracingWrapper { + /** Sequence number of this runnable/callable */ + int fSequenceNumber = -1; + + /** Trace of where the runnable/callable was submitted to the executor */ + StackTraceElement[] fSubmittedAt = null; + + /** Reference to the runnable/callable that submitted this runnable/callable to the executor */ + TracingWrapper fSubmittedBy = null; + + /** + * @param offset the number of items in the stack trace not to be printed + */ + TracingWrapper(int offset) { + StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); + fSubmittedAt = new StackTraceElement[stackTrace.length - offset]; + System.arraycopy(stackTrace, offset - 1, fSubmittedAt, 0, fSubmittedAt.length); + if (isInExecutorThread() && fCurrentlyExecuting != null) { + fSubmittedBy = fCurrentlyExecuting; + } + } + + void traceExecution() { + fSequenceNumber = fSequenceCounter++; + fCurrentlyExecuting = this; + + // Write to console only if tracing is enabled (as opposed to tracing or assertions). + if (DEBUG_EXECUTOR) { + StringBuilder traceBuilder = new StringBuilder(); + + // Record the time + long time = System.currentTimeMillis(); + long seconds = (time / 1000) % 1000; + if (seconds < 100) traceBuilder.append('0'); + if (seconds < 10) traceBuilder.append('0'); + traceBuilder.append(seconds); + traceBuilder.append(','); + long millis = time % 1000; + if (millis < 100) traceBuilder.append('0'); + if (millis < 10) traceBuilder.append('0'); + traceBuilder.append(millis); + traceBuilder.append(' '); + + // Record the executor # + traceBuilder.append('#'); + traceBuilder.append(fSequenceNumber); + traceBuilder.append(' '); + + // Append executable class name + traceBuilder.append(getExecutable().getClass().getName()); + if (getExecutable() instanceof DsfExecutable) { + DsfExecutable dsfExecutable = (DsfExecutable)getExecutable(); + if (dsfExecutable.fCreatedAt != null || dsfExecutable.fCreatedBy != null) { + traceBuilder.append("\n Created "); + if (dsfExecutable.fCreatedBy != null) { + traceBuilder.append(" by #"); + traceBuilder.append(dsfExecutable.fCreatedBy.fSequenceNumber); + } + if (dsfExecutable.fCreatedAt != null) { + traceBuilder.append(" at "); + traceBuilder.append(dsfExecutable.fCreatedAt[0].toString()); + } + } + } + + // Submitted info + traceBuilder.append("\n "); + traceBuilder.append("Submitted"); + if (fSubmittedBy != null) { + traceBuilder.append(" by #"); + traceBuilder.append(fSubmittedBy.fSequenceNumber); + } + traceBuilder.append(" at "); + traceBuilder.append(fSubmittedAt[0].toString()); + + // Finally, the executable's toString(). + traceBuilder.append("\n "); + traceBuilder.append(getExecutable().toString()); + + // Finally write out to console + DsfPlugin.debug(traceBuilder.toString()); + } + } + + abstract protected Object getExecutable(); + } + + class TracingWrapperRunnable extends TracingWrapper implements Runnable { + final Runnable fRunnable; + public TracingWrapperRunnable(Runnable runnable, int offset) { + super(offset); + fRunnable = runnable; + } + + protected Object getExecutable() { return fRunnable; } + + public void run() { + traceExecution(); + fRunnable.run(); + } + } + + public class TracingWrapperCallable extends TracingWrapper implements Callable { + final Callable fCallable; + public TracingWrapperCallable(Callable callable, int offset) { + super(offset); + fCallable = callable; + } + + protected Object getExecutable() { return fCallable; } + + public T call() throws Exception { + traceExecution(); + return fCallable.call(); + } + } + + @Override + public ScheduledFuture schedule(Callable callable, long delay, TimeUnit unit) { + if(DEBUG_EXECUTOR || ASSERTIONS_ENABLED) { + if ( !(callable instanceof TracingWrapper) ) { + callable = new TracingWrapperCallable(callable, 6); + } + } + return super.schedule(callable, delay, unit); + } + @Override + public ScheduledFuture schedule(Runnable command, long delay, TimeUnit unit) { + if(DEBUG_EXECUTOR || ASSERTIONS_ENABLED) { + if ( !(command instanceof TracingWrapper) ) { + command = new TracingWrapperRunnable(command, 6); + } + } + return super.schedule(command, delay, unit); + } + + @Override + public ScheduledFuture scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) { + if(DEBUG_EXECUTOR || ASSERTIONS_ENABLED) { + command = new TracingWrapperRunnable(command, 6); + } + return super.scheduleAtFixedRate(command, initialDelay, period, unit); + } + + @Override + public ScheduledFuture scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) { + if(DEBUG_EXECUTOR || ASSERTIONS_ENABLED) { + command = new TracingWrapperRunnable(command, 6); + } + return super.scheduleWithFixedDelay(command, initialDelay, delay, unit); + } + + @Override + public void execute(Runnable command) { + if(DEBUG_EXECUTOR || ASSERTIONS_ENABLED) { + command = new TracingWrapperRunnable(command, 6); + } + super.execute(command); + } + + @Override + public Future submit(Runnable command) { + if(DEBUG_EXECUTOR || ASSERTIONS_ENABLED) { + command = new TracingWrapperRunnable(command, 6); + } + return super.submit(command); + } + + @Override + public Future submit(Callable callable) { + if(DEBUG_EXECUTOR || ASSERTIONS_ENABLED) { + callable = new TracingWrapperCallable(callable, 6); + } + return super.submit(callable); + } + + @Override + public Future submit(Runnable command, T result) { + if(DEBUG_EXECUTOR || ASSERTIONS_ENABLED) { + command = new TracingWrapperRunnable(command, 6); + } + return super.submit(command, result); + } } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java index 1c7632d546b..28f504be1ab 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java @@ -63,4 +63,8 @@ abstract public class Done extends DsfRunnable { } return false; } + + public String toString() { + return getStatus().toString(); + } } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java new file mode 100644 index 00000000000..2a845472759 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.concurrent; + +import java.util.HashSet; +import java.util.Set; + +/** + * Base class for DSF-instrumented alternative to the Runnable/Callable interfaces. + *

    + * While it is perfectly fine for clients to call the DSF executor with + * an object only implementing the Runnable/Callable interface, the DsfExecutable + * contains fields and methods that used for debugging and tracing when + * tracing is enabled. + */ +public class DsfExecutable { + final StackTraceElement[] fCreatedAt; + final DefaultDsfExecutor.TracingWrapper fCreatedBy; + + @SuppressWarnings("unchecked") + public DsfExecutable() { + // Use assertion flag (-ea) to jre to avoid affecting performance when not debugging. + boolean assertsEnabled = false; + assert assertsEnabled = true; + if (assertsEnabled || DefaultDsfExecutor.DEBUG_EXECUTOR) { + // Find the runnable/callable that is currently running. + DefaultDsfExecutor executor = DefaultDsfExecutor.fThreadToExecutorMap.get(Thread.currentThread()); + if (executor != null) { + fCreatedBy = executor.fCurrentlyExecuting; + } else { + fCreatedBy = null; + } + + // Get the stack trace and find the first method that is not a + // constructor of this object. + StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); + Class thisClass = getClass(); + Set classNamesSet = new HashSet(); + while(thisClass != null) { + classNamesSet.add(thisClass.getName()); + thisClass = thisClass.getSuperclass(); + } + int i; + for (i = 3; i < stackTrace.length; i++) { + if ( !classNamesSet.contains(stackTrace[i].getClassName()) ) break; + } + fCreatedAt = new StackTraceElement[stackTrace.length - i]; + System.arraycopy(stackTrace, i, fCreatedAt, 0, fCreatedAt.length); + } else { + fCreatedAt = null; + fCreatedBy = null; + } + } +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfRunnable.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfRunnable.java index 47efc51d75b..5640af81dcd 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfRunnable.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfRunnable.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.dsf.concurrent; + /** * A DSF-instrumented alternative to the Runnable interface. *

    @@ -18,45 +19,5 @@ package org.eclipse.dd.dsf.concurrent; * contains fields and methods that used for debugging and tracing when * tracing is enabled. */ -abstract public class DsfRunnable implements Runnable { - private StackTraceElement [] fStackTrace = null; - private Runnable fSubmittedBy = null; - - public DsfRunnable() { - // Use assertion flag (-ea) to jre to avoid affecting performance when not debugging. - boolean assertsEnabled = false; - assert assertsEnabled = true; - if (assertsEnabled || DefaultDsfExecutor.DEBUG_EXECUTOR) { - fStackTrace = Thread.currentThread().getStackTrace(); - } - } - - public String toString () { - StringBuilder builder = new StringBuilder() ; - // If assertions are not turned on. - builder.append(super.toString()); - if (fStackTrace != null) { - builder.append ( "\n\tCreated at" ) ; - - // ommit the first elements in the stack trace - for (int i = 3; i < fStackTrace.length && i < 13; i++) { - if (i > 3) builder.append ( "\tat " ) ; - builder.append( fStackTrace [ i ] .toString ()) ; - builder.append( "\n" ) ; - } - if (fStackTrace.length > 13) { - builder.append("\t at ..."); - } - } - if (fSubmittedBy != null) { - builder.append("Submitted by \n"); - builder.append(fSubmittedBy.toString()); - } - - return builder.toString(); - } - - void setSubmittedBy(Runnable runnable) { - fSubmittedBy = runnable; - } +abstract public class DsfRunnable extends DsfExecutable implements Runnable { } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/GetDataDone.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/GetDataDone.java index 3a8784d10ee..c1e9af9ce8a 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/GetDataDone.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/GetDataDone.java @@ -30,4 +30,12 @@ public abstract class GetDataDone extends Done { * Returns the data value, null if not set. */ public V getData() { return fData; } + + public String toString() { + if (getData() != null) { + return getData().toString(); + } else { + return super.toString(); + } + } } From 4cde8d219c04816e5b35cd3a6946846bac6041b5 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 6 Oct 2006 20:35:08 +0000 Subject: [PATCH 020/834] Added standard error codes and refactored existing implementation to use them (bug# 159043). --- .../org/eclipse/dd/dsf/concurrent/Done.java | 6 +- .../eclipse/dd/dsf/concurrent/DsfQuery.java | 5 +- .../concurrent/GetDataDoneWithClientDone.java | 56 ------------------- .../eclipse/dd/dsf/service/DsfSession.java | 7 ++- .../eclipse/dd/dsf/service/IDsfService.java | 33 ++++++++++- 5 files changed, 42 insertions(+), 65 deletions(-) delete mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/GetDataDoneWithClientDone.java diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java index 28f504be1ab..5bff4d2d26b 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java @@ -48,16 +48,16 @@ abstract public class Done extends DsfRunnable { /** * Convenience method which checks for error in done, and propagates it - * to caller's client done. + * to caller's client done. * @return Returns true if there was an error that was propagated and * the caller can stop processing result. */ - protected boolean propagateErrorToClient(DsfExecutor executor, Done clientDone, int code, String message) { + protected boolean propagateErrorToClient(DsfExecutor executor, Done clientDone, String message) { if (clientDone.getStatus().getSeverity() == IStatus.CANCEL) { return true; } if (!getStatus().isOK()) { - clientDone.setErrorStatus(DsfPlugin.PLUGIN_ID, code, message, getStatus()); + clientDone.setErrorStatus(DsfPlugin.PLUGIN_ID, getStatus().getCode(), message, getStatus()); executor.execute(clientDone); return true; } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfQuery.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfQuery.java index bf26e3f77d4..b944df7bb09 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfQuery.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfQuery.java @@ -16,6 +16,7 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.DsfPlugin; +import org.eclipse.dd.dsf.service.IDsfService; /** * A convenience class that allows a client to retrieve data from services @@ -83,7 +84,7 @@ abstract public class DsfQuery { wait(); } } catch (InterruptedException e) { - fStatus = new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, -1, + fStatus = new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Interrupted exception while waiting for result.", e); fValid = true; } @@ -153,7 +154,7 @@ abstract public class DsfQuery { public synchronized void doneException(Throwable t) { if (fValid) return; - doneError(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, -1, + doneError(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Exception while computing result.", t)); } } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/GetDataDoneWithClientDone.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/GetDataDoneWithClientDone.java deleted file mode 100644 index a05877f1168..00000000000 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/GetDataDoneWithClientDone.java +++ /dev/null @@ -1,56 +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.concurrent; - -import org.eclipse.core.runtime.IStatus; - -/** - * Convenience extension to GetDataDone, which handles posting of the client's - * Done upon the completion of this GetDataDone. - * @param Class type of data. - * @deprecated This class has been replaced with the - * {@link Done#propagateErrorToClient(DsfExecutor, Done, int, String)} - * method. - */ -public abstract class GetDataDoneWithClientDone extends GetDataDone { - private DsfExecutor fExecutor; - private Done fClientDone; - - /** - * Constructor requires the Done to be posted as well as the executor to - * post it with. - */ - public GetDataDoneWithClientDone(DsfExecutor executor, Done clientDone) { - fExecutor = executor; - fClientDone = clientDone; - } - - /** - * The run method checks the client done for cancellation, and this done - * for errors. It calls doRun() for the sub-class execution, and posts - * the client done when finished. - */ - public final void run() { - if (fClientDone.getStatus().getSeverity() == IStatus.CANCEL) return; - if (!getStatus().isOK()) { - fClientDone.setStatus(getStatus()); - } else { - doRun(); - } - fExecutor.execute(fClientDone); - } - - /** - * Method to perform the actual work. It should not post the client done - * because it will be posted by this class in run(). - */ - protected abstract void doRun(); -} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java index 7f5b867504d..fc20317d3fb 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java @@ -261,9 +261,10 @@ public class DsfSession * @param serviceProperties properties of the service requesting the event to be dispatched */ public void dispatchEvent(final Object event, final Dictionary serviceProperties) { - getExecutor().submit(new DsfRunnable() { public void run() { - doDispatchEvent(event, serviceProperties); - }}); + getExecutor().submit(new DsfRunnable() { + public void run() { doDispatchEvent(event, serviceProperties);} + public String toString() { return "Event: " + event + ", from service " + serviceProperties; } + }); } /** diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java index b7f06f75db7..3b62dea946a 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java @@ -40,7 +40,38 @@ public interface IDsfService { * Property name for the session-id of this service. This property should be set by * all DSF services when they are registered with OSGI service framework. */ - static String PROP_SESSION_ID = "org.eclipse.dd.dsf.service.IService.session_id"; + final static String PROP_SESSION_ID = "org.eclipse.dd.dsf.service.IService.session_id"; + + /** + * Error code indicating that the service is in a state which does not allow the + * request to be processed. For example if the client requested target information + * after target was disconnected. + */ + final static int INVALID_STATE = 10001; + + /** + * Error code indicating that client supplied an invalid handle to the service. + * A handle could become invalid after an object it represents is removed from + * the system. + */ + final static int INVALID_HANDLE = 10002; + + /** + * Error code indicating that the client request is not supported/implemented. + */ + final static int NOT_SUPPORTED = 10003; + + /** + * Error code indicating that the request to a sub-service or an external process + * failed. + */ + final static int REQUEST_FAILED = 10004; + + /** + * Error code indicating an unexpected condition in the service, i.e. programming error. + */ + final static int INTERNAL_ERROR = 10005; + /** * Returns the executor that should be used to call methods of this service. From 103d6ac39c421a897c69d22a3a74f69ca7753588 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Mon, 9 Oct 2006 22:22:49 +0000 Subject: [PATCH 021/834] Added annotations to indicate thead access policy for objects used with DSF (bug# 154273). --- .../dsf/ui/model/DataViewModelSchemaNode.java | 6 ++- .../dd/dsf/ui/model/IViewModelContext.java | 2 + .../dd/dsf/ui/model/IViewModelSchemaNode.java | 2 + .../dd/dsf/ui/model/ViewModelProvider.java | 9 ++++- .../dsf/concurrent/ConfinedToDsfExecutor.java | 38 +++++++++++++++++++ .../dd/dsf/concurrent/DefaultDsfExecutor.java | 28 ++++++++------ .../org/eclipse/dd/dsf/concurrent/Done.java | 1 + .../dd/dsf/concurrent/DsfExecutable.java | 1 + .../dd/dsf/concurrent/DsfExecutor.java | 1 + .../eclipse/dd/dsf/concurrent/DsfQuery.java | 1 + .../eclipse/dd/dsf/concurrent/Immutable.java | 32 ++++++++++++++++ .../eclipse/dd/dsf/concurrent/ThreadSafe.java | 35 +++++++++++++++++ .../org/eclipse/dd/dsf/model/AbstractDMC.java | 2 + .../src/org/eclipse/dd/dsf/model/DMCs.java | 4 ++ .../eclipse/dd/dsf/model/DataModelEvent.java | 5 ++- .../dd/dsf/model/IDataModelContext.java | 2 + .../eclipse/dd/dsf/model/IDataModelData.java | 1 - .../eclipse/dd/dsf/service/DsfSession.java | 33 ++++++++++++---- .../eclipse/dd/dsf/service/IDsfService.java | 2 + 19 files changed, 179 insertions(+), 26 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ConfinedToDsfExecutor.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Immutable.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ThreadSafe.java diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/DataViewModelSchemaNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/DataViewModelSchemaNode.java index 04a7fed2faf..781d0162301 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/DataViewModelSchemaNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/DataViewModelSchemaNode.java @@ -14,6 +14,7 @@ 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; @@ -35,9 +36,10 @@ abstract public class DataViewModelSchemaNode implements IViewModelSchemaNode { /** * IViewModelContext implementation used for this schema node. */ + @Immutable public class DataVMC implements IViewModelContext { - IViewModelContext fParent; - IDataModelContext fDmc; + private final IViewModelContext fParent; + private final IDataModelContext fDmc; public DataVMC(IViewModelContext parent, IDataModelContext dataModelContext) { fParent = parent; diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/IViewModelContext.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/IViewModelContext.java index 02dbf460d6d..cc14081913f 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/IViewModelContext.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/IViewModelContext.java @@ -11,10 +11,12 @@ package org.eclipse.dd.dsf.ui.model; import org.eclipse.core.runtime.IAdaptable; +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 { /** diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/IViewModelSchemaNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/IViewModelSchemaNode.java index 3e6679e1b12..788fc63a781 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/IViewModelSchemaNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/IViewModelSchemaNode.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.dsf.ui.model; +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; @@ -27,6 +28,7 @@ import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; * of other data in the view tree. * @see ViewModelProvider */ +@ConfinedToDsfExecutor("") @SuppressWarnings("restriction") public interface IViewModelSchemaNode { diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/ViewModelProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/ViewModelProvider.java index a36fccca031..1246d15ae5e 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/ViewModelProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/ViewModelProvider.java @@ -15,9 +15,11 @@ 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; @@ -44,10 +46,11 @@ import org.eclipse.debug.internal.ui.viewers.provisional.IModelProxy; * @see IModelProxy * @see IViewModelSchemaNode */ +@ConfinedToDsfExecutor("fSession#getExecutor") @SuppressWarnings("restriction") public class ViewModelProvider extends AbstractModelProxy { - private DsfSession fSession; + private final DsfSession fSession; /** * Counter for whether the model proxy is currently installed in the viewer. @@ -66,7 +69,7 @@ public class ViewModelProvider extends AbstractModelProxy * 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() { + IViewModelContext fRootVMC = new IViewModelContext(){ public IViewModelContext getParent() { return null; } public IViewModelSchemaNode getSchemaNode() { return null; } public Object getAdapter(Class adapter) { @@ -209,10 +212,12 @@ public class ViewModelProvider extends AbstractModelProxy public boolean isConflicting(ISchedulingRule rule) { return rule == this; } }; + @ThreadSafe public void installed() { fProxyActive++; } + @ThreadSafe public void dispose() { fProxyActive--; super.dispose(); diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ConfinedToDsfExecutor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ConfinedToDsfExecutor.java new file mode 100644 index 00000000000..3b880946af5 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ConfinedToDsfExecutor.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.concurrent; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation idicating that given package, class, method, or field can be + * access safely only from a DSF executor thread. If declared on package or type, + * a field or method could still be declared with an annotation indicating that it's + * thread-safe. + *

    + * Note: the runtime retention policy is there to allow automated testing + * and validation code. + * + * @param value The value indicates the method to use to obtain the executor. + * It should be null if it cannot be determined from the given object. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.PACKAGE, ElementType.TYPE, ElementType.METHOD, ElementType.FIELD}) +@Inherited +@Documented +public @interface ConfinedToDsfExecutor { + String value(); +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java index bae93caaf90..1453b258d82 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java @@ -24,6 +24,7 @@ import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; +import org.eclipse.core.runtime.ILog; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; @@ -70,18 +71,21 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor } catch (CancellationException e) { // Ignore also } catch (ExecutionException e) { if (e.getCause() != null) { - DsfPlugin.getDefault().getLog().log(new Status( - IStatus.ERROR, DsfPlugin.PLUGIN_ID, -1, "Uncaught exception in DSF executor thread", e.getCause())); - - // Print out the stack trace to console if assertions are enabled. - if(ASSERTIONS_ENABLED) { - ByteArrayOutputStream outStream = new ByteArrayOutputStream(512); - PrintStream printStream = new PrintStream(outStream); - try { - printStream.write("Uncaught exception in session executor thread: ".getBytes()); - } catch (IOException e2) {} - e.getCause().printStackTrace(new PrintStream(outStream)); - System.err.println(outStream.toString()); + ILog log = DsfPlugin.getDefault().getLog(); + if (log != null) { + log.log(new Status( + IStatus.ERROR, DsfPlugin.PLUGIN_ID, -1, "Uncaught exception in DSF executor thread", e.getCause())); + + // Print out the stack trace to console if assertions are enabled. + if(ASSERTIONS_ENABLED) { + ByteArrayOutputStream outStream = new ByteArrayOutputStream(512); + PrintStream printStream = new PrintStream(outStream); + try { + printStream.write("Uncaught exception in session executor thread: ".getBytes()); + } catch (IOException e2) {} + e.getCause().printStackTrace(new PrintStream(outStream)); + System.err.println(outStream.toString()); + } } } } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java index 5bff4d2d26b..7136de89b8c 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java @@ -23,6 +23,7 @@ import org.eclipse.dd.dsf.DsfPlugin; * clients have to make sure that access to this object is thread safe if * it's used outside of the caller's dispatch thread. */ +@ConfinedToDsfExecutor("") abstract public class Done extends DsfRunnable { private IStatus fStatus = Status.OK_STATUS; diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java index 2a845472759..6ed2646a003 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java @@ -21,6 +21,7 @@ import java.util.Set; * contains fields and methods that used for debugging and tracing when * tracing is enabled. */ +@Immutable public class DsfExecutable { final StackTraceElement[] fCreatedAt; final DefaultDsfExecutor.TracingWrapper fCreatedBy; diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutor.java index a3243f4cbb8..b8e895d41da 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutor.java @@ -20,6 +20,7 @@ import java.util.concurrent.ScheduledExecutorService; * to be exclusive to the executor, it could be shared with * another event dispatch service, such as the SWT display dispatch thread. */ +@ThreadSafe public interface DsfExecutor extends ScheduledExecutorService { /** diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfQuery.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfQuery.java index b944df7bb09..351f84bd674 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfQuery.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfQuery.java @@ -27,6 +27,7 @@ import org.eclipse.dd.dsf.service.IDsfService; * * @see java.util.concurrent.Callable */ +@ThreadSafe abstract public class DsfQuery { private V fResult; diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Immutable.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Immutable.java new file mode 100644 index 00000000000..2987d7f802e --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Immutable.java @@ -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.concurrent; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation idicating that given class is immutable and thus thread-safe. + * This annotation is not automatically inherited by sub-classes, since + * sub-classes need to make sure that they are immutable as well. + *

    + * Note: the runtime retention policy is there to allow automated testing + * and validation code. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@Documented +public @interface Immutable { + +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ThreadSafe.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ThreadSafe.java new file mode 100644 index 00000000000..af24e0d4120 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ThreadSafe.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.concurrent; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation idicating that given package, class, method, or field can be + * access safely from any thread. If declared on package or type, a field + * or method could still be declared with an annotation indicating that it's + * not thread-safe. + *

    + * Note: the runtime retention policy is there to allow automated testing + * and validation code. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.PACKAGE, ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR}) +@Inherited +@Documented +public @interface ThreadSafe { + +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/AbstractDMC.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/AbstractDMC.java index ecc291300e0..7defea3c20e 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/AbstractDMC.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/AbstractDMC.java @@ -11,6 +11,7 @@ package org.eclipse.dd.dsf.model; import org.eclipse.core.runtime.PlatformObject; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.dsf.service.AbstractDsfService; import org.eclipse.dd.dsf.service.DsfSession; @@ -20,6 +21,7 @@ import org.eclipse.dd.dsf.service.DsfSession; * correctly. * @param Data model data that this context is for. */ +@Immutable public class AbstractDMC extends PlatformObject implements IDataModelContext { diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/DMCs.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/DMCs.java index 923621244b6..a63f490ab3f 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/DMCs.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/DMCs.java @@ -10,6 +10,8 @@ *******************************************************************************/ package org.eclipse.dd.dsf.model; +import org.eclipse.dd.dsf.concurrent.ThreadSafe; + /** * Holder for utility static methods for manipulating IDataModelContext @@ -24,6 +26,7 @@ public class DMCs { * @param ancestorType Class type of the desired DMC ancestor. * @return Returns the ancestor if found, null otherwise. */ + @ThreadSafe @SuppressWarnings("unchecked") public static V getAncestorOfType(IDataModelContext ctx, Class ancestorType) { if (ancestorType.isAssignableFrom(ctx.getClass())) { @@ -50,6 +53,7 @@ public class DMCs { * @param potentialAncestor Ancestor DMC to look for. * @return true if a match is found. */ + @ThreadSafe public static boolean isAncestorOf(IDataModelContext dmc, IDataModelContext potentialAncestor) { // Check the direct parents for a match. for (IDataModelContext parentDmc : dmc.getParents()) { diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/DataModelEvent.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/DataModelEvent.java index 681b62defae..b6acb420b30 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/DataModelEvent.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/DataModelEvent.java @@ -10,12 +10,15 @@ *******************************************************************************/ package org.eclipse.dd.dsf.model; +import org.eclipse.dd.dsf.concurrent.Immutable; + /** * Base implementation of the IDataModelContext interface. */ +@Immutable public class DataModelEvent implements IDataModelEvent { - private V fModelContext; + private final V fModelContext; public DataModelEvent(V context) { fModelContext = context; } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelContext.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelContext.java index 362182961ab..2c2ff5af6d3 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelContext.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelContext.java @@ -11,6 +11,7 @@ package org.eclipse.dd.dsf.model; import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.dd.dsf.concurrent.Immutable; /** * The base class for data model objects. @@ -42,6 +43,7 @@ import org.eclipse.core.runtime.IAdaptable; * * @see IDataModelData */ +@Immutable public interface IDataModelContext extends IAdaptable { /** diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelData.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelData.java index 5d3df186db0..b40bc85f523 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelData.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelData.java @@ -18,7 +18,6 @@ package org.eclipse.dd.dsf.model; *

    * This interface is intended primarily to allow for future development of * a generic API to parametrize data model data. - * */ public interface IDataModelData { diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java index fc20317d3fb..7c541cf5a94 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java @@ -27,8 +27,10 @@ import java.util.TreeMap; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.DsfPlugin; +import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; import org.eclipse.dd.dsf.concurrent.DsfExecutor; import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.osgi.framework.Filter; /** @@ -47,13 +49,12 @@ import org.osgi.framework.Filter; * * @see org.eclipse.dd.dsf.concurrent.DsfExecutor */ +@ConfinedToDsfExecutor("getExecutor") public class DsfSession -{ - +{ /** * Listener for session started events. This listener is always going to be * called in the dispatch thread of the session's executor. - * */ public static interface SessionStartedListener { /** @@ -86,12 +87,15 @@ public class DsfSession } /** Returns a session instance for given session identifier */ + @ThreadSafe public static DsfSession getSession(String sessionId) { - for (DsfSession session : fgActiveSessions) { - if (session.getId().equals(sessionId)) { - return session; - } - } + synchronized(fgActiveSessions) { + for (DsfSession session : fgActiveSessions) { + if (session.getId().equals(sessionId)) { + return session; + } + } + } return null; } @@ -99,6 +103,7 @@ public class DsfSession * Registers a listener for session started events. * Can be called on any thread. */ + @ThreadSafe public static void addSessionStartedListener(SessionStartedListener listener) { assert !fSessionStartedListeners.contains(listener); fSessionStartedListeners.add(listener); @@ -108,6 +113,7 @@ public class DsfSession * Un-registers a listener for session started events. * Can be called on any thread. */ + @ThreadSafe public static void removeSessionStartedListener(SessionStartedListener listener) { assert fSessionStartedListeners.contains(listener); fSessionStartedListeners.remove(listener); @@ -117,6 +123,7 @@ public class DsfSession * Registers a listener for session ended events. * Can be called on any thread. */ + @ThreadSafe public static void addSessionEndedListener(SessionEndedListener listener) { assert !fSessionEndedListeners.contains(listener); fSessionEndedListeners.add(listener); @@ -126,6 +133,7 @@ public class DsfSession * Un-registers a listener for session ended events. * Can be called on any thread. */ + @ThreadSafe public static void removeSessionEndedListener(SessionEndedListener listener) { assert fSessionEndedListeners.contains(listener); fSessionEndedListeners.remove(listener); @@ -139,6 +147,7 @@ public class DsfSession * @param ownerId ID (plugin ID preferably) of the owner of this session * @return instance object of the new session */ + @ThreadSafe public static DsfSession startSession(DsfExecutor executor, String ownerId) { synchronized(fgActiveSessions) { final DsfSession newSession = new DsfSession(executor, ownerId, Integer.toString(fgSessionIdCounter++)); @@ -160,6 +169,7 @@ public class DsfSession * executor. * @param session session to terminate */ + @ThreadSafe public static void endSession(final DsfSession session) { synchronized(fgActiveSessions) { if (!fgActiveSessions.contains(session)) { @@ -260,6 +270,7 @@ public class DsfSession * @param event to be sent out * @param serviceProperties properties of the service requesting the event to be dispatched */ + @ThreadSafe public void dispatchEvent(final Object event, final Dictionary serviceProperties) { getExecutor().submit(new DsfRunnable() { public void run() { doDispatchEvent(event, serviceProperties);} @@ -273,6 +284,7 @@ public class DsfSession * @param adapter adapter instance to register * @see org.eclipse.dsdp.model.AbstractDMC#getAdapter */ + @ThreadSafe public void registerModelAdapter(Class adapterType, Object adapter) { fAdapters.put(adapterType, adapter); } @@ -282,6 +294,7 @@ public class DsfSession * @param adapterType adapter type to unregister * @see org.eclipse.dsdp.model.AbstractDMC#getAdapter */ + @ThreadSafe public void unregisterModelAdapter(Class adapterType) { fAdapters.remove(adapterType); } @@ -292,14 +305,17 @@ public class DsfSession * @return adapter object for given type, null if none is registered with the session * @see org.eclipse.dsdp.model.AbstractDMC#getAdapter */ + @ThreadSafe public Object getModelAdapter(Class adapterType) { return fAdapters.get(adapterType); } + @ThreadSafe public boolean equals(Object other) { return other instanceof DsfSession && fId.equals(((DsfSession)other).fId); } + @ThreadSafe public int hashCode() { return fId.hashCode(); } private void doDispatchEvent(Object event, Dictionary serviceProperties) { @@ -391,6 +407,7 @@ public class DsfSession /** * Class to be instanciated only using startSession() */ + @ThreadSafe private DsfSession(DsfExecutor executor, String ownerId, String id) { fId = id; fOwnerId = ownerId; diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java index 3b62dea946a..5db2136b8b0 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java @@ -12,6 +12,7 @@ package org.eclipse.dd.dsf.service; import java.util.Dictionary; +import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; import org.eclipse.dd.dsf.concurrent.Done; import org.eclipse.dd.dsf.concurrent.DsfExecutor; @@ -34,6 +35,7 @@ import org.eclipse.dd.dsf.concurrent.DsfExecutor; * * @see org.osgi.framework.BundleContext#registerService(String[], Object, Dictionary) */ +@ConfinedToDsfExecutor("getExecutor") public interface IDsfService { /** From 72f1dfc37dabee64dfe41b9dbbc2a457a97c463f Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Wed, 11 Oct 2006 21:33:15 +0000 Subject: [PATCH 022/834] Buckminster build integration. --- plugins/org.eclipse.dd.dsf/.cvsignore | 2 +- plugins/org.eclipse.dd.dsf/make/build.xml | 10 ++++++ .../org.eclipse.dd.dsf.cspec | 32 +++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 plugins/org.eclipse.dd.dsf/make/build.xml create mode 100644 plugins/org.eclipse.dd.dsf/org.eclipse.dd.dsf.cspec diff --git a/plugins/org.eclipse.dd.dsf/.cvsignore b/plugins/org.eclipse.dd.dsf/.cvsignore index ba077a4031a..8b137891791 100644 --- a/plugins/org.eclipse.dd.dsf/.cvsignore +++ b/plugins/org.eclipse.dd.dsf/.cvsignore @@ -1 +1 @@ -bin + diff --git a/plugins/org.eclipse.dd.dsf/make/build.xml b/plugins/org.eclipse.dd.dsf/make/build.xml new file mode 100644 index 00000000000..45d83b3bc66 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/make/build.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/plugins/org.eclipse.dd.dsf/org.eclipse.dd.dsf.cspec b/plugins/org.eclipse.dd.dsf/org.eclipse.dd.dsf.cspec new file mode 100644 index 00000000000..6538c547428 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/org.eclipse.dd.dsf.cspec @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From ccaf90ca8361a56d94fb858e82c1749e41f96f84 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Wed, 11 Oct 2006 21:48:36 +0000 Subject: [PATCH 023/834] buckminster --- plugins/org.eclipse.dd.dsf/org.eclipse.dd.dsf.cspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf/org.eclipse.dd.dsf.cspec b/plugins/org.eclipse.dd.dsf/org.eclipse.dd.dsf.cspec index 6538c547428..f9cd278ceb5 100644 --- a/plugins/org.eclipse.dd.dsf/org.eclipse.dd.dsf.cspec +++ b/plugins/org.eclipse.dd.dsf/org.eclipse.dd.dsf.cspec @@ -1,5 +1,5 @@ - + From 099b4be9ec1dd36cf3cfde41311d2a8aa6ae3077 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Wed, 11 Oct 2006 22:12:49 +0000 Subject: [PATCH 024/834] buckminster --- plugins/org.eclipse.dd.dsf/.classpath | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf/.classpath b/plugins/org.eclipse.dd.dsf/.classpath index 304e86186aa..eb62460abf6 100644 --- a/plugins/org.eclipse.dd.dsf/.classpath +++ b/plugins/org.eclipse.dd.dsf/.classpath @@ -3,5 +3,5 @@ - + From 2edc366817b1b1eaef767d19fc683eda455ef282 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Wed, 11 Oct 2006 22:29:51 +0000 Subject: [PATCH 025/834] buckminster --- plugins/org.eclipse.dd.dsf/make/dsf.jardesc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 plugins/org.eclipse.dd.dsf/make/dsf.jardesc diff --git a/plugins/org.eclipse.dd.dsf/make/dsf.jardesc b/plugins/org.eclipse.dd.dsf/make/dsf.jardesc new file mode 100644 index 00000000000..08e46f5eccd --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/make/dsf.jardesc @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + From a617b5e8fba68ae63b2034ec2a57af55ca9b23bf Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Fri, 13 Oct 2006 20:51:24 +0000 Subject: [PATCH 026/834] buckminster --- .../{org.eclipse.dd.dsf.cspec => org.eclipse.dd.dsf.cspex} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename plugins/org.eclipse.dd.dsf/{org.eclipse.dd.dsf.cspec => org.eclipse.dd.dsf.cspex} (89%) diff --git a/plugins/org.eclipse.dd.dsf/org.eclipse.dd.dsf.cspec b/plugins/org.eclipse.dd.dsf/org.eclipse.dd.dsf.cspex similarity index 89% rename from plugins/org.eclipse.dd.dsf/org.eclipse.dd.dsf.cspec rename to plugins/org.eclipse.dd.dsf/org.eclipse.dd.dsf.cspex index f9cd278ceb5..8402605eb63 100644 --- a/plugins/org.eclipse.dd.dsf/org.eclipse.dd.dsf.cspec +++ b/plugins/org.eclipse.dd.dsf/org.eclipse.dd.dsf.cspex @@ -1,5 +1,5 @@ - + @@ -29,4 +29,4 @@ - + From 6ed5cc8d0e2d26e92afd7ccc3f78112f88681da7 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Fri, 13 Oct 2006 20:59:10 +0000 Subject: [PATCH 027/834] buckminster --- .../{org.eclipse.dd.dsf.cspex => buckminster.cspex} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename plugins/org.eclipse.dd.dsf/{org.eclipse.dd.dsf.cspex => buckminster.cspex} (100%) diff --git a/plugins/org.eclipse.dd.dsf/org.eclipse.dd.dsf.cspex b/plugins/org.eclipse.dd.dsf/buckminster.cspex similarity index 100% rename from plugins/org.eclipse.dd.dsf/org.eclipse.dd.dsf.cspex rename to plugins/org.eclipse.dd.dsf/buckminster.cspex From 3f86dad9d5f2767c358726097b9b0fd2dfc9c610 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 13 Oct 2006 22:34:59 +0000 Subject: [PATCH 028/834] Refactored DsfSequence class (bug# 159048). Also added tracing of executables that were garbage-disposed without ever being run. --- .../src/org/eclipse/dd/dsf/DsfPlugin.java | 18 + .../dsf/concurrent/ConfinedToDsfExecutor.java | 2 +- .../dd/dsf/concurrent/DefaultDsfExecutor.java | 37 +- .../org/eclipse/dd/dsf/concurrent/Done.java | 2 +- .../dd/dsf/concurrent/DsfExecutable.java | 75 ++- .../eclipse/dd/dsf/concurrent/DsfQuery.java | 239 ++++---- .../dd/dsf/concurrent/DsfSequence.java | 515 +++++++++++++----- .../dd/dsf/concurrent/StackTraceWrapper.java | 31 ++ 8 files changed, 619 insertions(+), 300 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/StackTraceWrapper.java diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/DsfPlugin.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/DsfPlugin.java index abcae5d1d16..0e05acf461c 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/DsfPlugin.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/DsfPlugin.java @@ -76,6 +76,24 @@ public class DsfPlugin extends Plugin { System.out.println(message); } } + + public static String getDebugTime() { + StringBuilder traceBuilder = new StringBuilder(); + + // Record the time + long time = System.currentTimeMillis(); + long seconds = (time / 1000) % 1000; + if (seconds < 100) traceBuilder.append('0'); + if (seconds < 10) traceBuilder.append('0'); + traceBuilder.append(seconds); + traceBuilder.append(','); + long millis = time % 1000; + if (millis < 100) traceBuilder.append('0'); + if (millis < 10) traceBuilder.append('0'); + traceBuilder.append(millis); + return traceBuilder.toString(); + } + } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ConfinedToDsfExecutor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ConfinedToDsfExecutor.java index 3b880946af5..9feab36de06 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ConfinedToDsfExecutor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ConfinedToDsfExecutor.java @@ -30,7 +30,7 @@ import java.lang.annotation.Target; * It should be null if it cannot be determined from the given object. */ @Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.PACKAGE, ElementType.TYPE, ElementType.METHOD, ElementType.FIELD}) +@Target({ElementType.PACKAGE, ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR}) @Inherited @Documented public @interface ConfinedToDsfExecutor { diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java index 1453b258d82..44e07542379 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java @@ -91,7 +91,6 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor } } } - // // Utilities used for tracing. @@ -132,7 +131,7 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor int fSequenceNumber = -1; /** Trace of where the runnable/callable was submitted to the executor */ - StackTraceElement[] fSubmittedAt = null; + StackTraceWrapper fSubmittedAt = null; /** Reference to the runnable/callable that submitted this runnable/callable to the executor */ TracingWrapper fSubmittedBy = null; @@ -142,8 +141,8 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor */ TracingWrapper(int offset) { StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); - fSubmittedAt = new StackTraceElement[stackTrace.length - offset]; - System.arraycopy(stackTrace, offset - 1, fSubmittedAt, 0, fSubmittedAt.length); + fSubmittedAt = new StackTraceWrapper(new StackTraceElement[stackTrace.length - offset]); + System.arraycopy(stackTrace, offset - 1, fSubmittedAt.fStackTraceElements, 0, fSubmittedAt.fStackTraceElements.length); if (isInExecutorThread() && fCurrentlyExecuting != null) { fSubmittedBy = fCurrentlyExecuting; } @@ -158,16 +157,7 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor StringBuilder traceBuilder = new StringBuilder(); // Record the time - long time = System.currentTimeMillis(); - long seconds = (time / 1000) % 1000; - if (seconds < 100) traceBuilder.append('0'); - if (seconds < 10) traceBuilder.append('0'); - traceBuilder.append(seconds); - traceBuilder.append(','); - long millis = time % 1000; - if (millis < 100) traceBuilder.append('0'); - if (millis < 10) traceBuilder.append('0'); - traceBuilder.append(millis); + traceBuilder.append(DsfPlugin.getDebugTime()); traceBuilder.append(' '); // Record the executor # @@ -187,7 +177,7 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor } if (dsfExecutable.fCreatedAt != null) { traceBuilder.append(" at "); - traceBuilder.append(dsfExecutable.fCreatedAt[0].toString()); + traceBuilder.append(dsfExecutable.fCreatedAt.fStackTraceElements[0].toString()); } } } @@ -200,7 +190,7 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor traceBuilder.append(fSubmittedBy.fSequenceNumber); } traceBuilder.append(" at "); - traceBuilder.append(fSubmittedAt[0].toString()); + traceBuilder.append(fSubmittedAt.fStackTraceElements[0].toString()); // Finally, the executable's toString(). traceBuilder.append("\n "); @@ -214,6 +204,7 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor abstract protected Object getExecutable(); } + class TracingWrapperRunnable extends TracingWrapper implements Runnable { final Runnable fRunnable; public TracingWrapperRunnable(Runnable runnable, int offset) { @@ -225,6 +216,13 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor public void run() { traceExecution(); + + // If debugging a DSF exeutable, mark that it was executed. + if (DEBUG_EXECUTOR && fRunnable instanceof DsfExecutable) { + ((DsfExecutable)fRunnable).setExecuted(); + } + + // Finally invoke the runnable code. fRunnable.run(); } } @@ -240,6 +238,13 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor public T call() throws Exception { traceExecution(); + + // If debugging a DSF exeutable, mark that it was executed. + if (DEBUG_EXECUTOR && fCallable instanceof DsfExecutable) { + ((DsfExecutable)fCallable).setExecuted(); + } + + // Finally invoke the runnable code. return fCallable.call(); } } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java index 7136de89b8c..2f5f26ac0c0 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java @@ -53,7 +53,7 @@ abstract public class Done extends DsfRunnable { * @return Returns true if there was an error that was propagated and * the caller can stop processing result. */ - protected boolean propagateErrorToClient(DsfExecutor executor, Done clientDone, String message) { + protected boolean propagateError(DsfExecutor executor, Done clientDone, String message) { if (clientDone.getStatus().getSeverity() == IStatus.CANCEL) { return true; } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java index 6ed2646a003..4b2f96e3ee8 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java @@ -13,6 +13,9 @@ package org.eclipse.dd.dsf.concurrent; import java.util.HashSet; import java.util.Set; +import org.eclipse.core.runtime.Platform; +import org.eclipse.dd.dsf.DsfPlugin; + /** * Base class for DSF-instrumented alternative to the Runnable/Callable interfaces. *

    @@ -23,15 +26,48 @@ import java.util.Set; */ @Immutable public class DsfExecutable { - final StackTraceElement[] fCreatedAt; + /** + * Flag indicating that tracing of the DSF executor is enabled. It enables + * storing of the "creator" information as well as tracing of disposed + * runnables that have not been submitted to the executor. + */ + static boolean DEBUG_EXECUTOR = false; + + /** + * Flag indicating that assertions are enabled. It enables storing of the + * "creator" executable for debugging purposes. + */ + static boolean ASSERTIONS_ENABLED = false; + + static { + assert ASSERTIONS_ENABLED = true; + DEBUG_EXECUTOR = DsfPlugin.DEBUG && "true".equals( //$NON-NLS-1$ + Platform.getDebugOption("org.eclipse.dd.dsf/debug/executor")); //$NON-NLS-1$ + assert ASSERTIONS_ENABLED = true; + } + + /** + * Field that holds the stack trace of where this executable was created. + * Used for tracing and debugging only. + */ + final StackTraceWrapper fCreatedAt; + + /** + * Field holding the reference of the executable that created this + * executable. Used for tracing only. + */ final DefaultDsfExecutor.TracingWrapper fCreatedBy; + /** + * Flag indicating whether this executable was ever executed by an + * executor. Used for tracing only. + */ + private boolean fExecuted = false; + @SuppressWarnings("unchecked") public DsfExecutable() { // Use assertion flag (-ea) to jre to avoid affecting performance when not debugging. - boolean assertsEnabled = false; - assert assertsEnabled = true; - if (assertsEnabled || DefaultDsfExecutor.DEBUG_EXECUTOR) { + if (ASSERTIONS_ENABLED || DEBUG_EXECUTOR) { // Find the runnable/callable that is currently running. DefaultDsfExecutor executor = DefaultDsfExecutor.fThreadToExecutorMap.get(Thread.currentThread()); if (executor != null) { @@ -53,11 +89,38 @@ public class DsfExecutable { for (i = 3; i < stackTrace.length; i++) { if ( !classNamesSet.contains(stackTrace[i].getClassName()) ) break; } - fCreatedAt = new StackTraceElement[stackTrace.length - i]; - System.arraycopy(stackTrace, i, fCreatedAt, 0, fCreatedAt.length); + fCreatedAt = new StackTraceWrapper(new StackTraceElement[stackTrace.length - i]); + System.arraycopy(stackTrace, i, fCreatedAt.fStackTraceElements, 0, fCreatedAt.fStackTraceElements.length); } else { fCreatedAt = null; fCreatedBy = null; } } + + /** + * Marks this executable to indicate that it has been executed by the + * executor. To be invoked only by DsfExecutor. + */ + void setExecuted() { + fExecuted = true; + } + + @Override + protected void finalize() { + if (DEBUG_EXECUTOR && !fExecuted) { + StringBuilder traceBuilder = new StringBuilder(); + + // Record the time + traceBuilder.append(DsfPlugin.getDebugTime()); + traceBuilder.append(' '); + + // Record the event + traceBuilder.append("DsfExecutable was never executed:\n "); + traceBuilder.append(this); + traceBuilder.append("\nCreated at:"); + traceBuilder.append(fCreatedAt); + + DsfPlugin.debug(traceBuilder.toString()); + } + } } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfQuery.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfQuery.java index 351f84bd674..fce82bb2f65 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfQuery.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfQuery.java @@ -10,13 +10,13 @@ *******************************************************************************/ package org.eclipse.dd.dsf.concurrent; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.locks.AbstractQueuedSynchronizer; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.DsfPlugin; -import org.eclipse.dd.dsf.service.IDsfService; /** * A convenience class that allows a client to retrieve data from services @@ -28,135 +28,124 @@ import org.eclipse.dd.dsf.service.IDsfService; * @see java.util.concurrent.Callable */ @ThreadSafe -abstract public class DsfQuery { - - private V fResult; - private boolean fValid; - private DsfExecutor fExecutor; - private Future fFuture; - private boolean fWaiting; - private IStatus fStatus = Status.OK_STATUS; - - public DsfQuery(DsfExecutor executor) { - fExecutor = executor; +abstract public class DsfQuery extends DsfRunnable + implements Future +{ + /** The synchronization object for this query */ + final Sync fSync = new Sync(); + + public V get() throws InterruptedException, ExecutionException { return fSync.doGet(); } + + public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { + return fSync.doGet(); } - + /** - * Start data retrieval. - * Client must implement this method to do whatever is needed to retrieve data. - * Retrieval can be (but does not have to be) asynchronious - it meas this method can return - * before data is retrieved. When data is ready Proxy must be notified by calling done() method. - */ - protected abstract void execute(); - - /** - * Allows deriving classes to implement their own snipped additional - * cancellation code. + * Don't try to interrupt the DSF executor thread, just ignore the request + * if set. */ - protected void revokeChildren(V result) {}; - - /** - * Get data associated with this proxy. This method is thread safe and - * it will block until data is ready. Because it's a blocking call and it waits - * for commands to be processed on the dispatch thread, this methods itself - * CANNOT be called on the dispatch thread. - */ - public synchronized V get() { - assert !fExecutor.isInExecutorThread(); - if(!fValid) { - if (!fWaiting) { - fFuture = fExecutor.submit(new DsfRunnable() { - public void run() { - // Note: not sure if this try-catch is desirable. It might encourage - // implementors to not catch its own exceptions. If the query code takes - // more than one dispatch, then this code will not be helpful anyway. - try { - DsfQuery.this.execute(); - } catch (Throwable t) { - doneException(t); - } - } - }); - } - - fWaiting = true; - try { - while(fWaiting) { - wait(); - } - } catch (InterruptedException e) { - fStatus = new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, - "Interrupted exception while waiting for result.", e); - fValid = true; - } - assert fValid; - } - return fResult; + public boolean cancel(boolean mayInterruptIfRunning) { + return fSync.doCancel(); } - /** - * Same as get(), but with code to automatically re-threw the exception if one - * was reported by the run() method. - */ - public V getWithThrows() throws CoreException { - V retVal = get(); - if (!getStatus().isOK()) { - throw new CoreException(getStatus()); - } - return retVal; - } + public boolean isCancelled() { return fSync.doIsCancelled(); } - public IStatus getStatus() { return fStatus; } + public boolean isDone() { return fSync.doIsDone(); } - /** Abort current operation and keep old proxy data */ - public synchronized void cancel() { - assert fExecutor.isInExecutorThread(); - assert !fWaiting || !fValid; - if (fWaiting) { - fFuture.cancel(false); - fWaiting = false; - notifyAll(); - } else if (fValid) { - revokeChildren(fResult); - } - fValid = true; + + protected void done(V result) { + fSync.doSet(result); } - /** Abort current operation and set proxy data to 'result' */ - public synchronized void cancel(V newResult) { - fResult = newResult; - cancel(); - } - - public Object getCachedResult() { - return fResult; - } - - public boolean isValid() { return fValid; } - - public synchronized void done(V result) { - // Valid could be true if request was cancelled while data was - // being retrieved, and then done() was called. - if (fValid) return; - - fResult = result; - fValid = true; - if (fWaiting) { - fWaiting = false; - notifyAll(); - } - } - - public synchronized void doneError(IStatus errorStatus) { - if (fValid) return; - fStatus = errorStatus; - done(null); - } - - public synchronized void doneException(Throwable t) { - if (fValid) return; - doneError(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, - "Exception while computing result.", t)); + protected void doneException(Throwable t) { + fSync.doSetException(t); } + + abstract protected void execute(); + + public void run() { + if (fSync.doRun()) { + execute(); + } + } + + @SuppressWarnings("serial") + final class Sync extends AbstractQueuedSynchronizer { + private static final int STATE_RUNNING = 1; + private static final int STATE_DONE = 2; + private static final int STATE_CANCELLED = 4; + + private V fResult; + private Throwable fException; + + private boolean ranOrCancelled(int state) { + return (state & (STATE_DONE | STATE_CANCELLED)) != 0; + } + + protected int tryAcquireShared(int ignore) { + return doIsDone()? 1 : -1; + } + + protected boolean tryReleaseShared(int ignore) { + return true; + } + + boolean doIsCancelled() { + return getState() == STATE_CANCELLED; + } + + boolean doIsDone() { + return ranOrCancelled(getState()); + } + + V doGet() throws InterruptedException, ExecutionException { + acquireSharedInterruptibly(0); + if (getState() == STATE_CANCELLED) throw new CancellationException(); + if (fException != null) throw new ExecutionException(fException); + return fResult; + } + + V doGet(long nanosTimeout) throws InterruptedException, ExecutionException, TimeoutException { + if (!tryAcquireSharedNanos(0, nanosTimeout)) throw new TimeoutException(); + if (getState() == STATE_CANCELLED) throw new CancellationException(); + if (fException != null) throw new ExecutionException(fException); + return fResult; + } + + void doSet(V v) { + while(true) { + int s = getState(); + if (ranOrCancelled(s)) return; + if (compareAndSetState(s, STATE_DONE)) break; + } + fResult = v; + releaseShared(0); + } + + void doSetException(Throwable t) { + while(true) { + int s = getState(); + if (ranOrCancelled(s)) return; + if (compareAndSetState(s, STATE_DONE)) break; + } + fException = t; + fResult = null; + releaseShared(0); + } + + boolean doCancel() { + while(true) { + int s = getState(); + if (ranOrCancelled(s)) return false; + if (compareAndSetState(s, STATE_CANCELLED)) break; + } + releaseShared(0); + return true; + } + + boolean doRun() { + return compareAndSetState(0, STATE_RUNNING); + } + } } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java index 3de19cd88ae..6fe0903cd82 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java @@ -10,8 +10,17 @@ *******************************************************************************/ package org.eclipse.dd.dsf.concurrent; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.locks.AbstractQueuedSynchronizer; + +import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.DsfPlugin; @@ -39,202 +48,406 @@ import org.eclipse.dd.dsf.DsfPlugin; * has to be re-implemented every time. The Sequence class tries to address * this problem by containing this pattern in a single class. */ -abstract public class DsfSequence { +@ThreadSafe +abstract public class DsfSequence extends DsfRunnable implements Future { /** - * The abstract class that each step has to implement + * The abstract class that each step has to implement. */ - abstract public class Step { - public void execute() { stepFinished(); } - public void rollBack() { stepRolledBack(); } + abstract public static class Step { + private DsfSequence fSequence; + + /** + * Sets the sequence that this step belongs to. It is only accessible + * by the sequence itself, and is not meant to be called by sequence + * sub-classes. + */ + void setSequence(DsfSequence sequence) { fSequence = sequence; } + + /** Returns the sequence that this step is running in. */ + public DsfSequence getSequence() { return fSequence; } + + /** + * Executes the next step. Overriding classes should perform the + * work in this method. + * @param done Result token to submit to executor when step is finished. + */ + public void execute(Done done) { + getSequence().getExecutor().execute(done); + } + + /** + * Roll back gives the step implementation a chance to undo the + * operation that was performed by execute(). + * @param done Result token to submit to executor when rolling back the step is finished. + */ + public void rollBack(Done done) { + getSequence().getExecutor().execute(done); + } + + /** + * Returns the number of progress monitor ticks corresponding to this + * step. + */ public int getTicks() { return 1; } } - private DsfExecutor fExecutor; - private Step[] fSteps; - private Done fDoneQC; - private String fTaskName; - private String fRollbackTaskName; - private IProgressMonitor fProgressMonitor = new NullProgressMonitor(); + /** The synchronization object for this future */ + final Sync fSync = new Sync(); + + /** + * Executor that this sequence is running in. It is used by the sequence + * to submit the runnables for steps, and for submitting the result. + */ + final private DsfExecutor fExecutor; + + /** + * Result callback to invoke when the sequence is finished. Intended to + * be used when the sequence is created and invoked from the executor + * thread. Otherwise, the {@link Future#get()} method is the appropriate + * method of retrieving the result. + */ + final private Done fDone; + + /** Status indicating the success/failure of the test. Used internally only. */ + @ConfinedToDsfExecutor("getExecutor") + private IStatus fStatus = Status.OK_STATUS; + + @ConfinedToDsfExecutor("getExecutor") private int fCurrentStepIdx = 0; - boolean fCancelled = false; - /** - * Default constructor. If this constructor is used, the steps need to be initialized - * before the sequence can be invoked. - * @param executor the DSF executor which will be used to invoke all steps - */ - public DsfSequence(DsfExecutor executor) { - this(executor, null); + /** Task name for this sequence used with the progress monitor */ + final private String fTaskName; + + /** Task name used when the sequence is being rolled back. */ + final private String fRollbackTaskName; + + final private IProgressMonitor fProgressMonitor; + + + + /** Convenience constructor with limited arguments. */ + public DsfSequence(DsfExecutor executor) { + this(executor, new NullProgressMonitor(), "", "", null); } - + + /** Convenience constructor with limited arguments. */ + public DsfSequence(DsfExecutor executor, Done done) { + this(executor, new NullProgressMonitor(), "", "", done); + } + /** - * Constructor that initialized the steps. - * @param executor the DSF executor which will be used to invoke all steps - * @param steps sequence steps + * Constructor that initialized the steps and the result callback. + * @param executor The DSF executor which will be used to invoke all steps. + * @param pm Progress monitor for monitoring this sequence. This parameter cannot be null. + * @param taskName Name that will be used in call to {@link IProgressMonitor#beginTask(String, int)}, + * when the task is started. + * @param rollbackTaskName Name that will be used in call to {@link IProgressMonitor#subTask(String)} + * if the task is cancelled or aborted. + * @param Result that will be submitted to executor when sequence is finished. Can be null if calling from + * non-executor thread and using {@link Future#get()} method to wait for the sequence result. */ - public DsfSequence(DsfExecutor executor, Step[] steps) { + + public DsfSequence(DsfExecutor executor, IProgressMonitor pm, String taskName, String rollbackTaskName, Done done) { fExecutor = executor; - fSteps = steps; + fProgressMonitor = pm; + fTaskName = taskName; + fRollbackTaskName = rollbackTaskName; + fDone = done; } + + /** + * Returns the steps to be executed. It is up to the deriving class to + * supply the steps and to ensure that the list of steps will not be + * modified after the sequence is constructed. + */ + abstract public Step[] getSteps(); + /** Returns the DSF executor for this sequence */ public DsfExecutor getExecutor() { return fExecutor; } - /** - * Sets the done callback to be submitted when the sequence is finished. - * If the sequence is submitted by a caller in the dispatch thread, this is - * the way that the original caller can be notified of the sequence - * completion. If the caller blocks and waits for the sequence - * completion, the Done callback is not necessary. - * @param doneQC callback to submit when sequence completes, can be null - */ - public void setDone(Done doneQC) { - fDoneQC = doneQC; - } - /** * Returns the Done callback that is registered with the Sequence * @param doneQC callback that will be submitted when sequence completes, * null if there is no callback configured */ - public Done getDone() { return fDoneQC; } - - /** Sets the steps to be executed. */ - public void setSteps(Step[] steps) { - assert fCurrentStepIdx == 0; - fSteps = steps; - } - - /** Returns the steps to be executed. */ - public Step[] getSteps() { return fSteps; } + public Done getDone() { return fDone; } /** - * Returns index of the step that is currently being executed. - *
    NOTE: After sequence is invoked, this method should be called - * only in the DSF executor thread. - * @return + * The get method blocks until sequence is complete, but always returns null. + * @see java.concurrent.Future#get */ - public int getCurrentIdx() { return fCurrentStepIdx; } - - /** - * Sets the progress monitor that will be called by the sequence with udpates. - * @param pm - */ - public void setProgressMonitor(IProgressMonitor pm) { fProgressMonitor = pm; } - - /** - * Sets the task name for this sequence. To be used with progress monitor; - * @param taskName - */ - public void setTaskName(String taskName) { fTaskName = taskName; } - - /** - * Sets the task name to be used with progress monitor, if this sequence needs - * to be rolled back as result of cancellation or error. - * @param taskName - */ - public void setRollBackTaskName(String n) { fRollbackTaskName = n; } - - - /** Submits this sequence to the executor. */ - public void invokeLater() { - getExecutor().submit( new DsfRunnable() { public void run() { doInvoke(); } }); - } - - /** - * Submits this sequence to the DSF executor, and blocks waiting for the - * sequence to complete. - *
    NOTE: This method is NOT to be called on the DSF executor thread. - */ - public synchronized void invoke() { - assert !fExecutor.isInExecutorThread() : - "Cannot be called on dispatch thread: " + this; - setDone(new Done() { - public void run() { - synchronized(DsfSequence.this) { DsfSequence.this.notifyAll(); } - } - }); - invokeLater(); - try { - wait(); - } catch (InterruptedException e) {} + public Object get() throws InterruptedException, ExecutionException { + fSync.doGet(); + return null; } - private void doInvoke() { - assert fCurrentStepIdx == 0; - if (fTaskName != null) { - fProgressMonitor.subTask(fTaskName); + /** + * The get method blocks until sequence is complete or until timeout is + * reached, but always returns null. + * @see java.concurrent.Future#get + */ + public Object get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { + fSync.doGet(); + return null; + } + + /** + * Don't try to interrupt the DSF executor thread, just ignore the request + * if set. + */ + public boolean cancel(boolean mayInterruptIfRunning) { + return fSync.doCancel(); + } + + public boolean isCancelled() { return fSync.doIsCancelled(); } + + public boolean isDone() { return fSync.doIsDone(); } + + + public void run() { + // Change the state to running. + if (fSync.doRun()) { + // Set the reference to this sequence in each step. + int totalTicks = 0; + for (Step step : getSteps()) { + step.setSequence(this); + totalTicks += step.getTicks(); + } + + // Set the task name + if (fTaskName != null) { + fProgressMonitor.beginTask(fTaskName, totalTicks); + } + + // Call the first step + executeStep(0); + } else { + fSync.doFinish(); } - fSteps[fCurrentStepIdx].execute(); - } - - /** - * Cancells the execution of this sequence. The roll-back will start when - * the current step completes. - * - */ - public void cancel() { - fCancelled = true; } /** * To be called only by the step implementation, Tells the sequence to * submit the next step. */ - public void stepFinished() { - getExecutor().submit(new DsfRunnable() { public void run() { - fProgressMonitor.worked(getSteps()[fCurrentStepIdx].getTicks()); - fCurrentStepIdx++; - if (fCurrentStepIdx < fSteps.length) { - if (fCancelled) { - abort(new Status( - IStatus.CANCEL, DsfPlugin.PLUGIN_ID, -1, - "Cancelled" + fTaskName != null ? ": " + fTaskName : "", - null)); - } - fSteps[fCurrentStepIdx].execute(); + private void executeStep(int nextStepIndex) { + if (isCancelled()) { + cancelExecution(); + } else { + if (nextStepIndex < getSteps().length) { + fCurrentStepIdx = nextStepIndex; + getSteps()[fCurrentStepIdx].execute(new Done() { + final private int fStepIdx = fCurrentStepIdx; + public void run() { + // Check if we're still the correct step. + assert fStepIdx == fCurrentStepIdx; + + // Proceed to the next step. + if (getStatus().isOK()) { + fProgressMonitor.worked(getSteps()[fStepIdx].getTicks()); + executeStep(fStepIdx + 1); + } else { + abortExecution(getStatus()); + } + } + public String toString() { + return "DsfSequence \"" + fTaskName + "\", result for executing step #" + fStepIdx + " = " + getStatus(); + } + }); } else { - if (fDoneQC != null) getExecutor().submit(fDoneQC); + finish(); } - }}); + } } /** * To be called only by the step implementation. Tells the sequence to * roll back next step. */ - public void stepRolledBack() { - getExecutor().submit(new DsfRunnable() { public void run() { - fProgressMonitor.worked(getSteps()[fCurrentStepIdx].getTicks()); - fCurrentStepIdx--; - if (fCurrentStepIdx >= 0) { - fSteps[fCurrentStepIdx].rollBack(); - } else { - if (fDoneQC != null) getExecutor().submit(fDoneQC); - } - }}); + private void rollBackStep(int stepIdx) { + if (stepIdx >= 0) { + fCurrentStepIdx = stepIdx; + getSteps()[fCurrentStepIdx].rollBack(new Done() { + final private int fStepIdx = fCurrentStepIdx; + public void run() { + // Check if we're still the correct step. + assert fStepIdx == fCurrentStepIdx; + + // Proceed to the next step. + if (getStatus().isOK()) { + fProgressMonitor.worked(getSteps()[fStepIdx].getTicks()); + rollBackStep(fStepIdx - 1); + } else { + abortRollBack(getStatus()); + } + }; + @Override + public String toString() { + return "DsfSequence \"" + fTaskName + "\", result for rolling back step #" + fStepIdx + " = " + getStatus(); + } + }); + } else { + finish(); + } } - + /** - * To be called only by step implementation. Tells the sequence - * that its execution is to be aborted and it should start rolling back - * the sequence as if it was cancelled by user. - * @param error + * Tells the sequence that its execution is to be aborted and it + * should start rolling back the sequence as if it was cancelled by user. */ - public void abort(final IStatus error) { - getExecutor().submit(new DsfRunnable() { public void run() { - if (fRollbackTaskName != null) { - fProgressMonitor.subTask(fRollbackTaskName); - } - fDoneQC.setStatus(error); - fCurrentStepIdx--; - if (fCurrentStepIdx >= 0) { - fSteps[fCurrentStepIdx].rollBack(); - } else { - if (fDoneQC != null) getExecutor().submit(fDoneQC); - } - }}); + private void cancelExecution() { + if (fRollbackTaskName != null) { + fProgressMonitor.subTask(fRollbackTaskName); + } + fStatus = new Status(IStatus.CANCEL, DsfPlugin.PLUGIN_ID, "Sequence \"" + fTaskName + "\" cancelled."); + if (fDone != null) { + fDone.setStatus(fStatus); + } + + /* + * No need to call fSync, it should have been taken care of by + * Future#cancel method. + * + * Note that we're rolling back starting with the current step, + * because the current step was fully executed. This is unlike + * abortExecution() where the current step caused the roll-back. + */ + rollBackStep(fCurrentStepIdx); + } + + /** + * Tells the sequence that its execution is to be aborted and it + * should start rolling back the sequence as if it was cancelled by user. + */ + private void abortExecution(final IStatus error) { + if (fRollbackTaskName != null) { + fProgressMonitor.subTask(fRollbackTaskName); + } + fStatus = error; + if (fDone != null) { + fDone.setStatus(error); + } + fSync.doAbort(new CoreException(error)); + + // Roll back starting with previous step, since current step failed. + rollBackStep(fCurrentStepIdx - 1); + } + + /** + * Tells the sequence that that is rolling back, to abort roll back, and + * notify the clients. + */ + private void abortRollBack(final IStatus error) { + if (fRollbackTaskName != null) { + fProgressMonitor.subTask(fRollbackTaskName); + } + + /* + * Compose new status based on previous status information and new + * error information. + */ + MultiStatus newStatus = + new MultiStatus(DsfPlugin.PLUGIN_ID, error.getCode(), + "Sequence \"" + fTaskName + "\" failed while rolling back.", null); + newStatus.merge(error); + newStatus.merge(fStatus); + fStatus = newStatus; + + if (fDone != null) { + fDone.setStatus(newStatus); + } + + finish(); } + private void finish() { + if (fDone != null) getExecutor().submit(fDone); + fSync.doFinish(); + } + + @SuppressWarnings("serial") + final class Sync extends AbstractQueuedSynchronizer { + private static final int STATE_RUNNING = 1; + private static final int STATE_FINISHED = 2; + private static final int STATE_ABORTING = 4; + private static final int STATE_ABORTED = 8; + private static final int STATE_CANCELLING = 16; + private static final int STATE_CANCELLED = 32; + + private Throwable fException; + + private boolean isFinished(int state) { + return (state & (STATE_FINISHED | STATE_CANCELLED | STATE_ABORTED)) != 0; + } + + protected int tryAcquireShared(int ignore) { + return doIsDone()? 1 : -1; + } + + protected boolean tryReleaseShared(int ignore) { + return true; + } + + boolean doIsCancelled() { + int state = getState(); + return (state & (STATE_CANCELLING | STATE_CANCELLED)) != 0; + } + + boolean doIsDone() { + return isFinished(getState()); + } + + void doGet() throws InterruptedException, ExecutionException { + acquireSharedInterruptibly(0); + if (getState() == STATE_CANCELLED) throw new CancellationException(); + if (fException != null) throw new ExecutionException(fException); + } + + void doGet(long nanosTimeout) throws InterruptedException, ExecutionException, TimeoutException { + if (!tryAcquireSharedNanos(0, nanosTimeout)) throw new TimeoutException(); + if (getState() == STATE_CANCELLED) throw new CancellationException(); + if (fException != null) throw new ExecutionException(fException); + } + + void doAbort(Throwable t) { + while(true) { + int s = getState(); + if (isFinished(s)) return; + if (compareAndSetState(s, STATE_ABORTING)) break; + } + fException = t; + } + + boolean doCancel() { + while(true) { + int s = getState(); + if (isFinished(s)) return false; + if (s == STATE_ABORTING) return false; + if (compareAndSetState(s, STATE_CANCELLING)) break; + } + return true; + } + + void doFinish() { + while(true) { + int s = getState(); + if (isFinished(s)) return; + if (s == STATE_ABORTING) { + if (compareAndSetState(s, STATE_ABORTED)) break; + } else if (s == STATE_CANCELLING) { + if (compareAndSetState(s, STATE_CANCELLED)) break; + } else { + if (compareAndSetState(s, STATE_FINISHED)) break; + } + } + releaseShared(0); + } + + boolean doRun() { + return compareAndSetState(0, STATE_RUNNING); + } + } + } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/StackTraceWrapper.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/StackTraceWrapper.java new file mode 100644 index 00000000000..26352039d28 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/StackTraceWrapper.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.concurrent; + +/** + * Untility class for easy pretty-printing stack traces. Local to the + * concurrent package. + */ +@Immutable +class StackTraceWrapper { + final StackTraceElement[] fStackTraceElements; + + StackTraceWrapper(StackTraceElement[] elements) { fStackTraceElements = elements; } + + public String toString() { + StringBuilder builder = new StringBuilder(fStackTraceElements.length * 30); + for (int i = 0; i < fStackTraceElements.length && i < 10; i++) { + builder.append(fStackTraceElements[i]); + if (i < fStackTraceElements.length && i < 10) builder.append("\n at "); + } + return builder.toString(); + } +} From cfeb1e5d314f1a4be4328b63fbefecc63376ecec Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Mon, 16 Oct 2006 07:58:52 +0000 Subject: [PATCH 029/834] Added ability to cancell DsfSequence using the progress monitor (bug# 159048). --- .../dd/dsf/concurrent/DsfSequence.java | 117 +++++++++++------- 1 file changed, 71 insertions(+), 46 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java index 6fe0903cd82..5af2bd97a7a 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java @@ -233,33 +233,55 @@ abstract public class DsfSequence extends DsfRunnable implements Future * submit the next step. */ private void executeStep(int nextStepIndex) { + /* + * At end of each step check progress monitor to see if it's cancelled. + * If progress monitor is cancelled, mark the whole sequence as + * cancelled. + */ + if (fProgressMonitor.isCanceled()) { + cancel(false); + } + + /* + * If sequence was cencelled during last step (or before the sequence + * was ever executed), start rolling back the execution. + */ if (isCancelled()) { cancelExecution(); - } else { - if (nextStepIndex < getSteps().length) { - fCurrentStepIdx = nextStepIndex; - getSteps()[fCurrentStepIdx].execute(new Done() { - final private int fStepIdx = fCurrentStepIdx; - public void run() { - // Check if we're still the correct step. - assert fStepIdx == fCurrentStepIdx; - - // Proceed to the next step. - if (getStatus().isOK()) { - fProgressMonitor.worked(getSteps()[fStepIdx].getTicks()); - executeStep(fStepIdx + 1); - } else { - abortExecution(getStatus()); - } - } - public String toString() { - return "DsfSequence \"" + fTaskName + "\", result for executing step #" + fStepIdx + " = " + getStatus(); - } - }); - } else { - finish(); - } + return; + } + + /* + * Check if we've reached the last step. Note that if execution was + * cancelled during the last step (and thus the sequence is + * technically finished, since it was cancelled it will be rolled + * back. + */ + if (nextStepIndex >= getSteps().length) { + finish(); + return; } + + // Proceed with executing next step. + fCurrentStepIdx = nextStepIndex; + getSteps()[fCurrentStepIdx].execute(new Done() { + final private int fStepIdx = fCurrentStepIdx; + public void run() { + // Check if we're still the correct step. + assert fStepIdx == fCurrentStepIdx; + + // Proceed to the next step. + if (getStatus().isOK()) { + fProgressMonitor.worked(getSteps()[fStepIdx].getTicks()); + executeStep(fStepIdx + 1); + } else { + abortExecution(getStatus()); + } + } + public String toString() { + return "DsfSequence \"" + fTaskName + "\", result for executing step #" + fStepIdx + " = " + getStatus(); + } + }); } /** @@ -267,30 +289,33 @@ abstract public class DsfSequence extends DsfRunnable implements Future * roll back next step. */ private void rollBackStep(int stepIdx) { - if (stepIdx >= 0) { - fCurrentStepIdx = stepIdx; - getSteps()[fCurrentStepIdx].rollBack(new Done() { - final private int fStepIdx = fCurrentStepIdx; - public void run() { - // Check if we're still the correct step. - assert fStepIdx == fCurrentStepIdx; - - // Proceed to the next step. - if (getStatus().isOK()) { - fProgressMonitor.worked(getSteps()[fStepIdx].getTicks()); - rollBackStep(fStepIdx - 1); - } else { - abortRollBack(getStatus()); - } - }; - @Override - public String toString() { - return "DsfSequence \"" + fTaskName + "\", result for rolling back step #" + fStepIdx + " = " + getStatus(); - } - }); - } else { + // If we reach before step 0, finish roll back. + if (stepIdx < 0) { finish(); + return; } + + // Proceed with rolling back given step. + fCurrentStepIdx = stepIdx; + getSteps()[fCurrentStepIdx].rollBack(new Done() { + final private int fStepIdx = fCurrentStepIdx; + public void run() { + // Check if we're still the correct step. + assert fStepIdx == fCurrentStepIdx; + + // Proceed to the next step. + if (getStatus().isOK()) { + fProgressMonitor.worked(getSteps()[fStepIdx].getTicks()); + rollBackStep(fStepIdx - 1); + } else { + abortRollBack(getStatus()); + } + }; + @Override + public String toString() { + return "DsfSequence \"" + fTaskName + "\", result for rolling back step #" + fStepIdx + " = " + getStatus(); + } + }); } /** From bc54ad145e8a7b021310496a1f680c83021d08ce Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Mon, 16 Oct 2006 14:49:55 +0000 Subject: [PATCH 030/834] Added unit tests for standard service functionality (159680). --- .../dd/dsf/concurrent/DefaultDsfExecutor.java | 35 +++--- .../eclipse/dd/dsf/concurrent/DsfQuery.java | 31 ++++- .../dd/dsf/concurrent/DsfSequence.java | 115 ++++++++++++------ 3 files changed, 123 insertions(+), 58 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java index 44e07542379..436568ef959 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java @@ -71,27 +71,30 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor } catch (CancellationException e) { // Ignore also } catch (ExecutionException e) { if (e.getCause() != null) { - ILog log = DsfPlugin.getDefault().getLog(); - if (log != null) { - log.log(new Status( - IStatus.ERROR, DsfPlugin.PLUGIN_ID, -1, "Uncaught exception in DSF executor thread", e.getCause())); - - // Print out the stack trace to console if assertions are enabled. - if(ASSERTIONS_ENABLED) { - ByteArrayOutputStream outStream = new ByteArrayOutputStream(512); - PrintStream printStream = new PrintStream(outStream); - try { - printStream.write("Uncaught exception in session executor thread: ".getBytes()); - } catch (IOException e2) {} - e.getCause().printStackTrace(new PrintStream(outStream)); - System.err.println(outStream.toString()); - } - } + logException(t); } } } } + static void logException(Throwable t) { + ILog log = DsfPlugin.getDefault().getLog(); + if (log != null) { + log.log(new Status( + IStatus.ERROR, DsfPlugin.PLUGIN_ID, -1, "Uncaught exception in DSF executor thread", t)); + } + // Print out the stack trace to console if assertions are enabled. + if(ASSERTIONS_ENABLED) { + ByteArrayOutputStream outStream = new ByteArrayOutputStream(512); + PrintStream printStream = new PrintStream(outStream); + try { + printStream.write("Uncaught exception in session executor thread: ".getBytes()); + } catch (IOException e2) {} + t.printStackTrace(new PrintStream(outStream)); + System.err.println(outStream.toString()); + } + } + // // Utilities used for tracing. // diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfQuery.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfQuery.java index fce82bb2f65..014818b5566 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfQuery.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfQuery.java @@ -17,6 +17,8 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.locks.AbstractQueuedSynchronizer; +import org.eclipse.core.runtime.CoreException; + /** * A convenience class that allows a client to retrieve data from services @@ -53,19 +55,36 @@ abstract public class DsfQuery extends DsfRunnable public boolean isDone() { return fSync.doIsDone(); } - protected void done(V result) { - fSync.doSet(result); - } - protected void doneException(Throwable t) { fSync.doSetException(t); } - abstract protected void execute(); + abstract protected void execute(GetDataDone done); public void run() { if (fSync.doRun()) { - execute(); + try { + execute(new GetDataDone() { + public void run() { + if (getStatus().isOK()) fSync.doSet(getData()); + else fSync.doSetException(new CoreException(getStatus())); + } + }); + } catch(Throwable t) { + /* + * Catching the exception here will only work if the exception + * happens within the execute. It will not work in cases when + * the execute submits other runnables, and the other runnables + * encounter the exception. + */ + fSync.doSetException(t); + + /* + * Since we caught the exception, it will not be logged by + * DefaultDsfExecutable.afterExecution(). So log it here. + */ + DefaultDsfExecutor.logException(t); + } } } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java index 5af2bd97a7a..e6794500f36 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java @@ -160,6 +160,11 @@ abstract public class DsfSequence extends DsfRunnable implements Future * Returns the steps to be executed. It is up to the deriving class to * supply the steps and to ensure that the list of steps will not be * modified after the sequence is constructed. + *

    + * Steps are purposely not accepted as part of the DsfConstructor, in + * order to allow deriving classes to create the steps as a field. And a + * setSteps() method is not provided, to guarantee that the steps will not + * be modified once set (perhaps this is a bit paranoid, but oh well). */ abstract public Step[] getSteps(); @@ -264,24 +269,43 @@ abstract public class DsfSequence extends DsfRunnable implements Future // Proceed with executing next step. fCurrentStepIdx = nextStepIndex; - getSteps()[fCurrentStepIdx].execute(new Done() { - final private int fStepIdx = fCurrentStepIdx; - public void run() { - // Check if we're still the correct step. - assert fStepIdx == fCurrentStepIdx; - - // Proceed to the next step. - if (getStatus().isOK()) { - fProgressMonitor.worked(getSteps()[fStepIdx].getTicks()); - executeStep(fStepIdx + 1); - } else { - abortExecution(getStatus()); + try { + getSteps()[fCurrentStepIdx].execute(new Done() { + final private int fStepIdx = fCurrentStepIdx; + public void run() { + // Check if we're still the correct step. + assert fStepIdx == fCurrentStepIdx; + + // Proceed to the next step. + if (getStatus().isOK()) { + fProgressMonitor.worked(getSteps()[fStepIdx].getTicks()); + executeStep(fStepIdx + 1); + } else { + abortExecution(getStatus()); + } } - } - public String toString() { - return "DsfSequence \"" + fTaskName + "\", result for executing step #" + fStepIdx + " = " + getStatus(); - } - }); + public String toString() { + return "DsfSequence \"" + fTaskName + "\", result for executing step #" + fStepIdx + " = " + getStatus(); + } + }); + } catch(Throwable t) { + /* + * Catching the exception here will only work if the exception + * happens within the execute method. It will not work in cases + * when the execute submits other runnables, and the other runnables + * encounter the exception. + */ + abortExecution(new Status( + IStatus.ERROR, DsfPlugin.PLUGIN_ID, 0, + "Unhandled exception when executing DsfSequence " + this + ", step #" + fCurrentStepIdx, + t)); + + /* + * Since we caught the exception, it will not be logged by + * DefaultDsfExecutable.afterExecution(). So log it here. + */ + DefaultDsfExecutor.logException(t); + } } /** @@ -297,25 +321,44 @@ abstract public class DsfSequence extends DsfRunnable implements Future // Proceed with rolling back given step. fCurrentStepIdx = stepIdx; - getSteps()[fCurrentStepIdx].rollBack(new Done() { - final private int fStepIdx = fCurrentStepIdx; - public void run() { - // Check if we're still the correct step. - assert fStepIdx == fCurrentStepIdx; - - // Proceed to the next step. - if (getStatus().isOK()) { - fProgressMonitor.worked(getSteps()[fStepIdx].getTicks()); - rollBackStep(fStepIdx - 1); - } else { - abortRollBack(getStatus()); - } - }; - @Override - public String toString() { - return "DsfSequence \"" + fTaskName + "\", result for rolling back step #" + fStepIdx + " = " + getStatus(); - } - }); + try { + getSteps()[fCurrentStepIdx].rollBack(new Done() { + final private int fStepIdx = fCurrentStepIdx; + public void run() { + // Check if we're still the correct step. + assert fStepIdx == fCurrentStepIdx; + + // Proceed to the next step. + if (getStatus().isOK()) { + fProgressMonitor.worked(getSteps()[fStepIdx].getTicks()); + rollBackStep(fStepIdx - 1); + } else { + abortRollBack(getStatus()); + } + }; + @Override + public String toString() { + return "DsfSequence \"" + fTaskName + "\", result for rolling back step #" + fStepIdx + " = " + getStatus(); + } + }); + } catch(Throwable t) { + /* + * Catching the exception here will only work if the exception + * happens within the execute method. It will not work in cases + * when the execute submits other runnables, and the other runnables + * encounter the exception. + */ + abortRollBack(new Status( + IStatus.ERROR, DsfPlugin.PLUGIN_ID, 0, + "Unhandled exception when rolling back DsfSequence " + this + ", step #" + fCurrentStepIdx, + t)); + + /* + * Since we caught the exception, it will not be logged by + * DefaultDsfExecutable.afterExecution(). So log it here. + */ + DefaultDsfExecutor.logException(t); + } } /** From 3173aac06ccf5aa5fd946fa02469699b07cc0eac Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 19 Oct 2006 07:30:24 +0000 Subject: [PATCH 031/834] Refactored timers example to use scheduling executor. --- .../dd/dsf/concurrent/DefaultDsfExecutor.java | 12 ++++++++++-- .../org/eclipse/dd/dsf/concurrent/DsfSequence.java | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java index 436568ef959..1cbc1e25901 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java @@ -66,12 +66,20 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor if (r instanceof Future) { Future future = (Future)r; try { - future.get(); + /* + * Try to retrieve the value, which should throw exception in + * case when exception was thrown within the Runnable/Callable. + * Must call isDone(), because scheduled futures would block + * on get. + */ + if (future.isDone()) { + future.get(); + } } catch (InterruptedException e) { // Ignore } catch (CancellationException e) { // Ignore also } catch (ExecutionException e) { if (e.getCause() != null) { - logException(t); + logException(e.getCause()); } } } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java index e6794500f36..ee1dfc7853f 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java @@ -369,7 +369,7 @@ abstract public class DsfSequence extends DsfRunnable implements Future if (fRollbackTaskName != null) { fProgressMonitor.subTask(fRollbackTaskName); } - fStatus = new Status(IStatus.CANCEL, DsfPlugin.PLUGIN_ID, "Sequence \"" + fTaskName + "\" cancelled."); + fStatus = new Status(IStatus.CANCEL, DsfPlugin.PLUGIN_ID, -1, "Sequence \"" + fTaskName + "\" cancelled.", null); if (fDone != null) { fDone.setStatus(fStatus); } From 9ff6415403942fb4fa820451544f42ad75ead3f5 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 1 Nov 2006 21:53:48 +0000 Subject: [PATCH 032/834] - 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. --- .../org.eclipse.dd.dsf.debug.ui/.classpath | 7 + plugins/org.eclipse.dd.dsf.debug.ui/.project | 28 ++ .../.settings/org.eclipse.jdt.core.prefs | 12 + .../META-INF/MANIFEST.MF | 22 ++ .../build.properties | 4 + .../plugin.properties | 13 + .../dd/dsf/debug/ui/DsfDebugUIPlugin.java | 61 ++++ .../ui/viewmodel/DebugViewModelProvider.java | 70 ++++ .../DebugViewSelectionRootLayoutNode.java | 116 +++++++ .../ui/viewmodel/RegisterGroupLayoutNode.java | 103 ++++++ .../ui/viewmodel/RegisterLayoutNode.java | 128 +++++++ .../ui/viewmodel/StackFramesLayoutNode.java | 272 +++++++++++++++ .../StandardLaunchRootLayoutNode.java | 103 ++++++ .../viewmodel/StandardProcessLayoutNode.java | 192 ++++++++++ .../debug/ui/viewmodel/ThreadLayoutNode.java | 99 ++++++ plugins/org.eclipse.dd.dsf.debug/.classpath | 7 + plugins/org.eclipse.dd.dsf.debug/.cvsignore | 1 + plugins/org.eclipse.dd.dsf.debug/.options | 2 + plugins/org.eclipse.dd.dsf.debug/.project | 28 ++ .../.settings/org.eclipse.jdt.core.prefs | 12 + .../.settings/org.eclipse.jdt.ui.prefs | 3 + .../META-INF/MANIFEST.MF | 14 + .../org.eclipse.dd.dsf.debug/build.properties | 5 + .../plugin.properties | 13 + plugins/org.eclipse.dd.dsf.debug/plugin.xml | 5 + .../eclipse/dd/dsf/debug/DsfDebugPlugin.java | 79 +++++ .../dd/dsf/debug/service}/IAddress.java | 2 +- .../dsf/debug/service}/IBackEndProcess.java | 2 +- .../dd/dsf/debug/service}/IBreakpoints.java | 28 +- .../dd/dsf/debug/service}/IExpressions.java | 26 +- .../dd/dsf/debug/service}/IMemory.java | 4 +- .../dd/dsf/debug/service}/IModules.java | 44 +-- .../dsf/debug/service}/INativeProcesses.java | 40 +-- .../eclipse/dd/dsf/debug/service}/IOS.java | 32 +- .../dd/dsf/debug/service}/IRegisters.java | 34 +- .../dd/dsf/debug/service}/IRunControl.java | 56 +-- .../dd/dsf/debug/service}/ISourceLookup.java | 4 +- .../eclipse/dd/dsf/debug/service}/IStack.java | 30 +- .../dsf/debug/service}/IStepQueueManager.java | 20 +- .../dd/dsf/debug/service}/ISymbols.java | 20 +- .../dd/dsf/debug/service/ITargets.java | 52 +++ .../META-INF/MANIFEST.MF | 2 +- .../dsf/ui/model/DataViewModelSchemaNode.java | 232 ------------- .../dd/dsf/ui/model/ViewModelProvider.java | 271 --------------- .../dsf/ui/viewmodel/AbstractVMAdapter.java | 164 +++++++++ .../ui/viewmodel/AbstractVMLayoutNode.java | 160 +++++++++ .../viewmodel/AbstractVMRootLayoutNode.java | 123 +++++++ .../ui/viewmodel/DMContextVMLayoutNode.java | 222 ++++++++++++ .../GetDataDoneWithRequestMonitor.java | 2 +- .../IVMContext.java} | 10 +- .../IVMLayoutNode.java} | 41 ++- .../dsf/ui/viewmodel/IVMRootLayoutNode.java | 55 +++ .../VMDelta.java} | 52 +-- .../dd/dsf/ui/viewmodel/VMProvider.java | 327 ++++++++++++++++++ .../dsf/ui/{model => viewmodel}/package.html | 4 +- .../org.eclipse.dd.dsf/META-INF/MANIFEST.MF | 6 +- .../dd/dsf/concurrent/DefaultDsfExecutor.java | 17 +- .../org/eclipse/dd/dsf/concurrent/Done.java | 2 +- .../{DoneTracker.java => DoneCollector.java} | 33 +- .../AbstractDMContext.java} | 30 +- .../AbstractDMEvent.java} | 11 +- .../DMCs.java => datamodel/DMContexts.java} | 47 ++- .../IDMContext.java} | 14 +- .../IDMData.java} | 16 +- .../IDMEvent.java} | 10 +- .../IDMService.java} | 14 +- .../dd/dsf/datamodel/ServiceDMContext.java | 32 ++ .../dd/dsf/{model => datamodel}/package.html | 0 .../org/eclipse/dd/dsf/debug/ITargets.java | 52 --- .../dd/dsf/service/AbstractDsfService.java | 62 +++- .../eclipse/dd/dsf/service/DsfSession.java | 8 +- 71 files changed, 2931 insertions(+), 881 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/.classpath create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/.project create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/.settings/org.eclipse.jdt.core.prefs create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/build.properties create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/plugin.properties create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/DsfDebugUIPlugin.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewModelProvider.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewSelectionRootLayoutNode.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/RegisterGroupLayoutNode.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/RegisterLayoutNode.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/StackFramesLayoutNode.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/StandardLaunchRootLayoutNode.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/StandardProcessLayoutNode.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/ThreadLayoutNode.java create mode 100644 plugins/org.eclipse.dd.dsf.debug/.classpath create mode 100644 plugins/org.eclipse.dd.dsf.debug/.cvsignore create mode 100644 plugins/org.eclipse.dd.dsf.debug/.options create mode 100644 plugins/org.eclipse.dd.dsf.debug/.project create mode 100644 plugins/org.eclipse.dd.dsf.debug/.settings/org.eclipse.jdt.core.prefs create mode 100644 plugins/org.eclipse.dd.dsf.debug/.settings/org.eclipse.jdt.ui.prefs create mode 100644 plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF create mode 100644 plugins/org.eclipse.dd.dsf.debug/build.properties create mode 100644 plugins/org.eclipse.dd.dsf.debug/plugin.properties create mode 100644 plugins/org.eclipse.dd.dsf.debug/plugin.xml create mode 100644 plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/DsfDebugPlugin.java rename plugins/{org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug => org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service}/IAddress.java (82%) rename plugins/{org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug => org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service}/IBackEndProcess.java (97%) rename plugins/{org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug => org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service}/IBreakpoints.java (56%) rename plugins/{org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug => org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service}/IExpressions.java (75%) rename plugins/{org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug => org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service}/IMemory.java (96%) rename plugins/{org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug => org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service}/IModules.java (73%) rename plugins/{org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug => org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service}/INativeProcesses.java (66%) rename plugins/{org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug => org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service}/IOS.java (69%) rename plugins/{org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug => org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service}/IRegisters.java (69%) rename plugins/{org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug => org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service}/IRunControl.java (60%) rename plugins/{org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug => org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service}/ISourceLookup.java (97%) rename plugins/{org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug => org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service}/IStack.java (69%) rename plugins/{org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug => org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service}/IStepQueueManager.java (75%) rename plugins/{org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug => org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service}/ISymbols.java (72%) create mode 100644 plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ITargets.java delete mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/DataViewModelSchemaNode.java delete mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/ViewModelProvider.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMRootLayoutNode.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java rename plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/{model => viewmodel}/GetDataDoneWithRequestMonitor.java (97%) rename plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/{model/IViewModelContext.java => viewmodel/IVMContext.java} (77%) rename plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/{model/IViewModelSchemaNode.java => viewmodel/IVMLayoutNode.java} (69%) create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMRootLayoutNode.java rename plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/{model/ViewModelDelta.java => viewmodel/VMDelta.java} (81%) create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMProvider.java rename plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/{model => viewmodel}/package.html (94%) rename plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/{DoneTracker.java => DoneCollector.java} (80%) rename plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/{model/AbstractDMC.java => datamodel/AbstractDMContext.java} (80%) rename plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/{model/DataModelEvent.java => datamodel/AbstractDMEvent.java} (71%) rename plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/{model/DMCs.java => datamodel/DMContexts.java} (58%) rename plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/{model/IDataModelContext.java => datamodel/IDMContext.java} (89%) rename plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/{model/IDataModelData.java => datamodel/IDMData.java} (67%) rename plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/{model/IDataModelEvent.java => datamodel/IDMEvent.java} (73%) rename plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/{model/IDataModelService.java => datamodel/IDMService.java} (76%) create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/ServiceDMContext.java rename plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/{model => datamodel}/package.html (100%) delete mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ITargets.java diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/.classpath b/plugins/org.eclipse.dd.dsf.debug.ui/.classpath new file mode 100644 index 00000000000..304e86186aa --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/.project b/plugins/org.eclipse.dd.dsf.debug.ui/.project new file mode 100644 index 00000000000..264961c7dd3 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/.project @@ -0,0 +1,28 @@ + + + org.eclipse.dd.dsf.debug.ui + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.dd.dsf.debug.ui/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000000..9091eab0ee6 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/.settings/org.eclipse.jdt.core.prefs @@ -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 diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..e312a803c6d --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF @@ -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 diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/build.properties b/plugins/org.eclipse.dd.dsf.debug.ui/build.properties new file mode 100644 index 00000000000..34d2e4d2dad --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.properties b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.properties new file mode 100644 index 00000000000..d7b098572ef --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.properties @@ -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 + diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/DsfDebugUIPlugin.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/DsfDebugUIPlugin.java new file mode 100644 index 00000000000..528fa8d8359 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/DsfDebugUIPlugin.java @@ -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); + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewModelProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewModelProvider.java new file mode 100644 index 00000000000..a3be1415e88 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewModelProvider.java @@ -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() { + public void run() { + if (getStatus().isOK()) { + getModelProxy().fireModelChangedNonDispatch(getData()); + } + } + }); + } + } + + + @Override + public void sessionDispose() { + DebugPlugin.getDefault().removeDebugEventListener(this); + super.sessionDispose(); + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewSelectionRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewSelectionRootLayoutNode.java new file mode 100644 index 00000000000..4752337b2ae --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewSelectionRootLayoutNode.java @@ -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 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( 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. + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/RegisterGroupLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/RegisterGroupLayoutNode.java new file mode 100644 index 00000000000..3701e2f8e41 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/RegisterGroupLayoutNode.java @@ -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 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() { 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 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() { 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() { + 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); + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/RegisterLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/RegisterLayoutNode.java new file mode 100644 index 00000000000..86b9ae992db --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/RegisterLayoutNode.java @@ -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 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() { + 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 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() { 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() { + 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); + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/StackFramesLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/StackFramesLayoutNode.java new file mode 100644 index 00000000000..57d77adfd42 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/StackFramesLayoutNode.java @@ -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 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 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() { 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 done) { + final IExecutionDMContext execDmc = findDmcInVmc(parentVmc, IExecutionDMContext.class); + + getServicesTracker().getService(IStack.class).getTopFrame( + execDmc, + new GetDataDone() { 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() { 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() { 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() { 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); + } + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/StandardLaunchRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/StandardLaunchRootLayoutNode.java new file mode 100644 index 00000000000..ef6add3693c --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/StandardLaunchRootLayoutNode.java @@ -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 fRootVMC; + final IVMContext[] fElements; + + public StandardLaunchRootLayoutNode(DsfExecutor executor, ILaunch launch) { + super(executor); + fRootVMC = new RootVMC(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 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; + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/StandardProcessLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/StandardProcessLayoutNode.java new file mode 100644 index 00000000000..5fe46857a7c --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/StandardProcessLayoutNode.java @@ -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 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 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); + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/ThreadLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/ThreadLayoutNode.java new file mode 100644 index 00000000000..d3b6d31277b --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/ThreadLayoutNode.java @@ -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 done) { + done.setData(Boolean.TRUE); + getExecutor().execute(done); + } + + public void getElements(final IVMContext parentVmc, final GetDataDone 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(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); + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug/.classpath b/plugins/org.eclipse.dd.dsf.debug/.classpath new file mode 100644 index 00000000000..eb62460abf6 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/plugins/org.eclipse.dd.dsf.debug/.cvsignore b/plugins/org.eclipse.dd.dsf.debug/.cvsignore new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug/.cvsignore @@ -0,0 +1 @@ + diff --git a/plugins/org.eclipse.dd.dsf.debug/.options b/plugins/org.eclipse.dd.dsf.debug/.options new file mode 100644 index 00000000000..54b07bac112 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug/.options @@ -0,0 +1,2 @@ +org.eclipse.dd.dsf/debug = false +org.eclipse.dd.dsf/debug/executor = false diff --git a/plugins/org.eclipse.dd.dsf.debug/.project b/plugins/org.eclipse.dd.dsf.debug/.project new file mode 100644 index 00000000000..340615eaab4 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug/.project @@ -0,0 +1,28 @@ + + + org.eclipse.dd.dsf.debug + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/plugins/org.eclipse.dd.dsf.debug/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.dd.dsf.debug/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000000..93a2ad59b5e --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug/.settings/org.eclipse.jdt.core.prefs @@ -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 diff --git a/plugins/org.eclipse.dd.dsf.debug/.settings/org.eclipse.jdt.ui.prefs b/plugins/org.eclipse.dd.dsf.debug/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 00000000000..087537fe3fb --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,3 @@ +#Sun Aug 06 18:10:27 CEST 2006 +eclipse.preferences.version=1 +internal.default.compliance=default diff --git a/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..ddac2dd0f5d --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF @@ -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 diff --git a/plugins/org.eclipse.dd.dsf.debug/build.properties b/plugins/org.eclipse.dd.dsf.debug/build.properties new file mode 100644 index 00000000000..e9863e281ea --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml diff --git a/plugins/org.eclipse.dd.dsf.debug/plugin.properties b/plugins/org.eclipse.dd.dsf.debug/plugin.properties new file mode 100644 index 00000000000..b22d03cf146 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug/plugin.properties @@ -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 + diff --git a/plugins/org.eclipse.dd.dsf.debug/plugin.xml b/plugins/org.eclipse.dd.dsf.debug/plugin.xml new file mode 100644 index 00000000000..33ca93ceb1b --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug/plugin.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/DsfDebugPlugin.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/DsfDebugPlugin.java new file mode 100644 index 00000000000..3ca12ae0ae0 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/DsfDebugPlugin.java @@ -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); + } + } +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IAddress.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IAddress.java similarity index 82% rename from plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IAddress.java rename to plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IAddress.java index 4175ec51a21..2f630505e4e 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IAddress.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IAddress.java @@ -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 diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IBackEndProcess.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBackEndProcess.java similarity index 97% rename from plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IBackEndProcess.java rename to plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBackEndProcess.java index d255acbff0a..a4f6ed39665 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IBackEndProcess.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBackEndProcess.java @@ -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; diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IBreakpoints.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java similarity index 56% rename from plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IBreakpoints.java rename to plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java index dab9151288f..864ac543f7c 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IBreakpoints.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java @@ -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 {} + public interface IBreakpointDMContext extends IDMContext {} - public interface IBreakpointData extends IDataModelData { + public interface IBreakpointDMData extends IDMData { IBreakpoint getPlatformBreakpoint(); BreakpointStatus getStatus(); } - public interface IBreakpointEvent extends IDataModelEvent {} + public interface IBreakpointDMEvent extends IDMEvent {} - 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 done); - public void getBreakpoints(IExecutionDMC execDmc, IBreakpoint platformBp, GetDataDone done); + public void getAllBreakpoints(IExecutionDMContext execDmc, GetDataDone done); + public void getBreakpoints(IExecutionDMContext execDmc, IBreakpoint platformBp, GetDataDone done); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IExpressions.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java similarity index 75% rename from plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IExpressions.java rename to plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java index 74969e81202..ee399aadfc8 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IExpressions.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java @@ -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 { + public interface IExpressionDMContext extends IDMContext { 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 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 {} + public interface IExpressionChangedDMEvent extends IDMEvent {} /** * 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> done); + void getSubExpressions(IExpressionDMContext exprCtx, GetDataDone> 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 done); + void getBaseExpressions(IExpressionDMContext exprContext, GetDataDone done); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IMemory.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java similarity index 96% rename from plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IMemory.java rename to plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java index c87fe7ccec0..1167a679cae 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IMemory.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java @@ -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 { diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IModules.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java similarity index 73% rename from plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IModules.java rename to plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java index caa2cb80667..f1f8212ecc9 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IModules.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java @@ -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 {} + public interface IModuleDMContext extends IDMContext {} /** * Event indicating a change in the symbol information for given context. */ - public interface ModulesChangedEvent extends IDataModelEvent {} + public interface ModulesChangedDMEvent extends IDMEvent {} /** * 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 done); + void getModules(ISymbolDMContext symCtx, GetDataDone done); /** * Calculates the line numbers corresponding to the given address. */ - void calcLineInfo(ISymbolDMC symCtx, IAddress address, GetDataDone done); + void calcLineInfo(ISymbolDMContext symCtx, IAddress address, GetDataDone done); /** * Calculates the addresses corresponding to the given source file location. */ - void calcAddressInfo(ISymbolDMC symCtx, String file, int line, int col, GetDataDone done); + void calcAddressInfo(ISymbolDMContext symCtx, String file, int line, int col, GetDataDone done); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/INativeProcesses.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/INativeProcesses.java similarity index 66% rename from plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/INativeProcesses.java rename to plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/INativeProcesses.java index 22476de3980..ce585e87ad9 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/INativeProcesses.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/INativeProcesses.java @@ -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 {} - public interface IProcessDMC extends IThreadDMC {} + public interface IThreadDMContext extends IDMContext {} + 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 {} + public interface ProcessChangedDMEvent extends IDMEvent {} /** * Retrieves the current list of processes running on target. */ - void getRunningProcesses(GetDataDone done); + void getRunningProcesses(GetDataDone 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 done); + void runNewProcess(String file, GetDataDone 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 done); + void debugNewProcess(String file, GetDataDone done); /** * Retrieves the list of processes which are currently under * debugger control. */ - void getProcessesBeingDebugged(GetDataDone done); + void getProcessesBeingDebugged(GetDataDone 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 done); + void canTerminate(IThreadDMContext thread, GetDataDone 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); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IOS.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IOS.java similarity index 69% rename from plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IOS.java rename to plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IOS.java index 4862e922375..a1b707b0c6e 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IOS.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IOS.java @@ -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 {} + public interface IOSDMContext extends IDMContext {} /** * 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 {} + public interface IObjectTypeDMContext extends IDMContext {} /** * 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 {} + public interface IObjectDMContext extends IDMContext {} /** * 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 done); + public void getObjectTypes(IOSDMContext os, IObjectTypeDMContext parent, GetDataDone 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 done); + public void getObjects(IOSDMContext os, IObjectTypeDMContext type, IObjectDMContext parent, GetDataDone done); /** * Attaches the debugger to given OS object context. */ - public void attachDebuggerToObject(IObjectDMC objectDmc, Done done); + public void attachDebuggerToObject(IObjectDMContext objectDmc, Done done); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IRegisters.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java similarity index 69% rename from plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IRegisters.java rename to plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java index de9409a5260..d03004c2f7d 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IRegisters.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java @@ -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 {} + public interface IRegisterGroupDMContext extends IDMContext {} /** * 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 {} + public interface IRegisterDMContext extends IDMContext {} /** Event indicating register value changed. */ - public interface IRegisterChangedEvent extends IDataModelEvent {} + public interface IRegisterChangedDMEvent extends IDMEvent {} /** 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 {} + public interface IBitFieldDMContext extends IDMContext {} /** * 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 done); + void getRegisterGroups(IRunControl.IExecutionDMContext execCtx, IStack.IFrameDMContext frameCtx, GetDataDone done); /** Retrieves list of sub-groups of given register group. */ - void getRegisterSubGroups(IRegisterGroupDMC groupCtx, GetDataDone done); + void getRegisterSubGroups(IRegisterGroupDMContext groupCtx, GetDataDone done); /** Retrieves registers in given register group. */ - void getRegisters(IRegisterGroupDMC groupCtx, GetDataDone done); + void getRegisters(IRegisterGroupDMContext groupCtx, GetDataDone done); /** Retrieves bit fields for given register */ - void getBitFields(IRegisterDMC regCtx, GetDataDone done); + void getBitFields(IRegisterDMContext regCtx, GetDataDone done); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IRunControl.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java similarity index 60% rename from plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IRunControl.java rename to plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java index 48b78e8783a..818b35c1487 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IRunControl.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java @@ -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 {} + public interface IExecutionDMContext extends IDMContext {} /** * 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 { + public interface ISuspendedDMEvent extends IDMEvent { StateChangeReason getReason(); } - public interface IResumedEvent extends IDataModelEvent { + public interface IResumedDMEvent extends IDMEvent { StateChangeReason getReason(); } - public interface IContainerSuspendedEvent extends IDataModelEvent { + public interface IContainerSuspendedDMEvent extends IDMEvent { StateChangeReason getReason(); } - public interface IContainerResumedEvent extends IDataModelEvent { + public interface IContainerResumedDMEvent extends IDMEvent { 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 { - IExecutionDMC getExecutionContext(); + public interface IStartedDMEvent extends IDMEvent { + 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 { - IExecutionDMC getExecutionContext(); + public interface IExitedDMEvent extends IDMEvent { + 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 done); + public void getExecutionContexts(IContainerDMContext c, GetDataDone 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); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ISourceLookup.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISourceLookup.java similarity index 97% rename from plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ISourceLookup.java rename to plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISourceLookup.java index 54f1341a1e5..74ddadcd4ce 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ISourceLookup.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISourceLookup.java @@ -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 diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStack.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java similarity index 69% rename from plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStack.java rename to plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java index 13936f96425..98ef485c0fd 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStack.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java @@ -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 {} + public interface IFrameDMContext extends IDMContext {} /** * 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 {} + public interface IVariableDMContext extends IDMContext {} /** * 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 done); + void getFrames(IRunControl.IExecutionDMContext execContext, GetDataDone 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 done); + void getTopFrame(IRunControl.IExecutionDMContext execContext, GetDataDone done); /** * Retrieves variables which were arguments to the stack frame's function. */ - void getArguments(IFrameDMC frameCtx, GetDataDone done); + void getArguments(IFrameDMContext frameCtx, GetDataDone done); /** * Retrieves variables local to the stack frame. */ - void getLocals(IFrameDMC frameCtx, GetDataDone done); + void getLocals(IFrameDMContext frameCtx, GetDataDone done); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStepQueueManager.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStepQueueManager.java similarity index 75% rename from plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStepQueueManager.java rename to plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStepQueueManager.java index aa92242269f..45d3cb45d08 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/IStepQueueManager.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStepQueueManager.java @@ -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 { + public interface ISteppingTimedOutEvent extends IDMEvent { } @@ -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); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ISymbols.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISymbols.java similarity index 72% rename from plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ISymbols.java rename to plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISymbols.java index be5d03437a4..446915da89d 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ISymbols.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISymbols.java @@ -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 {} +public interface ISymbols extends IDMService { + public interface ISymbolObjectDMContext extends IDMContext {} /** * 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 {} + public interface ISymbolDataChangedDMEvent extends IDMEvent {} /** * 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> done); + public void getSymbols(IModules.ISymbolDMContext symCtx, GetDataDone> done); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ITargets.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ITargets.java new file mode 100644 index 00000000000..75fda232788 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ITargets.java @@ -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 {} + + public interface ITargetDMData extends IDMData { + String getName(); + boolean isConnected(); + } + + public interface ITargetStateChanged extends IDMEvent {} + + public interface ICoreDMContext extends IDMContext {} + + public interface ICoreDMData extends IDMData { + String getName(); + boolean isConnected(); + IOS.IOSDMContext getOSDMContext(); + } + + public interface ICoreStateChangedDMEvent extends IDMEvent {} + + public void getTargets(GetDataDone done); + public void getCores(ITargetDMContext target, GetDataDone 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); + +} diff --git a/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF index 7e3baf87e0e..31c9f983458 100644 --- a/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF @@ -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 diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/DataViewModelSchemaNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/DataViewModelSchemaNode.java deleted file mode 100644 index 781d0162301..00000000000 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/DataViewModelSchemaNode.java +++ /dev/null @@ -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 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 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() { 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 findDMContext(IViewModelContext vmc, Class 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(); - } - } -} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/ViewModelProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/ViewModelProvider.java deleted file mode 100644 index 1246d15ae5e..00000000000 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/ViewModelProvider.java +++ /dev/null @@ -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. - *

    - * 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)hasElementsDone).getData().booleanValue(); - } - monitor.setIsContainer(isContainer); - monitor.done(); - }}; - for (IViewModelSchemaNode childNode : childSchemaNodes) { - childNode.hasElements( - vmc, - doneTracker.add( new GetDataDone() { 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() { 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(); - } -} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java new file mode 100644 index 00000000000..fd55c73dfc0 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java @@ -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 fViewModelProviders = + new HashMap(); + + 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; + } +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java new file mode 100644 index 00000000000..b675706758d --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java @@ -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() { + 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 + * true to the hasDeltaFlags() test for the given + * event. + */ + protected IVMLayoutNode[] getChildNodesWithDeltas(Object e) { + List nodes = new ArrayList(); + 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 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 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(); + } + + +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMRootLayoutNode.java new file mode 100644 index 00000000000..e443944c525 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMRootLayoutNode.java @@ -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 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 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 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 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()); + } + } +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java new file mode 100644 index 00000000000..4021d4df513 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java @@ -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 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 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 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 findDmcInVmc(IVMContext vmc, Class 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(); + } +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/GetDataDoneWithRequestMonitor.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/GetDataDoneWithRequestMonitor.java similarity index 97% rename from plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/GetDataDoneWithRequestMonitor.java rename to plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/GetDataDoneWithRequestMonitor.java index 50cf3712582..f675bc641d6 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/GetDataDoneWithRequestMonitor.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/GetDataDoneWithRequestMonitor.java @@ -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; diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/IViewModelContext.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMContext.java similarity index 77% rename from plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/IViewModelContext.java rename to plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMContext.java index cc14081913f..9c31035105a 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/IViewModelContext.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMContext.java @@ -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(); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/IViewModelSchemaNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMLayoutNode.java similarity index 69% rename from plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/IViewModelSchemaNode.java rename to plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMLayoutNode.java index 788fc63a781..982e95a6825 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/IViewModelSchemaNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMLayoutNode.java @@ -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. *

    - * 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 done); + public void hasElements(IVMContext parentVmc, GetDataDone 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 done); + public void getElements(IVMContext parentVmc, GetDataDone 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. diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMRootLayoutNode.java new file mode 100644 index 00000000000..251d74c7574 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMRootLayoutNode.java @@ -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 done); +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/ViewModelDelta.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java similarity index 81% rename from plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/ViewModelDelta.java rename to plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java index 9451da2e594..09c2c953bd2 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/ViewModelDelta.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java @@ -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]); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMProvider.java new file mode 100644 index 00000000000..c14b17e364b --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMProvider.java @@ -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. + *

    + * 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)hasElementsDone).getData().booleanValue(); + } + monitor.setIsContainer(isContainer); + monitor.done(); + } + }; + for (IVMLayoutNode childNode : parentVmc.getLayoutNode().getChildLayoutNodes()) { + childNode.hasElements( + parentVmc, + doneCollector.add( new GetDataDone() { 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() { + 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() { + 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 + "'"; + } + }); + } + } +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/package.html b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/package.html similarity index 94% rename from plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/package.html rename to plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/package.html index 166d66ee39c..12e15efaf52 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/model/package.html +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/package.html @@ -22,9 +22,9 @@ views.  

    Development Plans

    This package is also a work in progress and it is missing a major feature.  -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).  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.


    diff --git a/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF index 5b33ce3d3d5..efe81b8adf6 100644 --- a/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF @@ -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 diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java index 1cbc1e25901..df098ee83b3 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java @@ -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()); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java index 2f5f26ac0c0..975bdc7add6 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java @@ -66,6 +66,6 @@ abstract public class Done extends DsfRunnable { } public String toString() { - return getStatus().toString(); + return "Done: " + getStatus().toString(); } } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DoneTracker.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DoneCollector.java similarity index 80% rename from plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DoneTracker.java rename to plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DoneCollector.java index 3805a0e0b89..f62a34bf161 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DoneTracker.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DoneCollector.java @@ -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: *
    - *     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);
      *             }
      *         }));
      *     }
      * 
    */ -public abstract class DoneTracker extends Done { +public abstract class DoneCollector extends Done { + private final DsfExecutor fExecutor; private Map fDones = new HashMap(); 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 getDones() { return fDones; } + + @Override + public String toString() { + return "Done Collector: " + getStatus().toString(); + } } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/AbstractDMC.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMContext.java similarity index 80% rename from plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/AbstractDMC.java rename to plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMContext.java index 7defea3c20e..a69f213401e 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/AbstractDMC.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMContext.java @@ -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 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 Data Model data type that this context is for. */ @Immutable -public class AbstractDMC extends PlatformObject - implements IDataModelContext +public class AbstractDMContext extends PlatformObject + implements IDMContext { 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 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 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 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 diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/DataModelEvent.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMEvent.java similarity index 71% rename from plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/DataModelEvent.java rename to plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMEvent.java index b6acb420b30..acb4b79ba70 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/DataModelEvent.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMEvent.java @@ -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 implements IDataModelEvent { +public class AbstractDMEvent implements IDMEvent { private final V fModelContext; - public DataModelEvent(V context) { + public AbstractDMEvent(V context) { fModelContext = context; } - public V getDMC() { + public V getDMContext() { return fModelContext; } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/DMCs.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/DMContexts.java similarity index 58% rename from plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/DMCs.java rename to plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/DMContexts.java index a63f490ab3f..c9aaf7bd339 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/DMCs.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/DMContexts.java @@ -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 getAncestorOfType(IDataModelContext ctx, Class ancestorType) { + public static V getAncestorOfType(IDMContext ctx, Class 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 toList(IDMContext dmc) { + /* + * This method is implemented recursively, which is not necessarily + * the most efficient way to do this. + */ + List list = new ArrayList(); + list.add(dmc); + + for (IDMContext parentDmc : dmc.getParents()) { + list.addAll(toList(parentDmc)); + } + return list; + } } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelContext.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMContext.java similarity index 89% rename from plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelContext.java rename to plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMContext.java index 2c2ff5af6d3..b83ef7d325e 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelContext.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMContext.java @@ -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. *

    - * Note: DMC objects are meant to be immutable and thus accessible from + * 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. *

    - * Note #2: DMCs should also avoid holding references to service + * 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 extends IAdaptable +public interface IDMContext extends IAdaptable { /** * Each model context object needs to track the session from which it @@ -73,5 +73,5 @@ public interface IDataModelContext extends IAdaptable * the client. * @return parent context of this context. */ - public IDataModelContext[] getParents(); + public IDMContext[] getParents(); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelData.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMData.java similarity index 67% rename from plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelData.java rename to plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMData.java index b40bc85f523..9533c1476c1 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelData.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMData.java @@ -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. - *

    - * 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. diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelEvent.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMEvent.java similarity index 73% rename from plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelEvent.java rename to plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMEvent.java index 1806112cac9..d73dd889864 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelEvent.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMEvent.java @@ -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 DMC that is affected by this event. + * this base class only identifies the DM Context that is affected. + * @param Data Model context type that is affected by this event. */ -public interface IDataModelEvent { - V getDMC(); +public interface IDMEvent { + V getDMContext(); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelService.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMService.java similarity index 76% rename from plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelService.java rename to plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMService.java index 9ce857005fe..59824a8c0e1 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/IDataModelService.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMService.java @@ -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. *

    - * For completeness this service interface derives from IDataModelData - * and has a method which allows clients to retrieve the DMC that represents the - * service data. + * For completeness this service interface derives from IDMData + * 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. */ - void getModelData(IDataModelContext dmc, GetDataDone done); + void getModelData(IDMContext dmc, GetDataDone done); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/ServiceDMContext.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/ServiceDMContext.java new file mode 100644 index 00000000000..1f71becf043 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/ServiceDMContext.java @@ -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. + *

    + * Note: there should be only one instance of ServiceContext per service, so there + * is no need to implement the equals() methods. + */ +public class ServiceDMContext extends AbstractDMContext { + String fServiceDMID; + + public ServiceDMContext(AbstractDsfService service, String serviceDMID) { + super(service, null); + fServiceDMID = serviceDMID; + } + + public String toString() { return baseToString() + fServiceDMID; } + +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/package.html b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/package.html similarity index 100% rename from plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/model/package.html rename to plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/package.html diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ITargets.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ITargets.java deleted file mode 100644 index f142efe9393..00000000000 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/debug/ITargets.java +++ /dev/null @@ -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 {} - - public interface ITargetData extends IDataModelData { - String getName(); - boolean isConnected(); - } - - public interface ITargetStateChanged extends IDataModelEvent {} - - public interface ICoreDMC extends IDataModelContext {} - - public interface ICoreData extends IDataModelData { - String getName(); - boolean isConnected(); - IOS.IOSDMC getOSDMC(); - } - - public interface ICoreStateChanged extends IDataModelEvent {} - - public void getTargets(GetDataDone done); - public void getCores(ITargetDMC target, GetDataDone 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); - -} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java index 90bdc508b5a..81595302280 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java @@ -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(); diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java index 7c541cf5a94..807642efa87 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java @@ -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 fAdapters = Collections.synchronizedMap(new HashMap()); @@ -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) { From cd357e26e86aed37872571b78bb8bd5e64c370c7 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Sat, 4 Nov 2006 00:08:01 +0000 Subject: [PATCH 033/834] Fixed an NPE related to refactoring. --- .../ui/viewmodel/DebugViewSelectionRootLayoutNode.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewSelectionRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewSelectionRootLayoutNode.java index 4752337b2ae..0f92b623ca7 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewSelectionRootLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewSelectionRootLayoutNode.java @@ -37,6 +37,12 @@ public class DebugViewSelectionRootLayoutNode extends AbstractVMRootLayoutNode public DebugViewSelectionRootLayoutNode(DsfExecutor executor, IWorkbenchWindow window) { super(executor); + ISelection selection = DebugContextManager.getDefault().getActiveContext(window); + if (selection instanceof IStructuredSelection) { + fRootVMC = new RootVMC( this, ((IStructuredSelection)selection).getFirstElement() ); + } else { + fRootVMC = new RootVMC( this, null ); + } DebugContextManager.getDefault().addDebugContextListener(this, window); } @@ -103,10 +109,8 @@ public class DebugViewSelectionRootLayoutNode extends AbstractVMRootLayoutNode if (selection instanceof IStructuredSelection) { fRootVMC = new RootVMC( this, ((IStructuredSelection)selection).getFirstElement() ); } else { - fRootVMC = null; + fRootVMC = new RootVMC( this, 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) { From 3aacbfc8c0c927672bbb56f353fc970614ef91c9 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Tue, 7 Nov 2006 19:58:42 +0000 Subject: [PATCH 034/834] build --- .../.project | 17 ++++++ .../build.properties | 1 + .../feature.xml | 26 ++++++++ .../org.eclipse.dd.dsf.gdb-feature/.project | 17 ++++++ .../build.properties | 1 + .../feature.xml | 33 ++++++++++ .../org.eclipse.dd.dsf.sdk-feature/.project | 11 ++++ .../build.properties | 1 + .../feature.xml | 61 +++++++++++++++++++ .../org.eclipse.dd.dsf.test-feature/.project | 17 ++++++ .../build.properties | 1 + .../feature.xml | 26 ++++++++ 12 files changed, 212 insertions(+) create mode 100644 features/org.eclipse.dd.dsf.examples-feature/.project create mode 100644 features/org.eclipse.dd.dsf.examples-feature/build.properties create mode 100644 features/org.eclipse.dd.dsf.examples-feature/feature.xml create mode 100644 features/org.eclipse.dd.dsf.gdb-feature/.project create mode 100644 features/org.eclipse.dd.dsf.gdb-feature/build.properties create mode 100644 features/org.eclipse.dd.dsf.gdb-feature/feature.xml create mode 100644 features/org.eclipse.dd.dsf.sdk-feature/.project create mode 100644 features/org.eclipse.dd.dsf.sdk-feature/build.properties create mode 100644 features/org.eclipse.dd.dsf.sdk-feature/feature.xml create mode 100644 features/org.eclipse.dd.dsf.test-feature/.project create mode 100644 features/org.eclipse.dd.dsf.test-feature/build.properties create mode 100644 features/org.eclipse.dd.dsf.test-feature/feature.xml diff --git a/features/org.eclipse.dd.dsf.examples-feature/.project b/features/org.eclipse.dd.dsf.examples-feature/.project new file mode 100644 index 00000000000..69f77ac7b9f --- /dev/null +++ b/features/org.eclipse.dd.dsf.examples-feature/.project @@ -0,0 +1,17 @@ + + + org.eclipse.dd.dsf.examples-feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/features/org.eclipse.dd.dsf.examples-feature/build.properties b/features/org.eclipse.dd.dsf.examples-feature/build.properties new file mode 100644 index 00000000000..64f93a9f0b7 --- /dev/null +++ b/features/org.eclipse.dd.dsf.examples-feature/build.properties @@ -0,0 +1 @@ +bin.includes = feature.xml diff --git a/features/org.eclipse.dd.dsf.examples-feature/feature.xml b/features/org.eclipse.dd.dsf.examples-feature/feature.xml new file mode 100644 index 00000000000..b15949ebcd5 --- /dev/null +++ b/features/org.eclipse.dd.dsf.examples-feature/feature.xml @@ -0,0 +1,26 @@ + + + + + [Enter Feature Description here.] + + + + [Enter Copyright Description here.] + + + + [Enter License Description here.] + + + + + diff --git a/features/org.eclipse.dd.dsf.gdb-feature/.project b/features/org.eclipse.dd.dsf.gdb-feature/.project new file mode 100644 index 00000000000..a498d5a339c --- /dev/null +++ b/features/org.eclipse.dd.dsf.gdb-feature/.project @@ -0,0 +1,17 @@ + + + org.eclipse.dd.dsf.mi-feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/features/org.eclipse.dd.dsf.gdb-feature/build.properties b/features/org.eclipse.dd.dsf.gdb-feature/build.properties new file mode 100644 index 00000000000..64f93a9f0b7 --- /dev/null +++ b/features/org.eclipse.dd.dsf.gdb-feature/build.properties @@ -0,0 +1 @@ +bin.includes = feature.xml diff --git a/features/org.eclipse.dd.dsf.gdb-feature/feature.xml b/features/org.eclipse.dd.dsf.gdb-feature/feature.xml new file mode 100644 index 00000000000..cf588ea9ecc --- /dev/null +++ b/features/org.eclipse.dd.dsf.gdb-feature/feature.xml @@ -0,0 +1,33 @@ + + + + + [Enter Feature Description here.] + + + + [Enter Copyright Description here.] + + + + [Enter License Description here.] + + + + + + + diff --git a/features/org.eclipse.dd.dsf.sdk-feature/.project b/features/org.eclipse.dd.dsf.sdk-feature/.project new file mode 100644 index 00000000000..eb0a4bc6d98 --- /dev/null +++ b/features/org.eclipse.dd.dsf.sdk-feature/.project @@ -0,0 +1,11 @@ + + + org.eclipse.dd.dsf.sdk-feature + + + + + + + + diff --git a/features/org.eclipse.dd.dsf.sdk-feature/build.properties b/features/org.eclipse.dd.dsf.sdk-feature/build.properties new file mode 100644 index 00000000000..64f93a9f0b7 --- /dev/null +++ b/features/org.eclipse.dd.dsf.sdk-feature/build.properties @@ -0,0 +1 @@ +bin.includes = feature.xml diff --git a/features/org.eclipse.dd.dsf.sdk-feature/feature.xml b/features/org.eclipse.dd.dsf.sdk-feature/feature.xml new file mode 100644 index 00000000000..cc2ef1368ac --- /dev/null +++ b/features/org.eclipse.dd.dsf.sdk-feature/feature.xml @@ -0,0 +1,61 @@ + + + + + [Enter Feature Description here.] + + + + [Enter Copyright Description here.] + + + + [Enter License Description here.] + + + + + + + + + + + + + + + + + + + + diff --git a/features/org.eclipse.dd.dsf.test-feature/.project b/features/org.eclipse.dd.dsf.test-feature/.project new file mode 100644 index 00000000000..c1f5152ef13 --- /dev/null +++ b/features/org.eclipse.dd.dsf.test-feature/.project @@ -0,0 +1,17 @@ + + + org.eclipse.dd.dsf.test-feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/features/org.eclipse.dd.dsf.test-feature/build.properties b/features/org.eclipse.dd.dsf.test-feature/build.properties new file mode 100644 index 00000000000..64f93a9f0b7 --- /dev/null +++ b/features/org.eclipse.dd.dsf.test-feature/build.properties @@ -0,0 +1 @@ +bin.includes = feature.xml diff --git a/features/org.eclipse.dd.dsf.test-feature/feature.xml b/features/org.eclipse.dd.dsf.test-feature/feature.xml new file mode 100644 index 00000000000..4ac16cab1f4 --- /dev/null +++ b/features/org.eclipse.dd.dsf.test-feature/feature.xml @@ -0,0 +1,26 @@ + + + + + [Enter Feature Description here.] + + + + [Enter Copyright Description here.] + + + + [Enter License Description here.] + + + + + From 64bf23bf0a77e1c1ed9c518ee28f867ee408a1b7 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Tue, 7 Nov 2006 21:13:23 +0000 Subject: [PATCH 035/834] build --- features/org.eclipse.dd.dsf.examples-feature/feature.xml | 6 +++++- features/org.eclipse.dd.dsf.gdb-feature/feature.xml | 6 +++++- features/org.eclipse.dd.dsf.sdk-feature/feature.xml | 2 +- features/org.eclipse.dd.dsf.test-feature/feature.xml | 7 ++++++- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/features/org.eclipse.dd.dsf.examples-feature/feature.xml b/features/org.eclipse.dd.dsf.examples-feature/feature.xml index b15949ebcd5..39e1d73a776 100644 --- a/features/org.eclipse.dd.dsf.examples-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.examples-feature/feature.xml @@ -1,6 +1,6 @@ @@ -16,6 +16,10 @@ [Enter License Description here.] + + + + @@ -16,6 +16,10 @@ [Enter License Description here.] + + + + diff --git a/features/org.eclipse.dd.dsf.test-feature/feature.xml b/features/org.eclipse.dd.dsf.test-feature/feature.xml index 4ac16cab1f4..31ca18d0691 100644 --- a/features/org.eclipse.dd.dsf.test-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.test-feature/feature.xml @@ -1,6 +1,6 @@ @@ -16,6 +16,11 @@ [Enter License Description here.] + + + + + Date: Tue, 7 Nov 2006 21:49:31 +0000 Subject: [PATCH 036/834] build --- features/org.eclipse.dd.dsf.sdk-feature/.project | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/features/org.eclipse.dd.dsf.sdk-feature/.project b/features/org.eclipse.dd.dsf.sdk-feature/.project index eb0a4bc6d98..750d1c7eef7 100644 --- a/features/org.eclipse.dd.dsf.sdk-feature/.project +++ b/features/org.eclipse.dd.dsf.sdk-feature/.project @@ -5,7 +5,13 @@ + + org.eclipse.pde.FeatureBuilder + + + + org.eclipse.pde.FeatureNature From 94841c4ee3efc4a608afcf5de2265b440c3cf516 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 8 Nov 2006 03:00:20 +0000 Subject: [PATCH 037/834] - Ported to new debugger command APIs (bug# 163623). This makes DSF build with 3.3 M3, but breaks compatibility with 3.2. - Warnings cleanup. --- .../DebugViewSelectionRootLayoutNode.java | 48 +++++++++-------- .../debug/ui/viewmodel/ThreadLayoutNode.java | 15 ++++-- .../eclipse/dd/dsf/debug/DsfDebugPlugin.java | 2 +- .../dd/dsf/debug/service/IBackEndProcess.java | 2 +- .../dd/dsf/debug/service/IModules.java | 8 +-- .../dd/dsf/debug/service/ITargets.java | 4 +- .../org/eclipse/dd/dsf/ui/DsfUIPlugin.java | 2 +- .../dsf/ui/viewmodel/AbstractVMAdapter.java | 19 ++++--- .../ui/viewmodel/AbstractVMLayoutNode.java | 13 ++++- .../viewmodel/AbstractVMRootLayoutNode.java | 5 +- .../ui/viewmodel/DMContextVMLayoutNode.java | 21 ++++---- .../GetDataDoneWithRequestMonitor.java | 51 ------------------- .../dd/dsf/ui/viewmodel/VMProvider.java | 19 +++++-- .../src/org/eclipse/dd/dsf/DsfPlugin.java | 2 +- .../dd/dsf/concurrent/DefaultDsfExecutor.java | 22 ++++---- .../org/eclipse/dd/dsf/concurrent/Done.java | 2 +- .../dd/dsf/concurrent/DoneCollector.java | 4 +- .../dd/dsf/concurrent/DsfExecutable.java | 4 +- .../dd/dsf/concurrent/DsfSequence.java | 20 ++++---- .../dd/dsf/concurrent/StackTraceWrapper.java | 2 +- .../dd/dsf/datamodel/AbstractDMContext.java | 15 +++--- .../dd/dsf/datamodel/AbstractDMEvent.java | 2 +- .../eclipse/dd/dsf/datamodel/DMContexts.java | 12 ++--- .../eclipse/dd/dsf/datamodel/IDMContext.java | 2 +- .../eclipse/dd/dsf/datamodel/IDMEvent.java | 2 +- .../eclipse/dd/dsf/datamodel/IDMService.java | 2 +- .../dd/dsf/service/AbstractDsfService.java | 11 +++- .../dd/dsf/service/DsfServicesTracker.java | 9 ++-- .../eclipse/dd/dsf/service/DsfSession.java | 28 ++++++---- .../eclipse/dd/dsf/service/IDsfService.java | 3 +- 30 files changed, 175 insertions(+), 176 deletions(-) delete mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/GetDataDoneWithRequestMonitor.java diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewSelectionRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewSelectionRootLayoutNode.java index 0f92b623ca7..9a2722ffd32 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewSelectionRootLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewSelectionRootLayoutNode.java @@ -11,17 +11,18 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel; import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; 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.debug.ui.DebugUITools; +import org.eclipse.debug.ui.contexts.DebugContextEvent; +import org.eclipse.debug.ui.contexts.IDebugContextListener; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchWindow; /** @@ -29,7 +30,6 @@ import org.eclipse.ui.IWorkbenchWindow; * 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 { @@ -37,18 +37,18 @@ public class DebugViewSelectionRootLayoutNode extends AbstractVMRootLayoutNode public DebugViewSelectionRootLayoutNode(DsfExecutor executor, IWorkbenchWindow window) { super(executor); - ISelection selection = DebugContextManager.getDefault().getActiveContext(window); + ISelection selection = DebugUITools.getDebugContextManager().getContextService(window).getActiveContext(); if (selection instanceof IStructuredSelection) { fRootVMC = new RootVMC( this, ((IStructuredSelection)selection).getFirstElement() ); } else { fRootVMC = new RootVMC( this, null ); } - DebugContextManager.getDefault().addDebugContextListener(this, window); + DebugUITools.getDebugContextManager().addDebugContextListener(this); } @Override public void sessionDispose() { - DebugContextManager.getDefault().removeDebugContextListener(this); + DebugUITools.getDebugContextManager().removeDebugContextListener(this); super.sessionDispose(); } @@ -75,17 +75,14 @@ public class DebugViewSelectionRootLayoutNode extends AbstractVMRootLayoutNode */ @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()); + 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)) { @@ -105,16 +102,17 @@ public class DebugViewSelectionRootLayoutNode extends AbstractVMRootLayoutNode return fRootVMC; } - public void contextActivated(ISelection selection, IWorkbenchPart part) { - if (selection instanceof IStructuredSelection) { - fRootVMC = new RootVMC( this, ((IStructuredSelection)selection).getFirstElement() ); - } else { - fRootVMC = new RootVMC( this, null ); - } - } - - public void contextChanged(ISelection selection, IWorkbenchPart part) { - // No need to do anything. Element changes should be handled - // through standard event handlers. + public void debugContextChanged(DebugContextEvent event) { + final ISelection selection = event.getContext(); + getExecutor().execute(new DsfRunnable() { + public void run() { + if (selection instanceof IStructuredSelection) { + fRootVMC = new RootVMC( DebugViewSelectionRootLayoutNode.this, + ((IStructuredSelection)selection).getFirstElement() ); + } else { + fRootVMC = new RootVMC( DebugViewSelectionRootLayoutNode.this, null ); + } + } + }); } } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/ThreadLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/ThreadLayoutNode.java index d3b6d31277b..507dcda8d57 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/ThreadLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/ThreadLayoutNode.java @@ -20,9 +20,9 @@ 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.dd.dsf.ui.viewmodel.DMContextVMLayoutNode.DMContextVMContext; import org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor; import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; import org.eclipse.debug.ui.DebugUITools; @@ -69,9 +69,16 @@ public class ThreadLayoutNode extends DMContextVMLayoutNode { processes.getModelData( processes.getThreadForExecutionContext(dmc), - new GetDataDoneWithRequestMonitor(result) { public void doRun() { - result.setLabels(new String[] { getData().getName() }); - }}); + new GetDataDone() { + public void run() { + if (!getStatus().isOK() || !getData().isValid()) { + result.done(); + return; + } + result.setLabels(new String[] { getData().getName() }); + result.done(); + } + }); } public boolean hasDeltaFlagsForDMEvent(IDMEvent e) { diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/DsfDebugPlugin.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/DsfDebugPlugin.java index 3ca12ae0ae0..a0b8f8b600b 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/DsfDebugPlugin.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/DsfDebugPlugin.java @@ -20,7 +20,7 @@ import org.osgi.framework.BundleContext; public class DsfDebugPlugin extends Plugin { // The plug-in ID - public static final String PLUGIN_ID = "org.eclipse.dd.dsf.debug.debug.service"; + public static final String PLUGIN_ID = "org.eclipse.dd.dsf.debug.debug.service"; //$NON-NLS-1$ // The shared instance private static DsfDebugPlugin fgPlugin; diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBackEndProcess.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBackEndProcess.java index a4f6ed39665..f8a5cfa159e 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBackEndProcess.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBackEndProcess.java @@ -26,7 +26,7 @@ public interface IBackEndProcess extends IDsfService { * same time, a service property is needed to allow clients to distinguish * between them. */ - static final String PROCESS_ID = "org.eclipse.dsdp.DSF.debug.BackendProcess.PROCESS_ID"; + static final String PROCESS_ID = "org.eclipse.dsdp.DSF.debug.BackendProcess.PROCESS_ID"; //$NON-NLS-1$ /** * Event indicating that the back end process has terminated. diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java index f1f8212ecc9..0c96960a1ec 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java @@ -30,12 +30,12 @@ public interface IModules extends IDMService { * 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 ISymbolDMContext extends IDMContext {} + public interface ISymbolDMContext extends IDMContext{} /** * Module context represents a single module that is loaded. */ - public interface IModuleDMContext extends IDMContext {} + public interface IModuleDMContext extends IDMContext {} /** * Event indicating a change in the symbol information for given context. @@ -90,7 +90,7 @@ public interface IModules extends IDMService { * Symbol context data includes a mapping between run-time addresses and * module-section-offset coordinates. */ - public interface SymbolDMData extends IDMData { + public interface ISymbolDMData extends IDMData { /** Convert link-time address 'addr' to run-time address */ public long convertToRT(ModuleSectionOffset mso); @@ -99,7 +99,7 @@ public interface IModules extends IDMService { } /** Module information. */ - public interface ModuleDMData extends IDMData { + public interface IModuleDMData extends IDMData { String getName(); String getFile(); long getTimeStamp(); diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ITargets.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ITargets.java index 75fda232788..c6740dea672 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ITargets.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ITargets.java @@ -29,7 +29,7 @@ public interface ITargets extends IDMService { boolean isConnected(); } - public interface ITargetStateChanged extends IDMEvent {} + public interface ITargetStateChanged extends IDMEvent {} public interface ICoreDMContext extends IDMContext {} @@ -39,7 +39,7 @@ public interface ITargets extends IDMService { IOS.IOSDMContext getOSDMContext(); } - public interface ICoreStateChangedDMEvent extends IDMEvent {} + public interface ICoreStateChangedDMEvent extends IDMEvent {} public void getTargets(GetDataDone done); public void getCores(ITargetDMContext target, GetDataDone done); diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/DsfUIPlugin.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/DsfUIPlugin.java index 9b2c7cb05b7..164a2f69e1f 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/DsfUIPlugin.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/DsfUIPlugin.java @@ -19,7 +19,7 @@ import org.osgi.framework.BundleContext; public class DsfUIPlugin extends AbstractUIPlugin { // The plug-in ID - public static final String PLUGIN_ID = "org.eclipse.dd.dsf.ui"; + public static final String PLUGIN_ID = "org.eclipse.dd.dsf.ui"; //$NON-NLS-1$ // The shared instance private static DsfUIPlugin fgPlugin; diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java index fd55c73dfc0..b136046b82c 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java @@ -98,13 +98,13 @@ abstract public class AbstractVMAdapter 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.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "No model provider for object: " + object.toString(), null)); //$NON-NLS-1$ result.done(); } provider.retrieveLabel(object, result); } @Override - public String toString() { return "Switch to dispatch thread to execute retrieveLabel()"; } + public String toString() { return "Switch to dispatch thread to execute retrieveLabel()"; } //$NON-NLS-1$ }); } catch(RejectedExecutionException e) { // This can happen if session is being shut down. @@ -120,12 +120,12 @@ abstract public class AbstractVMAdapter 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.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "No model provider for object: " + element.toString(), null)); //$NON-NLS-1$ result.done(); } provider.isContainer(element, result); } - public String toString() { return "Switch to dispatch thread to execute isContainer()"; } + public String toString() { return "Switch to dispatch thread to execute isContainer()"; } //$NON-NLS-1$ }); } catch(RejectedExecutionException e) { // This can happen if session is being shut down. @@ -141,12 +141,12 @@ abstract public class AbstractVMAdapter 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.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "No model provider for object: " + element.toString(), null)); //$NON-NLS-1$ result.done(); } provider.retrieveChildren(element, result); } - public String toString() { return "Switch to dispatch thread to execute retrieveChildren()"; } + public String toString() { return "Switch to dispatch thread to execute retrieveChildren()"; } //$NON-NLS-1$ }); } catch(RejectedExecutionException e) { // This can happen if session is being shut down. @@ -155,8 +155,13 @@ abstract public class AbstractVMAdapter } public IModelProxy createModelProxy(Object element, IPresentationContext context) { + /* + * Model proxy is the object that correlates events from the data model + * into view model deltas that the view can process. We only need to + * create a proxy for the root element of the tree. + */ VMProvider provider = getViewModelProvider(context); - if (provider != null) { + if (provider != null && element.equals(provider.getRootLayoutNode().getRootVMC().getInputObject())) { return provider.getModelProxy(); } return null; diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java index b675706758d..634f03c58b3 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java @@ -94,7 +94,16 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { parent.getVMC(), new GetDataDone() { public void run() { - if (propagateError(getExecutor(), done, "Failed to retrieve elements in layout node " + AbstractVMLayoutNode.this)) return; + if (propagateError(getExecutor(), done, "Failed to retrieve elements in layout node " + AbstractVMLayoutNode.this)) return; //$NON-NLS-1$ + + /* + * Check for an empty list of elements. If it's empty then we + * don't have to call the children nodes, so return here. + */ + if (getData().length == 0) { + getExecutor().execute(done); + } + /* * 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. @@ -152,7 +161,7 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { * that the layout node depends on, are not available. */ protected void handleFailedRetrieveLabel(ILabelRequestMonitor result) { - result.setLabels(new String[] { "..."} ); + result.setLabels(new String[] { "..."} ); //$NON-NLS-1$ result.done(); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMRootLayoutNode.java index e443944c525..ab4bbc43d40 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMRootLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMRootLayoutNode.java @@ -39,6 +39,7 @@ abstract public class AbstractVMRootLayoutNode extends AbstractVMLayoutNode impl public IVMLayoutNode getLayoutNode() { return fVMRootLayoutNode; } + @SuppressWarnings("unchecked") public Object getAdapter(Class adapter) { if (fInputObject instanceof IAdaptable) { return ((IAdaptable)fInputObject).getAdapter(adapter); @@ -55,7 +56,7 @@ abstract public class AbstractVMRootLayoutNode extends AbstractVMLayoutNode impl return fInputObject.hashCode(); } - public String toString() { return "Root VMC for " + fInputObject.toString(); } + public String toString() { return "Root VMC for " + fInputObject.toString(); } //$NON-NLS-1$ } public AbstractVMRootLayoutNode(DsfExecutor executor) { @@ -111,7 +112,7 @@ abstract public class AbstractVMRootLayoutNode extends AbstractVMLayoutNode impl */ final DoneCollector doneCollector = new DoneCollector(getExecutor()) { public void run() { - if (propagateError(getExecutor(), done, "Failed to generate child deltas.")) return; + if (propagateError(getExecutor(), done, "Failed to generate child deltas.")) return; //$NON-NLS-1$ done.setData(rootDelta); getExecutor().execute(done); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java index 4021d4df513..122209c834a 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java @@ -38,17 +38,18 @@ abstract public class DMContextVMLayoutNode extends AbstractVMLayoutNode { @Immutable public class DMContextVMContext implements IVMContext { private final IVMContext fParent; - private final IDMContext fDmc; + private final IDMContext fDmc; - public DMContextVMContext(IVMContext parent, IDMContext dmc) { + public DMContextVMContext(IVMContext parent, IDMContext dmc) { fParent = parent; fDmc = dmc; } - public IDMContext getDMC() { return fDmc; } + public IDMContext getDMC() { return fDmc; } public IVMContext getParent() { return fParent; } public IVMLayoutNode getLayoutNode() { return DMContextVMLayoutNode.this; } + @SuppressWarnings("unchecked") public Object getAdapter(Class adapter) { return fDmc.getAdapter(adapter); } @@ -66,7 +67,7 @@ abstract public class DMContextVMLayoutNode extends AbstractVMLayoutNode { } public String toString() { - return fParent.toString() + "->" + fDmc.toString(); + return fParent.toString() + "->" + fDmc.toString(); //$NON-NLS-1$ } } @@ -75,7 +76,7 @@ abstract public class DMContextVMLayoutNode extends AbstractVMLayoutNode { /** Class type that the elements of this schema node are based on. */ - private Class fDMCClassType; + private Class> fDMCClassType; /** * Constructor initializes instance data, except for the child nodes. @@ -84,7 +85,7 @@ abstract public class DMContextVMLayoutNode extends AbstractVMLayoutNode { * @param dmcClassType * @see #setChildNodes(IVMLayoutNode[]) */ - public DMContextVMLayoutNode(DsfSession session, Class dmcClassType) { + public DMContextVMLayoutNode(DsfSession session, Class> dmcClassType) { super(session.getExecutor()); fServices = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), session.getId()); fDMCClassType = dmcClassType; @@ -112,7 +113,7 @@ abstract public class DMContextVMLayoutNode extends AbstractVMLayoutNode { * DMC-specific version of {@link IVMLayoutNode#hasDeltaFlags(Object)}. * By default, it falls back on the super-class implementation. */ - protected boolean hasDeltaFlagsForDMEvent(IDMEvent e) { + protected boolean hasDeltaFlagsForDMEvent(IDMEvent e) { return super.hasDeltaFlags(e); } @@ -129,7 +130,7 @@ abstract public class DMContextVMLayoutNode extends AbstractVMLayoutNode { * 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) { + 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 @@ -138,7 +139,7 @@ abstract public class DMContextVMLayoutNode extends AbstractVMLayoutNode { * behavior and generate a IModelDelta for every element in this schema * node. */ - IDMContext dmc = DMContexts.getAncestorOfType(e.getDMContext(), fDMCClassType); + IDMContext dmc = DMContexts.getAncestorOfType(e.getDMContext(), fDMCClassType); if (dmc != null) { IVMLayoutNode[] childNodes = getChildNodesWithDeltas(e); if (childNodes.length == 0) { @@ -179,7 +180,7 @@ abstract public class DMContextVMLayoutNode extends AbstractVMLayoutNode { * @param dmcs Array of DMC objects to build return array on. * @return Array of IVMContext objects. */ - protected IVMContext[] dmcs2vmcs(IVMContext parent, IDMContext[] dmcs) { + protected IVMContext[] dmcs2vmcs(IVMContext parent, IDMContext[] dmcs) { IVMContext[] vmContexts = new IVMContext[dmcs.length]; for (int i = 0; i < dmcs.length; i++) { vmContexts[i] = new DMContextVMContext(parent, dmcs[i]); diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/GetDataDoneWithRequestMonitor.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/GetDataDoneWithRequestMonitor.java deleted file mode 100644 index f675bc641d6..00000000000 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/GetDataDoneWithRequestMonitor.java +++ /dev/null @@ -1,51 +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.viewmodel; - -import org.eclipse.dd.dsf.concurrent.GetDataDone; -import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousRequestMonitor; - -/** - * Convenience extension to GetDataDone, which handles notifying the - * IAsynchronousRequestMonitor when the done is executed. - * @param Class type of data. - */ -@SuppressWarnings("restriction") -public abstract class GetDataDoneWithRequestMonitor extends GetDataDone { - /** Monitor to be posted when this done is executed. */ - private IAsynchronousRequestMonitor fMonitor; - - /** Constructor requires the monitor */ - public GetDataDoneWithRequestMonitor(IAsynchronousRequestMonitor monitor) { - fMonitor = monitor; - } - - /** - * Run method checks the request monitor for cancellation and checks this - * done's status before calling doRun(). Finally it takes care of - * notifying the request montior that request is finished. - */ - public final void run() { - if (fMonitor.isCanceled()) return; - if (!getStatus().isOK()) { - fMonitor.setStatus(getStatus()); - } else { - doRun(); - } - fMonitor.done(); - } - - /** - * Method to perform the actual work. It should not call monitor.done(), - * because it will be called by this class in run(). - */ - protected abstract void doRun(); -} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMProvider.java index c14b17e364b..524c92dc0ba 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMProvider.java @@ -29,6 +29,7 @@ import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousLabelAdapt 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.IModelChangedListener; import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.provisional.IModelProxy; @@ -75,6 +76,18 @@ public class VMProvider fProxyActive--; super.dispose(); } + + @Override + public void removeModelChangedListener(IModelChangedListener listener) { + // TODO Auto-generated method stub + super.removeModelChangedListener(listener); + } + + @Override + public void addModelChangedListener(IModelChangedListener listener) { + // TODO Auto-generated method stub + super.addModelChangedListener(listener); + } /** * Fires given delta using a job. Processing the delta on the dispatch @@ -206,7 +219,7 @@ public class VMProvider * 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"; + assert false : "We should never get here, because isContainer() should have returned false"; //$NON-NLS-1$ monitor.done(); return; } @@ -310,7 +323,7 @@ public class VMProvider * @param e */ @DsfServiceEventHandler - public void eventDispatched(final IDMEvent event) { + public void eventDispatched(final IDMEvent event) { if (fRootLayoutNode.hasDeltaFlags(event)) { fRootLayoutNode.createDelta(event, new GetDataDone() { public void run() { @@ -319,7 +332,7 @@ public class VMProvider } } @Override public String toString() { - return "Result of a delta for event: '" + event.toString() + "' in VMP: '" + VMProvider.this + "'"; + return "Result of a delta for event: '" + event.toString() + "' in VMP: '" + VMProvider.this + "'"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } }); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/DsfPlugin.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/DsfPlugin.java index 0e05acf461c..1e3f7290dec 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/DsfPlugin.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/DsfPlugin.java @@ -20,7 +20,7 @@ import org.osgi.framework.BundleContext; public class DsfPlugin extends Plugin { // The plug-in ID - public static final String PLUGIN_ID = "org.eclipse.dd.dsf"; + public static final String PLUGIN_ID = "org.eclipse.dd.dsf"; //$NON-NLS-1$ // The shared instance private static DsfPlugin fgPlugin; diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java index df098ee83b3..d4feb038cb5 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java @@ -43,7 +43,7 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor Thread fThread; public Thread newThread(Runnable r) { assert fThread == null; // Should be called only once. - fThread = new Thread(new ThreadGroup("DSF Thread Group"), r, "DSF Dispatch Thread", 0); + fThread = new Thread(new ThreadGroup("DSF Thread Group"), r, "DSF Dispatch Thread", 0); //$NON-NLS-1$//$NON-NLS-2$ return fThread; } } @@ -64,7 +64,7 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor @Override protected void afterExecute(Runnable r, Throwable t) { if (r instanceof Future) { - Future future = (Future)r; + Future future = (Future)r; try { /* * Try to retrieve the value, which should throw exception in @@ -89,14 +89,14 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor ILog log = DsfPlugin.getDefault().getLog(); if (log != null) { log.log(new Status( - IStatus.ERROR, DsfPlugin.PLUGIN_ID, -1, "Uncaught exception in DSF executor thread", t)); + IStatus.ERROR, DsfPlugin.PLUGIN_ID, -1, "Uncaught exception in DSF executor thread", t)); //$NON-NLS-1$ } // Print out the stack trace to console if assertions are enabled. if(ASSERTIONS_ENABLED) { ByteArrayOutputStream outStream = new ByteArrayOutputStream(512); PrintStream printStream = new PrintStream(outStream); try { - printStream.write("Uncaught exception in session executor thread: ".getBytes()); + printStream.write("Uncaught exception in session executor thread: ".getBytes()); //$NON-NLS-1$ } catch (IOException e2) {} t.printStackTrace(new PrintStream(outStream)); System.err.println(outStream.toString()); @@ -180,32 +180,32 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor traceBuilder.append(getExecutable().getClass().getName()); // Add executable's toString(). - traceBuilder.append("\n "); + traceBuilder.append("\n "); //$NON-NLS-1$ 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 "); //$NON-NLS-1$ if (dsfExecutable.fCreatedBy != null) { - traceBuilder.append(" by #"); + traceBuilder.append(" by #"); //$NON-NLS-1$ traceBuilder.append(dsfExecutable.fCreatedBy.fSequenceNumber); } if (dsfExecutable.fCreatedAt != null) { - traceBuilder.append(" at "); + traceBuilder.append(" at "); //$NON-NLS-1$ traceBuilder.append(dsfExecutable.fCreatedAt.fStackTraceElements[0].toString()); } } } // Submitted info - traceBuilder.append("\n submitted"); + traceBuilder.append("\n submitted"); //$NON-NLS-1$ if (fSubmittedBy != null) { - traceBuilder.append(" by #"); + traceBuilder.append(" by #"); //$NON-NLS-1$ traceBuilder.append(fSubmittedBy.fSequenceNumber); } - traceBuilder.append(" at "); + traceBuilder.append(" at "); //$NON-NLS-1$ traceBuilder.append(fSubmittedAt.fStackTraceElements[0].toString()); // Finally write out to console diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java index 975bdc7add6..34f258266af 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java @@ -66,6 +66,6 @@ abstract public class Done extends DsfRunnable { } public String toString() { - return "Done: " + getStatus().toString(); + return "Done: " + getStatus().toString(); //$NON-NLS-1$ } } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DoneCollector.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DoneCollector.java index f62a34bf161..8fce539f983 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DoneCollector.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DoneCollector.java @@ -48,7 +48,7 @@ public abstract class DoneCollector extends Done { * */ public DoneCollector(DsfExecutor executor) { - setStatus(new MultiStatus(DsfPlugin.PLUGIN_ID, 0, "Collective status for set of sub-operations.", null)); + setStatus(new MultiStatus(DsfPlugin.PLUGIN_ID, 0, "Collective status for set of sub-operations.", null)); //$NON-NLS-1$ fExecutor = executor; } @@ -108,6 +108,6 @@ public abstract class DoneCollector extends Done { @Override public String toString() { - return "Done Collector: " + getStatus().toString(); + return "Done Collector: " + getStatus().toString(); //$NON-NLS-1$ } } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java index 4b2f96e3ee8..748aa8d2772 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java @@ -115,9 +115,9 @@ public class DsfExecutable { traceBuilder.append(' '); // Record the event - traceBuilder.append("DsfExecutable was never executed:\n "); + traceBuilder.append("DsfExecutable was never executed:\n "); //$NON-NLS-1$ traceBuilder.append(this); - traceBuilder.append("\nCreated at:"); + traceBuilder.append("\nCreated at:"); //$NON-NLS-1$ traceBuilder.append(fCreatedAt); DsfPlugin.debug(traceBuilder.toString()); diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java index ee1dfc7853f..e2ba546b311 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java @@ -110,10 +110,10 @@ abstract public class DsfSequence extends DsfRunnable implements Future final private Done fDone; /** Status indicating the success/failure of the test. Used internally only. */ - @ConfinedToDsfExecutor("getExecutor") + @ConfinedToDsfExecutor("getExecutor") private IStatus fStatus = Status.OK_STATUS; - @ConfinedToDsfExecutor("getExecutor") + @ConfinedToDsfExecutor("getExecutor") private int fCurrentStepIdx = 0; /** Task name for this sequence used with the progress monitor */ @@ -128,12 +128,12 @@ abstract public class DsfSequence extends DsfRunnable implements Future /** Convenience constructor with limited arguments. */ public DsfSequence(DsfExecutor executor) { - this(executor, new NullProgressMonitor(), "", "", null); + this(executor, new NullProgressMonitor(), "", "", null); //$NON-NLS-1$ //$NON-NLS-2$ } /** Convenience constructor with limited arguments. */ public DsfSequence(DsfExecutor executor, Done done) { - this(executor, new NullProgressMonitor(), "", "", done); + this(executor, new NullProgressMonitor(), "", "", done); //$NON-NLS-1$ //$NON-NLS-2$ } /** @@ -285,7 +285,7 @@ abstract public class DsfSequence extends DsfRunnable implements Future } } public String toString() { - return "DsfSequence \"" + fTaskName + "\", result for executing step #" + fStepIdx + " = " + getStatus(); + return "DsfSequence \"" + fTaskName + "\", result for executing step #" + fStepIdx + " = " + getStatus(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } }); } catch(Throwable t) { @@ -297,7 +297,7 @@ abstract public class DsfSequence extends DsfRunnable implements Future */ abortExecution(new Status( IStatus.ERROR, DsfPlugin.PLUGIN_ID, 0, - "Unhandled exception when executing DsfSequence " + this + ", step #" + fCurrentStepIdx, + "Unhandled exception when executing DsfSequence " + this + ", step #" + fCurrentStepIdx, //$NON-NLS-1$ //$NON-NLS-2$ t)); /* @@ -338,7 +338,7 @@ abstract public class DsfSequence extends DsfRunnable implements Future }; @Override public String toString() { - return "DsfSequence \"" + fTaskName + "\", result for rolling back step #" + fStepIdx + " = " + getStatus(); + return "DsfSequence \"" + fTaskName + "\", result for rolling back step #" + fStepIdx + " = " + getStatus(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } }); } catch(Throwable t) { @@ -350,7 +350,7 @@ abstract public class DsfSequence extends DsfRunnable implements Future */ abortRollBack(new Status( IStatus.ERROR, DsfPlugin.PLUGIN_ID, 0, - "Unhandled exception when rolling back DsfSequence " + this + ", step #" + fCurrentStepIdx, + "Unhandled exception when rolling back DsfSequence " + this + ", step #" + fCurrentStepIdx, //$NON-NLS-1$ //$NON-NLS-2$ t)); /* @@ -369,7 +369,7 @@ abstract public class DsfSequence extends DsfRunnable implements Future if (fRollbackTaskName != null) { fProgressMonitor.subTask(fRollbackTaskName); } - fStatus = new Status(IStatus.CANCEL, DsfPlugin.PLUGIN_ID, -1, "Sequence \"" + fTaskName + "\" cancelled.", null); + fStatus = new Status(IStatus.CANCEL, DsfPlugin.PLUGIN_ID, -1, "Sequence \"" + fTaskName + "\" cancelled.", null); //$NON-NLS-1$ //$NON-NLS-2$ if (fDone != null) { fDone.setStatus(fStatus); } @@ -418,7 +418,7 @@ abstract public class DsfSequence extends DsfRunnable implements Future */ MultiStatus newStatus = new MultiStatus(DsfPlugin.PLUGIN_ID, error.getCode(), - "Sequence \"" + fTaskName + "\" failed while rolling back.", null); + "Sequence \"" + fTaskName + "\" failed while rolling back.", null); //$NON-NLS-1$ //$NON-NLS-2$ newStatus.merge(error); newStatus.merge(fStatus); fStatus = newStatus; diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/StackTraceWrapper.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/StackTraceWrapper.java index 26352039d28..aa0e71f4498 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/StackTraceWrapper.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/StackTraceWrapper.java @@ -24,7 +24,7 @@ class StackTraceWrapper { StringBuilder builder = new StringBuilder(fStackTraceElements.length * 30); for (int i = 0; i < fStackTraceElements.length && i < 10; i++) { builder.append(fStackTraceElements[i]); - if (i < fStackTraceElements.length && i < 10) builder.append("\n at "); + if (i < fStackTraceElements.length && i < 10) builder.append("\n at "); //$NON-NLS-1$ } return builder.toString(); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMContext.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMContext.java index a69f213401e..11350e58f13 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMContext.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMContext.java @@ -27,20 +27,20 @@ public class AbstractDMContext extends PlatformObject { private final String fSessionId; private final String fServiceFilter; - private final IDMContext[] fParents; + private final IDMContext[] fParents; /** * Main constructor provides all data needed to implement the IModelContext * interface. */ - public AbstractDMContext(String sessionId, String filter, IDMContext[] parents) { + public AbstractDMContext(String sessionId, String filter, IDMContext[] parents) { fSessionId = sessionId; fServiceFilter = filter; fParents = parents; } /** Convenience constructor */ - public AbstractDMContext(AbstractDsfService service, IDMContext parent) { + public AbstractDMContext(AbstractDsfService service, IDMContext parent) { this(service.getSession().getId(), service.getServiceFilter(), parent == null ? new IDMContext[] {} : new IDMContext[] { parent }); @@ -55,13 +55,13 @@ public class AbstractDMContext extends PlatformObject protected boolean baseEquals(Object other) { if (other == null) return false; if ( !(other.getClass().equals(getClass()))) return false; - IDMContext otherCtx = (IDMContext)other; + IDMContext otherCtx = (IDMContext)other; return getSessionId().equals(otherCtx.getSessionId()) && getServiceFilter().equals(otherCtx.getServiceFilter()) && areParentsEqual(otherCtx.getParents()); } - private boolean areParentsEqual(IDMContext[] 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 AbstractDMContext extends PlatformObject protected String baseToString() { StringBuffer retVal = new StringBuffer(); - for (IDMContext parent : fParents) { + for (IDMContext parent : fParents) { retVal.append(parent); } return retVal.toString(); @@ -89,7 +89,7 @@ public class AbstractDMContext extends PlatformObject public String getSessionId() { return fSessionId; } public String getServiceFilter() { return fServiceFilter; } - public IDMContext[] getParents() { return fParents; } + public IDMContext[] getParents() { return fParents; } /** * Overrides the standard platform getAdapter to provide session-specific @@ -106,6 +106,7 @@ public class AbstractDMContext extends PlatformObject * session is equally important. * @see org.eclipse.runtime.IAdapterManager */ + @SuppressWarnings("unchecked") public Object getAdapter(Class adapterType) { Object retVal = null; DsfSession session = DsfSession.getSession(fSessionId); diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMEvent.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMEvent.java index acb4b79ba70..68d2fc9842f 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMEvent.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMEvent.java @@ -17,7 +17,7 @@ import org.eclipse.dd.dsf.concurrent.Immutable; * required DM-Context reference. */ @Immutable -public class AbstractDMEvent implements IDMEvent { +public class AbstractDMEvent> implements IDMEvent { private final V fModelContext; public AbstractDMEvent(V context) { diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/DMContexts.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/DMContexts.java index c9aaf7bd339..6b7e0bd0e71 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/DMContexts.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/DMContexts.java @@ -56,16 +56,16 @@ public class DMContexts { * @return true if a match is found. */ @ThreadSafe - public static boolean isAncestorOf(IDMContext dmc, IDMContext potentialAncestor) { + public static boolean isAncestorOf(IDMContext dmc, IDMContext potentialAncestor) { // Check the direct parents for a match. - for (IDMContext parentDmc : dmc.getParents()) { + for (IDMContext parentDmc : dmc.getParents()) { if (potentialAncestor.equals(parentDmc)) { return true; } } // Recursively check the parents' parents for a match. - for (IDMContext parentDmc : dmc.getParents()) { + for (IDMContext parentDmc : dmc.getParents()) { if (isAncestorOf(parentDmc, potentialAncestor)) { return true; } @@ -80,15 +80,15 @@ public class DMContexts { * into a list. */ @ThreadSafe - public static List toList(IDMContext dmc) { + public static List> toList(IDMContext dmc) { /* * This method is implemented recursively, which is not necessarily * the most efficient way to do this. */ - List list = new ArrayList(); + List> list = new ArrayList>(); list.add(dmc); - for (IDMContext parentDmc : dmc.getParents()) { + for (IDMContext parentDmc : dmc.getParents()) { list.addAll(toList(parentDmc)); } return list; diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMContext.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMContext.java index b83ef7d325e..0fc319c2f64 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMContext.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMContext.java @@ -73,5 +73,5 @@ public interface IDMContext extends IAdaptable * the client. * @return parent context of this context. */ - public IDMContext[] getParents(); + public IDMContext[] getParents(); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMEvent.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMEvent.java index d73dd889864..373689b3877 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMEvent.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMEvent.java @@ -16,6 +16,6 @@ package org.eclipse.dd.dsf.datamodel; * this base class only identifies the DM Context that is affected. * @param Data Model context type that is affected by this event. */ -public interface IDMEvent { +public interface IDMEvent > { V getDMContext(); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMService.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMService.java index 59824a8c0e1..895dca5bbd0 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMService.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMService.java @@ -26,7 +26,7 @@ public interface IDMService extends IDsfService, IDMData { * usually used in events to indicate that lists of contexts in this * service are changed. */ - IDMContext getServiceContext(); + IDMContext getServiceContext(); /** * Retrieves model data object for given context. This method makes it diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java index 81595302280..b70e857ef65 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java @@ -42,6 +42,7 @@ abstract public class AbstractDsfService private DsfServicesTracker fTracker; /** Properties that this service was registered with */ + @SuppressWarnings("unchecked") private Dictionary fProperties; /** Properties that this service was registered with */ @@ -58,9 +59,14 @@ abstract public class AbstractDsfService } public DsfExecutor getExecutor() { return fSession.getExecutor(); } + + @SuppressWarnings("unchecked") public Dictionary getProperties() { return fProperties; } + public String getServiceFilter() { return fFilter; } + public int getStartupNumber() { return fStartupNumber; } + public void initialize(Done done) { fTracker = new DsfServicesTracker(getBundleContext(), fSession.getId()); fStartupNumber = fSession.getAndIncrementServiceStartupCounter(); @@ -136,9 +142,10 @@ abstract public class AbstractDsfService /** * Generates an LDAP filter to uniquely identify this service. */ + @SuppressWarnings("unchecked") private String generateFilter(Dictionary properties) { StringBuffer filter = new StringBuffer(); - filter.append("(&"); + filter.append("(&"); //$NON-NLS-1$ for (Enumeration keys = properties.keys(); keys.hasMoreElements();) { Object key = keys.nextElement(); @@ -151,7 +158,7 @@ abstract public class AbstractDsfService for (Object arrayValue : (Object[])value) { filter.append('('); filter.append(key.toString()); - filter.append("=*"); + filter.append("=*"); //$NON-NLS-1$ filter.append(arrayValue.toString()); filter.append(')'); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServicesTracker.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServicesTracker.java index 6c9b440e31c..7ea47d7af0b 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServicesTracker.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServicesTracker.java @@ -43,7 +43,7 @@ import org.osgi.framework.ServiceReference; public class DsfServicesTracker { private static String getServiceFilter(String sessionId) { - return ("(" + IDsfService.PROP_SESSION_ID + "=" + sessionId + ")").intern(); + return ("(" + IDsfService.PROP_SESSION_ID + "=" + sessionId + ")").intern(); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ } private static class ServiceKey @@ -93,6 +93,7 @@ public class DsfServicesTracker { * session-ID * @return OSGI service reference object to the desired service, null if not found */ + @SuppressWarnings("unchecked") public ServiceReference getServiceReference(Class serviceClass, String filter) { ServiceKey key = new ServiceKey(serviceClass.getName().intern(), filter != null ? filter : fServiceFilter); if (fServiceReferences.containsKey(key)) { @@ -109,7 +110,7 @@ public class DsfServicesTracker { return references[0]; } } catch(InvalidSyntaxException e) { - assert false : "Invalid session ID syntax"; + assert false : "Invalid session ID syntax"; //$NON-NLS-1$ } return null; } @@ -154,8 +155,8 @@ public class DsfServicesTracker { * to avoid leaking OSGI service references. */ public void dispose() { - for (Iterator itr = fServices.keySet().iterator(); itr.hasNext();) { - fBundleContext.ungetService((ServiceReference)itr.next()); + for (Iterator itr = fServices.keySet().iterator(); itr.hasNext();) { + fBundleContext.ungetService(itr.next()); itr.remove(); } } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java index 807642efa87..b7eb38ad1d2 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java @@ -49,7 +49,7 @@ import org.osgi.framework.Filter; * * @see org.eclipse.dd.dsf.concurrent.DsfExecutor */ -@ConfinedToDsfExecutor("getExecutor") +@ConfinedToDsfExecutor("getExecutor") public class DsfSession { /** @@ -222,6 +222,7 @@ public class DsfSession * IModelContext.getAdapter() method. * @see org.eclipse.dd.dsf.datamodel.AbstractDMContext#getAdapter */ + @SuppressWarnings("unchecked") private Map fAdapters = Collections.synchronizedMap(new HashMap()); /** Returns the owner ID of this session */ @@ -271,10 +272,11 @@ public class DsfSession * @param serviceProperties properties of the service requesting the event to be dispatched */ @ThreadSafe + @SuppressWarnings("unchecked") public void dispatchEvent(final Object event, final Dictionary serviceProperties) { getExecutor().submit(new DsfRunnable() { public void run() { doDispatchEvent(event, serviceProperties);} - public String toString() { return "Event: " + event + ", from service " + serviceProperties; } + public String toString() { return "Event: " + event + ", from service " + serviceProperties; } //$NON-NLS-1$ //$NON-NLS-2$ }); } @@ -285,6 +287,7 @@ public class DsfSession * @see org.eclipse.dsdp.model.AbstractDMContext#getAdapter */ @ThreadSafe + @SuppressWarnings("unchecked") public void registerModelAdapter(Class adapterType, Object adapter) { fAdapters.put(adapterType, adapter); } @@ -295,6 +298,7 @@ public class DsfSession * @see org.eclipse.dsdp.model.AbstractDMContext#getAdapter */ @ThreadSafe + @SuppressWarnings("unchecked") public void unregisterModelAdapter(Class adapterType) { fAdapters.remove(adapterType); } @@ -306,6 +310,7 @@ public class DsfSession * @see org.eclipse.dsdp.model.AbstractDMContext#getAdapter */ @ThreadSafe + @SuppressWarnings("unchecked") public Object getModelAdapter(Class adapterType) { return fAdapters.get(adapterType); } @@ -318,6 +323,7 @@ public class DsfSession @ThreadSafe public int hashCode() { return fId.hashCode(); } + @SuppressWarnings("unchecked") private void doDispatchEvent(Object event, Dictionary serviceProperties) { // Build a list of listeners; SortedMap> listeners = new TreeMap>(new Comparator() { @@ -349,8 +355,8 @@ public class DsfSession Method[] allMethods = entry.getValue(); List matchingMethods = new ArrayList(); for (Method method : allMethods) { - assert method.getParameterTypes().length > 0 : eventClass.getName() + "." + method.getName() - + " signature contains zero parameters"; + assert method.getParameterTypes().length > 0 : eventClass.getName() + "." + method.getName() //$NON-NLS-1$ + + " signature contains zero parameters"; //$NON-NLS-1$ if ( method.getParameterTypes()[0].isAssignableFrom(eventClass) ) { matchingMethods.add(method); } @@ -368,13 +374,13 @@ public class DsfSession } catch (IllegalAccessException e) { DsfPlugin.getDefault().getLog().log(new Status( - IStatus.ERROR, DsfPlugin.PLUGIN_ID, -1, "Security exception when calling a service event handler method", e)); - assert false : "IServiceEventListener.ServiceHandlerMethod method not accessible, is listener declared public?"; + IStatus.ERROR, DsfPlugin.PLUGIN_ID, -1, "Security exception when calling a service event handler method", e)); //$NON-NLS-1$ + assert false : "IServiceEventListener.ServiceHandlerMethod method not accessible, is listener declared public?"; //$NON-NLS-1$ } catch (InvocationTargetException e) { DsfPlugin.getDefault().getLog().log(new Status( - IStatus.ERROR, DsfPlugin.PLUGIN_ID, -1, "Invocation exception when calling a service event handler method", e)); - assert false : "Exception thrown by a IServiceEventListener.ServiceHandlerMethod method"; + IStatus.ERROR, DsfPlugin.PLUGIN_ID, -1, "Invocation exception when calling a service event handler method", e)); //$NON-NLS-1$ + assert false : "Exception thrown by a IServiceEventListener.ServiceHandlerMethod method"; //$NON-NLS-1$ } } } @@ -389,17 +395,17 @@ public class DsfSession if (method.isAnnotationPresent(DsfServiceEventHandler.class)) { Class[] paramTypes = method.getParameterTypes(); if (paramTypes.length > 2) { - throw new IllegalArgumentException("ServiceEventHandler method has incorrect number of parameters"); + throw new IllegalArgumentException("ServiceEventHandler method has incorrect number of parameters"); //$NON-NLS-1$ } retVal.add(method); } } } catch(SecurityException e) { - throw new IllegalArgumentException("No permission to access ServiceEventHandler method"); + throw new IllegalArgumentException("No permission to access ServiceEventHandler method"); //$NON-NLS-1$ } if (retVal.isEmpty()) { - throw new IllegalArgumentException("No methods marked with @ServiceEventHandler in listener, is listener declared public?"); + throw new IllegalArgumentException("No methods marked with @ServiceEventHandler in listener, is listener declared public?"); //$NON-NLS-1$ } return retVal.toArray(new Method[retVal.size()]); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java index 5db2136b8b0..77bd7654078 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java @@ -42,7 +42,7 @@ public interface IDsfService { * Property name for the session-id of this service. This property should be set by * all DSF services when they are registered with OSGI service framework. */ - final static String PROP_SESSION_ID = "org.eclipse.dd.dsf.service.IService.session_id"; + final static String PROP_SESSION_ID = "org.eclipse.dd.dsf.service.IService.session_id"; //$NON-NLS-1$ /** * Error code indicating that the service is in a state which does not allow the @@ -84,6 +84,7 @@ public interface IDsfService { /** * Returns the map of properties that this service was registered with. */ + @SuppressWarnings("unchecked") Dictionary getProperties(); /** From 56e3520f7ac1aea61415a638c997deb99cfbabfc Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 8 Nov 2006 03:04:30 +0000 Subject: [PATCH 038/834] Temporarily moved ThreadsLayoutNode to org.eclipse.dd.dsf.mi, to get rid of dependency from org.eclipse.dd.dsf.debug.ui on org.eclipse.dd.dsf.mi.core. --- .../META-INF/MANIFEST.MF | 3 +- .../debug/ui/viewmodel/ThreadLayoutNode.java | 106 ------------------ 2 files changed, 1 insertion(+), 108 deletions(-) delete mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/ThreadLayoutNode.java diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF index e312a803c6d..e5261d510a5 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF @@ -14,8 +14,7 @@ Require-Bundle: org.eclipse.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 + org.eclipse.dd.dsf.debug Eclipse-LazyStart: true Export-Package: org.eclipse.dd.dsf.debug.ui.viewmodel diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/ThreadLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/ThreadLayoutNode.java deleted file mode 100644 index 507dcda8d57..00000000000 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/ThreadLayoutNode.java +++ /dev/null @@ -1,106 +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.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.IVMContext; -import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; -import org.eclipse.dd.dsf.ui.viewmodel.DMContextVMLayoutNode.DMContextVMContext; -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 done) { - done.setData(Boolean.TRUE); - getExecutor().execute(done); - } - - public void getElements(final IVMContext parentVmc, final GetDataDone 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 GetDataDone() { - public void run() { - if (!getStatus().isOK() || !getData().isValid()) { - result.done(); - return; - } - result.setLabels(new String[] { getData().getName() }); - 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.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); - } -} From 91d23282637427b8895cefcc3e84cffde2feb21c Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 10 Nov 2006 00:18:15 +0000 Subject: [PATCH 039/834] Finished refactoring view model adapter, cleaned up warnings, added column support (bugs 159161, 159679, 161981). --- .../META-INF/MANIFEST.MF | 4 +- .../dd/dsf/debug/ui/DsfDebugUIPlugin.java | 2 +- .../DebugViewSelectionRootLayoutNode.java | 4 +- .../LaunchViewModelProvider.java} | 16 +- .../{ => launch}/StackFramesLayoutNode.java | 28 +-- .../StandardLaunchRootLayoutNode.java | 4 +- .../StandardProcessLayoutNode.java | 14 +- .../register/MessagesForRegisterVM.java | 20 ++ .../register/RegisterColumnPresentation.java | 72 ++++++ .../RegisterGroupLayoutNode.java | 54 ++-- .../{ => register}/RegisterLayoutNode.java | 22 +- .../register/RegisterVMProvider.java | 46 ++++ .../ui/viewmodel/register/messages.properties | 3 + .../dsf/ui/viewmodel/AbstractVMAdapter.java | 71 ++++-- .../ui/viewmodel/AbstractVMLayoutNode.java | 7 +- .../viewmodel/AbstractVMRootLayoutNode.java | 2 +- .../ui/viewmodel/DMContextVMLayoutNode.java | 162 ++++++++++-- .../dd/dsf/ui/viewmodel/IVMLayoutNode.java | 7 +- .../dd/dsf/ui/viewmodel/VMProvider.java | 237 +++++++++++------- .../dd/dsf/service/DsfServicesTracker.java | 17 +- 20 files changed, 573 insertions(+), 219 deletions(-) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/{DebugViewModelProvider.java => launch/LaunchViewModelProvider.java} (84%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/{ => launch}/StackFramesLayoutNode.java (94%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/{ => launch}/StandardLaunchRootLayoutNode.java (97%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/{ => launch}/StandardProcessLayoutNode.java (95%) create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/MessagesForRegisterVM.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterColumnPresentation.java rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/{ => register}/RegisterGroupLayoutNode.java (65%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/{ => register}/RegisterLayoutNode.java (86%) create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/messages.properties diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF index e5261d510a5..28fe51ed363 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF @@ -17,5 +17,7 @@ Require-Bundle: org.eclipse.ui, org.eclipse.dd.dsf.debug Eclipse-LazyStart: true Export-Package: - org.eclipse.dd.dsf.debug.ui.viewmodel + org.eclipse.dd.dsf.debug.ui.viewmodel, + org.eclipse.dd.dsf.debug.ui.viewmodel.register, + org.eclipse.dd.dsf.debug.ui.viewmodel.launch Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/DsfDebugUIPlugin.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/DsfDebugUIPlugin.java index 528fa8d8359..f38e404fc17 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/DsfDebugUIPlugin.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/DsfDebugUIPlugin.java @@ -10,7 +10,7 @@ import org.osgi.framework.BundleContext; public class DsfDebugUIPlugin extends AbstractUIPlugin { // The plug-in ID - public static final String PLUGIN_ID = "org.eclipse.dd.dsf.debug.ui"; + public static final String PLUGIN_ID = "org.eclipse.dd.dsf.debug.ui"; //$NON-NLS-1$ // The shared instance private static DsfDebugUIPlugin plugin; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewSelectionRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewSelectionRootLayoutNode.java index 9a2722ffd32..18d00b8d4b4 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewSelectionRootLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewSelectionRootLayoutNode.java @@ -47,9 +47,9 @@ public class DebugViewSelectionRootLayoutNode extends AbstractVMRootLayoutNode } @Override - public void sessionDispose() { + public void dispose() { DebugUITools.getDebugContextManager().removeDebugContextListener(this); - super.sessionDispose(); + super.dispose(); } /** diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewModelProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/LaunchViewModelProvider.java similarity index 84% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewModelProvider.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/LaunchViewModelProvider.java index a3be1415e88..1999f647def 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewModelProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/LaunchViewModelProvider.java @@ -8,10 +8,11 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel; +package org.eclipse.dd.dsf.debug.ui.viewmodel.launch; import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.GetDataDone; +import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode; import org.eclipse.dd.dsf.ui.viewmodel.VMProvider; @@ -25,11 +26,11 @@ import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; * */ @SuppressWarnings("restriction") -public class DebugViewModelProvider extends VMProvider +public class LaunchViewModelProvider extends VMProvider implements IDebugEventSetListener { - - public DebugViewModelProvider(DsfSession session, IVMRootLayoutNode rootLayoutNode) { + @ThreadSafe + public LaunchViewModelProvider(DsfSession session, IVMRootLayoutNode rootLayoutNode) { super(session, rootLayoutNode); DebugPlugin.getDefault().addDebugEventListener(this); } @@ -50,7 +51,7 @@ public class DebugViewModelProvider extends VMProvider * Just like with DMC events, go through all the layout nodes and * collect delta information for the received event. */ - if (getRootLayoutNode().hasDeltaFlags(event)) { + if (getRootLayoutNode() != null && getRootLayoutNode().hasDeltaFlags(event)) { getRootLayoutNode().createDelta(event, new GetDataDone() { public void run() { if (getStatus().isOK()) { @@ -61,10 +62,9 @@ public class DebugViewModelProvider extends VMProvider } } - @Override - public void sessionDispose() { + public void dispose() { DebugPlugin.getDefault().removeDebugEventListener(this); - super.sessionDispose(); + super.dispose(); } } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/StackFramesLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java similarity index 94% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/StackFramesLayoutNode.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java index 57d77adfd42..91458bd6894 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/StackFramesLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel; +package org.eclipse.dd.dsf.debug.ui.viewmodel.launch; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.dd.dsf.concurrent.Done; @@ -34,7 +34,7 @@ import org.eclipse.jface.resource.ImageDescriptor; @SuppressWarnings("restriction") -public class StackFramesLayoutNode extends DMContextVMLayoutNode { +public class StackFramesLayoutNode extends DMContextVMLayoutNode { public IVMContext[] fCachedOldFramesVMCs; @@ -72,7 +72,7 @@ public class StackFramesLayoutNode extends DMContextVMLayoutNode { if (getServicesTracker().getService(IRunControl.class).isStepping(execDmc)) { getElementsTopStackFrameOnly(parentVmc, done); } else { - propagateError(getExecutor(), done, "Failed retrieving stack frames"); + propagateError(getExecutor(), done, "Failed retrieving stack frames"); //$NON-NLS-1$ } return; } @@ -95,7 +95,7 @@ public class StackFramesLayoutNode extends DMContextVMLayoutNode { getServicesTracker().getService(IStack.class).getTopFrame( execDmc, new GetDataDone() { public void run() { - if (propagateError(getExecutor(), done, "Failed retrieving top stack frame")) return; + if (propagateError(getExecutor(), done, "Failed retrieving top stack frame")) return; //$NON-NLS-1$ IVMContext topFrameVmc = new DMContextVMContext(parentVmc, getData()); // If there are old frames cached, use them and only substitute the top frame object. Otherwise, create @@ -110,7 +110,7 @@ public class StackFramesLayoutNode extends DMContextVMLayoutNode { }}); } - public void retrieveLabel(IVMContext vmc, final ILabelRequestMonitor result) { + public void retrieveLabel(IVMContext vmc, final ILabelRequestMonitor result, String[] columns) { final IExecutionDMContext execDmc = findDmcInVmc(vmc, IExecutionDMContext.class); if (execDmc == null || getServicesTracker().getService(IStack.class) == null || getServicesTracker().getService(IRunControl.class) == null) { result.done(); @@ -142,9 +142,9 @@ public class StackFramesLayoutNode extends DMContextVMLayoutNode { // If failed set a dummy label, and only propagate the // error if we are not stepping, since that would be a // common cause of failure. - result.setLabels(new String[] { "..." }); + result.setLabels(new String[] { "..." }); //$NON-NLS-1$ if (!getServicesTracker().getService(IRunControl.class).isStepping(execDmc)) { - MultiStatus status = new MultiStatus(DsfDebugUIPlugin.PLUGIN_ID, 0, "Failed to retrieve stack frame label", null); + MultiStatus status = new MultiStatus(DsfDebugUIPlugin.PLUGIN_ID, 0, "Failed to retrieve stack frame label", null); //$NON-NLS-1$ status.add(getStatus()); result.setStatus(status); } @@ -164,22 +164,22 @@ public class StackFramesLayoutNode extends DMContextVMLayoutNode { // Add the function name if (getData().getFunction() != null && getData().getFunction().length() != 0) { - label.append(" "); + label.append(" "); //$NON-NLS-1$ label.append(getData().getFunction()); - label.append("()"); + label.append("()"); //$NON-NLS-1$ } // Add full file name if (getData().getFile() != null && getData().getFile().length() != 0) { - label.append(" at "); + label.append(" at "); //$NON-NLS-1$ label.append(getData().getFile()); } // Add line number if (getData().getLine() >= 0) { - label.append(":"); + label.append(":"); //$NON-NLS-1$ label.append(getData().getLine()); - label.append(" "); + label.append(" "); //$NON-NLS-1$ } // Add the address @@ -191,7 +191,7 @@ public class StackFramesLayoutNode extends DMContextVMLayoutNode { }}); } - public boolean hasDeltaFlagsForDMEvent(IDMEvent e) { + public boolean hasDeltaFlagsForDMEvent(IDMEvent e) { // This node generates delta if the timers have changed, or if the // label has changed. return e instanceof IRunControl.ISuspendedDMEvent || @@ -200,7 +200,7 @@ public class StackFramesLayoutNode extends DMContextVMLayoutNode { super.hasDeltaFlagsForDMEvent(e); } - public void buildDeltaForDMEvent(final IDMEvent e, final VMDelta parent, final Done done) { + public void buildDeltaForDMEvent(final IDMEvent e, final VMDelta parent, final Done done) { if (getServicesTracker().getService(IStack.class) == null || getServicesTracker().getService(IRunControl.class) == null) { // Required services have not initialized yet. Ignore the event. super.buildDeltaForDMEvent(e, parent, done); diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/StandardLaunchRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java similarity index 97% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/StandardLaunchRootLayoutNode.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java index ef6add3693c..ac19bf205f3 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/StandardLaunchRootLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel; +package org.eclipse.dd.dsf.debug.ui.viewmodel.launch; import org.eclipse.dd.dsf.concurrent.DoneCollector; import org.eclipse.dd.dsf.concurrent.DsfExecutor; @@ -87,7 +87,7 @@ public class StandardLaunchRootLayoutNode extends AbstractVMRootLayoutNode */ final DoneCollector doneCollector = new DoneCollector(getExecutor()) { public void run() { - if (propagateError(getExecutor(), done, "Failed to generate child deltas.")) return; + if (propagateError(getExecutor(), done, "Failed to generate child deltas.")) return; //$NON-NLS-1$ done.setData(delta); getExecutor().execute(done); } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/StandardProcessLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessLayoutNode.java similarity index 95% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/StandardProcessLayoutNode.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessLayoutNode.java index 5fe46857a7c..652034f9416 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/StandardProcessLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessLayoutNode.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel; +package org.eclipse.dd.dsf.debug.ui.viewmodel.launch; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; @@ -54,9 +54,9 @@ public class StandardProcessLayoutNode extends AbstractVMLayoutNode { } public IVMContext getParent() { return fParentVmc; } - public IVMLayoutNode getLayoutNode() { return StandardProcessLayoutNode.this; } - public Object getAdapter(Class adapter) { return fProcess.getAdapter(adapter); } - public String toString() { return "IProcess " + fProcess.toString(); } + public IVMLayoutNode getLayoutNode() { return StandardProcessLayoutNode.this; } + @SuppressWarnings("unchecked") public Object getAdapter(Class adapter) { return fProcess.getAdapter(adapter); } + public String toString() { return "IProcess " + fProcess.toString(); } //$NON-NLS-1$ public String getAttribute(String key) { return fProcess.getAttribute(key); } public int getExitValue() throws DebugException { return fProcess.getExitValue(); } @@ -85,7 +85,7 @@ public class StandardProcessLayoutNode extends AbstractVMLayoutNode { * layout is misconfigured. */ assert false; - done.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Can't get list of processes, because there is no launch.", null)); + done.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Can't get list of processes, because there is no launch.", null)); //$NON-NLS-1$ getExecutor().execute(done); return; } @@ -108,7 +108,7 @@ public class StandardProcessLayoutNode extends AbstractVMLayoutNode { ILaunch launch = findLaunch(parentVmc); if (launch == null) { assert false; - done.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Can't get list of processes, because there is no launch.", null)); + done.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Can't get list of processes, because there is no launch.", null)); //$NON-NLS-1$ getExecutor().execute(done); return; } @@ -118,7 +118,7 @@ public class StandardProcessLayoutNode extends AbstractVMLayoutNode { } // @see org.eclipse.dd.dsf.ui.viewmodel.IViewModelLayoutNode#retrieveLabel(org.eclipse.dd.dsf.ui.viewmodel.IVMContext, org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor) - public void retrieveLabel(IVMContext vmc, ILabelRequestMonitor result) { + public void retrieveLabel(IVMContext vmc, ILabelRequestMonitor result, String[] columns) { /* * The implementation of IAdapterFactory that uses this node should not diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/MessagesForRegisterVM.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/MessagesForRegisterVM.java new file mode 100644 index 00000000000..c0ef4c28346 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/MessagesForRegisterVM.java @@ -0,0 +1,20 @@ +package org.eclipse.dd.dsf.debug.ui.viewmodel.register; + +import org.eclipse.osgi.util.NLS; + +public class MessagesForRegisterVM extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.dd.dsf.debug.ui.viewmodel.register.messages"; //$NON-NLS-1$ + + public static String RegisterColumnPresentation_description; + + public static String RegisterColumnPresentation_name; + + public static String RegisterColumnPresentation_value; + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, MessagesForRegisterVM.class); + } + + private MessagesForRegisterVM() { + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterColumnPresentation.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterColumnPresentation.java new file mode 100644 index 00000000000..c259d78b3a1 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterColumnPresentation.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel.register; + +import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation; +import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; +import org.eclipse.jface.resource.ImageDescriptor; + +/** + * + */ +@SuppressWarnings("restriction") +public class RegisterColumnPresentation implements IColumnPresentation { + + public static final String ID = DsfDebugUIPlugin.PLUGIN_ID + ".REGISTERS_COLUMN_PRESENTATION_ID"; //$NON-NLS-1$ + public static final String COL_NAME = ID + ".COL_NAME"; //$NON-NLS-1$ + public static final String COL_VALUE = ID + ".COL_VALUE"; //$NON-NLS-1$ + public static final String COL_DESCRIPTION = ID + ".COL_DESCRIPTION"; //$NON-NLS-1$ + + // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#init(org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext) + public void init(IPresentationContext context) {} + + // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#dispose() + public void dispose() {} + + // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getAvailableColumns() + public String[] getAvailableColumns() { + return new String[] { COL_NAME, COL_VALUE, COL_DESCRIPTION }; + } + + // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getHeader(java.lang.String) + public String getHeader(String id) { + if (COL_NAME.equals(id)) { + return MessagesForRegisterVM.RegisterColumnPresentation_name; + } else if (COL_VALUE.equals(id)) { + return MessagesForRegisterVM.RegisterColumnPresentation_value; + } else if (COL_DESCRIPTION.equals(id)) { + return MessagesForRegisterVM.RegisterColumnPresentation_description; + } + return null; + } + + // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getId() + public String getId() { + return ID; + } + + // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getImageDescriptor(java.lang.String) + public ImageDescriptor getImageDescriptor(String id) { + return null; + } + + // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getInitialColumns() + public String[] getInitialColumns() { + return new String[] { COL_NAME, COL_VALUE }; + } + + // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#isOptional() + public boolean isOptional() { + return true; + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/RegisterGroupLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java similarity index 65% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/RegisterGroupLayoutNode.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java index 3701e2f8e41..ef96b6ac340 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/RegisterGroupLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java @@ -8,24 +8,26 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel; +package org.eclipse.dd.dsf.debug.ui.viewmodel.register; import org.eclipse.dd.dsf.concurrent.Done; import org.eclipse.dd.dsf.concurrent.GetDataDone; +import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMEvent; import org.eclipse.dd.dsf.debug.service.IRegisters; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupData; import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.DMContextVMLayoutNode; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; -import org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.RGB; @SuppressWarnings("restriction") -public class RegisterGroupLayoutNode extends DMContextVMLayoutNode { +public class RegisterGroupLayoutNode extends DMContextVMLayoutNode { public RegisterGroupLayoutNode(DsfSession session) { super(session, IRegisters.IRegisterGroupDMContext.class); @@ -43,7 +45,7 @@ public class RegisterGroupLayoutNode extends DMContextVMLayoutNode { getServicesTracker().getService(IRegisters.class).getRegisterGroups( execDmc, null, new GetDataDone() { public void run() { - if (propagateError(getExecutor(), done, "Failed to retrieve register groups")) return; + if (propagateError(getExecutor(), done, "Failed to retrieve register groups")) return; //$NON-NLS-1$ done.setData(getData().length != 0); getExecutor().execute(done); }}); @@ -61,43 +63,31 @@ public class RegisterGroupLayoutNode extends DMContextVMLayoutNode { getServicesTracker().getService(IRegisters.class).getRegisterGroups( execDmc, null, new GetDataDone() { public void run() { - if (propagateError(getExecutor(), done, "Failed to retrieve register groups")) return; + if (propagateError(getExecutor(), done, "Failed to retrieve register groups")) return; //$NON-NLS-1$ done.setData(dmcs2vmcs(parentVmc, getData())); getExecutor().execute(done); }}); } - public void retrieveLabel( final IVMContext vmc , final ILabelRequestMonitor result ) { - if (getServicesTracker().getService(IRegisters.class) == null) { - result.done(); - return; - } - - final IRegisterGroupDMContext registerGroupDmc = (IRegisterGroupDMContext) ( (DMContextVMContext) vmc ).getDMC() ; - - getServicesTracker().getService( IRegisters.class ).getModelData( - registerGroupDmc, - new GetDataDone() { - public void run() { - if (!getStatus().isOK()) { - // Some error conditions are expected. - assert getStatus().getCode() == IDsfService.INVALID_STATE || getStatus().getCode() == IDsfService.INVALID_HANDLE : getStatus().toString(); - result.setLabels( new String[] { "...", "...", "..." } ) ; - } else { - result.setLabels(new String[] { getData().getName(), "", getData().getDescription() }); //$NON-NLS-1$ - } - result.done(); - return; - } - } - ) ; + @Override + protected void fillColumnLabel(IDMContext dmContext, IRegisterGroupData dmData, + String columnId, int idx, String[] text, ImageDescriptor[] image, + FontData[] fontData, RGB[] foreground, RGB[] background) + { + if (RegisterColumnPresentation.COL_NAME.equals(columnId)) { + text[idx] = dmData.getName(); + } else if (RegisterColumnPresentation.COL_VALUE.equals(columnId)) { + text[idx] = ""; //$NON-NLS-1$ + } else if (RegisterColumnPresentation.COL_DESCRIPTION.equals(columnId)) { + text[idx] = dmData.getDescription(); + } } - public boolean hasDeltaFlagsForDMEvent(IDMEvent e) { + public boolean hasDeltaFlagsForDMEvent(IDMEvent e) { return super.hasDeltaFlagsForDMEvent(e); } - public void buildDeltaForDMEvent(final IDMEvent e, final VMDelta parent, final Done done) { + public void buildDeltaForDMEvent(final IDMEvent e, final VMDelta parent, final Done done) { super.buildDeltaForDMEvent(e, parent, done); } } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/RegisterLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java similarity index 86% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/RegisterLayoutNode.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java index 86b9ae992db..dce21df6358 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/RegisterLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel; +package org.eclipse.dd.dsf.debug.ui.viewmodel.register; import org.eclipse.dd.dsf.concurrent.Done; import org.eclipse.dd.dsf.concurrent.GetDataDone; @@ -27,7 +27,7 @@ import org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor; import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; @SuppressWarnings("restriction") -public class RegisterLayoutNode extends DMContextVMLayoutNode { +public class RegisterLayoutNode extends DMContextVMLayoutNode { public IVMContext[] fCachedRegisterVMCs; @@ -48,7 +48,7 @@ public class RegisterLayoutNode extends DMContextVMLayoutNode { registerGroupDmc, new GetDataDone() { public void run() { - if (propagateError(getExecutor(), done, "Failed to retrieve registers")) return; + if (propagateError(getExecutor(), done, "Failed to retrieve registers")) return; //$NON-NLS-1$ done.setData(getData().length != 0); getExecutor().execute(done); } @@ -66,13 +66,13 @@ public class RegisterLayoutNode extends DMContextVMLayoutNode { getServicesTracker().getService( IRegisters.class ).getRegisters( execDmc, new GetDataDone() { public void run() { - if (propagateError(getExecutor(), done, "Failed to retrieve registers")) return; + if (propagateError(getExecutor(), done, "Failed to retrieve registers")) return; //$NON-NLS-1$ done.setData( dmcs2vmcs( parentVmc, getData()) ); getExecutor().execute(done); }}); } - public void retrieveLabel( final IVMContext vmc , final ILabelRequestMonitor result ) { + public void retrieveLabel(final IVMContext vmc , final ILabelRequestMonitor result, String[] columns) { if ( getServicesTracker().getService( IRegisters.class ) == null ) { result.done(); @@ -88,11 +88,11 @@ public class RegisterLayoutNode extends DMContextVMLayoutNode { if ( !getStatus().isOK() ) { assert getStatus().getCode() == IDsfService.INVALID_STATE || getStatus().getCode() == IDsfService.INVALID_HANDLE : getStatus().toString(); // Some error conditions are expected. - result.setLabels( new String[] { "...", "...", "..." } ) ; + result.setLabels( new String[] { "...", "...", "..." } ) ; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } else { String size = getData().getDescription(); String value = getData().getHexValue(); - if ("".equals(size)) { + if ("".equals(size)) { //$NON-NLS-1$ if ( value.contains( "uint64" ) ) { //$NON-NLS-1$ size = "64 bit register" ; //$NON-NLS-1$ } else if ( value.contains( "v4_float" ) ) { //$NON-NLS-1$ @@ -110,17 +110,19 @@ public class RegisterLayoutNode extends DMContextVMLayoutNode { ) ; } - public boolean hasDeltaFlagsForDMEvent( IDMEvent e ) { + public boolean hasDeltaFlagsForDMEvent( IDMEvent e ) { return (e instanceof IRunControl.ISuspendedDMEvent) || super.hasDeltaFlagsForDMEvent(e) ; } - public void buildDeltaForDMEvent( final IDMEvent e, final VMDelta parent, final Done done ) { + public void buildDeltaForDMEvent( final IDMEvent e, final VMDelta parent, final Done done ) { if (e instanceof IRunControl.ISuspendedDMEvent) { // Create a delta that the whole register group has changed. parent.addFlags(IModelDelta.CONTENT); } if (e instanceof IRegisters.IRegisterChangedDMEvent) { - parent.addNode(new DMContextVMContext(parent.getVMC(), e.getDMContext()), IModelDelta.STATE); + parent.addNode( + new DMContextVMContext(parent.getVMC(), ((IRegisters.IRegisterChangedDMEvent)e).getDMContext()), + IModelDelta.STATE); } super.buildDeltaForDMEvent(e, parent, done); diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java new file mode 100644 index 00000000000..24e9527c19a --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel.register; + +import org.eclipse.dd.dsf.debug.ui.viewmodel.DebugViewSelectionRootLayoutNode; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.VMProvider; +import org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation; +import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; + +/** + * + */ +@SuppressWarnings("restriction") +public class RegisterVMProvider extends VMProvider { + public RegisterVMProvider(DsfSession session, IPresentationContext context) { + super(session, null); + IVMRootLayoutNode debugViewSelection = new DebugViewSelectionRootLayoutNode( + getSession().getExecutor(), context.getPart().getSite().getWorkbenchWindow() ); + IVMLayoutNode registerGroupNode = new RegisterGroupLayoutNode(getSession()); + debugViewSelection.setChildNodes(new IVMLayoutNode[] { registerGroupNode }); + IVMLayoutNode registerNode = new RegisterLayoutNode(getSession()); + registerGroupNode.setChildNodes(new IVMLayoutNode[] { registerNode }); + setRootLayoutNode(debugViewSelection); + } + + @Override + public IColumnPresentation createColumnPresentation(Object element) { + return new RegisterColumnPresentation(); + } + + @Override + public String getColumnPresentationId(Object element) { + return RegisterColumnPresentation.ID; + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/messages.properties b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/messages.properties new file mode 100644 index 00000000000..5b6ea684c42 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/messages.properties @@ -0,0 +1,3 @@ +RegisterColumnPresentation_name=Name +RegisterColumnPresentation_value=Value +RegisterColumnPresentation_description=Description diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java index b136046b82c..43caaf6a69f 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.dsf.ui.viewmodel; +import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.concurrent.RejectedExecutionException; @@ -25,6 +26,8 @@ import org.eclipse.dd.dsf.ui.DsfUIPlugin; import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousContentAdapter; import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousLabelAdapter; import org.eclipse.debug.internal.ui.viewers.provisional.IChildrenRequestMonitor; +import org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation; +import org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentationFactoryAdapter; import org.eclipse.debug.internal.ui.viewers.provisional.IContainerRequestMonitor; import org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor; import org.eclipse.debug.internal.ui.viewers.provisional.IModelProxy; @@ -39,37 +42,46 @@ import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; abstract public class AbstractVMAdapter implements IAsynchronousLabelAdapter, IAsynchronousContentAdapter, - IModelProxyFactoryAdapter + IModelProxyFactoryAdapter, + IColumnPresentationFactoryAdapter { private final DsfSession fSession; @ConfinedToDsfExecutor("getSession().getExecutor()") - private Map fViewModelProviders = - new HashMap(); + private final Map fViewModelProviders = + Collections.synchronizedMap( new HashMap() ); + /** + * Constructor for the View Model session. It is tempting to have the + * adapter register itself here with the session as the model adapter, but + * that would mean that the adapter might get accessed on another thread + * even before the deriving class is fully constructed. So it it better + * to have the owner of this object register it with the session. + * @param session + */ public AbstractVMAdapter(DsfSession session) { fSession = session; - // regieterModelAdapter() is thread safe, so we're OK calling it from here. - fSession.registerModelAdapter(IAsynchronousLabelAdapter.class, this); - fSession.registerModelAdapter(IAsynchronousContentAdapter.class, this); - fSession.registerModelAdapter(IModelProxyFactoryAdapter.class, this); } - @ConfinedToDsfExecutor("getSession().getExecutor()") + @ThreadSafe abstract protected VMProvider createViewModelProvider(IPresentationContext context); protected DsfSession getSession() { return fSession; } - @ConfinedToDsfExecutor("getSession().getExecutor()") + @ThreadSafe private VMProvider getViewModelProvider(IPresentationContext context) { - VMProvider provider = fViewModelProviders.get(context); - if (provider == null) { - provider = createViewModelProvider(context); - if (provider != null) { - fViewModelProviders.put(context, provider); + assert DsfSession.isSessionActive(getSession().getId()); + + synchronized(fViewModelProviders) { + VMProvider provider = fViewModelProviders.get(context); + if (provider == null) { + provider = createViewModelProvider(context); + if (provider != null) { + fViewModelProviders.put(context, provider); + } } + return provider; } - return provider; } @ConfinedToDsfExecutor("getSession().getExecutor()") @@ -80,12 +92,8 @@ abstract public class AbstractVMAdapter public void dispose() { assert getSession().getExecutor().isInExecutorThread(); - fSession.unregisterModelAdapter(IAsynchronousLabelAdapter.class); - fSession.unregisterModelAdapter(IAsynchronousContentAdapter.class); - fSession.unregisterModelAdapter(IModelProxyFactoryAdapter.class); - for (VMProvider provider : fViewModelProviders.values()) { - provider.sessionDispose(); + provider.dispose(); } fViewModelProviders.clear(); } @@ -101,7 +109,7 @@ abstract public class AbstractVMAdapter result.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "No model provider for object: " + object.toString(), null)); //$NON-NLS-1$ result.done(); } - provider.retrieveLabel(object, result); + provider.retrieveLabel(object, result, context.getColumns()); } @Override public String toString() { return "Switch to dispatch thread to execute retrieveLabel()"; } //$NON-NLS-1$ @@ -161,9 +169,28 @@ abstract public class AbstractVMAdapter * create a proxy for the root element of the tree. */ VMProvider provider = getViewModelProvider(context); - if (provider != null && element.equals(provider.getRootLayoutNode().getRootVMC().getInputObject())) { + if (provider != null && + provider.getRootLayoutNode() != null && + element.equals(provider.getRootLayoutNode().getRootVMC().getInputObject())) + { return provider.getModelProxy(); } return null; } + + public String getColumnPresentationId(IPresentationContext context, Object element) { + VMProvider provider = getViewModelProvider(context); + if (provider != null) { + return provider.getColumnPresentationId(element); + } + return null; + } + + public IColumnPresentation createColumnPresentation(IPresentationContext context, Object element) { + VMProvider provider = getViewModelProvider(context); + if (provider != null) { + return provider.createColumnPresentation(element); + } + return null; + } } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java index 634f03c58b3..562f867f2d6 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java @@ -51,9 +51,9 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { return fChildNodes; } - public void sessionDispose() { + public void dispose() { for (IVMLayoutNode childNode : getChildLayoutNodes()) { - childNode.sessionDispose(); + childNode.dispose(); } } @@ -122,7 +122,7 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { } }); } - + /** * Convenience method that returns the child layout nodes which return * true to the hasDeltaFlags() test for the given @@ -165,5 +165,4 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { result.done(); } - } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMRootLayoutNode.java index ab4bbc43d40..baacc1cfc7c 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMRootLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMRootLayoutNode.java @@ -88,7 +88,7 @@ abstract public class AbstractVMRootLayoutNode extends AbstractVMLayoutNode impl * There is no use case for a root node implementing this method, but its * easier to just impelemnt it for sake of uniformity of model. */ - public void retrieveLabel(IVMContext vmc, ILabelRequestMonitor result) { + public void retrieveLabel(IVMContext vmc, ILabelRequestMonitor result, String[] columns) { result.done(); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java index 122209c834a..005aef1da0f 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java @@ -10,17 +10,29 @@ *******************************************************************************/ package org.eclipse.dd.dsf.ui.viewmodel; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.Done; import org.eclipse.dd.dsf.concurrent.DoneCollector; +import org.eclipse.dd.dsf.concurrent.GetDataDone; import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.datamodel.IDMData; import org.eclipse.dd.dsf.datamodel.IDMEvent; +import org.eclipse.dd.dsf.datamodel.IDMService; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.DsfUIPlugin; import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode.IRootVMC; +import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousLabelAdapter; +import org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentationFactoryAdapter; +import org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor; import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.RGB; /** @@ -30,7 +42,7 @@ import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; * are of the same class type. */ @SuppressWarnings("restriction") -abstract public class DMContextVMLayoutNode extends AbstractVMLayoutNode { +abstract public class DMContextVMLayoutNode extends AbstractVMLayoutNode { /** * IVMContext implementation used for this schema node. @@ -38,25 +50,33 @@ abstract public class DMContextVMLayoutNode extends AbstractVMLayoutNode { @Immutable public class DMContextVMContext implements IVMContext { private final IVMContext fParent; - private final IDMContext fDmc; + private final IDMContext fDmc; - public DMContextVMContext(IVMContext parent, IDMContext dmc) { + public DMContextVMContext(IVMContext parent, IDMContext dmc) { fParent = parent; fDmc = dmc; } - public IDMContext getDMC() { return fDmc; } + public IDMContext getDMC() { return fDmc; } public IVMContext getParent() { return fParent; } public IVMLayoutNode getLayoutNode() { return DMContextVMLayoutNode.this; } + /** + * The IAdaptable implementation. If the adapter is the DM context, + * return the context, otherwise delegate to IDMContext.getAdapter(). + */ @SuppressWarnings("unchecked") public Object getAdapter(Class adapter) { - return fDmc.getAdapter(adapter); + if (adapter.isInstance(fDmc)) { + return fDmc; + } else { + return fDmc.getAdapter(adapter); + } } public boolean equals(Object other) { - if (!(other instanceof DMContextVMContext)) return false; - DMContextVMContext otherVmc = (DMContextVMContext)other; + if (!(other instanceof DMContextVMLayoutNode.DMContextVMContext)) return false; + DMContextVMLayoutNode.DMContextVMContext otherVmc = (DMContextVMLayoutNode.DMContextVMContext)other; return DMContextVMLayoutNode.this.equals(otherVmc.getLayoutNode()) && fParent.equals(otherVmc.fParent) && fDmc.equals(otherVmc.fDmc); @@ -75,8 +95,13 @@ abstract public class DMContextVMLayoutNode extends AbstractVMLayoutNode { private DsfServicesTracker fServices; - /** Class type that the elements of this schema node are based on. */ - private Class> fDMCClassType; + /** + * Concrete class type that the elements of this schema node are based on. + * Even though the data model type is a parameter the DMContextVMLayoutNode, + * this type is erased at runtime, so a concrete class typs of the DMC + * is needed for instanceof chacks. + */ + private Class> fDMCClassType; /** * Constructor initializes instance data, except for the child nodes. @@ -85,14 +110,12 @@ abstract public class DMContextVMLayoutNode extends AbstractVMLayoutNode { * @param dmcClassType * @see #setChildNodes(IVMLayoutNode[]) */ - public DMContextVMLayoutNode(DsfSession session, Class> dmcClassType) { + public DMContextVMLayoutNode(DsfSession session, Class> dmcClassType) { super(session.getExecutor()); fServices = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), session.getId()); fDMCClassType = dmcClassType; } - - - + /** * Returns the services tracker for sub-class use. */ @@ -100,6 +123,111 @@ abstract public class DMContextVMLayoutNode extends AbstractVMLayoutNode { return fServices; } + /** + * The default implementation of the retrieve label method. It acquires + * the service, using parameters in the DMC, then it fetches the model + * data from the service, and then it calls the protected method + * fillColumnLabel() for each column. The deriving classes should override + * this method if a different method of computing the label is needed. + * + * @see #fillColumnLabel(IDMData, String, int, String[], ImageDescriptor[], FontData[], RGB[], RGB[]) + */ + @SuppressWarnings("unchecked") + public void retrieveLabel(IVMContext vmc, final ILabelRequestMonitor result, final String[] columns) { + /* + * Extract the DMContext from the VMContext, see DMContextVMContext.getAdapter(). + * Since the VMContext is supplied by this node, the DMContext should never be null. + * Note: had to suppress type cast warnings here, because getAdapter() does not support + * generics, and even if it did, I'm not sure it would help. + */ + final IDMContext dmc = (IDMContext)(vmc).getAdapter(IDMContext.class); + if (dmc == null) { + assert false; + result.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Invalid VMC type", null)); //$NON-NLS-1$ + result.done(); + return; + } + + /* + * Get the instance of the service using the service filter in the DMContext + * If null it could mean that the service already shut down, and the view + * is holding stale elements which will be cleaned up shortly. + */ + IDMService dmService = (IDMService)getServicesTracker().getService(null, dmc.getServiceFilter()); + if (dmService == null) { + handleFailedRetrieveLabel(result); + return; + } + + dmService.getModelData( + dmc, + new GetDataDone() { + public void run() { + /* + * Check that the request was evaluated and data is still + * valid. The request could fail if the state of the + * service changed during the request, but the view model + * has not been updated yet. + */ + if (!getStatus().isOK() || !getData().isValid()) { + assert getStatus().isOK() || + getStatus().getCode() != IDsfService.INTERNAL_ERROR || + getStatus().getCode() != IDsfService.NOT_SUPPORTED; + handleFailedRetrieveLabel(result); + return; + } + + /* + * If columns are configured, call the protected methods to + * fill in column values. + */ + String[] localColumns = columns; + if (localColumns == null) localColumns = new String[] { null }; + + String[] text = new String[localColumns.length]; + ImageDescriptor[] image = new ImageDescriptor[localColumns.length]; + FontData[] fontData = new FontData[localColumns.length]; + RGB[] foreground = new RGB[localColumns.length]; + RGB[] background = new RGB[localColumns.length]; + for (int i = 0; i < localColumns.length; i++) { + fillColumnLabel(dmc, getData(), localColumns[i], i, text, image, fontData, foreground, background); + } + result.setLabels(text); + result.setImageDescriptors(image); + result.setFontDatas(fontData); + result.setBackgrounds(background); + result.setForegrounds(foreground); + result.done(); + } + }); + } + + /** + * Fills in label information for given column. This method is intended to + * be overriden by deriving classes, to supply label information specific + * to the node.
    + * The implementation should fill in the correct value in each array at the + * given index. + * @param dmContext Data Model Context object for which the label is generated. + * @param dmData Data Model Data object retrieved from the model service. + * for the DM Context supplied to the retrieveLabel() call. + * @param columnId Name of the column to fill in, null if no columns specified. + * @param idx Index to fill in in the label arrays. + * @param text + * @param image + * @param fontData + * @param foreground + * @param background + * + * @see IAsynchronousLabelAdapter + * @see IColumnPresentationFactoryAdapter + */ + protected void fillColumnLabel(IDMContext dmContext, V dmData, String columnId, int idx, String[] text, + ImageDescriptor[] image, FontData[] fontData, RGB[] foreground, RGB[] background ) + { + text[idx] = ""; //$NON-NLS-1$ + } + @Override public boolean hasDeltaFlags(Object e) { if (e instanceof IDMEvent) { @@ -139,7 +267,7 @@ abstract public class DMContextVMLayoutNode extends AbstractVMLayoutNode { * behavior and generate a IModelDelta for every element in this schema * node. */ - IDMContext dmc = DMContexts.getAncestorOfType(e.getDMContext(), fDMCClassType); + IDMContext dmc = DMContexts.getAncestorOfType(e.getDMContext(), fDMCClassType); if (dmc != null) { IVMLayoutNode[] childNodes = getChildNodesWithDeltas(e); if (childNodes.length == 0) { @@ -180,7 +308,7 @@ abstract public class DMContextVMLayoutNode extends AbstractVMLayoutNode { * @param dmcs Array of DMC objects to build return array on. * @return Array of IVMContext objects. */ - protected IVMContext[] dmcs2vmcs(IVMContext parent, IDMContext[] dmcs) { + protected IVMContext[] dmcs2vmcs(IVMContext parent, IDMContext[] dmcs) { IVMContext[] vmContexts = new IVMContext[dmcs.length]; for (int i = 0; i < dmcs.length; i++) { vmContexts[i] = new DMContextVMContext(parent, dmcs[i]); @@ -216,8 +344,8 @@ abstract public class DMContextVMLayoutNode extends AbstractVMLayoutNode { return null; } - public void sessionDispose() { + public void dispose() { fServices.dispose(); - super.sessionDispose(); + super.dispose(); } } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMLayoutNode.java index 982e95a6825..4a677ebb2c4 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMLayoutNode.java @@ -15,6 +15,7 @@ import org.eclipse.dd.dsf.concurrent.Done; import org.eclipse.dd.dsf.concurrent.GetDataDone; import org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor; import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; /** * View model layout nodes are combined together into a tree, to collectively @@ -52,8 +53,10 @@ public interface IVMLayoutNode { * Retrieves the label for the given element. * @param vmc Element for which to retrieve label information. * @param result Monitor which accepts the data. + * @param columns Currently configured columns in view. + * @see IPresentationContext */ - public void retrieveLabel(IVMContext vmc, ILabelRequestMonitor result); + public void retrieveLabel(IVMContext vmc, ILabelRequestMonitor result, String[] columns); /** * Configures the child layout nodes for this node. @@ -89,5 +92,5 @@ public interface IVMLayoutNode { /** * Disposes the resources held by this node. */ - public void sessionDispose(); + public void dispose(); } \ No newline at end of file diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMProvider.java index 524c92dc0ba..9f26d2e1a40 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMProvider.java @@ -27,11 +27,13 @@ import org.eclipse.debug.internal.ui.viewers.provisional.AbstractModelProxy; import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousContentAdapter; import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousLabelAdapter; import org.eclipse.debug.internal.ui.viewers.provisional.IChildrenRequestMonitor; +import org.eclipse.debug.internal.ui.viewers.provisional.IColumnEditorFactoryAdapter; +import org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation; import org.eclipse.debug.internal.ui.viewers.provisional.IContainerRequestMonitor; import org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelChangedListener; import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.provisional.IModelProxy; +import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; /** * View model provider implements the asynchronous view model functionality for @@ -52,83 +54,48 @@ import org.eclipse.debug.internal.ui.viewers.provisional.IModelProxy; @SuppressWarnings("restriction") public class VMProvider { - @ThreadSafe - public class ModelProxy extends AbstractModelProxy { - /** - * Counter for whether the model proxy is currently installed in the viewer. - * Data model events are processed only if the model proxy is active. - */ - private int fProxyActive = 0; - - /** - * Scheduling rule for running the update jobs. - */ - private ISchedulingRule fModelChangeRule = new ISchedulingRule() { - public boolean contains(ISchedulingRule rule) { return this == rule; } - public boolean isConflicting(ISchedulingRule rule) { return rule == this; } - }; - - public void installed() { - fProxyActive++; - } - - public void dispose() { - fProxyActive--; - super.dispose(); - } - - @Override - public void removeModelChangedListener(IModelChangedListener listener) { - // TODO Auto-generated method stub - super.removeModelChangedListener(listener); - } - - @Override - public void addModelChangedListener(IModelChangedListener listener) { - // TODO Auto-generated method stub - super.addModelChangedListener(listener); - } - - /** - * Fires given delta using a job. Processing the delta on the dispatch - * thread can lead to dead-locks. - * @param delta - */ - public void fireModelChangedNonDispatch(final IModelDelta delta) { - if (fProxyActive <= 0) return; - - Job job = new Job("Processing view model delta.") { //$NON-NLS-1$ - protected IStatus run(IProgressMonitor monitor) { - fireModelChanged(delta); - return Status.OK_STATUS; - } - }; - job.setPriority(Job.INTERACTIVE); - job.setRule(fModelChangeRule); - job.schedule(); - } - - } - private final DsfSession fSession; private final ModelProxy fModelProxy = new ModelProxy(); + /** + * It is theoretically possible for a VMProvider to be disposed before it + * has a chance to register itself as event listener. This flag is used + * to avoid removing itself as listener in such situation. + */ + private boolean fRegisteredAsEventListener = false; + + /** + * The root node for this model provider. The root layout node could be + * null when first created, to allow sub-classes to prorperly configure the + * root node in the sub-class constructor. + */ private IVMRootLayoutNode fRootLayoutNode; /** - * Constructs the view model provider for given DSF session. + * Constructs the view model provider for given DSF session. The + * constructor is thread-safe to allow VM provider to be constructed + * synchronously when a call to getAdapter() is made on an element + * in a view. */ + @ThreadSafe public VMProvider(DsfSession session, IVMRootLayoutNode rootLayoutNode) { fSession = session; - setRootLayoutNode(rootLayoutNode); + fRootLayoutNode = rootLayoutNode; // Add ourselves as listener for DM events events. - session.addServiceEventListener(this, null); + session.getExecutor().execute(new Runnable() { + public void run() { + if (DsfSession.isSessionActive(getSession().getId())) { + getSession().addServiceEventListener(VMProvider.this, null); + fRegisteredAsEventListener = true; + } + } + }); } /** Sets the layout nodes */ public void setRootLayoutNode(IVMRootLayoutNode rootLayoutNode) { if (fRootLayoutNode != null) { - fRootLayoutNode.sessionDispose(); + fRootLayoutNode.dispose(); } fRootLayoutNode = rootLayoutNode; } @@ -138,9 +105,13 @@ public class VMProvider } /** Called to dispose the provider. */ - public void sessionDispose() { - fSession.removeServiceEventListener(this); - fRootLayoutNode.sessionDispose(); + public void dispose() { + if (fRegisteredAsEventListener) { + fSession.removeServiceEventListener(this); + } + if (fRootLayoutNode != null) { + fRootLayoutNode.dispose(); + } } protected DsfSession getSession() { return fSession; } @@ -248,6 +219,71 @@ public class VMProvider } } + /** + * Retrieves the label information for given object. + * The implementation converts the object into a VM-Context, then delegates + * to the context's layout node. + * Note: this method must be called on the provider's dispatch thread. + + * @see IAsynchronousLabelAdapter#retrieveLabel(Object, org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext, ILabelRequestMonitor) + */ + public void retrieveLabel(Object object, ILabelRequestMonitor result, String[] columns) + { + IVMContext vmc = getVmcForObject(object); + if (vmc == null) { + result.done(); + return; + } + + vmc.getLayoutNode().retrieveLabel(vmc, result, columns); + } + + public ModelProxy getModelProxy() { + return fModelProxy; + } + + + /** + * Creates the column presentation for the given object. This method is meant + * to be overriden by deriving class to provide view-specific functionality. + * The default is to return null, meaning no columns. + *

    + * The viewer only reads the column presentation for the root/input element of + * the tree/table, so the VMProvider must be configured to own the root element + * in the view in order for this setting to be effective. + *

    + * Note: since the IColumnEditorFactoryAdapter interface is synchronous, and since + * column info is fairly static, this method is thread-safe, and it will + * not be called on the executor thread. + * + * @see IColumnEditorFactoryAdapter#createColumnEditor(IPresentationContext, Object) + */ + @ThreadSafe + public IColumnPresentation createColumnPresentation(Object element) { + return null; + } + + /** + * Returns the ID of the column presentation for the given object. This method + * is meant to be overriden by deriving class to provide view-specific + * functionality. The default is to return null, meaning no columns. + *

    + * The viewer only reads the column presentation for the root/input element of + * the tree/table, so the VMProvider must be configured to own the root element + * in the view in order for this setting to be effective. + *

    + * Note: since the IColumnEditorFactoryAdapter interface is synchronous, and since + * column info is fairly static, this method is thread-safe, and it will + * not be called on the executor thread. + * + * @see IColumnEditorFactoryAdapter#getColumnEditorId(IPresentationContext, Object) + */ + @ThreadSafe + public String getColumnPresentationId(Object element) { + return null; + } + + /** * Convenience method that finds the VMC corresponding to given parent * argument given to isContainer() or retrieveChildren(). @@ -293,28 +329,7 @@ public class VMProvider } return false; } - - - /** - * Retrieves the label information for given VMC. - * Note: this method must be called on the provider's dispatch thread. - * @see IAsynchronousLabelAdapter#retrieveLabel(Object, org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext, ILabelRequestMonitor) - */ - public void retrieveLabel(Object object, final ILabelRequestMonitor result) - { - IVMContext vmc = getVmcForObject(object); - if (vmc == null) { - result.done(); - return; - } - - vmc.getLayoutNode().retrieveLabel(vmc, result); - } - - public ModelProxy getModelProxy() { - return fModelProxy; - } - + /** * Handle "data model changed" event by generating a delta object for each * view and passing it to the corresponding view model provider. The view @@ -337,4 +352,50 @@ public class VMProvider }); } } + + @ThreadSafe + public class ModelProxy extends AbstractModelProxy { + /** + * Counter for whether the model proxy is currently installed in the viewer. + * Data model events are processed only if the model proxy is active. + */ + private int fProxyActive = 0; + + /** + * Scheduling rule for running the update jobs. + */ + private ISchedulingRule fModelChangeRule = new ISchedulingRule() { + public boolean contains(ISchedulingRule rule) { return this == rule; } + public boolean isConflicting(ISchedulingRule rule) { return rule == this; } + }; + + public void installed() { + fProxyActive++; + } + + public void dispose() { + fProxyActive--; + super.dispose(); + } + + /** + * Fires given delta using a job. Processing the delta on the dispatch + * thread can lead to dead-locks. + * @param delta + */ + public void fireModelChangedNonDispatch(final IModelDelta delta) { + if (fProxyActive <= 0) return; + + Job job = new Job("Processing view model delta.") { //$NON-NLS-1$ + protected IStatus run(IProgressMonitor monitor) { + fireModelChanged(delta); + return Status.OK_STATUS; + } + }; + job.setPriority(Job.INTERACTIVE); + job.setRule(fModelChangeRule); + job.schedule(); + } + + } } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServicesTracker.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServicesTracker.java index 7ea47d7af0b..1253077b32a 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServicesTracker.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServicesTracker.java @@ -48,23 +48,24 @@ public class DsfServicesTracker { private static class ServiceKey { - String fClassString; + String fClassName; String fFilter; - public ServiceKey(String classString, String filter) { - fClassString = classString; + public ServiceKey(Class clazz, String filter) { + fClassName = clazz != null ? clazz.getName() : null; fFilter = filter; } public boolean equals(Object other) { // I guess this doesn't have to assume fFilter can be null, but oh well. - return other instanceof ServiceKey && - ((ServiceKey)other).fClassString.equals(fClassString) && + return other instanceof ServiceKey && + ((fClassName == null && ((ServiceKey)other).fClassName == null) || + (fClassName != null && fClassName.equals(((ServiceKey)other).fClassName))) && ((fFilter == null && ((ServiceKey)other).fFilter == null) || (fFilter != null && fFilter.equals(((ServiceKey)other).fFilter))); } public int hashCode() { - return fClassString.hashCode() + (fFilter == null ? 0 : fFilter.hashCode()); + return (fClassName == null ? 0 : fClassName.hashCode()) + (fFilter == null ? 0 : fFilter.hashCode()); } } @@ -95,13 +96,13 @@ public class DsfServicesTracker { */ @SuppressWarnings("unchecked") public ServiceReference getServiceReference(Class serviceClass, String filter) { - ServiceKey key = new ServiceKey(serviceClass.getName().intern(), filter != null ? filter : fServiceFilter); + ServiceKey key = new ServiceKey(serviceClass, filter != null ? filter : fServiceFilter); if (fServiceReferences.containsKey(key)) { return fServiceReferences.get(key); } try { - ServiceReference[] references = fBundleContext.getServiceReferences(key.fClassString, key.fFilter); + ServiceReference[] references = fBundleContext.getServiceReferences(key.fClassName, key.fFilter); assert references == null || references.length <= 1; if (references == null || references.length == 0) { return null; From 2b72c663b0d52ed1e9c6b4c4aff250f22bd9cb03 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Sat, 11 Nov 2006 00:10:15 +0000 Subject: [PATCH 040/834] Added cell-editor support to DSF view model (bug# 159681). --- .../dsf/ui/viewmodel/AbstractVMAdapter.java | 21 +++++- .../ui/viewmodel/AbstractVMLayoutNode.java | 21 ++++++ .../ui/viewmodel/DMContextVMLayoutNode.java | 11 ++- .../dd/dsf/ui/viewmodel/IVMLayoutNode.java | 27 +++++++ .../dd/dsf/ui/viewmodel/VMProvider.java | 72 ++++++++++++++----- ...hreadSafeAndProhibitedFromDsfExecutor.java | 43 +++++++++++ .../dd/dsf/datamodel/AbstractDMContext.java | 2 +- .../dd/dsf/datamodel/AbstractDMEvent.java | 2 +- 8 files changed, 178 insertions(+), 21 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ThreadSafeAndProhibitedFromDsfExecutor.java diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java index 43caaf6a69f..a759c952ec6 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java @@ -26,6 +26,8 @@ import org.eclipse.dd.dsf.ui.DsfUIPlugin; import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousContentAdapter; import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousLabelAdapter; import org.eclipse.debug.internal.ui.viewers.provisional.IChildrenRequestMonitor; +import org.eclipse.debug.internal.ui.viewers.provisional.IColumnEditor; +import org.eclipse.debug.internal.ui.viewers.provisional.IColumnEditorFactoryAdapter; import org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation; import org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentationFactoryAdapter; import org.eclipse.debug.internal.ui.viewers.provisional.IContainerRequestMonitor; @@ -43,7 +45,8 @@ abstract public class AbstractVMAdapter implements IAsynchronousLabelAdapter, IAsynchronousContentAdapter, IModelProxyFactoryAdapter, - IColumnPresentationFactoryAdapter + IColumnPresentationFactoryAdapter, + IColumnEditorFactoryAdapter { private final DsfSession fSession; @@ -193,4 +196,20 @@ abstract public class AbstractVMAdapter } return null; } + + public IColumnEditor createColumnEditor(IPresentationContext context, Object element) { + VMProvider provider = getViewModelProvider(context); + if (provider != null) { + return provider.createColumnEditor(element); + } + return null; + } + + public String getColumnEditorId(IPresentationContext context, Object element) { + VMProvider provider = getViewModelProvider(context); + if (provider != null) { + return provider.getColumnEditorId(element); + } + return null; + } } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java index 562f867f2d6..3fca9124448 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java @@ -17,8 +17,11 @@ 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.IColumnEditor; +import org.eclipse.debug.internal.ui.viewers.provisional.IColumnEditorFactoryAdapter; import org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor; import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; /** * @@ -123,6 +126,24 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { }); } + /** + * Default implementation of the IColumnEditorFactoryAdapter delegate. It + * returns null, which means that no cell editor is configured. + * @see IColumnEditorFactoryAdapter#createColumnEditor(IPresentationContext, Object) + */ + public IColumnEditor createColumnEditor(IVMContext vmc) { + return null; + } + + /** + * Default implementation of the IColumnEditorFactoryAdapter delegate. It + * returns null, which means that no cell editor is configured. + * @see IColumnEditorFactoryAdapter#getColumnEditorId(IPresentationContext, Object) + */ + public String getColumnEditorId(IVMContext vmc) { + return null; + } + /** * Convenience method that returns the child layout nodes which return * true to the hasDeltaFlags() test for the given diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java index 005aef1da0f..dbfda1753ab 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java @@ -94,6 +94,7 @@ abstract public class DMContextVMLayoutNode extends AbstractV /** Service tracker to be used by sub-classes */ private DsfServicesTracker fServices; + private DsfSession fSession; /** * Concrete class type that the elements of this schema node are based on. @@ -112,10 +113,18 @@ abstract public class DMContextVMLayoutNode extends AbstractV */ public DMContextVMLayoutNode(DsfSession session, Class> dmcClassType) { super(session.getExecutor()); + fSession = session; fServices = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), session.getId()); fDMCClassType = dmcClassType; } - + + /** + * Returns the session for use by sub-classes. + */ + protected DsfSession getSession() { + return fSession; + } + /** * Returns the services tracker for sub-class use. */ diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMLayoutNode.java index 4a677ebb2c4..0d2d3f3014f 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMLayoutNode.java @@ -13,6 +13,9 @@ 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.concurrent.ThreadSafeAndProhibitedFromDsfExecutor; +import org.eclipse.debug.internal.ui.viewers.provisional.IColumnEditor; +import org.eclipse.debug.internal.ui.viewers.provisional.IColumnEditorFactoryAdapter; import org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor; import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; @@ -89,6 +92,30 @@ public interface IVMLayoutNode { */ public void buildDelta(Object event, VMDelta parent, Done done); + /** + * Creates a column editor for the given element. The interface that this + * method is delegated to is synchronous, therefore it also needs to be thread + * safe. + * + * @see IColumnEditorFactoryAdapter#createColumnEditor(IPresentationContext, Object) + * @param vmc VM Context to return the editor for + * @return + */ + @ThreadSafeAndProhibitedFromDsfExecutor("") + public IColumnEditor createColumnEditor(IVMContext vmc); + + /** + * Returns the ID of the editor for the given element. The interface that this + * method is delegated to is synchronous, therefore it also needs to be thread + * safe. + * + * @see IColumnEditorFactoryAdapter#getColumnEditorId(IPresentationContext, Object) + * @param vmc VM Context to return the editor ID for + * @return + */ + @ThreadSafeAndProhibitedFromDsfExecutor("") + public String getColumnEditorId(IVMContext vmc); + /** * Disposes the resources held by this node. */ diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMProvider.java index 9f26d2e1a40..029b25ff52b 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMProvider.java @@ -10,6 +10,8 @@ *******************************************************************************/ package org.eclipse.dd.dsf.ui.viewmodel; +import java.util.concurrent.atomic.AtomicReference; + import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; @@ -27,8 +29,10 @@ 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.IColumnEditor; import org.eclipse.debug.internal.ui.viewers.provisional.IColumnEditorFactoryAdapter; import org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation; +import org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentationFactoryAdapter; import org.eclipse.debug.internal.ui.viewers.provisional.IContainerRequestMonitor; import org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor; import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; @@ -67,9 +71,9 @@ public class VMProvider /** * The root node for this model provider. The root layout node could be * null when first created, to allow sub-classes to prorperly configure the - * root node in the sub-class constructor. + * root node in the sub-class constructor. */ - private IVMRootLayoutNode fRootLayoutNode; + private AtomicReference fRootLayoutNodeRef = new AtomicReference(); /** * Constructs the view model provider for given DSF session. The @@ -80,7 +84,7 @@ public class VMProvider @ThreadSafe public VMProvider(DsfSession session, IVMRootLayoutNode rootLayoutNode) { fSession = session; - fRootLayoutNode = rootLayoutNode; + fRootLayoutNodeRef.set(rootLayoutNode); // Add ourselves as listener for DM events events. session.getExecutor().execute(new Runnable() { public void run() { @@ -92,16 +96,25 @@ public class VMProvider }); } - /** Sets the layout nodes */ + /** + * Sets the layout nodes. This method is thread-safe, because it might + * be called fromthe constructor, which itself is thread-safe. + */ + @ThreadSafe public void setRootLayoutNode(IVMRootLayoutNode rootLayoutNode) { - if (fRootLayoutNode != null) { - fRootLayoutNode.dispose(); + final IVMRootLayoutNode oldRootLayoutNode = fRootLayoutNodeRef.getAndSet(rootLayoutNode); + if (oldRootLayoutNode != null) { + // IVMLayoutNode has to be called on dispatch thread... for now at least. + getSession().getExecutor().execute( new Runnable() { + public void run() { + oldRootLayoutNode.dispose(); + } + }); } - fRootLayoutNode = rootLayoutNode; } public IVMRootLayoutNode getRootLayoutNode() { - return fRootLayoutNode; + return fRootLayoutNodeRef.get(); } /** Called to dispose the provider. */ @@ -109,8 +122,8 @@ public class VMProvider if (fRegisteredAsEventListener) { fSession.removeServiceEventListener(this); } - if (fRootLayoutNode != null) { - fRootLayoutNode.dispose(); + if (fRootLayoutNodeRef != null) { + fRootLayoutNodeRef.get().dispose(); } } @@ -256,7 +269,7 @@ public class VMProvider * column info is fairly static, this method is thread-safe, and it will * not be called on the executor thread. * - * @see IColumnEditorFactoryAdapter#createColumnEditor(IPresentationContext, Object) + * @see IColumnPresentationFactoryAdapter#createColumnPresentation(IPresentationContext, Object) */ @ThreadSafe public IColumnPresentation createColumnPresentation(Object element) { @@ -283,6 +296,24 @@ public class VMProvider return null; } + public IColumnEditor createColumnEditor(Object element) { + IVMContext vmc = getVmcForObject(element); + if (vmc == null) { + return null; + } + + return vmc.getLayoutNode().createColumnEditor(vmc); + } + + public String getColumnEditorId(Object element) { + IVMContext vmc = getVmcForObject(element); + if (vmc == null) { + return null; + } + + return vmc.getLayoutNode().getColumnEditorId(vmc); + } + /** * Convenience method that finds the VMC corresponding to given parent @@ -298,9 +329,14 @@ public class VMProvider * 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){ + IVMRootLayoutNode rootLayoutNode = getRootLayoutNode(); + if (rootLayoutNode == null) { + return null; + } + else if (parent.equals(rootLayoutNode.getRootVMC().getInputObject())) { + return rootLayoutNode.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 @@ -308,7 +344,7 @@ public class VMProvider * request is a stale request. So just ignore it. */ if (isOurLayoutNode( ((IVMContext)parent).getLayoutNode(), - new IVMLayoutNode[] { fRootLayoutNode } )) + new IVMLayoutNode[] { rootLayoutNode } )) { return (IVMContext)parent; } @@ -339,8 +375,10 @@ public class VMProvider */ @DsfServiceEventHandler public void eventDispatched(final IDMEvent event) { - if (fRootLayoutNode.hasDeltaFlags(event)) { - fRootLayoutNode.createDelta(event, new GetDataDone() { + IVMRootLayoutNode rootLayoutNode = getRootLayoutNode(); + + if (rootLayoutNode != null && rootLayoutNode.hasDeltaFlags(event)) { + rootLayoutNode.createDelta(event, new GetDataDone() { public void run() { if (getStatus().isOK()) { fModelProxy.fireModelChangedNonDispatch(getData()); diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ThreadSafeAndProhibitedFromDsfExecutor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ThreadSafeAndProhibitedFromDsfExecutor.java new file mode 100644 index 00000000000..24a41981cfa --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ThreadSafeAndProhibitedFromDsfExecutor.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.concurrent; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation idicating that given package, class, method, can be accessed on + * any thread, except on the dispatch thread of given DsfExecutor. + *
    This restriction is desirable if it is expected that the implementation + * behavior is to block the calling thread and execute a transaction using an + * executor. In this situation, if the call is made on the executor's dispach + * thread, the execution would dead-lock. + *
    + * If declared on package or type, a field or method could still be declared + * with an annotation indicating that it's thread-safe. + *

    + * Note: the runtime retention policy is there to allow automated testing + * and validation code. + * + * @param value The value indicates the method to use to obtain the executor. + * It should be null if it cannot be determined from the given object. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.PACKAGE, ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR}) +@Inherited +@Documented +public @interface ThreadSafeAndProhibitedFromDsfExecutor { + String value(); +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMContext.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMContext.java index 11350e58f13..b428ba83337 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMContext.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMContext.java @@ -22,7 +22,7 @@ import org.eclipse.dd.dsf.service.DsfSession; * @param Data Model data type that this context is for. */ @Immutable -public class AbstractDMContext extends PlatformObject +abstract public class AbstractDMContext extends PlatformObject implements IDMContext { private final String fSessionId; diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMEvent.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMEvent.java index 68d2fc9842f..9ea389977cc 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMEvent.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMEvent.java @@ -17,7 +17,7 @@ import org.eclipse.dd.dsf.concurrent.Immutable; * required DM-Context reference. */ @Immutable -public class AbstractDMEvent> implements IDMEvent { +abstract public class AbstractDMEvent> implements IDMEvent { private final V fModelContext; public AbstractDMEvent(V context) { From 30a3f6f919c9196d02652e727e4e59f994445970 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Tue, 14 Nov 2006 19:37:51 +0000 Subject: [PATCH 041/834] added plugin.xml --- plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml new file mode 100644 index 00000000000..33ca93ceb1b --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml @@ -0,0 +1,5 @@ + + + + + From 4d3c78eee1a1d82cb05f100bb21430d0e2d49953 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Tue, 14 Nov 2006 20:05:15 +0000 Subject: [PATCH 042/834] JAVAC won't compile A.B var = (A.B) myObj; --- .../org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java index dbfda1753ab..7458113910a 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java @@ -76,7 +76,7 @@ abstract public class DMContextVMLayoutNode extends AbstractV public boolean equals(Object other) { if (!(other instanceof DMContextVMLayoutNode.DMContextVMContext)) return false; - DMContextVMLayoutNode.DMContextVMContext otherVmc = (DMContextVMLayoutNode.DMContextVMContext)other; + DMContextVMLayoutNode.DMContextVMContext otherVmc = (DMContextVMLayoutNode.DMContextVMContext)other; return DMContextVMLayoutNode.this.equals(otherVmc.getLayoutNode()) && fParent.equals(otherVmc.fParent) && fDmc.equals(otherVmc.fDmc); From 1ae33e7c6adfcba6b7f0306e2e2f9184096210ec Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Tue, 14 Nov 2006 20:06:07 +0000 Subject: [PATCH 043/834] A.B var = (A.B) myObj; --- .../org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java index 7458113910a..8114f091d38 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java @@ -76,7 +76,7 @@ abstract public class DMContextVMLayoutNode extends AbstractV public boolean equals(Object other) { if (!(other instanceof DMContextVMLayoutNode.DMContextVMContext)) return false; - DMContextVMLayoutNode.DMContextVMContext otherVmc = (DMContextVMLayoutNode.DMContextVMContext)other; + DMContextVMLayoutNode.DMContextVMContext otherVmc = (DMContextVMLayoutNode.DMContextVMContext)other; return DMContextVMLayoutNode.this.equals(otherVmc.getLayoutNode()) && fParent.equals(otherVmc.fParent) && fDmc.equals(otherVmc.fDmc); From b4e24d81677a2919d0d0b71e055d13c364b1b1b3 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Tue, 14 Nov 2006 20:15:34 +0000 Subject: [PATCH 044/834] JAVAC A.B var = (A.B) myObj; --- .../org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java index 8114f091d38..7458113910a 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java @@ -76,7 +76,7 @@ abstract public class DMContextVMLayoutNode extends AbstractV public boolean equals(Object other) { if (!(other instanceof DMContextVMLayoutNode.DMContextVMContext)) return false; - DMContextVMLayoutNode.DMContextVMContext otherVmc = (DMContextVMLayoutNode.DMContextVMContext)other; + DMContextVMLayoutNode.DMContextVMContext otherVmc = (DMContextVMLayoutNode.DMContextVMContext)other; return DMContextVMLayoutNode.this.equals(otherVmc.getLayoutNode()) && fParent.equals(otherVmc.fParent) && fDmc.equals(otherVmc.fDmc); From 43d24e8bec654b779bfd66d87064e46e8778acf4 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Tue, 14 Nov 2006 20:21:01 +0000 Subject: [PATCH 045/834] JAVAC DMContextVMLayoutNode.DMContextVMContext otherVmc = ... --- .../org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java index 7458113910a..5a7a1247c40 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java @@ -76,7 +76,7 @@ abstract public class DMContextVMLayoutNode extends AbstractV public boolean equals(Object other) { if (!(other instanceof DMContextVMLayoutNode.DMContextVMContext)) return false; - DMContextVMLayoutNode.DMContextVMContext otherVmc = (DMContextVMLayoutNode.DMContextVMContext)other; + DMContextVMLayoutNode.DMContextVMContext otherVmc = (DMContextVMLayoutNode.DMContextVMContext)other; return DMContextVMLayoutNode.this.equals(otherVmc.getLayoutNode()) && fParent.equals(otherVmc.fParent) && fDmc.equals(otherVmc.fDmc); From db88b4e1cad349560dde6a3a5d488345ee10990a Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Tue, 14 Nov 2006 20:27:30 +0000 Subject: [PATCH 046/834] JAVAC if (!(other instanceof DMContextVMLayoutNode.DMContextVMContext)) return false; --- .../org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java index 5a7a1247c40..eefeebaa56f 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java @@ -75,7 +75,7 @@ abstract public class DMContextVMLayoutNode extends AbstractV } public boolean equals(Object other) { - if (!(other instanceof DMContextVMLayoutNode.DMContextVMContext)) return false; + if (!(other instanceof DMContextVMLayoutNode.DMContextVMContext)) return false; DMContextVMLayoutNode.DMContextVMContext otherVmc = (DMContextVMLayoutNode.DMContextVMContext)other; return DMContextVMLayoutNode.this.equals(otherVmc.getLayoutNode()) && fParent.equals(otherVmc.fParent) && From f26cd356291375fa3858df0c4043de645e6cf7fa Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Tue, 14 Nov 2006 22:22:41 +0000 Subject: [PATCH 047/834] All plugins will start with version 0.9.0. Europa will include the release of 0.9.0. Created a plugin.xml for org.eclipse.dd.dsf.ui. --- plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF | 2 +- plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF | 2 +- plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF | 2 +- plugins/org.eclipse.dd.dsf.ui/plugin.xml | 5 +++++ plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF | 2 +- 5 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf.ui/plugin.xml diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF index 28fe51ed363..f043727ab9e 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-Vendor: %providerName Bundle-SymbolicName: org.eclipse.dd.dsf.debug.ui -Bundle-Version: 1.0.0 +Bundle-Version: 0.9.0 Bundle-Activator: org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin Bundle-Localization: plugin Require-Bundle: org.eclipse.ui, diff --git a/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF index ddac2dd0f5d..e438fd1debe 100644 --- a/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-Vendor: %providerName Bundle-SymbolicName: org.eclipse.dd.dsf.debug -Bundle-Version: 1.0.0 +Bundle-Version: 0.9.0 Bundle-Activator: org.eclipse.dd.dsf.debug.DsfDebugPlugin Bundle-Localization: plugin Require-Bundle: org.eclipse.core.runtime, diff --git a/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF index 31c9f983458..bc80cddac17 100644 --- a/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-Vendor: %providerName Bundle-SymbolicName: org.eclipse.dd.dsf.ui -Bundle-Version: 1.0.0 +Bundle-Version: 0.9.0 Bundle-Activator: org.eclipse.dd.dsf.ui.DsfUIPlugin Bundle-Localization: plugin Require-Bundle: org.eclipse.ui, diff --git a/plugins/org.eclipse.dd.dsf.ui/plugin.xml b/plugins/org.eclipse.dd.dsf.ui/plugin.xml new file mode 100644 index 00000000000..33ca93ceb1b --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/plugin.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF index efe81b8adf6..3f616f08a98 100644 --- a/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-Vendor: %providerName Bundle-SymbolicName: org.eclipse.dd.dsf -Bundle-Version: 1.0.0 +Bundle-Version: 0.9.0 Bundle-Activator: org.eclipse.dd.dsf.DsfPlugin Bundle-Localization: plugin Require-Bundle: org.eclipse.core.runtime From 43788934ab0fb029a1d40f1865194f00ee606368 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Tue, 14 Nov 2006 22:56:39 +0000 Subject: [PATCH 048/834] Feature versions to 0.9.0. --- features/org.eclipse.dd.dsf.examples-feature/feature.xml | 4 ++-- features/org.eclipse.dd.dsf.gdb-feature/feature.xml | 4 ++-- features/org.eclipse.dd.dsf.sdk-feature/feature.xml | 2 +- features/org.eclipse.dd.dsf.test-feature/feature.xml | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/features/org.eclipse.dd.dsf.examples-feature/feature.xml b/features/org.eclipse.dd.dsf.examples-feature/feature.xml index 39e1d73a776..caad9397279 100644 --- a/features/org.eclipse.dd.dsf.examples-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.examples-feature/feature.xml @@ -2,7 +2,7 @@ + version="0.9.0"> [Enter Feature Description here.] @@ -17,7 +17,7 @@ - + + version="0.9.0"> [Enter Feature Description here.] @@ -17,7 +17,7 @@ - + diff --git a/features/org.eclipse.dd.dsf.test-feature/feature.xml b/features/org.eclipse.dd.dsf.test-feature/feature.xml index 31ca18d0691..52aaf777329 100644 --- a/features/org.eclipse.dd.dsf.test-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.test-feature/feature.xml @@ -2,7 +2,7 @@ + version="0.9.0"> [Enter Feature Description here.] @@ -17,8 +17,8 @@ - - + + Date: Wed, 22 Nov 2006 21:08:30 +0000 Subject: [PATCH 049/834] Flexible Hierarchy 3.3 APIs (bug 164341). --- .../src/org/eclipse/dd/dsf/concurrent/Done.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java index 34f258266af..4c07703eeb4 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java @@ -10,6 +10,8 @@ *******************************************************************************/ package org.eclipse.dd.dsf.concurrent; +import java.util.concurrent.Executor; + import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.Status; @@ -53,7 +55,7 @@ abstract public class Done extends DsfRunnable { * @return Returns true if there was an error that was propagated and * the caller can stop processing result. */ - protected boolean propagateError(DsfExecutor executor, Done clientDone, String message) { + protected boolean propagateError(Executor executor, Done clientDone, String message) { if (clientDone.getStatus().getSeverity() == IStatus.CANCEL) { return true; } From b191075ec4d85f4cc588e7556be42d8f15e4745e Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 30 Nov 2006 22:47:43 +0000 Subject: [PATCH 050/834] Ported to new flexible hierarchy APIs (bug 164341). --- .../DebugViewSelectionRootLayoutNode.java | 81 ++- .../launch/LaunchViewModelProvider.java | 70 -- .../launch/StackFramesLayoutNode.java | 402 ++++++----- .../launch/StandardLaunchRootLayoutNode.java | 89 ++- .../launch/StandardProcessLayoutNode.java | 121 ++-- .../register/RegisterColumnPresentation.java | 4 +- .../register/RegisterGroupLayoutNode.java | 102 +-- .../register/RegisterLayoutNode.java | 127 ++-- .../register/RegisterVMProvider.java | 26 +- .../META-INF/MANIFEST.MF | 3 +- .../dsf/ui/viewmodel/AbstractVMAdapter.java | 270 ++++---- .../ui/viewmodel/AbstractVMLayoutNode.java | 443 +++++++++--- .../dsf/ui/viewmodel/AbstractVMProvider.java | 648 ++++++++++++++++++ .../viewmodel/AbstractVMRootLayoutNode.java | 117 ++-- .../ui/viewmodel/DMContextVMLayoutNode.java | 360 ---------- .../dd/dsf/ui/viewmodel/IVMAdapter.java | 19 + .../dd/dsf/ui/viewmodel/IVMContext.java | 8 +- .../dd/dsf/ui/viewmodel/IVMLayoutNode.java | 119 ++-- .../dd/dsf/ui/viewmodel/IVMProvider.java | 40 ++ .../dsf/ui/viewmodel/IVMRootLayoutNode.java | 19 +- .../eclipse/dd/dsf/ui/viewmodel/VMDelta.java | 204 +++--- .../dd/dsf/ui/viewmodel/VMProvider.java | 439 ------------ .../ui/viewmodel/dm/AbstractDMVMAdapter.java | 44 ++ .../viewmodel/dm/AbstractDMVMLayoutNode.java | 501 ++++++++++++++ .../ui/viewmodel/dm/AbstractDMVMProvider.java | 139 ++++ .../dd/dsf/concurrent/DefaultDsfExecutor.java | 21 +- .../dd/dsf/concurrent/DoneCollector.java | 40 +- .../dd/dsf/concurrent/DsfExecutable.java | 22 +- .../dd/dsf/datamodel/AbstractDMContext.java | 9 +- .../dd/dsf/datamodel/ServiceDMContext.java | 5 +- .../eclipse/dd/dsf/service/IDsfService.java | 6 +- 31 files changed, 2619 insertions(+), 1879 deletions(-) delete mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/LaunchViewModelProvider.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java delete mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMAdapter.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java delete mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMProvider.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMAdapter.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProvider.java diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewSelectionRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewSelectionRootLayoutNode.java index 18d00b8d4b4..a147deafe8f 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewSelectionRootLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewSelectionRootLayoutNode.java @@ -10,14 +10,15 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.viewmodel; -import org.eclipse.dd.dsf.concurrent.DsfExecutor; -import org.eclipse.dd.dsf.concurrent.DsfRunnable; 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.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; 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.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode.DMVMContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.ui.DebugUITools; import org.eclipse.debug.ui.contexts.DebugContextEvent; import org.eclipse.debug.ui.contexts.IDebugContextListener; @@ -27,21 +28,26 @@ 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 + * Views such as variables and registers base their content on the * selection in Debug view, and this node provides tracking of that selection. + *

    + * Note: The variables/registers views track the selection using the same + * IDebugContextListener interface, but they only use the first element of the + * selection, as in IStructuredSelection.getFirstElement(). Therefore the root + * node also has to use the first element as the root object instead of the + * whole selection. */ +@SuppressWarnings("restriction") public class DebugViewSelectionRootLayoutNode extends AbstractVMRootLayoutNode implements IVMRootLayoutNode, IDebugContextListener { - private RootVMC fRootVMC; + private ISelection fSelection; - public DebugViewSelectionRootLayoutNode(DsfExecutor executor, IWorkbenchWindow window) { - super(executor); - ISelection selection = DebugUITools.getDebugContextManager().getContextService(window).getActiveContext(); - if (selection instanceof IStructuredSelection) { - fRootVMC = new RootVMC( this, ((IStructuredSelection)selection).getFirstElement() ); - } else { - fRootVMC = new RootVMC( this, null ); + public DebugViewSelectionRootLayoutNode(AbstractVMProvider provider) { + super(provider); + IWorkbenchWindow activeWindow = DsfDebugUIPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow(); + if (activeWindow != null) { + fSelection = DebugUITools.getDebugContextManager().getContextService(activeWindow).getActiveContext(); } DebugUITools.getDebugContextManager().addDebugContextListener(this); } @@ -53,7 +59,7 @@ public class DebugViewSelectionRootLayoutNode extends AbstractVMRootLayoutNode } /** - * If the input object is a DMC-VMC, and the event is a DMC event. + * If the input object is a Data Model context, and the event is a DMC event. * Then we can filter the event to make sure that the view does not * react to events that relate to objects outside this view. * @@ -74,45 +80,58 @@ public class DebugViewSelectionRootLayoutNode extends AbstractVMRootLayoutNode * determine whether a delta is needed. */ @Override - public boolean hasDeltaFlags(Object event) { - if (event instanceof IDMEvent && fRootVMC.getInputObject() instanceof DMContextVMContext) { + public int getDeltaFlags(Object event) { + IDMContext inputDmc = getSelectedDMC(); + if (event instanceof IDMEvent && inputDmc != null) { 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; + return super.getDeltaFlags(event); } } } if (potentialMatchFound && !matchFound) { - return false; + return IModelDelta.NO_CHANGE; } } - return super.hasDeltaFlags(event); + return super.getDeltaFlags(event); } - public IRootVMC getRootVMC() { - return fRootVMC; + /** + * Returns the full selection as it came from the DebugContextManager. + * @return + */ + public ISelection getSelection() { + return fSelection; + } + + public Object getRootObject() { + if (fSelection instanceof IStructuredSelection) { + return ((IStructuredSelection)fSelection).getFirstElement(); + } + return null; } public void debugContextChanged(DebugContextEvent event) { - final ISelection selection = event.getContext(); - getExecutor().execute(new DsfRunnable() { - public void run() { - if (selection instanceof IStructuredSelection) { - fRootVMC = new RootVMC( DebugViewSelectionRootLayoutNode.this, - ((IStructuredSelection)selection).getFirstElement() ); - } else { - fRootVMC = new RootVMC( DebugViewSelectionRootLayoutNode.this, null ); - } + fSelection = event.getContext(); + } + + private IDMContext getSelectedDMC() { + Object selection = fSelection; + if (selection instanceof IStructuredSelection) { + IStructuredSelection structSelection = (IStructuredSelection)selection; + if (structSelection.getFirstElement() instanceof DMVMContext) + { + return ((DMVMContext)structSelection.getFirstElement()).getDMC(); } - }); + } + return null; } } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/LaunchViewModelProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/LaunchViewModelProvider.java deleted file mode 100644 index 1999f647def..00000000000 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/LaunchViewModelProvider.java +++ /dev/null @@ -1,70 +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.ui.viewmodel.launch; - -import org.eclipse.dd.dsf.concurrent.DsfRunnable; -import org.eclipse.dd.dsf.concurrent.GetDataDone; -import org.eclipse.dd.dsf.concurrent.ThreadSafe; -import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode; -import org.eclipse.dd.dsf.ui.viewmodel.VMProvider; -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 LaunchViewModelProvider extends VMProvider - implements IDebugEventSetListener -{ - @ThreadSafe - public LaunchViewModelProvider(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() != null && getRootLayoutNode().hasDeltaFlags(event)) { - getRootLayoutNode().createDelta(event, new GetDataDone() { - public void run() { - if (getStatus().isOK()) { - getModelProxy().fireModelChangedNonDispatch(getData()); - } - } - }); - } - } - - @Override - public void dispose() { - DebugPlugin.getDefault().removeDebugEventListener(this); - super.dispose(); - } -} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java index 91458bd6894..0bd4d240637 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java @@ -10,9 +10,11 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.viewmodel.launch; -import org.eclipse.core.runtime.MultiStatus; +import java.util.List; + import org.eclipse.dd.dsf.concurrent.Done; import org.eclipse.dd.dsf.concurrent.GetDataDone; +import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMEvent; import org.eclipse.dd.dsf.debug.service.IRunControl; import org.eclipse.dd.dsf.debug.service.IStack; @@ -21,66 +23,77 @@ 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.AbstractVMProvider; 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.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; 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 class StackFramesLayoutNode extends AbstractDMVMLayoutNode { - public IVMContext[] fCachedOldFramesVMCs; + public IVMContext[] fCachedOldFrameVMCs; - public StackFramesLayoutNode(DsfSession session) { - super(session, IStack.IFrameDMContext.class); + public StackFramesLayoutNode(AbstractVMProvider provider, DsfSession session) { + super(provider, session, IStack.IFrameDMContext.class); } - public void hasElements(IVMContext parentVmc, final GetDataDone 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; - } + @Override + protected void updateHasElementsInSessionThread(IHasChildrenUpdate[] updates) { - done.setData(getServicesTracker().getService(IStack.class).isStackAvailable(execDmc)); - getExecutor().execute(done); + for (IHasChildrenUpdate update : updates) { + if (!checkService(IStack.class, null, update)) return; + + IExecutionDMContext execDmc = findDmcInPath(update.getElementPath(), IExecutionDMContext.class); + if (execDmc == null) { + handleFailedUpdate(update); + return; + } + + update.setHasChilren(getServicesTracker().getService(IStack.class).isStackAvailable(execDmc)); + update.done(); + } } - public void getElements(final IVMContext parentVmc, final GetDataDone 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); + @Override + protected void updateElementsInSessionThread(final IChildrenUpdate update) { + if (!checkService(IStack.class, null, update)) return; + + final IExecutionDMContext execDmc = findDmcInPath(update.getElementPath(), IExecutionDMContext.class); + if (execDmc == null) { + handleFailedUpdate(update); return; } getServicesTracker().getService(IStack.class).getFrames( execDmc, - new GetDataDone() { 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"); //$NON-NLS-1$ + new GetDataDone() { + 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 (!checkService(IRunControl.class, null, update)) return; + if (getServicesTracker().getService(IRunControl.class).isStepping(execDmc)) { + getElementsTopStackFrameOnly(update); + } else { + update.done(); + } + return; } - return; + // Store the VMC element array, in case we need to use it when + fCachedOldFrameVMCs = dmcs2vmcs(getData()); + for (int i = 0; i < fCachedOldFrameVMCs.length; i++) update.setChild(fCachedOldFrameVMCs[i], i); + update.done(); } - // Store the VMC element array, in case we need to use it when - fCachedOldFramesVMCs = dmcs2vmcs(parentVmc, getData()); - done.setData(fCachedOldFramesVMCs); - getExecutor().execute(done); - }}); + }); } /** @@ -89,184 +102,197 @@ public class StackFramesLayoutNode extends DMContextVMLayoutNode done) { - final IExecutionDMContext execDmc = findDmcInVmc(parentVmc, IExecutionDMContext.class); + private void getElementsTopStackFrameOnly(final IChildrenUpdate update) { + final IExecutionDMContext execDmc = findDmcInPath(update.getElementPath(), IExecutionDMContext.class); + if (execDmc == null) { + handleFailedUpdate(update); + return; + } getServicesTracker().getService(IStack.class).getTopFrame( execDmc, new GetDataDone() { public void run() { - if (propagateError(getExecutor(), done, "Failed retrieving top stack frame")) return; //$NON-NLS-1$ - IVMContext topFrameVmc = new DMContextVMContext(parentVmc, getData()); + if (!getStatus().isOK()) { + handleFailedUpdate(update); + return; + } + IVMContext topFrameVmc = new DMVMContext(getData()); + + update.setChild(topFrameVmc, 0); // 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); + if (fCachedOldFrameVMCs != null && fCachedOldFrameVMCs.length >= 1) { + fCachedOldFrameVMCs[0] = topFrameVmc; + for (int i = 0; i < fCachedOldFrameVMCs.length; i++) update.setChild(fCachedOldFrameVMCs[i], i); } else { - done.setData(new IVMContext[] { topFrameVmc }); + update.setChild(topFrameVmc, 0); } - getExecutor().execute(done); + update.done(); }}); } - public void retrieveLabel(IVMContext vmc, final ILabelRequestMonitor result, String[] columns) { - final IExecutionDMContext execDmc = findDmcInVmc(vmc, IExecutionDMContext.class); - if (execDmc == null || getServicesTracker().getService(IStack.class) == null || getServicesTracker().getService(IRunControl.class) == null) { - result.done(); - return; - } - + @Override + protected void fillColumnLabel(IDMContext dmContext, IFrameDMData dmData, String columnId, int idx, + ILabelUpdate update) + { + if (idx != 0) return; + + final IExecutionDMContext execDmc = findDmcInPath(update.getElementPath(), IExecutionDMContext.class); + IRunControl runControlService = getServicesTracker().getService(IRunControl.class); + IStepQueueManager stepQueueMgrService = getServicesTracker().getService(IStepQueueManager.class); + if (execDmc == null || runControlService == null || stepQueueMgrService == null) return; + String imageKey = null; - IRunControl rc = getServicesTracker().getService(IRunControl.class); - if (rc.isSuspended(execDmc) || - (rc.isStepping(execDmc) && !getServicesTracker().getService(IStepQueueManager.class).isSteppingTimedOut(execDmc))) + if (runControlService.isSuspended(execDmc) || + (runControlService.isStepping(execDmc) && !stepQueueMgrService.isSteppingTimedOut(execDmc))) { imageKey = IDebugUIConstants.IMG_OBJS_STACKFRAME; } else { imageKey = IDebugUIConstants.IMG_OBJS_STACKFRAME_RUNNING; } - result.setImageDescriptors(new ImageDescriptor[] { DebugUITools.getImageDescriptor(imageKey) }); + update.setImageDescriptor(DebugUITools.getImageDescriptor(imageKey), 0); - IFrameDMContext frameDmc = (IFrameDMContext)((DMContextVMContext)vmc).getDMC(); - getServicesTracker().getService(IStack.class).getModelData( - frameDmc, - new GetDataDone() { 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[] { "..." }); //$NON-NLS-1$ - if (!getServicesTracker().getService(IRunControl.class).isStepping(execDmc)) { - MultiStatus status = new MultiStatus(DsfDebugUIPlugin.PLUGIN_ID, 0, "Failed to retrieve stack frame label", null); //$NON-NLS-1$ - 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(" "); //$NON-NLS-1$ - label.append(getData().getFunction()); - label.append("()"); //$NON-NLS-1$ - } - - // Add full file name - if (getData().getFile() != null && getData().getFile().length() != 0) { - label.append(" at "); //$NON-NLS-1$ - label.append(getData().getFile()); - } - - // Add line number - if (getData().getLine() >= 0) { - label.append(":"); //$NON-NLS-1$ - label.append(getData().getLine()); - label.append(" "); //$NON-NLS-1$ - } - - // Add the address - label.append(getData().getAddress()); - - // Set the label to the result listener - result.setLabels(new String[] { label.toString() }); - result.done(); - }}); + // + // Finally, if all goes well, set the label. + // + StringBuilder label = new StringBuilder(); + + // Add frame number (if total number of frames in known) + if (fCachedOldFrameVMCs != null) { + label.append(fCachedOldFrameVMCs.length - dmData.getLevel()); + } + + // Add the function name + if (dmData.getFunction() != null && dmData.getFunction().length() != 0) { + label.append(" "); //$NON-NLS-1$ + label.append(dmData.getFunction()); + label.append("()"); //$NON-NLS-1$ + } + + // Add full file name + if (dmData.getFile() != null && dmData.getFile().length() != 0) { + label.append(" at "); //$NON-NLS-1$ + label.append(dmData.getFile()); + } + + // Add line number + if (dmData.getLine() >= 0) { + label.append(":"); //$NON-NLS-1$ + label.append(dmData.getLine()); + label.append(" "); //$NON-NLS-1$ + } + + // Add the address + label.append(dmData.getAddress()); + + // Set the label to the result listener + update.setLabel(label.toString(), 0); } - public boolean hasDeltaFlagsForDMEvent(IDMEvent e) { + protected void handleFailedUpdate(IViewerUpdate update) { + if (update instanceof ILabelUpdate) { + // Avoid repainting the label if it's not available. This only slows + // down the display. + } else { + super.handleFailedUpdate(update); + } + } + + + @Override + protected int getNodeDeltaFlagsForDMEvent(org.eclipse.dd.dsf.datamodel.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); + if (e instanceof IRunControl.ISuspendedDMEvent) { + return IModelDelta.CONTENT | IModelDelta.EXPAND | IModelDelta.SELECT; + } else if (e instanceof IRunControl.IResumedDMEvent) { + if (((IRunControl.IResumedDMEvent)e).getReason() == StateChangeReason.STEP) { + return IModelDelta.STATE; + } else { + return IModelDelta.CONTENT; + } + } else if (e instanceof IStepQueueManager.ISteppingTimedOutEvent) { + return IModelDelta.CONTENT; + } + return 0; } - public void buildDeltaForDMEvent(final IDMEvent e, final VMDelta parent, final Done done) { - if (getServicesTracker().getService(IStack.class) == null || getServicesTracker().getService(IRunControl.class) == null) { + @Override + protected void buildDeltaForDMEvent(final IDMEvent e, final VMDelta parent, final int nodeOffset, final Done done) { + if (e instanceof IRunControl.ISuspendedDMEvent) { + buildDeltaForSuspendedEvent((IRunControl.ISuspendedDMEvent)e, parent, nodeOffset, done); + } else if (e instanceof IRunControl.IResumedDMEvent) { + buildDeltaForResumedEvent((IRunControl.IResumedDMEvent)e, parent, nodeOffset, done); + } else if (e instanceof IStepQueueManager.ISteppingTimedOutEvent) { + buildDeltaForSteppingTimedOutEvent((IStepQueueManager.ISteppingTimedOutEvent)e, parent, nodeOffset, done); + } else { + // Call super-class to build sub-node delta's. + super.buildDeltaForDMEvent(e, parent, nodeOffset, done); + } + } + + private void buildDeltaForSuspendedEvent(final IRunControl.ISuspendedDMEvent e, final VMDelta parent, final int nodeOffset, final Done done) { + IRunControl runControlService = getServicesTracker().getService(IRunControl.class); + IStack stackService = getServicesTracker().getService(IStack.class); + if (stackService == null || runControlService == null) { // Required services have not initialized yet. Ignore the event. - super.buildDeltaForDMEvent(e, parent, done); + super.buildDeltaForDMEvent(e, parent, nodeOffset, 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() { 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() { 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. + // 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 (!runControlService.isStepping(e.getDMContext())) { parent.addFlags(IModelDelta.CONTENT); - super.buildDeltaForDMEvent(e, parent, done); - } else { - // Call super-class to build sub-node delta's. - super.buildDeltaForDMEvent(e, parent, done); } + + // 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( + new ElementsUpdate( + new GetDataDone>() { + public void run() { + if (getStatus().isOK() && getData().size() != 0) { + parent.addNode( getData().get(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().size() >= 2) { + parent.addNode( getData().get(1), IModelDelta.STATE); + } + } + // Even in case of errors, call super-class to complete building of the delta. + StackFramesLayoutNode.super.buildDeltaForDMEvent(e, parent, nodeOffset, done); + } + }, + parent) + ); + } + + private void buildDeltaForResumedEvent(final IRunControl.IResumedDMEvent e, final VMDelta parent, final int nodeOffset, final Done done) { + IStack stackService = getServicesTracker().getService(IStack.class); + if (stackService == null) { + // Required services have not initialized yet. Ignore the event. + super.buildDeltaForDMEvent(e, parent, nodeOffset, done); + return; + } + + IRunControl.IResumedDMEvent resumedEvent = (IRunControl.IResumedDMEvent)e; + if (resumedEvent.getReason() != StateChangeReason.STEP) { + // 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); + fCachedOldFrameVMCs = null; + } + super.buildDeltaForDMEvent(e, parent, nodeOffset, done); + } + + private void buildDeltaForSteppingTimedOutEvent(final IStepQueueManager.ISteppingTimedOutEvent e, final VMDelta parent, final int nodeOffset, final Done done) { + // Repaint the stack frame images to have the running symbol. + parent.addFlags(IModelDelta.CONTENT); + super.buildDeltaForDMEvent(e, parent, nodeOffset, done); } } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java index ac19bf205f3..e45c8623912 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java @@ -10,20 +10,24 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.viewmodel.launch; -import org.eclipse.dd.dsf.concurrent.DoneCollector; -import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import org.eclipse.dd.dsf.concurrent.Done; import org.eclipse.dd.dsf.concurrent.GetDataDone; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; 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.ILaunchManager; import org.eclipse.debug.core.model.IDebugElement; import org.eclipse.debug.core.model.IProcess; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; /** * Layout node for the standard ILaunch object. This node can only be used at @@ -34,34 +38,29 @@ import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; public class StandardLaunchRootLayoutNode extends AbstractVMRootLayoutNode implements IVMRootLayoutNode { - final private RootVMC fRootVMC; - final IVMContext[] fElements; + final private ILaunch fLaunch; - public StandardLaunchRootLayoutNode(DsfExecutor executor, ILaunch launch) { - super(executor); - fRootVMC = new RootVMC(this, launch); - fElements = new IVMContext[] { fRootVMC }; + public StandardLaunchRootLayoutNode(AbstractVMProvider provider, ILaunch launch) { + super(provider); + fLaunch = launch; } @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. - */ + public int getDeltaFlags(Object e) { 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); + if (de.getSource() instanceof IProcess && + !((IProcess)de.getSource()).getLaunch().equals(fLaunch) ) + { + return IModelDelta.NO_CHANGE; + } + else if (de.getSource() instanceof IDebugElement && + !((IDebugElement)de.getSource()).getLaunch().equals(fLaunch) ) + { + return IModelDelta.NO_CHANGE; } } - return super.hasDeltaFlags(e); + return super.getDeltaFlags(e); } public void createDelta(Object event, final GetDataDone done) { @@ -70,34 +69,26 @@ public class StandardLaunchRootLayoutNode extends AbstractVMRootLayoutNode * 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()); + ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager(); + List launchList = Arrays.asList(manager.getLaunches()); + final VMDelta viewRootDelta = new VMDelta(manager, 0, IModelDelta.NO_CHANGE, launchList.size()); + final VMDelta rootDelta = viewRootDelta.addNode(getRootObject(), launchList.indexOf(fLaunch), IModelDelta.NO_CHANGE); - final IVMLayoutNode[] childNodes = getChildNodesWithDeltas(event); - if (childNodes.length == 0) { - done.setData(delta); - getExecutor().execute(done); - return; - } + final Map childNodeDeltas = getChildNodesWithDeltas(event); + assert childNodeDeltas.size() != 0 : "Caller should make sure that there are deltas for given event."; //$NON-NLS-1$ - /* - * 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; //$NON-NLS-1$ - done.setData(delta); - getExecutor().execute(done); - } - }; - for (final IVMLayoutNode childNode : childNodes) { - childNode.buildDelta(event, rootDelta, doneCollector.addNoActionDone()); - } + callChildNodesToBuildDelta( + childNodeDeltas, rootDelta, event, + new Done() { + public void run() { + if (propagateError(getExecutor(), done, "Failed to create delta.")); //$NON-NLS-1$ + done.setData(viewRootDelta); + getExecutor().execute(done); + } + }); } - public IRootVMC getRootVMC() { - return fRootVMC; + public Object getRootObject() { + return fLaunch; } } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessLayoutNode.java index 652034f9416..78f34c3eaa9 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessLayoutNode.java @@ -10,25 +10,23 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.viewmodel.launch; -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.AbstractVMProvider; 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.model.provisional.IChildrenCountUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; +import org.eclipse.jface.viewers.TreePath; /** * Layout node for the standard platform debug model IProcess object. This @@ -43,19 +41,20 @@ 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 class VMC extends AbstractVMContext + implements IProcess { - private final IVMContext fParentVmc; private final IProcess fProcess; - VMC(IVMContext parentVmc, IProcess process) { - fParentVmc = parentVmc; + VMC(IProcess process) { + super(getVMProvider().getVMAdapter(), StandardProcessLayoutNode.this); fProcess = process; } - public IVMContext getParent() { return fParentVmc; } public IVMLayoutNode getLayoutNode() { return StandardProcessLayoutNode.this; } - @SuppressWarnings("unchecked") public Object getAdapter(Class adapter) { return fProcess.getAdapter(adapter); } + @SuppressWarnings("unchecked") public Object getAdapter(Class adapter) { + return fProcess.getAdapter(adapter); + } public String toString() { return "IProcess " + fProcess.toString(); } //$NON-NLS-1$ public String getAttribute(String key) { return fProcess.getAttribute(key); } @@ -72,21 +71,17 @@ public class StandardProcessLayoutNode extends AbstractVMLayoutNode { public int hashCode() { return fProcess.hashCode(); } } - public StandardProcessLayoutNode(DsfExecutor executor) { - super(executor); + public StandardProcessLayoutNode(AbstractVMProvider provider) { + super(provider); } - // @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 done) { - ILaunch launch = findLaunch(parentVmc); + public void updateElements(IChildrenUpdate update) { + ILaunch launch = findLaunch(update.getElementPath()); if (launch == null) { - /* - * There is no launch in the parent of this node. This means that the - * layout is misconfigured. - */ + // 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)); //$NON-NLS-1$ - getExecutor().execute(done); + update.done(); return; } @@ -95,30 +90,43 @@ public class StandardProcessLayoutNode extends AbstractVMLayoutNode { * 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]); + update.setChild(new VMC(processes[i]), i); } - done.setData(processVmcs); - getExecutor().execute(done); + update.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 done) { - ILaunch launch = findLaunch(parentVmc); + + public void updateElementCount(IChildrenCountUpdate update) { + ILaunch launch = findLaunch(update.getElementPath()); 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)); //$NON-NLS-1$ - getExecutor().execute(done); + assert false; + update.setChildCount(0); + update.done(); return; } - done.setData(launch.getProcesses().length != 0); - getExecutor().execute(done); + update.setChildCount(launch.getProcesses().length); + update.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 updateHasElements(IHasChildrenUpdate[] updates) { + for (IHasChildrenUpdate update : updates) { + ILaunch launch = findLaunch(update.getElementPath()); + if (launch == null) { + assert false; + update.setHasChilren(false); + update.done(); + return; + } + + update.setHasChilren(launch.getProcesses().length != 0); + update.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, String[] columns) { + public void updateLabel(IVMContext vmc, ILabelRequestMonitor result, String[] columns) { /* * The implementation of IAdapterFactory that uses this node should not @@ -134,30 +142,33 @@ public class StandardProcessLayoutNode extends AbstractVMLayoutNode { * 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()); + private ILaunch findLaunch(TreePath path) { + for (int i = path.getSegmentCount() - 1; i >= 0; i--) { + if (path.getSegment(i) instanceof ILaunch) { + return (ILaunch)path.getSegment(i); + } } + return null; } @Override - public boolean hasDeltaFlags(Object e) { + public int getDeltaFlags(Object e) { + int myFlags = 0; 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); + if ( de.getSource() instanceof IProcess && + (de.getKind() == DebugEvent.CHANGE || + de.getKind() == DebugEvent.CREATE || + de.getKind() == DebugEvent.TERMINATE) ) + { + myFlags = IModelDelta.STATE; + } } - return super.hasDeltaFlags(e); + return myFlags | super.getDeltaFlags(e); } @Override - public void buildDelta(Object e, VMDelta parent, Done done) { + public void buildDelta(Object e, VMDelta parent, int nodeOffset, Done done) { if (e instanceof DebugEvent && ((DebugEvent)e).getSource() instanceof IProcess) { DebugEvent de = (DebugEvent)e; if (de.getKind() == DebugEvent.CHANGE) { @@ -173,12 +184,12 @@ public class StandardProcessLayoutNode extends AbstractVMLayoutNode { */ getExecutor().execute(done); } else { - super.buildDelta(e, parent, done); + super.buildDelta(e, parent, nodeOffset, done); } } protected void handleChange(DebugEvent event, VMDelta parent) { - parent.addNode(new VMC(parent.getVMC(), (IProcess)event.getSource()), IModelDelta.STATE); + parent.addNode(new VMC((IProcess)event.getSource()), IModelDelta.STATE); } protected void handleCreate(DebugEvent event, VMDelta parent) { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterColumnPresentation.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterColumnPresentation.java index c259d78b3a1..779980b0586 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterColumnPresentation.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterColumnPresentation.java @@ -11,8 +11,8 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.register; import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; -import org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.jface.resource.ImageDescriptor; /** diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java index ef96b6ac340..f924d815f3b 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java @@ -10,84 +10,58 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.viewmodel.register; -import org.eclipse.dd.dsf.concurrent.Done; import org.eclipse.dd.dsf.concurrent.GetDataDone; import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.datamodel.IDMEvent; import org.eclipse.dd.dsf.debug.service.IRegisters; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupData; import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.ui.viewmodel.DMContextVMLayoutNode; -import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; -import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.graphics.RGB; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; @SuppressWarnings("restriction") -public class RegisterGroupLayoutNode extends DMContextVMLayoutNode { +public class RegisterGroupLayoutNode extends AbstractDMVMLayoutNode { - public RegisterGroupLayoutNode(DsfSession session) { - super(session, IRegisters.IRegisterGroupDMContext.class); - } - - public void hasElements( final IVMContext parentVmc , final GetDataDone 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() { public void run() { - if (propagateError(getExecutor(), done, "Failed to retrieve register groups")) return; //$NON-NLS-1$ - done.setData(getData().length != 0); - getExecutor().execute(done); - }}); - } - - public void getElements( final IVMContext parentVmc, final GetDataDone 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() { public void run() { - if (propagateError(getExecutor(), done, "Failed to retrieve register groups")) return; //$NON-NLS-1$ - done.setData(dmcs2vmcs(parentVmc, getData())); - getExecutor().execute(done); - }}); + public RegisterGroupLayoutNode(AbstractVMProvider provider, DsfSession session) { + super(provider, session, IRegisters.IRegisterGroupDMContext.class); } @Override - protected void fillColumnLabel(IDMContext dmContext, IRegisterGroupData dmData, - String columnId, int idx, String[] text, ImageDescriptor[] image, - FontData[] fontData, RGB[] foreground, RGB[] background) - { - if (RegisterColumnPresentation.COL_NAME.equals(columnId)) { - text[idx] = dmData.getName(); - } else if (RegisterColumnPresentation.COL_VALUE.equals(columnId)) { - text[idx] = ""; //$NON-NLS-1$ - } else if (RegisterColumnPresentation.COL_DESCRIPTION.equals(columnId)) { - text[idx] = dmData.getDescription(); - } + protected void updateElementsInSessionThread(final IChildrenUpdate update) { + if (!checkService(IRegisters.class, null, update)) return; + + final IExecutionDMContext execDmc = findDmcInPath(update.getElementPath(), IExecutionDMContext.class) ; + + if (execDmc != null) { + getServicesTracker().getService(IRegisters.class).getRegisterGroups( + execDmc, null, + new GetDataDone() { public void run() { + if (!getStatus().isOK()) { + update.done(); + return; + } + fillUpdateWithVMCs(update, getData()); + update.done(); + }}); + } else { + handleFailedUpdate(update); + } + } - 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); + @Override + protected void fillColumnLabel(IDMContext dmContext, IRegisterGroupData dmData, + String columnId, int idx, ILabelUpdate update) + { + if (RegisterColumnPresentation.COL_NAME.equals(columnId)) { + update.setLabel(dmData.getName(), idx); + } else if (RegisterColumnPresentation.COL_VALUE.equals(columnId)) { + update.setLabel("", idx); //$NON-NLS-1$ + } else if (RegisterColumnPresentation.COL_DESCRIPTION.equals(columnId)) { + update.setLabel(dmData.getDescription(), idx); + } } } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java index dce21df6358..dfdf80b19fd 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java @@ -12,6 +12,7 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.register; import org.eclipse.dd.dsf.concurrent.Done; import org.eclipse.dd.dsf.concurrent.GetDataDone; +import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMEvent; import org.eclipse.dd.dsf.debug.service.IRegisters; import org.eclipse.dd.dsf.debug.service.IRunControl; @@ -19,112 +20,86 @@ 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.AbstractVMProvider; 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.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; @SuppressWarnings("restriction") -public class RegisterLayoutNode extends DMContextVMLayoutNode { +public class RegisterLayoutNode extends AbstractDMVMLayoutNode { public IVMContext[] fCachedRegisterVMCs; - public RegisterLayoutNode(DsfSession session) { - super(session, IRegisters.IRegisterDMContext.class); + public RegisterLayoutNode(AbstractVMProvider provider, DsfSession session) { + super(provider, session, IRegisters.IRegisterDMContext.class); } - public void hasElements( final IVMContext parentVmc , final GetDataDone done ) { - final IRegisterGroupDMContext registerGroupDmc = findDmcInVmc(parentVmc, IRegisterGroupDMContext.class); + @Override + protected void updateElementsInSessionThread(final IChildrenUpdate update) { + final IRegisterGroupDMContext execDmc = findDmcInPath(update.getElementPath(), IRegisterGroupDMContext.class); - if (registerGroupDmc == null || getServicesTracker().getService(IRegisters.class) == null) { - done.setData(Boolean.FALSE); - getExecutor().execute(done); + if (execDmc == null) { + handleFailedUpdate(update); return; } - getServicesTracker().getService( IRegisters.class ).getRegisters( - registerGroupDmc, + getServicesTracker().getService(IRegisters.class).getRegisters( + execDmc, new GetDataDone() { public void run() { - if (propagateError(getExecutor(), done, "Failed to retrieve registers")) return; //$NON-NLS-1$ - done.setData(getData().length != 0); - getExecutor().execute(done); + if (!getStatus().isOK()) { + handleFailedUpdate(update); + } + fillUpdateWithVMCs(update, getData()); + update.done(); } }); } - - public void getElements( final IVMContext parentVmc , final GetDataDone 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() { public void run() { - if (propagateError(getExecutor(), done, "Failed to retrieve registers")) return; //$NON-NLS-1$ - done.setData( dmcs2vmcs( parentVmc, getData()) ); - getExecutor().execute(done); - }}); - } - public void retrieveLabel(final IVMContext vmc , final ILabelRequestMonitor result, String[] columns) { - - if ( getServicesTracker().getService( IRegisters.class ) == null ) { - result.done(); - return; - } - - final IRegisterDMContext registerDmc = (IRegisterDMContext) ( (DMContextVMContext) vmc ).getDMC() ; - - getServicesTracker().getService( IRegisters.class ).getModelData( - registerDmc , - new GetDataDone() { - 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[] { "...", "...", "..." } ) ; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } else { - String size = getData().getDescription(); - String value = getData().getHexValue(); - if ("".equals(size)) { //$NON-NLS-1$ - if ( value.contains( "uint64" ) ) { //$NON-NLS-1$ - size = "64 bit register" ; //$NON-NLS-1$ - } else if ( value.contains( "v4_float" ) ) { //$NON-NLS-1$ - size = "128 bit register" ; //$NON-NLS-1$ - } - } - - result.setLabels(new String[] { getData().getName(), getData().getHexValue(), size }); - } - - result.done() ; - return ; + @Override + protected void fillColumnLabel(IDMContext dmContext, IRegisterDMData dmData, String columnId, + int idx, ILabelUpdate update) + { + if (RegisterColumnPresentation.COL_NAME.equals(columnId)) { + update.setLabel(dmData.getName(), idx); + } else if (RegisterColumnPresentation.COL_VALUE.equals(columnId)) { + update.setLabel(dmData.getHexValue(), idx); + } else if (RegisterColumnPresentation.COL_DESCRIPTION.equals(columnId)) { + String size = dmData.getDescription(); + String value = dmData.getHexValue(); + if ("".equals(size)) { //$NON-NLS-1$ + if ( value.contains( "uint64" ) ) { //$NON-NLS-1$ + size = "64 bit register" ; //$NON-NLS-1$ + } else if ( value.contains( "v4_float" ) ) { //$NON-NLS-1$ + size = "128 bit register" ; //$NON-NLS-1$ } } - ) ; + update.setLabel(size, idx); + } } - public boolean hasDeltaFlagsForDMEvent( IDMEvent e ) { - return (e instanceof IRunControl.ISuspendedDMEvent) || super.hasDeltaFlagsForDMEvent(e) ; + @Override + protected int getNodeDeltaFlagsForDMEvent(IDMEvent e) { + if (e instanceof IRunControl.ISuspendedDMEvent) { + return IModelDelta.CONTENT; + } else if (e instanceof IRegisters.IRegisterChangedDMEvent) { + return IModelDelta.STATE; + } + return IModelDelta.NO_CHANGE; } - public void buildDeltaForDMEvent( final IDMEvent e, final VMDelta parent, final Done done ) { + @Override + protected void buildDeltaForDMEvent(IDMEvent e, VMDelta parent, int nodeOffset, 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(), ((IRegisters.IRegisterChangedDMEvent)e).getDMContext()), - IModelDelta.STATE); + parent.addNode( new DMVMContext(((IRegisters.IRegisterChangedDMEvent)e).getDMContext()), IModelDelta.STATE ); } - - super.buildDeltaForDMEvent(e, parent, done); + super.buildDeltaForDMEvent(e, parent, nodeOffset, done); } } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java index 24e9527c19a..f40284a2fc2 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java @@ -12,35 +12,35 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.register; import org.eclipse.dd.dsf.debug.ui.viewmodel.DebugViewSelectionRootLayoutNode; import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode; -import org.eclipse.dd.dsf.ui.viewmodel.VMProvider; -import org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; /** * */ @SuppressWarnings("restriction") -public class RegisterVMProvider extends VMProvider { - public RegisterVMProvider(DsfSession session, IPresentationContext context) { - super(session, null); - IVMRootLayoutNode debugViewSelection = new DebugViewSelectionRootLayoutNode( - getSession().getExecutor(), context.getPart().getSite().getWorkbenchWindow() ); - IVMLayoutNode registerGroupNode = new RegisterGroupLayoutNode(getSession()); +public class RegisterVMProvider extends AbstractDMVMProvider { + public RegisterVMProvider(AbstractVMAdapter adapter, IPresentationContext context, DsfSession session) { + super(adapter, context, session); + IVMRootLayoutNode debugViewSelection = new DebugViewSelectionRootLayoutNode(this); + IVMLayoutNode registerGroupNode = new RegisterGroupLayoutNode(this, getSession()); debugViewSelection.setChildNodes(new IVMLayoutNode[] { registerGroupNode }); - IVMLayoutNode registerNode = new RegisterLayoutNode(getSession()); + IVMLayoutNode registerNode = new RegisterLayoutNode(this, getSession()); registerGroupNode.setChildNodes(new IVMLayoutNode[] { registerNode }); setRootLayoutNode(debugViewSelection); } - + @Override - public IColumnPresentation createColumnPresentation(Object element) { + public IColumnPresentation createColumnPresentation(IPresentationContext context, Object element) { return new RegisterColumnPresentation(); } @Override - public String getColumnPresentationId(Object element) { + public String getColumnPresentationId(IPresentationContext context, Object element) { return RegisterColumnPresentation.ID; } } diff --git a/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF index bc80cddac17..6070a58d0f0 100644 --- a/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF @@ -11,5 +11,6 @@ Require-Bundle: org.eclipse.ui, org.eclipse.dd.dsf, org.eclipse.debug.ui Eclipse-LazyStart: true -Export-Package: org.eclipse.dd.dsf.ui.viewmodel +Export-Package: org.eclipse.dd.dsf.ui.viewmodel, + org.eclipse.dd.dsf.ui.viewmodel.dm Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java index a759c952ec6..163e67a9593 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java @@ -13,46 +13,39 @@ package org.eclipse.dd.dsf.ui.viewmodel; import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; 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.DefaultDsfExecutor; 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.IColumnEditor; -import org.eclipse.debug.internal.ui.viewers.provisional.IColumnEditorFactoryAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation; -import org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentationFactoryAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.IContainerRequestMonitor; -import org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelProxy; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelProxyFactoryAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; /** - * Base implementation for DSF-based view model adapters. + * Base implementation for View Model Adapters. The implementation uses + * its own single-thread executor for communicating with providers and + * layout nodes. */ @ThreadSafe @SuppressWarnings("restriction") -abstract public class AbstractVMAdapter - implements IAsynchronousLabelAdapter, - IAsynchronousContentAdapter, - IModelProxyFactoryAdapter, - IColumnPresentationFactoryAdapter, - IColumnEditorFactoryAdapter +abstract public class AbstractVMAdapter implements IVMAdapter { - private final DsfSession fSession; + private final ExecutorService fExecutor; + private boolean fDisposed; - @ConfinedToDsfExecutor("getSession().getExecutor()") - private final Map fViewModelProviders = - Collections.synchronizedMap( new HashMap() ); + private final Map fViewModelProviders = + Collections.synchronizedMap( new HashMap() ); /** * Constructor for the View Model session. It is tempting to have the @@ -62,21 +55,32 @@ abstract public class AbstractVMAdapter * to have the owner of this object register it with the session. * @param session */ - public AbstractVMAdapter(DsfSession session) { - fSession = session; + public AbstractVMAdapter() { + fExecutor = new DefaultDsfExecutor(); } - @ThreadSafe - abstract protected VMProvider createViewModelProvider(IPresentationContext context); - - protected DsfSession getSession() { return fSession; } + /** + * Returns the executor that will be used to communicate with the providers + * and the layout nodes. + * @return + */ + public Executor getExecutor() { + return fExecutor; + } + /** + * Creates a new View Model Provider for given presentation context. Returns null + * if the presentation context is not supported. + */ + @ThreadSafe + abstract protected IVMProvider createViewModelProvider(IPresentationContext context); + @ThreadSafe - private VMProvider getViewModelProvider(IPresentationContext context) { - assert DsfSession.isSessionActive(getSession().getId()); - + private IVMProvider getViewModelProvider(IPresentationContext context) { synchronized(fViewModelProviders) { - VMProvider provider = fViewModelProviders.get(context); + if (fDisposed) return null; + + IVMProvider provider = fViewModelProviders.get(context); if (provider == null) { provider = createViewModelProvider(context); if (provider != null) { @@ -87,129 +91,113 @@ abstract public class AbstractVMAdapter } } - @ConfinedToDsfExecutor("getSession().getExecutor()") - public void install(IPresentationContext context) { - } - - @ConfinedToDsfExecutor("getSession().getExecutor()") public void dispose() { - assert getSession().getExecutor().isInExecutorThread(); + // Execute the shutdown in adapter's dispatch thread. + getExecutor().execute(new DsfRunnable() { + public void run() { + synchronized(fViewModelProviders) { + fDisposed = true; + for (IVMProvider provider : fViewModelProviders.values()) { + provider.dispose(); + } + fViewModelProviders.clear(); + } + fExecutor.shutdown(); + } + }); + } + + public void update(IHasChildrenUpdate[] updates) { + handleUpdates(updates); + } + + public void update(IChildrenCountUpdate[] updates) { + handleUpdates(updates); + } + + public void update(final IChildrenUpdate[] updates) { + handleUpdates(updates); + } + + private void handleUpdates(final IViewerUpdate[] updates) { + try { + getExecutor().execute(new DsfRunnable() { + public void run() { + IPresentationContext context = null; + int firstIdx = 0; + int curIdx = 0; + for (curIdx = 0; curIdx < updates.length; curIdx++) { + if (!updates[curIdx].getPresentationContext().equals(context)) { + if (context != null) { + callProviderWithUpdate(updates, firstIdx, curIdx); + } + context = updates[curIdx].getPresentationContext(); + firstIdx = curIdx; + } + } + callProviderWithUpdate(updates, firstIdx, curIdx); + } + }); + } catch(RejectedExecutionException e) { + } + } + + private void callProviderWithUpdate(IViewerUpdate[] updates, int startIdx, int endIdx) { + final IVMProvider provider = getViewModelProvider(updates[0].getPresentationContext()); + if (provider == null) { + for (IViewerUpdate update : updates) { + update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, + "No model provider for update " + update, null)); //$NON-NLS-1$ + update.done(); + } + return; + } + if (startIdx == 0 && endIdx == updates.length) { + if (updates instanceof IHasChildrenUpdate[]) provider.update((IHasChildrenUpdate[])updates); + else if (updates instanceof IChildrenCountUpdate[]) provider.update((IChildrenCountUpdate[])updates); + else if (updates instanceof IChildrenUpdate[]) provider.update((IChildrenUpdate[])updates); + } else { + if (updates instanceof IHasChildrenUpdate[]) { + IHasChildrenUpdate[] providerUpdates = new IHasChildrenUpdate[endIdx - startIdx]; + System.arraycopy(updates, startIdx, providerUpdates, 0, endIdx - startIdx); + provider.update(providerUpdates); + } + else if (updates instanceof IChildrenCountUpdate[]) { + IChildrenCountUpdate[] providerUpdates = new IChildrenCountUpdate[endIdx - startIdx]; + System.arraycopy(updates, startIdx, providerUpdates, 0, endIdx - startIdx); + provider.update(providerUpdates); + } + else if (updates instanceof IChildrenUpdate[]) { + IChildrenUpdate[] providerUpdates = new IChildrenUpdate[endIdx - startIdx]; + System.arraycopy(updates, startIdx, providerUpdates, 0, endIdx - startIdx); + provider.update(providerUpdates); + } + } + } - for (VMProvider provider : fViewModelProviders.values()) { - provider.dispose(); - } - 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)); //$NON-NLS-1$ - result.done(); - } - provider.retrieveLabel(object, result, context.getColumns()); - } - @Override - public String toString() { return "Switch to dispatch thread to execute retrieveLabel()"; } //$NON-NLS-1$ - }); - } 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)); //$NON-NLS-1$ - result.done(); - } - provider.isContainer(element, result); - } - public String toString() { return "Switch to dispatch thread to execute isContainer()"; } //$NON-NLS-1$ - }); - } 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)); //$NON-NLS-1$ - result.done(); - } - provider.retrieveChildren(element, result); - } - public String toString() { return "Switch to dispatch thread to execute retrieveChildren()"; } //$NON-NLS-1$ - }); - } catch(RejectedExecutionException e) { - // This can happen if session is being shut down. - result.done(); - } - } - public IModelProxy createModelProxy(Object element, IPresentationContext context) { - /* - * Model proxy is the object that correlates events from the data model - * into view model deltas that the view can process. We only need to - * create a proxy for the root element of the tree. - */ - VMProvider provider = getViewModelProvider(context); - if (provider != null && - provider.getRootLayoutNode() != null && - element.equals(provider.getRootLayoutNode().getRootVMC().getInputObject())) - { - return provider.getModelProxy(); - } - return null; - } - - public String getColumnPresentationId(IPresentationContext context, Object element) { - VMProvider provider = getViewModelProvider(context); + IVMProvider provider = getViewModelProvider(context); if (provider != null) { - return provider.getColumnPresentationId(element); + return provider.createModelProxy(element, context); } return null; } public IColumnPresentation createColumnPresentation(IPresentationContext context, Object element) { - VMProvider provider = getViewModelProvider(context); + final IVMProvider provider = getViewModelProvider(context); if (provider != null) { - return provider.createColumnPresentation(element); + return provider.createColumnPresentation(context, element); } return null; } - public IColumnEditor createColumnEditor(IPresentationContext context, Object element) { - VMProvider provider = getViewModelProvider(context); + public String getColumnPresentationId(IPresentationContext context, Object element) { + final IVMProvider provider = getViewModelProvider(context); if (provider != null) { - return provider.createColumnEditor(element); + return provider.getColumnPresentationId(context, element); } return null; } - public String getColumnEditorId(IPresentationContext context, Object element) { - VMProvider provider = getViewModelProvider(context); - if (provider != null) { - return provider.getColumnEditorId(element); - } - return null; - } + } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java index 3fca9124448..2d1b36ab055 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java @@ -11,39 +11,57 @@ package org.eclipse.dd.dsf.ui.viewmodel; import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; import java.util.List; +import java.util.Map; +import java.util.concurrent.Executor; +import java.util.concurrent.RejectedExecutionException; +import org.eclipse.core.runtime.IStatus; 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.IColumnEditor; -import org.eclipse.debug.internal.ui.viewers.provisional.IColumnEditorFactoryAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactoryAdapter; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactoryAdapter; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; +import org.eclipse.jface.viewers.TreePath; /** - * + * Base implementation of the View Model layout node. + * The main functionality implemented here is for building the view model + * deltas (IModelDelta), based on the flags returned by child nodes. */ @SuppressWarnings("restriction") abstract public class AbstractVMLayoutNode implements IVMLayoutNode { - private final DsfExecutor fExecutor; + private final AbstractVMProvider fProvider; + private boolean fDisposed = false; /** Child schema nodes of this node. */ private IVMLayoutNode[] fChildNodes = new IVMLayoutNode[0]; - public AbstractVMLayoutNode(DsfExecutor executor) { - fExecutor = executor; + public AbstractVMLayoutNode(AbstractVMProvider provider) { + fProvider = provider; } /** * Accessor method for sub-classes. */ - protected DsfExecutor getExecutor() { - return fExecutor; + protected Executor getExecutor() { + return fProvider.getExecutor(); + } + + protected IVMProvider getVMProvider() { + return fProvider; } public void setChildNodes(IVMLayoutNode[] childNodes) { @@ -55,6 +73,7 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { } public void dispose() { + fDisposed = true; for (IVMLayoutNode childNode : getChildLayoutNodes()) { childNode.dispose(); } @@ -64,11 +83,12 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { * If any of the children nodes have delta flags, that means that this * node has to generate a delta as well. */ - public boolean hasDeltaFlags(Object e) { + public int getDeltaFlags(Object e) { + int retVal = 0; for (IVMLayoutNode childNode : getChildLayoutNodes()) { - if (childNode.hasDeltaFlags(e)) return true; + retVal |= childNode.getDeltaFlags(e); } - return false; + return retVal; } /** @@ -76,72 +96,159 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { * 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) { + public void buildDelta(final Object event, final VMDelta parentDelta, final int nodeOffset, final Done done) { + // Find the child nodes that have deltas for the given event. + final Map childNodeDeltas = getChildNodesWithDeltas(event); + + // If no child layout nodes have deltas we can stop here. + if (childNodeDeltas.size() == 0) { getExecutor().execute(done); return; } + + // Check if the child delta only has an IModelDelta.CONTENT or + // IModelDelta.STATE flags. If that's the case, we can skip + // creating a delta for this node, because the TreeUpdatePolicy does not + // use the full path from the delta to handle these flags. + // Similarly, the index argument is not necessary either. + boolean mustGetElements = false; + for (int childDelta : childNodeDeltas.values()) { + if ((childDelta & ~IModelDelta.CONTENT & ~IModelDelta.STATE) != 0) { + mustGetElements = true; + } + } + if (!mustGetElements) { + callChildNodesToBuildDelta(childNodeDeltas, parentDelta, event, done); + } else { + // 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. + updateElements(new ElementsUpdate( + new GetDataDone>() { + public void run() { + if (fDisposed) return; + + // Check for an empty list of elements. If it's empty then we + // don't have to call the children nodes, so return here. + // No need to propagate error, there's no means or need to display it. + if (!getStatus().isOK() || getData().size() == 0) { + getExecutor().execute(done); + return; + } + + final DoneCollector elementsDeltasDoneCollector = new DoneCollector() { + public void run() { + if (isDisposed()) return; + getExecutor().execute(done); + } + }; - /* - * 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() { - public void run() { - if (propagateError(getExecutor(), done, "Failed to retrieve elements in layout node " + AbstractVMLayoutNode.this)) return; //$NON-NLS-1$ - - /* - * Check for an empty list of elements. If it's empty then we - * don't have to call the children nodes, so return here. - */ - if (getData().length == 0) { - getExecutor().execute(done); - } - - /* - * 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()); + // For each element from this node, create a new delta, + // and then call all the child nodes to build their delta. + for (int i = 0; i < getData().size(); i++) { + VMDelta delta = parentDelta.addNode((IVMContext)getData().get(i), nodeOffset + i, IModelDelta.NO_CHANGE); + callChildNodesToBuildDelta( + childNodeDeltas, delta, event, + elementsDeltasDoneCollector.add(new Done() { + public void run() { + elementsDeltasDoneCollector.doneDone(this); + } + })); } } - } - }); + }, + parentDelta)); + } } - /** - * Default implementation of the IColumnEditorFactoryAdapter delegate. It - * returns null, which means that no cell editor is configured. - * @see IColumnEditorFactoryAdapter#createColumnEditor(IPresentationContext, Object) - */ - public IColumnEditor createColumnEditor(IVMContext vmc) { - return null; + protected void callChildNodesToBuildDelta(final Map nodes, final VMDelta delta, final Object event, final Done done) { + assert nodes.size() != 0; + + // Check if any of the child nodes are will generate IModelDelta.SELECT or + // IModelDelta.EXPAND flags. If so, we must calcuate the index for this + // VMC. + boolean calculateOffsets = false; + for (int childDelta : nodes.values()) { + if ( (childDelta & (IModelDelta.SELECT | IModelDelta.EXPAND)) != 0 ) { + calculateOffsets = true; + break; + } + } + + getChildNodesElementOffsets(delta, !calculateOffsets, new GetDataDone>() { + public void run() { + final DoneCollector childrenBuildDeltaDoneCollector = new DoneCollector() { + public void run() { + if (isDisposed()) return; + getExecutor().execute(done); + } + }; + + // Set the total count of number of children in the parent delta. + delta.setChildCount(getData().get(null)); + + for (IVMLayoutNode node : nodes.keySet()) { + node.buildDelta( + event, delta, getData().get(node), + childrenBuildDeltaDoneCollector.add(new Done() { + public void run() { + childrenBuildDeltaDoneCollector.doneDone(this); + }}) + ); + } + } + }); } - /** - * Default implementation of the IColumnEditorFactoryAdapter delegate. It - * returns null, which means that no cell editor is configured. - * @see IColumnEditorFactoryAdapter#getColumnEditorId(IPresentationContext, Object) - */ - public String getColumnEditorId(IVMContext vmc) { - return null; + private void getChildNodesElementOffsets(IModelDelta delta, boolean fakeIt, final GetDataDone> done) { + assert getChildLayoutNodes().length != 0; + + if (!fakeIt) { + final Integer[] counts = new Integer[getChildLayoutNodes().length]; + final DoneCollector childrenCountDoneCollector = new DoneCollector() { + public void run() { + if (isDisposed()) return; + if (propagateError(getExecutor(), done, "")) return; //$NON-NLS-1$ + Map data = new HashMap(); + int offset = 0; + for (int i = 0; i < getChildLayoutNodes().length; i++) { + data.put(getChildLayoutNodes()[i], offset); + offset += counts[i]; + } + // As the final value, put the total count in the return map, with null key. + data.put(null, offset); + done.setData(data); + getExecutor().execute(done); + } + }; + + for (int i = 0; i < getChildLayoutNodes().length; i++) { + final int nodeIndex = i; + getChildLayoutNodes()[i].updateElementCount( + new ElementsCountUpdate( + childrenCountDoneCollector.add(new GetDataDone() { + public void run() { + counts[nodeIndex] = getData(); + childrenCountDoneCollector.doneDone(this); + } + }), + delta) + ); + } + } else { + Map data = new HashMap(); + for (int i = 0; i < getChildLayoutNodes().length; i++) { + data.put(getChildLayoutNodes()[i], -1); + } + data.put(null, -1); + done.setData(data); + getExecutor().execute(done); + } + } + + protected boolean isDisposed() { + return fDisposed; } /** @@ -149,41 +256,173 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { * true to the hasDeltaFlags() test for the given * event. */ - protected IVMLayoutNode[] getChildNodesWithDeltas(Object e) { - List nodes = new ArrayList(); + protected Map getChildNodesWithDeltas(Object e) { + Map nodes = new HashMap(); for (final IVMLayoutNode childNode : getChildLayoutNodes()) { - if (childNode.hasDeltaFlags(e)) { - nodes.add(childNode); + int delta = childNode.getDeltaFlags(e); + if (delta != IModelDelta.NO_CHANGE) { + nodes.put(childNode, delta); } } - 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 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 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[] { "..."} ); //$NON-NLS-1$ - result.done(); + return nodes; } + /** + * Convenience method that returns a token value in case when the services + * that the layout node depends on, are not available. + */ + protected boolean checkUpdate(IViewerUpdate update) { + if (update.isCanceled()) return false; + if (fDisposed) { + handleFailedUpdate(update); + return false; + } + return true; + } + + protected void handleFailedUpdate(IViewerUpdate update) { + if (update instanceof IHasChildrenUpdate) { + ((IHasChildrenUpdate)update).setHasChilren(false); + } else if (update instanceof IChildrenCountUpdate) { + ((IChildrenCountUpdate)update).setChildCount(0); + } else if (update instanceof ILabelUpdate) { + ILabelUpdate labelUpdate = (ILabelUpdate)update; + String[] columns = labelUpdate.getPresentationContext().getColumns(); + for (int i = 0; i < (columns != null ? columns.length : 1); i++) { + labelUpdate.setLabel("...", i); //$NON-NLS-1$ + } + } + update.done(); + } + + public static class AbstractVMContext implements IVMContext { + protected final IVMAdapter fVMAdapter; + protected final IVMLayoutNode fLayoutNode; + + public AbstractVMContext(IVMAdapter adapter, IVMLayoutNode node) { + fVMAdapter = adapter; + fLayoutNode = node; + } + + public IVMLayoutNode getLayoutNode() { return fLayoutNode; } + + /** + * IAdapter implementation returns the IVMAdapter instance for the + * interfaces that are actually implemented by the VM Adapter. These + * should at least include {@link IElementContentProvider}, + * {@link IModelProxyFactoryAdapter}, and + * {@link IColumnPresentationFactoryAdapter}. + */ + @SuppressWarnings("unchecked") + public Object getAdapter(Class adapter) { + if (adapter.isInstance(fVMAdapter)) { + return fVMAdapter; + } else if (adapter.isInstance(fLayoutNode)) { + return fLayoutNode; + } + return null; + } + } + + protected class ViewerUpdate implements IViewerUpdate { + final private Done fDone; + private boolean fDoneInvoked = false; + final private TreePath fTreePath; + private IStatus fStatus; + private boolean fCancelled = false; + + public ViewerUpdate(Done done, IModelDelta delta) { + fDone = done; + List elementList = new LinkedList(); + IModelDelta listDelta = delta; + elementList.add(0, listDelta.getElement()); + while (listDelta.getParentDelta() != null) { + elementList.add(0, listDelta.getElement()); + listDelta = listDelta.getParentDelta(); + } + fTreePath = new TreePath(elementList.toArray()); + } + + public ViewerUpdate(Done done, TreePath path) { + fDone = done; + fTreePath = path; + } + + public Object getElement(TreePath path) { + // If not asking for root, just return the last segment in path. + if (path.getSegmentCount() > 0) { + return path.getLastSegment(); + } + // Calculate the root of the viewer. + return getVMProvider().getRootLayoutNode().getRootObject(); + } + + public Object getElement() { + return getElementPath().getLastSegment(); + } + + public IPresentationContext getPresentationContext() { return getVMProvider().getPresentationContext(); } + public TreePath getElementPath() { return fTreePath; } + public IStatus getStatus() { return fStatus; } + public void setStatus(IStatus status) { fStatus = status; } + public void beginTask(String name, int totalWork) {} + public void internalWorked(double work) {} + public boolean isCanceled() { return fCancelled; } + public void setCanceled(boolean value) { fCancelled = value; } + public void setTaskName(String name) {} + public void subTask(String name) {} + public void worked(int work) {} + + public void done() { + assert !fDoneInvoked; + fDoneInvoked = true; + try { + getExecutor().execute(fDone); + } catch (RejectedExecutionException e) { + } + } + } + + protected class ElementsCountUpdate extends ViewerUpdate implements IChildrenCountUpdate { + private final GetDataDone fDone; + + public ElementsCountUpdate(GetDataDone done, IModelDelta delta) { + super(done, delta); + fDone = done; + } + + public void setChildCount(int numChildren) { + fDone.setData(numChildren); + } + } + + protected class ElementsUpdate extends ViewerUpdate implements IChildrenUpdate { + private final List fChildren = new ArrayList(); + private GetDataDone> fDone; + + public ElementsUpdate(GetDataDone> done, IModelDelta delta) { + super(done, delta); + fDone = done; + fDone.setData(fChildren); + } + + public ElementsUpdate(GetDataDone> done, TreePath path) { + super(done, path); + fDone = done; + fDone.setData(fChildren); + } + + public int getOffset() { + return -1; + } + + public int getLength() { + return -1; + } + + public void setChild(Object child, int offset) { + fChildren.add(offset, child); + } + } + } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java new file mode 100644 index 00000000000..821b1e1184c --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java @@ -0,0 +1,648 @@ +/******************************************************************************* + * 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.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Executor; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.atomic.AtomicReference; + +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.IDsfService; +import org.eclipse.dd.dsf.ui.DsfUIPlugin; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactoryAdapter; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; +import org.eclipse.debug.internal.ui.viewers.provisional.AbstractModelProxy; +import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousContentAdapter; +import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousLabelAdapter; +import org.eclipse.debug.internal.ui.viewers.provisional.IColumnEditorFactoryAdapter; +import org.eclipse.jface.viewers.TreePath; +import org.eclipse.jface.viewers.Viewer; + +/** + * 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. + *

    + * 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("getVMAdapter#getExecutor") +@SuppressWarnings("restriction") +abstract public class AbstractVMProvider implements IVMProvider +{ + private final AbstractVMAdapter fVMAdapter; + private final IPresentationContext fPresentationContext; + private final ModelProxy fModelProxy = new ModelProxy(); + private boolean fDisposed = false; + + /** + * The root node for this model provider. The root layout node could be + * null when first created, to allow sub-classes to prorperly configure the + * root node in the sub-class constructor. + */ + private AtomicReference fRootLayoutNodeRef = new AtomicReference(); + + /** + * Constructs the view model provider for given DSF session. The + * constructor is thread-safe to allow VM provider to be constructed + * synchronously when a call to getAdapter() is made on an element + * in a view. + */ + public AbstractVMProvider(AbstractVMAdapter adapter, IPresentationContext presentationContext) { + fVMAdapter = adapter; + fPresentationContext = presentationContext; + } + + public IVMAdapter getVMAdapter() { + return fVMAdapter; + } + + public IPresentationContext getPresentationContext() { + return fPresentationContext; + } + + /** + * Sets the root node for this provider. + */ + @ThreadSafe + protected void setRootLayoutNode(IVMRootLayoutNode rootLayoutNode) { + final IVMRootLayoutNode oldRootLayoutNode = fRootLayoutNodeRef.getAndSet(rootLayoutNode); + if (oldRootLayoutNode != null) { + oldRootLayoutNode.dispose(); + } + } + + protected ModelProxy getModelProxy() { + return fModelProxy; + } + + @ThreadSafe + public IVMRootLayoutNode getRootLayoutNode() { + return fRootLayoutNodeRef.get(); + } + + /** Called to dispose the provider. */ + public void dispose() { + fDisposed = true; + if (fRootLayoutNodeRef.get() != null) { + fRootLayoutNodeRef.get().dispose(); + } + } + + protected boolean isDisposed() { + return fDisposed; + } + + /** + * Convenience method to access the View Model's executor. + */ + public Executor getExecutor() { return fVMAdapter.getExecutor(); } + + + public void update(IHasChildrenUpdate[] updates) { + // Sort the updates by the layout node. + Map> nodeUpdatesMap = new HashMap>(); + for (IHasChildrenUpdate update : updates) { + // Get the VM Context for last element in path. + IVMLayoutNode layoutNode = getLayoutNodeObject(update.getElement()); + if (layoutNode == null) { + // Stale update, most likely as a result of the layout nodes being + // changed. Just ignore it. + if (!update.isCanceled()) update.done(); + continue; + } + if (!nodeUpdatesMap.containsKey(layoutNode)) { + nodeUpdatesMap.put(layoutNode, new ArrayList()); + } + nodeUpdatesMap.get(layoutNode).add(update); + } + + // Iterate through the nodes in the sorted map. + for (IVMLayoutNode node : nodeUpdatesMap.keySet()) { + updateNode(node, nodeUpdatesMap.get(node).toArray(new IHasChildrenUpdate[nodeUpdatesMap.get(node).size()])); + } + } + + private void updateNode(IVMLayoutNode node, final IHasChildrenUpdate[] updates) { + // If parent element's layout node has no children, just set the + // result and coninue to next element. + if (node.getChildLayoutNodes().length == 0) { + for (IHasChildrenUpdate update : updates) { + update.setHasChilren(false); + } + return; + } + + HasElementsUpdate[][] elementsUpdates = + new HasElementsUpdate[node.getChildLayoutNodes().length][updates.length]; + for (int i = 0; i < updates.length; i ++) + { + final IHasChildrenUpdate update = updates[i]; + for (int j = 0; j < node.getChildLayoutNodes().length; j++) + { + final DoneCollector> hasChildrenDoneCollector = + new DoneCollector>() { + public void run() { + // Status is OK, only if all dones are OK. + if (getStatus().isOK()) { + boolean isContainer = false; + for (GetDataDone hasElementsDone : getDones().keySet()) { + isContainer |= hasElementsDone.getStatus().isOK() && + hasElementsDone.getData().booleanValue(); + } + update.setHasChilren(isContainer); + update.done(); + } + } + }; + + elementsUpdates[j][i] = new HasElementsUpdate( + update, + hasChildrenDoneCollector.add(new GetDataDone() { + public void run() { + hasChildrenDoneCollector.doneDone(this); + } + })); + } + } + + for (int j = 0; j < node.getChildLayoutNodes().length; j++) { + node.getChildLayoutNodes()[j].updateHasElements(elementsUpdates[j]); + } + } + + + public void update(final IChildrenCountUpdate[] updates) { + for (final IChildrenCountUpdate update : updates) { + if (update.isCanceled()) continue; + + getChildrenCountsForNode( + update, update.getElementPath(), + new GetDataDone() { + public void run() { + if (getStatus().isOK()) { + int numChildren = 0; + for (Integer count : getData()) { + numChildren += count.intValue(); + } + update.setChildCount(numChildren); + } else { + update.setChildCount(0); + } + update.done(); + } + }); + } + } + + public void update(IChildrenUpdate[] updates) { + for (final IChildrenUpdate update : updates) { + getChildrenCountsForNode( + update, update.getElementPath(), + new GetDataDone() { + public void run() { + if (!getStatus().isOK()) { + update.done(); + return; + } + updateChildrenWithCounts(update, getData()); + } + }); + } + } + + + private void getChildrenCountsForNode(IViewerUpdate update, TreePath elementPath, final GetDataDone done) { + if (isDisposed()) return; + + // Get the VM Context for last element in path. + final IVMLayoutNode layoutNode = getLayoutNodeObject(update.getElement()); + if (layoutNode == null) { + // Stale update. Just ignore. + done.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, + "Stale update.", null)); //$NON-NLS-1$ + getExecutor().execute(done); + return; + } + + IVMLayoutNode[] childNodes = layoutNode.getChildLayoutNodes(); + + // If parent element's layout node has no children, just mark done and + // return. + if (childNodes.length == 0) { + done.setData(new Integer[0]); + getExecutor().execute(done); + return; + } + + + // Get the mapping of all the counts. + final Integer[] counts = new Integer[childNodes.length]; + final DoneCollector childrenCountDoneCollector = + new DoneCollector() { + public void run() { + if (fDisposed) return; + if (propagateError(getExecutor(), done, "")) return; //$NON-NLS-1$ + done.setData(counts); + getExecutor().execute(done); + } + }; + + for (int i = 0; i < childNodes.length; i++) { + final int nodeIndex = i; + childNodes[i].updateElementCount( + new ElementsCountUpdate( + update, + childrenCountDoneCollector.add(new GetDataDone() { + public void run() { + if (getStatus().isOK()) { + assert getData() != null; + counts[nodeIndex] = getData(); + } + childrenCountDoneCollector.doneDone(this); + } + }), + elementPath) + ); + } + } + + private void updateChildrenWithCounts(final IChildrenUpdate update, Integer[] nodeElementCounts) { + final IVMLayoutNode layoutNode = getLayoutNodeObject(update.getElement()); + if (layoutNode == null) { + // Stale update. Just ignore. + if (!update.isCanceled()) update.done(); + } + + // Create the done collector to mark update when querying all children nodes is finished. + final DoneCollector elementsDoneCollector = + new DoneCollector() { + public void run() { + if (!update.isCanceled()) update.done(); + } + }; + + // Iterate through all child nodes and if requested range matches, call them to + // get their elements. + int updateStartIdx = update.getOffset(); + int updateEndIdx = update.getOffset() + update.getLength(); + int idx = 0; + IVMLayoutNode[] layoutNodes = layoutNode.getChildLayoutNodes(); + for (int i = 0; i < layoutNodes.length; i++) { + final int nodeStartIdx = idx; + final int nodeEndIdx = idx + nodeElementCounts[i]; + idx = nodeEndIdx; + + // Check if update range overlaps the node's range. + if (updateStartIdx <= nodeEndIdx && updateEndIdx > nodeStartIdx) { + final int elementsStartIdx = Math.max(updateStartIdx - nodeStartIdx, 0); + final int elementsEndIdx = Math.min(updateEndIdx - nodeStartIdx, nodeElementCounts[i]); + + layoutNodes[i].updateElements( + new ElementsUpdate( + update, + elementsDoneCollector.add(new Done() { + public void run() { + elementsDoneCollector.doneDone(this); + } + }), + nodeStartIdx, elementsStartIdx, elementsEndIdx - elementsStartIdx) + ); + } + } + + // Guard against invalid queries. + if (elementsDoneCollector.getDones().isEmpty()) { + update.done(); + } + + } + + public ModelProxy createModelProxy(Object element, IPresentationContext context) { + /* + * Model proxy is the object that correlates events from the data model + * into view model deltas that the view can process. We only need to + * create a proxy for the root element of the tree. + */ + if (getRootLayoutNode() != null && + element.equals(getRootLayoutNode().getRootObject())) + { + return fModelProxy; + } + return null; + } + + /** + * Creates the column presentation for the given object. This method is meant + * to be overriden by deriving class to provide view-specific functionality. + * The default is to return null, meaning no columns. + *

    + * The viewer only reads the column presentation for the root/input element of + * the tree/table, so the VMProvider must be configured to own the root element + * in the view in order for this setting to be effective. + *

    + * Note: since the IColumnEditorFactoryAdapter interface is synchronous, and since + * column info is fairly static, this method is thread-safe, and it will + * not be called on the executor thread. + * + * @see IColumnPresentationFactoryAdapter#createColumnPresentation(IPresentationContext, Object) + */ + public IColumnPresentation createColumnPresentation(IPresentationContext context, Object element) { + return null; + } + + /** + * Returns the ID of the column presentation for the given object. This method + * is meant to be overriden by deriving class to provide view-specific + * functionality. The default is to return null, meaning no columns. + *

    + * The viewer only reads the column presentation for the root/input element of + * the tree/table, so the VMProvider must be configured to own the root element + * in the view in order for this setting to be effective. + *

    + * Note: since the IColumnEditorFactoryAdapter interface is synchronous, and since + * column info is fairly static, this method is thread-safe, and it will + * not be called on the executor thread. + * + * @see IColumnEditorFactoryAdapter#getColumnEditorId(IPresentationContext, Object) + */ + public String getColumnPresentationId(IPresentationContext context, Object element) { + return null; + } + + + /** + * 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 IVMLayoutNode getLayoutNodeObject(Object element) { + /* + * First check to see if the parent object is the root object of the + * hierarchy. If that's the case, then retrieve the correcponding + * root VMC from the root node, and pass this root vmc to the root's + * child layout nodes. + */ + IVMRootLayoutNode rootLayoutNode = getRootLayoutNode(); + if (rootLayoutNode == null) { + return null; + } + else if (element.equals(rootLayoutNode.getRootObject())) { + return rootLayoutNode; + } + else if (element instanceof IVMContext){ + /* + * 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)element).getLayoutNode(), + new IVMLayoutNode[] { rootLayoutNode } )) + { + return ((IVMContext)element).getLayoutNode(); + } + } + 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; + } + + /** + * 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) { + IVMRootLayoutNode rootLayoutNode = getRootLayoutNode(); + + if (rootLayoutNode != null && rootLayoutNode.getDeltaFlags(event) != 0) { + rootLayoutNode.createDelta(event, new GetDataDone() { + public void run() { + if (getStatus().isOK()) { + fModelProxy.fireModelChangedNonDispatch(getData()); + } + } + @Override public String toString() { + return "Result of a delta for event: '" + event.toString() + "' in VMP: '" + AbstractVMProvider.this + "'" + "\n" + getData().toString(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } + }); + } + } + + @ThreadSafe + protected class ModelProxy extends AbstractModelProxy { + /** + * Counter for whether the model proxy is currently installed in the viewer. + * Data model events are processed only if the model proxy is active. + */ + private int fProxyActive = 0; + + /** + * Scheduling rule for running the update jobs. + */ + private ISchedulingRule fModelChangeRule = new ISchedulingRule() { + public boolean contains(ISchedulingRule rule) { return this == rule; } + public boolean isConflicting(ISchedulingRule rule) { return rule == this; } + }; + + public void installed(Viewer viewer) { + 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(); + } + + } + + class ViewerUpdate implements IViewerUpdate { + private IStatus fStatus; + private boolean fDoneInvoked = false; + final private Done fDone; + final protected IViewerUpdate fClientUpdate; + + public ViewerUpdate(IViewerUpdate clientUpdate, Done done) { + fDone = done; + fClientUpdate = clientUpdate; + } + + public Object getElement() { return fClientUpdate.getElement(); } + public TreePath getElementPath() { return fClientUpdate.getElementPath(); } + public IPresentationContext getPresentationContext() { return fClientUpdate.getPresentationContext(); } + + public IStatus getStatus() { return fStatus; } + public void setStatus(IStatus status) { fStatus = status; } + public void beginTask(String name, int totalWork) {} + public void internalWorked(double work) {} + public boolean isCanceled() { return fClientUpdate.isCanceled(); } + public void setCanceled(boolean value) { fClientUpdate.setCanceled(value); } + public void setTaskName(String name) {} + public void subTask(String name) {} + public void worked(int work) {} + + public void done() { + assert !fDoneInvoked; + fDoneInvoked = true; + try { + getExecutor().execute(fDone); + } catch (RejectedExecutionException e) { // Ignore + } + } + + } + + class HasElementsUpdate extends ViewerUpdate implements IHasChildrenUpdate { + + final private GetDataDone fDone; + + HasElementsUpdate(IHasChildrenUpdate clientUpdate, GetDataDone done) { + super(clientUpdate, done); + fDone = done; + } + + public TreePath getElementPath() { + return ((IHasChildrenUpdate)fClientUpdate).getElementPath(); + } + + public void setHasChilren(boolean hasChildren) { + fDone.setData(hasChildren); + } + + public void done() { + assert fDone.getData() != null || !fDone.getStatus().isOK(); + super.done(); + } + } + + class ElementsCountUpdate extends ViewerUpdate implements IChildrenCountUpdate { + final private GetDataDone fDone; + final private TreePath fElementPath; + + ElementsCountUpdate(IViewerUpdate clientUpdate, GetDataDone done, TreePath elementPath) { + super(clientUpdate, done); + fElementPath = elementPath; + fDone = done; + } + + public TreePath getElementPath() { + return fElementPath; + } + + public void setChildCount(int count) { + fDone.setData(count); + } + + public void done() { + assert fDone.getData() != null || !fDone.getStatus().isOK(); + super.done(); + } + + } + + class ElementsUpdate extends ViewerUpdate implements IChildrenUpdate { + private final int fClientOffset; + private final int fOffset; + private final int fLength; + + ElementsUpdate(IChildrenUpdate clientUpdate, Done done, int clientOffset, int offset, int length) { + super(clientUpdate, done); + fClientOffset = clientOffset; + fOffset = offset; + fLength = length; + } + + public int getOffset() { + return fOffset; + } + + public int getLength() { + return fLength; + } + + public TreePath getElementPath() { + return ((IChildrenUpdate)fClientUpdate).getElementPath(); + } + + public void setChild(Object child, int offset) { + if (offset >= fOffset && offset < (fOffset + fLength)) { + ((IChildrenUpdate)fClientUpdate).setChild(child, fClientOffset + offset); + } + } + + } +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMRootLayoutNode.java index baacc1cfc7c..53d5650d917 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMRootLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMRootLayoutNode.java @@ -10,12 +10,15 @@ *******************************************************************************/ 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 java.util.Map; + +import org.eclipse.dd.dsf.concurrent.Done; import org.eclipse.dd.dsf.concurrent.GetDataDone; -import org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; /** * @@ -23,44 +26,8 @@ import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; @SuppressWarnings("restriction") abstract public class AbstractVMRootLayoutNode extends AbstractVMLayoutNode implements IVMRootLayoutNode { - protected static class RootVMC 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; } - - @SuppressWarnings("unchecked") - 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(); } //$NON-NLS-1$ - } - - public AbstractVMRootLayoutNode(DsfExecutor executor) { - super(executor); + public AbstractVMRootLayoutNode(AbstractVMProvider provider) { + super(provider); } /** @@ -68,9 +35,20 @@ abstract public class AbstractVMRootLayoutNode extends AbstractVMLayoutNode impl * There is no use case for a root node implementing this method, but its * easier to just impelemnt it for sake of uniformity of model. */ - public void getElements(IVMContext parentVmc, GetDataDone done) { - done.setData(new IVMContext[] { getRootVMC() }); - getExecutor().execute(done); + public void updateElements(IChildrenUpdate update) { + // Ignore startIdx, endIdx, since there's only one element to be had. + update.setChild(getRootObject(), 0); + update.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 updateElementCount(IChildrenCountUpdate update) { + update.setChildCount(1); + update.done(); } /** @@ -78,9 +56,11 @@ abstract public class AbstractVMRootLayoutNode extends AbstractVMLayoutNode impl * There is no use case for a root node implementing this method, but its * easier to just impelemnt it for sake of uniformity of model. */ - public void hasElements(IVMContext parentVmc, GetDataDone done) { - done.setData(true); - getExecutor().execute(done); + public void updateHasElements(IHasChildrenUpdate[] updates) { + for (IHasChildrenUpdate update : updates) { + update.setHasChilren(true); + update.done(); + } } /** @@ -88,8 +68,8 @@ abstract public class AbstractVMRootLayoutNode extends AbstractVMLayoutNode impl * There is no use case for a root node implementing this method, but its * easier to just impelemnt it for sake of uniformity of model. */ - public void retrieveLabel(IVMContext vmc, ILabelRequestMonitor result, String[] columns) { - result.done(); + public void updateLabel(IVMContext vmc, ILabelUpdate update) { + update.done(); } /** @@ -97,28 +77,21 @@ abstract public class AbstractVMRootLayoutNode extends AbstractVMLayoutNode impl * is the input object into the view. */ public void createDelta(Object event, final GetDataDone done) { - final VMDelta rootDelta = new VMDelta(getRootVMC().getInputObject(), getRootVMC()); + final Map childNodeDeltas = getChildNodesWithDeltas(event); + assert childNodeDeltas.size() != 0 : "Caller should make sure that there are deltas for given event."; //$NON-NLS-1$ - final IVMLayoutNode[] childNodes = getChildNodesWithDeltas(event); - if (childNodes.length == 0) { - done.setData(rootDelta); - getExecutor().execute(done); - return; - } + // Always create the rootDelta, no matter what delta flags the child nodes have. + final VMDelta rootDelta = new VMDelta(getRootObject(), IModelDelta.NO_CHANGE); - /* - * 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; //$NON-NLS-1$ - done.setData(rootDelta); - getExecutor().execute(done); - } - }; - for (final IVMLayoutNode childNode : childNodes) { - childNode.buildDelta(event, rootDelta, doneCollector.addNoActionDone()); - } + callChildNodesToBuildDelta( + childNodeDeltas, rootDelta, event, + new Done() { + public void run() { + if (isDisposed()) return; + if (propagateError(getExecutor(), done, "Failed to create delta.")); //$NON-NLS-1$ + done.setData(rootDelta); + getExecutor().execute(done); + } + }); } } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java deleted file mode 100644 index eefeebaa56f..00000000000 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DMContextVMLayoutNode.java +++ /dev/null @@ -1,360 +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.viewmodel; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.concurrent.Done; -import org.eclipse.dd.dsf.concurrent.DoneCollector; -import org.eclipse.dd.dsf.concurrent.GetDataDone; -import org.eclipse.dd.dsf.concurrent.Immutable; -import org.eclipse.dd.dsf.datamodel.DMContexts; -import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.datamodel.IDMData; -import org.eclipse.dd.dsf.datamodel.IDMEvent; -import org.eclipse.dd.dsf.datamodel.IDMService; -import org.eclipse.dd.dsf.service.DsfServicesTracker; -import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; -import org.eclipse.dd.dsf.ui.DsfUIPlugin; -import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode.IRootVMC; -import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousLabelAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentationFactoryAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.graphics.RGB; - - -/** - * 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; } - - /** - * The IAdaptable implementation. If the adapter is the DM context, - * return the context, otherwise delegate to IDMContext.getAdapter(). - */ - @SuppressWarnings("unchecked") - public Object getAdapter(Class adapter) { - if (adapter.isInstance(fDmc)) { - return fDmc; - } else { - return fDmc.getAdapter(adapter); - } - } - - public boolean equals(Object other) { - if (!(other instanceof DMContextVMLayoutNode.DMContextVMContext)) return false; - DMContextVMLayoutNode.DMContextVMContext otherVmc = (DMContextVMLayoutNode.DMContextVMContext)other; - return DMContextVMLayoutNode.this.equals(otherVmc.getLayoutNode()) && - fParent.equals(otherVmc.fParent) && - fDmc.equals(otherVmc.fDmc); - } - - public int hashCode() { - return DMContextVMLayoutNode.this.hashCode() + fParent.hashCode() + fDmc.hashCode(); - } - - public String toString() { - return fParent.toString() + "->" + fDmc.toString(); //$NON-NLS-1$ - } - } - - /** Service tracker to be used by sub-classes */ - private DsfServicesTracker fServices; - - private DsfSession fSession; - - /** - * Concrete class type that the elements of this schema node are based on. - * Even though the data model type is a parameter the DMContextVMLayoutNode, - * this type is erased at runtime, so a concrete class typs of the DMC - * is needed for instanceof chacks. - */ - private Class> 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> dmcClassType) { - super(session.getExecutor()); - fSession = session; - fServices = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), session.getId()); - fDMCClassType = dmcClassType; - } - - /** - * Returns the session for use by sub-classes. - */ - protected DsfSession getSession() { - return fSession; - } - - /** - * Returns the services tracker for sub-class use. - */ - protected DsfServicesTracker getServicesTracker() { - return fServices; - } - - /** - * The default implementation of the retrieve label method. It acquires - * the service, using parameters in the DMC, then it fetches the model - * data from the service, and then it calls the protected method - * fillColumnLabel() for each column. The deriving classes should override - * this method if a different method of computing the label is needed. - * - * @see #fillColumnLabel(IDMData, String, int, String[], ImageDescriptor[], FontData[], RGB[], RGB[]) - */ - @SuppressWarnings("unchecked") - public void retrieveLabel(IVMContext vmc, final ILabelRequestMonitor result, final String[] columns) { - /* - * Extract the DMContext from the VMContext, see DMContextVMContext.getAdapter(). - * Since the VMContext is supplied by this node, the DMContext should never be null. - * Note: had to suppress type cast warnings here, because getAdapter() does not support - * generics, and even if it did, I'm not sure it would help. - */ - final IDMContext dmc = (IDMContext)(vmc).getAdapter(IDMContext.class); - if (dmc == null) { - assert false; - result.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Invalid VMC type", null)); //$NON-NLS-1$ - result.done(); - return; - } - - /* - * Get the instance of the service using the service filter in the DMContext - * If null it could mean that the service already shut down, and the view - * is holding stale elements which will be cleaned up shortly. - */ - IDMService dmService = (IDMService)getServicesTracker().getService(null, dmc.getServiceFilter()); - if (dmService == null) { - handleFailedRetrieveLabel(result); - return; - } - - dmService.getModelData( - dmc, - new GetDataDone() { - public void run() { - /* - * Check that the request was evaluated and data is still - * valid. The request could fail if the state of the - * service changed during the request, but the view model - * has not been updated yet. - */ - if (!getStatus().isOK() || !getData().isValid()) { - assert getStatus().isOK() || - getStatus().getCode() != IDsfService.INTERNAL_ERROR || - getStatus().getCode() != IDsfService.NOT_SUPPORTED; - handleFailedRetrieveLabel(result); - return; - } - - /* - * If columns are configured, call the protected methods to - * fill in column values. - */ - String[] localColumns = columns; - if (localColumns == null) localColumns = new String[] { null }; - - String[] text = new String[localColumns.length]; - ImageDescriptor[] image = new ImageDescriptor[localColumns.length]; - FontData[] fontData = new FontData[localColumns.length]; - RGB[] foreground = new RGB[localColumns.length]; - RGB[] background = new RGB[localColumns.length]; - for (int i = 0; i < localColumns.length; i++) { - fillColumnLabel(dmc, getData(), localColumns[i], i, text, image, fontData, foreground, background); - } - result.setLabels(text); - result.setImageDescriptors(image); - result.setFontDatas(fontData); - result.setBackgrounds(background); - result.setForegrounds(foreground); - result.done(); - } - }); - } - - /** - * Fills in label information for given column. This method is intended to - * be overriden by deriving classes, to supply label information specific - * to the node.
    - * The implementation should fill in the correct value in each array at the - * given index. - * @param dmContext Data Model Context object for which the label is generated. - * @param dmData Data Model Data object retrieved from the model service. - * for the DM Context supplied to the retrieveLabel() call. - * @param columnId Name of the column to fill in, null if no columns specified. - * @param idx Index to fill in in the label arrays. - * @param text - * @param image - * @param fontData - * @param foreground - * @param background - * - * @see IAsynchronousLabelAdapter - * @see IColumnPresentationFactoryAdapter - */ - protected void fillColumnLabel(IDMContext dmContext, V dmData, String columnId, int idx, String[] text, - ImageDescriptor[] image, FontData[] fontData, RGB[] foreground, RGB[] background ) - { - text[idx] = ""; //$NON-NLS-1$ - } - - @Override - public boolean hasDeltaFlags(Object e) { - if (e instanceof IDMEvent) { - 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 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 findDmcInVmc(IVMContext vmc, Class 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 dispose() { - fServices.dispose(); - super.dispose(); - } -} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMAdapter.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMAdapter.java new file mode 100644 index 00000000000..2d1c9dfaa05 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMAdapter.java @@ -0,0 +1,19 @@ +package org.eclipse.dd.dsf.ui.viewmodel; + +import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactoryAdapter; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactoryAdapter; + +/** + * The View Model adapter handles the layout of a given data model within a + * set of viewers. This adapter should be returned by an adapter factory for + * the input object of the viewer, and this adapter implementation will then + * populate the view contents. + */ +@ThreadSafe +@SuppressWarnings("restriction") +public interface IVMAdapter + extends IElementContentProvider, IModelProxyFactoryAdapter, IColumnPresentationFactoryAdapter +{ +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMContext.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMContext.java index 9c31035105a..aeacc41e922 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMContext.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMContext.java @@ -14,7 +14,7 @@ import org.eclipse.core.runtime.IAdaptable; import org.eclipse.dd.dsf.concurrent.Immutable; /** - * View model element which is stored as the data object of nodes in the viewer. + * View Model element which is stored as the data object of nodes in the viewer. */ @Immutable public interface IVMContext extends IAdaptable { @@ -23,10 +23,4 @@ public interface IVMContext extends IAdaptable { * Returns the layout node that originated this element. */ public IVMLayoutNode getLayoutNode(); - - /** - * Returns the parent of this element in the viewer layout. - * @return - */ - public IVMContext getParent(); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMLayoutNode.java index 0d2d3f3014f..883d0e23d0d 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMLayoutNode.java @@ -12,55 +12,67 @@ 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.concurrent.ThreadSafeAndProhibitedFromDsfExecutor; -import org.eclipse.debug.internal.ui.viewers.provisional.IColumnEditor; -import org.eclipse.debug.internal.ui.viewers.provisional.IColumnEditorFactoryAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; /** * 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. + * define the layout of a view. Each layout node generates elements of type + * IVMContext which are then stored in the viewer. *

    * 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 VMProvider + * @see AbstractDMVMProvider */ @ConfinedToDsfExecutor("") @SuppressWarnings("restriction") -public interface IVMLayoutNode { +public interface IVMLayoutNode +{ /** - * Retrieves information whether for the given parent node, there are any elements - * available. - * @param parentVmc Parent node, for which to calculate elements at the - * current level. - * @param done The data return token. + * Retrieves information whether for a given path in the viewer, + * there are any elements available in this node. + * + * @param updates The update objects which need to be filled in with results + * calculated by this method. + * Even though the "children" interface is reused, the updates refer to the + * elements of this layout node, and not it's children. */ - public void hasElements(IVMContext parentVmc, GetDataDone done); - - /** - * Retrieves the list of elements. - * @param parentVmc Parent node, for which to calculate elements at the - * current level. - * @param done The data return token. - */ - public void getElements(IVMContext parentVmc, GetDataDone done); - - /** - * Retrieves the label for the given element. - * @param vmc Element for which to retrieve label information. - * @param result Monitor which accepts the data. - * @param columns Currently configured columns in view. - * @see IPresentationContext - */ - public void retrieveLabel(IVMContext vmc, ILabelRequestMonitor result, String[] columns); + public void updateHasElements(IHasChildrenUpdate[] updates); + /** + * Retrieves the number of available elements in this node for the given + * path in the viewer. + * + * @param updates The update object which needs to be filled in with result + * calculated by this method. + * Even though the "children" interface is reused, the updates refer to the + * elements of this layout node, and not it's children. + */ + public void updateElementCount(IChildrenCountUpdate update); + + + /** + * Retrieves the element objects of this node for the given path in the + * viewer, and for the given range of indexes.
    + * Note: the range of children, denoted by ILabelUpdate.getOffset() + * and ILabelUpdate.getLength(), may not be specified, in which case these + * methods may return -1. This means that all the elements should be + * retrieved for this node.
    + * + * @param updates The update object which needs to be filled in with result + * calculated by this method. + * Even though the "children" interface is reused, the updates refer to the + * elements of this layout node, and not it's children. + */ + public void updateElements(IChildrenUpdate update); + + /** * Configures the child layout nodes for this node. * @param childNodes @@ -73,51 +85,28 @@ public interface IVMLayoutNode { public IVMLayoutNode[] getChildLayoutNodes(); /** - * Returns true/false indicating whether the given even will cause this - * schema node to generate a model delta. + * Returns the potential delta flags that would be generated by this node + * for the given event. * @param event Event to process. - * @return True if this node (or its children) would generate delta data - * due to this event. + * @return IModelDelta flags * @see IModelDelta */ - public boolean hasDeltaFlags(Object event); + public int getDeltaFlags(Object event); /** * Builds model delta information based on the given event. * @param event Event to process. * @param parent Parent model delta node that this object should add delta * data to. + * @param nodeOffset The offset of the first element in this node. This offset + * depends on the elements returned by the siblings of this layout node. * @param done Return token, which notifies the caller that the calculation is * complete. */ - public void buildDelta(Object event, VMDelta parent, Done done); + public void buildDelta(Object event, VMDelta parent, int nodeOffset, Done done); /** - * Creates a column editor for the given element. The interface that this - * method is delegated to is synchronous, therefore it also needs to be thread - * safe. - * - * @see IColumnEditorFactoryAdapter#createColumnEditor(IPresentationContext, Object) - * @param vmc VM Context to return the editor for - * @return - */ - @ThreadSafeAndProhibitedFromDsfExecutor("") - public IColumnEditor createColumnEditor(IVMContext vmc); - - /** - * Returns the ID of the editor for the given element. The interface that this - * method is delegated to is synchronous, therefore it also needs to be thread - * safe. - * - * @see IColumnEditorFactoryAdapter#getColumnEditorId(IPresentationContext, Object) - * @param vmc VM Context to return the editor ID for - * @return - */ - @ThreadSafeAndProhibitedFromDsfExecutor("") - public String getColumnEditorId(IVMContext vmc); - - /** - * Disposes the resources held by this node. + * Releases the resources held by this node. */ public void dispose(); } \ No newline at end of file diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java new file mode 100644 index 00000000000..44b2a3e6504 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java @@ -0,0 +1,40 @@ +package org.eclipse.dd.dsf.ui.viewmodel; + +import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactoryAdapter; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactoryAdapter; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; + +/** + * The View Model Provider handles the layout of a given model within a + * single viewer. The View Model Adapter delegates calls for view content to + * this object for a view that this provider handles. + */ +@ThreadSafe +@SuppressWarnings("restriction") +public interface IVMProvider + extends IElementContentProvider, IModelProxyFactoryAdapter, IColumnPresentationFactoryAdapter +{ + /** + * Returns the View Model Adapter that this provider belongs to. + */ + public IVMAdapter getVMAdapter(); + + /** + * Returns the root layout node that is configured in this provider. + * It may return null, if a root node is not yet configured. + */ + public IVMRootLayoutNode getRootLayoutNode(); + + /** + * Returns the presentation context of the viewer that this provider + * is configured for. + */ + public IPresentationContext getPresentationContext(); + + /** + * Cleans up the resources associated with this provider. + */ + public void dispose(); +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMRootLayoutNode.java index 251d74c7574..500ff56c64f 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMRootLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMRootLayoutNode.java @@ -11,7 +11,7 @@ package org.eclipse.dd.dsf.ui.viewmodel; import org.eclipse.dd.dsf.concurrent.GetDataDone; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; /** * Special type of the view model layout node, which can be used as a root node @@ -21,28 +21,13 @@ import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; @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(); + public Object getRootObject(); /** * Version of the {@link IVMLayoutNode#buildDelta(Object, ViewModelDelta, org.eclipse.dd.dsf.concurrent.Done)} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java index 09c2c953bd2..6c524768b3f 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java @@ -11,8 +11,9 @@ *******************************************************************************/ 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; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDeltaVisitor; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; /** * This delta class mostly just duplicates the ModelDelta implemention, but @@ -25,13 +26,13 @@ import org.eclipse.debug.internal.ui.viewers.provisional.ModelDelta; public class VMDelta extends ModelDelta { private VMDelta fParent; - private IVMContext fVmcElement; private Object fElement; private int fFlags; private VMDelta[] fNodes = EMPTY_NODES; private Object fReplacement; private int fIndex; private static final VMDelta[] EMPTY_NODES = new VMDelta[0]; + private int fChildCount = -1; /** * Constructs a new delta for the given element. @@ -39,9 +40,9 @@ public class VMDelta extends ModelDelta { * @param vmcElement model element * @param flags change flags */ - public VMDelta(IVMContext vmcElement, int flags) { - super(vmcElement, flags); - fVmcElement = vmcElement; + public VMDelta(Object element, int flags) { + super(element, flags); + fElement = element; fFlags = flags; } @@ -53,9 +54,9 @@ public class VMDelta extends ModelDelta { * @param replacement replacement element * @param flags change flags */ - public VMDelta(IVMContext vmcElement, Object replacement, int flags) { - super(vmcElement, replacement, flags); - fVmcElement = vmcElement; + public VMDelta(Object element, Object replacement, int flags) { + super(element, replacement, flags); + fElement = element; fReplacement = replacement; fFlags = flags; } @@ -68,40 +69,44 @@ public class VMDelta extends ModelDelta { * @param index insertion position * @param flags change flags */ - public VMDelta(IVMContext vmcElement, int index, int flags) { - super(vmcElement, index, flags); - fVmcElement = vmcElement; + public VMDelta(Object element, int index, int flags) { + super(element, index, flags); + fElement = element; fIndex = index; fFlags = flags; } /** - * Constructor for model delta based on non-VMC element. This delta is - * only needed for creating delta nodes for parent elements in the tree - * if the VMC elements are not at the root of the tree. - * @param element Element to create the delta for. - * @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. + * Constructs a new delta for the given element at the specified index + * relative to its parent with the given number of children. + * + * @param element model element + * @param index insertion position + * @param flags change flags + * @param childCount number of children this node has */ - public VMDelta(Object element, IVMContext vmcElement) { - super(element, IModelDelta.NO_CHANGE); + public VMDelta(Object element, int index, int flags, int childCount) { + super(element, index, flags, childCount); fElement = element; - fVmcElement = vmcElement; + fIndex = index; + fFlags = flags; + fChildCount = childCount; } - /** * Returns the non-VMC element if one is set, otherwise returns the VMC * element of this delta node. * @see org.eclipse.debug.internal.ui.viewers.IModelDelta#getElement() */ + @Override public Object getElement() { - return fElement != null ? fElement : fVmcElement; + return fElement; } /* (non-Javadoc) * @see org.eclipse.debug.internal.ui.viewers.IModelDelta#getFlags() */ + @Override public int getFlags() { return fFlags; } @@ -110,7 +115,9 @@ public class VMDelta extends ModelDelta { fFlags |= flags; } - public IVMContext getVMC() { return fVmcElement; } + public void setChildCount(int count) { + fChildCount = count; + } /** * Adds a child node to this delta with the given element and change flags, @@ -120,7 +127,7 @@ public class VMDelta extends ModelDelta { * @param flags change flags for child * @return newly created child delta */ - public VMDelta addNode(IVMContext element, int flags) { + public VMDelta addNode(Object element, int flags) { VMDelta node = new VMDelta(element, flags); node.setParent(this); addDelta(node); @@ -137,7 +144,7 @@ public class VMDelta extends ModelDelta { * @param flags change flags * @return newly created child delta */ - public VMDelta addNode(IVMContext element, Object replacement, int flags) { + public VMDelta addNode(Object element, Object replacement, int flags) { VMDelta node = new VMDelta(element, replacement, flags); node.setParent(this); addDelta(node); @@ -153,7 +160,7 @@ public class VMDelta extends ModelDelta { * @param flags change flags * @return newly created child delta */ - public VMDelta addNode(IVMContext element, int index, int flags) { + public VMDelta addNode(Object element, int index, int flags) { VMDelta node = new VMDelta(element, index, flags); node.setParent(this); addDelta(node); @@ -161,21 +168,22 @@ public class VMDelta extends ModelDelta { } /** - * Adds a node to the delta for a non-VMC element. This is used to - * construct the root branch of the delta before it is handed off to - * ViewModelProvider.handleDataModelEvent() - * @param element Element in the asynchronous view to create the new node for. - * @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. - * @return Returns the added delta node. + * Adds a child delta to this delta at the specified index with the + * given number of children, and returns the newly created child delta. + * + * @param element child element in insert + * @param index index of the element relative to parent + * @param flags change flags + * @param numChildren the number of children the element has + * @return newly created child delta */ - public VMDelta addNode(Object element, IVMContext vmcElement) { - VMDelta node = new VMDelta(element, vmcElement); + public ModelDelta addNode(Object element, int index, int flags, int numChildren) { + VMDelta node = new VMDelta(element, index, flags, numChildren); node.setParent(this); addDelta(node); return node; } - + /** * Sets the parent delta of this delta * @@ -184,17 +192,19 @@ public class VMDelta extends ModelDelta { void setParent(VMDelta node) { fParent = node; } - + /* (non-Javadoc) * @see org.eclipse.debug.internal.ui.viewers.IModelDelta#getParent() */ - public IModelDelta getParent() { + @Override + public IModelDelta getParentDelta() { return fParent; } /* (non-Javadoc) * @see org.eclipse.debug.internal.ui.viewers.IModelDelta#getReplacementElement() */ + @Override public Object getReplacementElement() { return fReplacement; } @@ -202,6 +212,7 @@ public class VMDelta extends ModelDelta { /* (non-Javadoc) * @see org.eclipse.debug.internal.ui.viewers.IModelDelta#getIndex() */ + @Override public int getIndex() { return fIndex; } @@ -209,7 +220,8 @@ public class VMDelta extends ModelDelta { /* (non-Javadoc) * @see org.eclipse.debug.internal.ui.viewers.IModelDelta#getNodes() */ - public VMDelta[] getNodes() { + @Override + public VMDelta[] getChildDeltas() { return fNodes; } @@ -224,6 +236,7 @@ public class VMDelta extends ModelDelta { } } + @Override public String toString() { StringBuffer buf = new StringBuffer(); buf.append("Model Delta Start\n"); //$NON-NLS-1$ @@ -233,43 +246,78 @@ public class VMDelta extends ModelDelta { } private void appendDetail(StringBuffer buf, VMDelta delta) { - buf.append("\tElement: "); //$NON-NLS-1$ - buf.append(delta.getElement()); - buf.append('\n'); - buf.append("\t\tFlags: "); //$NON-NLS-1$ - int flags = delta.getFlags(); - if (flags == 0) { - buf.append("NO_CHANGE"); //$NON-NLS-1$ - } else { - if ((flags & IModelDelta.ADDED) > 0) { - buf.append("ADDED | "); //$NON-NLS-1$ - } - if ((flags & IModelDelta.CONTENT) > 0) { - buf.append("CONTENT | "); //$NON-NLS-1$ - } - if ((flags & IModelDelta.EXPAND) > 0) { - buf.append("EXPAND | "); //$NON-NLS-1$ - } - if ((flags & IModelDelta.INSERTED) > 0) { - buf.append("INSERTED | "); //$NON-NLS-1$ - } - if ((flags & IModelDelta.REMOVED) > 0) { - buf.append("REMOVED | "); //$NON-NLS-1$ - } - if ((flags & IModelDelta.REPLACED) > 0) { - buf.append("REPLACED | "); //$NON-NLS-1$ - } - if ((flags & IModelDelta.SELECT) > 0) { - buf.append("SELECT | "); //$NON-NLS-1$ - } - if ((flags & IModelDelta.STATE) > 0) { - buf.append("STATE | "); //$NON-NLS-1$ - } - } - buf.append('\n'); - VMDelta[] nodes = delta.getNodes(); - for (int i = 0; i < nodes.length; i++) { - appendDetail(buf, nodes[i]); - } + buf.append("\tElement: "); //$NON-NLS-1$ + buf.append(delta.getElement()); + buf.append('\n'); + buf.append("\t\tFlags: "); //$NON-NLS-1$ + int flags = delta.getFlags(); + if (flags == 0) { + buf.append("NO_CHANGE"); //$NON-NLS-1$ + } else { + if ((flags & IModelDelta.ADDED) > 0) { + buf.append("ADDED | "); //$NON-NLS-1$ + } + if ((flags & IModelDelta.CONTENT) > 0) { + buf.append("CONTENT | "); //$NON-NLS-1$ + } + if ((flags & IModelDelta.EXPAND) > 0) { + buf.append("EXPAND | "); //$NON-NLS-1$ + } + if ((flags & IModelDelta.INSERTED) > 0) { + buf.append("INSERTED | "); //$NON-NLS-1$ + } + if ((flags & IModelDelta.REMOVED) > 0) { + buf.append("REMOVED | "); //$NON-NLS-1$ + } + if ((flags & IModelDelta.REPLACED) > 0) { + buf.append("REPLACED | "); //$NON-NLS-1$ + } + if ((flags & IModelDelta.SELECT) > 0) { + buf.append("SELECT | "); //$NON-NLS-1$ + } + if ((flags & IModelDelta.STATE) > 0) { + buf.append("STATE | "); //$NON-NLS-1$ + } + if ((flags & IModelDelta.INSTALL) > 0) { + buf.append("INSTALL | "); //$NON-NLS-1$ + } + if ((flags & IModelDelta.UNINSTALL) > 0) { + buf.append("UNINSTALL | "); //$NON-NLS-1$ + } + } + buf.append('\n'); + buf.append("\t\tIndex: "); //$NON-NLS-1$ + buf.append(delta.fIndex); + buf.append(" Child Count: "); //$NON-NLS-1$ + buf.append(delta.fChildCount); + buf.append('\n'); + IModelDelta[] nodes = delta.getChildDeltas(); + for (int i = 0; i < nodes.length; i++) { + appendDetail(buf, (VMDelta)nodes[i]); + } } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta#getChildCount() + */ + public int getChildCount() { + return fChildCount; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta#accept(org.eclipse.debug.internal.ui.viewers.provisional.IModelDeltaVisitor) + */ + public void accept(IModelDeltaVisitor visitor) { + doAccept(visitor, 0); + } + + protected void doAccept(IModelDeltaVisitor visitor, int depth) { + if (visitor.visit(this, depth)) { + ModelDelta[] childDeltas = getChildDeltas(); + for (int i = 0; i < childDeltas.length; i++) { + ((VMDelta)childDeltas[i]).doAccept(visitor, depth+1); + } + } + } + } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMProvider.java deleted file mode 100644 index 029b25ff52b..00000000000 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMProvider.java +++ /dev/null @@ -1,439 +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.viewmodel; - -import java.util.concurrent.atomic.AtomicReference; - -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.IColumnEditor; -import org.eclipse.debug.internal.ui.viewers.provisional.IColumnEditorFactoryAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation; -import org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentationFactoryAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.IContainerRequestMonitor; -import org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelProxy; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; - -/** - * View model provider implements the asynchronous view model functionality for - * 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. - *

    - * 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 -{ - private final DsfSession fSession; - private final ModelProxy fModelProxy = new ModelProxy(); - - /** - * It is theoretically possible for a VMProvider to be disposed before it - * has a chance to register itself as event listener. This flag is used - * to avoid removing itself as listener in such situation. - */ - private boolean fRegisteredAsEventListener = false; - - /** - * The root node for this model provider. The root layout node could be - * null when first created, to allow sub-classes to prorperly configure the - * root node in the sub-class constructor. - */ - private AtomicReference fRootLayoutNodeRef = new AtomicReference(); - - /** - * Constructs the view model provider for given DSF session. The - * constructor is thread-safe to allow VM provider to be constructed - * synchronously when a call to getAdapter() is made on an element - * in a view. - */ - @ThreadSafe - public VMProvider(DsfSession session, IVMRootLayoutNode rootLayoutNode) { - fSession = session; - fRootLayoutNodeRef.set(rootLayoutNode); - // Add ourselves as listener for DM events events. - session.getExecutor().execute(new Runnable() { - public void run() { - if (DsfSession.isSessionActive(getSession().getId())) { - getSession().addServiceEventListener(VMProvider.this, null); - fRegisteredAsEventListener = true; - } - } - }); - } - - /** - * Sets the layout nodes. This method is thread-safe, because it might - * be called fromthe constructor, which itself is thread-safe. - */ - @ThreadSafe - public void setRootLayoutNode(IVMRootLayoutNode rootLayoutNode) { - final IVMRootLayoutNode oldRootLayoutNode = fRootLayoutNodeRef.getAndSet(rootLayoutNode); - if (oldRootLayoutNode != null) { - // IVMLayoutNode has to be called on dispatch thread... for now at least. - getSession().getExecutor().execute( new Runnable() { - public void run() { - oldRootLayoutNode.dispose(); - } - }); - } - } - - public IVMRootLayoutNode getRootLayoutNode() { - return fRootLayoutNodeRef.get(); - } - - /** Called to dispose the provider. */ - public void dispose() { - if (fRegisteredAsEventListener) { - fSession.removeServiceEventListener(this); - } - if (fRootLayoutNodeRef != null) { - fRootLayoutNodeRef.get().dispose(); - } - } - - 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)hasElementsDone).getData().booleanValue(); - } - monitor.setIsContainer(isContainer); - monitor.done(); - } - }; - for (IVMLayoutNode childNode : parentVmc.getLayoutNode().getChildLayoutNodes()) { - childNode.hasElements( - parentVmc, - doneCollector.add( new GetDataDone() { 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"; //$NON-NLS-1$ - 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() { - public void run() { - if (getStatus().isOK()) { - monitor.addChildren(getData()); - } - doneCollector.doneDone(this); - } - })); - } - } - - /** - * Retrieves the label information for given object. - * The implementation converts the object into a VM-Context, then delegates - * to the context's layout node. - * Note: this method must be called on the provider's dispatch thread. - - * @see IAsynchronousLabelAdapter#retrieveLabel(Object, org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext, ILabelRequestMonitor) - */ - public void retrieveLabel(Object object, ILabelRequestMonitor result, String[] columns) - { - IVMContext vmc = getVmcForObject(object); - if (vmc == null) { - result.done(); - return; - } - - vmc.getLayoutNode().retrieveLabel(vmc, result, columns); - } - - public ModelProxy getModelProxy() { - return fModelProxy; - } - - - /** - * Creates the column presentation for the given object. This method is meant - * to be overriden by deriving class to provide view-specific functionality. - * The default is to return null, meaning no columns. - *

    - * The viewer only reads the column presentation for the root/input element of - * the tree/table, so the VMProvider must be configured to own the root element - * in the view in order for this setting to be effective. - *

    - * Note: since the IColumnEditorFactoryAdapter interface is synchronous, and since - * column info is fairly static, this method is thread-safe, and it will - * not be called on the executor thread. - * - * @see IColumnPresentationFactoryAdapter#createColumnPresentation(IPresentationContext, Object) - */ - @ThreadSafe - public IColumnPresentation createColumnPresentation(Object element) { - return null; - } - - /** - * Returns the ID of the column presentation for the given object. This method - * is meant to be overriden by deriving class to provide view-specific - * functionality. The default is to return null, meaning no columns. - *

    - * The viewer only reads the column presentation for the root/input element of - * the tree/table, so the VMProvider must be configured to own the root element - * in the view in order for this setting to be effective. - *

    - * Note: since the IColumnEditorFactoryAdapter interface is synchronous, and since - * column info is fairly static, this method is thread-safe, and it will - * not be called on the executor thread. - * - * @see IColumnEditorFactoryAdapter#getColumnEditorId(IPresentationContext, Object) - */ - @ThreadSafe - public String getColumnPresentationId(Object element) { - return null; - } - - public IColumnEditor createColumnEditor(Object element) { - IVMContext vmc = getVmcForObject(element); - if (vmc == null) { - return null; - } - - return vmc.getLayoutNode().createColumnEditor(vmc); - } - - public String getColumnEditorId(Object element) { - IVMContext vmc = getVmcForObject(element); - if (vmc == null) { - return null; - } - - return vmc.getLayoutNode().getColumnEditorId(vmc); - } - - - /** - * 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. - */ - IVMRootLayoutNode rootLayoutNode = getRootLayoutNode(); - if (rootLayoutNode == null) { - return null; - } - else if (parent.equals(rootLayoutNode.getRootVMC().getInputObject())) { - return rootLayoutNode.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[] { rootLayoutNode } )) - { - 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; - } - - /** - * 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) { - IVMRootLayoutNode rootLayoutNode = getRootLayoutNode(); - - if (rootLayoutNode != null && rootLayoutNode.hasDeltaFlags(event)) { - rootLayoutNode.createDelta(event, new GetDataDone() { - 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 + "'"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - }); - } - } - - @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(); - } - - } -} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMAdapter.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMAdapter.java new file mode 100644 index 00000000000..5035419519a --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMAdapter.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel.dm; + +import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; + +/** + * Base implementation for DSF-based view model adapters. + */ +@ThreadSafe +abstract public class AbstractDMVMAdapter extends AbstractVMAdapter +{ + private final DsfSession fSession; + + /** + * Constructor for the View Model session. It is tempting to have the + * adapter register itself here with the session as the model adapter, but + * that would mean that the adapter might get accessed on another thread + * even before the deriving class is fully constructed. So it it better + * to have the owner of this object register it with the session. + * @param session + */ + public AbstractDMVMAdapter(DsfSession session) { + super(); + fSession = session; + } + + /** + * Returns the DSF session that this adapter is associated with. + * @return + */ + protected DsfSession getSession() { return fSession; } + +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java new file mode 100644 index 00000000000..775ecdf61ab --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java @@ -0,0 +1,501 @@ +/******************************************************************************* + * 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.dm; + +import java.util.List; +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.Done; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.GetDataDone; +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.datamodel.IDMData; +import org.eclipse.dd.dsf.datamodel.IDMEvent; +import org.eclipse.dd.dsf.datamodel.IDMService; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.dsf.ui.DsfUIPlugin; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; +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.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactoryAdapter; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITreeSelection; +import org.eclipse.jface.viewers.TreePath; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.RGB; + + +/** + * 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 AbstractDMVMLayoutNode extends AbstractVMLayoutNode + implements IElementLabelProvider +{ + + /** + * IVMContext implementation used for this schema node. + */ + @Immutable + public class DMVMContext extends AbstractVMContext { + private final IDMContext fDmc; + + public DMVMContext(IDMContext dmc) { + super(getVMProvider().getVMAdapter(), AbstractDMVMLayoutNode.this); + fDmc = dmc; + } + + public IDMContext getDMC() { return fDmc; } + + /** + * The IAdaptable implementation. If the adapter is the DM context, + * return the context, otherwise delegate to IDMContext.getAdapter(). + */ + @SuppressWarnings("unchecked") + public Object getAdapter(Class adapter) { + Object superAdapter = super.getAdapter(adapter); + if (superAdapter != null) { + return superAdapter; + } else if (adapter.isInstance(fDmc)) { + return fDmc; + } else { + return fDmc.getAdapter(adapter); + } + } + + public boolean equals(Object other) { + if (!(other instanceof AbstractDMVMLayoutNode.DMVMContext)) return false; + DMVMContext otherVmc = (DMVMContext)other; + return AbstractDMVMLayoutNode.this.equals(otherVmc.getLayoutNode()) && + fDmc.equals(otherVmc.fDmc); + } + + public int hashCode() { + return AbstractDMVMLayoutNode.this.hashCode() + fDmc.hashCode(); + } + + public String toString() { + return fDmc.toString(); + } + } + + private DsfSession fSession; + + private DsfServicesTracker fServicesTracker; + + /** + * Concrete class type that the elements of this schema node are based on. + * Even though the data model type is a parameter the DMContextVMLayoutNode, + * this type is erased at runtime, so a concrete class typs of the DMC + * is needed for instanceof chacks. + */ + private Class> 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 AbstractDMVMLayoutNode(AbstractVMProvider provider, DsfSession session, Class> dmcClassType) { + super(provider); + fSession = session; + fServicesTracker = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), session.getId()); + fDMCClassType = dmcClassType; + } + + + public void dispose() { + fServicesTracker.dispose(); + super.dispose(); + } + + protected DsfSession getSession() { + return fSession; + } + + protected DsfServicesTracker getServicesTracker() { + return fServicesTracker; + } + + @Override + protected boolean checkUpdate(IViewerUpdate update) { + if (!super.checkUpdate(update)) return false; + + // Extract the VMC from the update (whatever the update sub-class. + Object element = update.getElement(); + if (element instanceof AbstractDMVMLayoutNode.DMVMContext) { + // If update element is a DMC, check if session is still alive. + IDMContext dmc = ((DMVMContext)element).getDMC(); + if (dmc.getSessionId() != getSession().getId() || !DsfSession.isSessionActive(dmc.getSessionId())) { + handleFailedUpdate(update); + return false; + } + } + return true; + } + + protected boolean checkService(Class serviceClass, String filter, IViewerUpdate update) { + if (getServicesTracker().getService(serviceClass, filter) == null) { + update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, + "Service " + serviceClass.getName() + " not available.", null)); //$NON-NLS-1$ //$NON-NLS-2$ + handleFailedUpdate(update); + return false; + } + return true; + } + + public void updateHasElements(final IHasChildrenUpdate[] updates) { + getSession().getExecutor().execute(new DsfRunnable() { + public void run() { + updateHasElementsInSessionThread(updates); + }}); + } + + protected void updateHasElementsInSessionThread(IHasChildrenUpdate[] updates) { + for (final IHasChildrenUpdate update : updates) { + if (!checkUpdate(update)) return; + + updateElementsInSessionThread( + new ElementsUpdate( + new GetDataDone>() { + public void run() { + if (!checkUpdate(update)) return; + if (getStatus().isOK()) { + update.setHasChilren(getData().size() != 0); + } else { + update.setHasChilren(false); + } + update.done(); + } + }, + update.getElementPath()) + ); + } + } + + public void updateElementCount(final IChildrenCountUpdate update) { + if (!checkUpdate(update)) return; + + getSession().getExecutor().execute(new DsfRunnable() { + public void run() { + // After every dispatch, must check if update still valid. + if (!checkUpdate(update)) return; + updateElementCountInSessionThread(update); + }}); + } + + protected void updateElementCountInSessionThread(final IChildrenCountUpdate update) { + updateElementsInSessionThread( + new ElementsUpdate( + new GetDataDone>() { + public void run() { + if (!checkUpdate(update)) return; + if (getStatus().isOK()) { + update.setChildCount(getData().size()); + } else { + update.setChildCount(0); + } + update.done(); + } + }, + update.getElementPath()) + ); + } + + public void updateElements(final IChildrenUpdate update) { + if (!checkUpdate(update)) return; + + getSession().getExecutor().execute(new DsfRunnable() { + public void run() { + // After every dispatch, must check if update still valid. + if (!checkUpdate(update)) return; + updateElementsInSessionThread(update); + }}); + } + + abstract protected void updateElementsInSessionThread(IChildrenUpdate update); + + public void update(final ILabelUpdate[] updates) { + try { + getSession().getExecutor().execute(new DsfRunnable() { + public void run() { + // After every dispatch, must check if update still valid. + updateLabelInSessionThread(updates); + }}); + } catch (RejectedExecutionException e) { + for (ILabelUpdate update : updates) { + handleFailedUpdate(update); + } + } + } + + /** + * The default implementation of the retrieve label method. It acquires + * the service, using parameters in the DMC, then it fetches the model + * data from the service, and then it calls the protected method + * fillColumnLabel() for each column. The deriving classes should override + * this method if a different method of computing the label is needed. + * + * @see #fillColumnLabel(IDMData, String, int, String[], ImageDescriptor[], FontData[], RGB[], RGB[]) + */ + protected void updateLabelInSessionThread(ILabelUpdate[] updates) { + for (final ILabelUpdate update : updates) { + final DMVMContext vmc = (DMVMContext)update.getElement(); + if (!checkService(null, vmc.getDMC().getServiceFilter(), update)) return; + + final IDMContext dmc = findDmcInPath(update.getElementPath(), fDMCClassType); + + ((IDMService)getServicesTracker().getService(null, vmc.getDMC().getServiceFilter())).getModelData( + dmc, + new GetDataDone() { + public void run() { + /* + * Check that the request was evaluated and data is still + * valid. The request could fail if the state of the + * service changed during the request, but the view model + * has not been updated yet. + */ + if (!getStatus().isOK() || !getData().isValid()) { + assert getStatus().isOK() || + getStatus().getCode() != IDsfService.INTERNAL_ERROR || + getStatus().getCode() != IDsfService.NOT_SUPPORTED; + handleFailedUpdate(update); + return; + } + + /* + * If columns are configured, call the protected methods to + * fill in column values. + */ + String[] localColumns = update.getPresentationContext().getColumns(); + if (localColumns == null) localColumns = new String[] { null }; + + for (int i = 0; i < localColumns.length; i++) { + fillColumnLabel(dmc, getData(), localColumns[i], i, update); + } + update.done(); + } + }); + } + } + + /** + * Fills in label information for given column. This method is intended to + * be overriden by deriving classes, to supply label information specific + * to the node.
    + * The implementation should fill in the correct value in each array at the + * given index. + * @param dmContext Data Model Context object for which the label is generated. + * @param dmData Data Model Data object retrieved from the model service. + * for the DM Context supplied to the retrieveLabel() call. + * @param columnId Name of the column to fill in, null if no columns specified. + * @param idx Index to fill in in the label arrays. + * @param update Update object to fill information to + * + * @see IElementLabelProvider + * @see IColumnPresentationFactoryAdapter + */ + protected void fillColumnLabel(IDMContext dmContext, V dmData, String columnId, int idx, ILabelUpdate update) { + update.setLabel("", idx); //$NON-NLS-1$ + } + + @Override + public int getDeltaFlags(Object e) { + int flags = 0; + if (e instanceof IDMEvent) { + flags = getNodeDeltaFlagsForDMEvent((IDMEvent)e); + } + return flags | super.getDeltaFlags(e); + } + + protected int getNodeDeltaFlagsForDMEvent(IDMEvent e) { + return IModelDelta.NO_CHANGE; + } + + @Override + public void buildDelta(final Object e, final VMDelta parentDelta, final int nodeOffset, final Done done) { + if (e instanceof IDMEvent) { + // Call handler for Data Model events. But check to make sure + // that session is still active. + if (DsfSession.isSessionActive(getSession().getId())) { + getSession().getExecutor().execute(new DsfRunnable() { + public void run() { + buildDeltaForDMEvent((IDMEvent)e, parentDelta, nodeOffset, done); + } + }); + } else { + if (isDisposed()) return; + getExecutor().execute(done); + } + } else { + super.buildDelta(e, parentDelta, nodeOffset, done); + } + } + + /** + * Handle all Data Model events. If a DM context in the event contains + * a context of the type tracked by this node, then this base implementation + * will only create a delta node for this one element. + */ + protected void buildDeltaForDMEvent(final IDMEvent event, final VMDelta parentDelta, final int nodeOffset, final Done done) { + IDMContext dmc = DMContexts.getAncestorOfType(event.getDMContext(), fDMCClassType); + + if (dmc != null) { + // Create the VM context based on the DM context from the DM event. + final IVMContext vmc = new DMVMContext(DMContexts.getAncestorOfType(event.getDMContext(), fDMCClassType)); + + final Map childNodeDeltas = getChildNodesWithDeltas(event); + if (childNodeDeltas.size() == 0) { + // There are no child nodes with deltas, just return to parent. + getExecutor().execute(done); + return; + } + + // Check if any of the child nodes are will generate IModelDelta.SELECT or + // IModelDelta.EXPAND flags. If so, we must calcuate the index for this + // VMC. + boolean calculateIndex = false; + for (int childDelta : childNodeDeltas.values()) { + if ( (childDelta & (IModelDelta.SELECT | IModelDelta.EXPAND)) != 0 ) { + calculateIndex = true; + break; + } + } + + if (calculateIndex) { + // Calculate the index of this node by retrieving all the + // elements and then finding the DMC that the event is for. + updateElements(new ElementsUpdate( + new GetDataDone>() { + public void run() { + if (isDisposed()) return; + + // Check for an empty list of elements. If it's empty then we + // don't have to call the children nodes, so return here. + // No need to propagate error, there's no means or need to display it. + if (!getStatus().isOK()) { + getExecutor().execute(done); + return; + } + + // Find the index. + int i; + for (i = 0; i < getData().size(); i++) { + if (vmc.equals(getData().get(i))) break; + } + if (i == getData().size()) { + // Element not found, no need to generate the delta. + getExecutor().execute(done); + } + + VMDelta delta = parentDelta.addNode(vmc, nodeOffset + i, IModelDelta.NO_CHANGE); + callChildNodesToBuildDelta(childNodeDeltas, delta, event, done); + } + }, + parentDelta)); + } else { + VMDelta delta = parentDelta.addNode(vmc, IModelDelta.NO_CHANGE); + callChildNodesToBuildDelta(childNodeDeltas, delta, event, done); + } + } else { + // The for this node was not found in the event. Call the + // super-class to resort to the default behavior which may add a + // delta node for every element in this node. + super.buildDelta(event, parentDelta, nodeOffset, 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(IDMContext[] dmcs) { + IVMContext[] vmContexts = new IVMContext[dmcs.length]; + for (int i = 0; i < dmcs.length; i++) { + vmContexts[i] = new DMVMContext(dmcs[i]); + } + return vmContexts; + } + + protected void fillUpdateWithVMCs(IChildrenUpdate update, IDMContext[] dmcs) { + int startIdx = update.getOffset() != -1 ? update.getOffset() : 0; + int endIdx = update.getLength() != -1 ? startIdx + update.getLength() : dmcs.length; + for (int i = startIdx; i < endIdx; i++) { + update.setChild(new DMVMContext(dmcs[i]), i); + } + } + + /** + * Searches for a DMC of given type in the tree patch contained in given + * VMC. Only a DMC in the same session will be returned. + * @param 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 T findDmcInPath(TreePath path, Class dmcType) { + T retVal = null; + for (int i = path.getSegmentCount() - 1; i >= 0; i--) { + if (path.getSegment(i) instanceof AbstractDMVMLayoutNode.DMVMContext) { + IDMContext dmc = ((DMVMContext)path.getSegment(i)).getDMC(); + if ( dmc.getSessionId().equals(getSession().getId()) ) { + retVal = DMContexts.getAncestorOfType(dmc, dmcType); + if (retVal != null) break; + } + } + } + // Search the root object of the layout hierarchy. + if (retVal == null) { + Object inputObject = getVMProvider().getRootLayoutNode().getRootObject(); + if (inputObject instanceof ITreeSelection) { + ITreeSelection inputSelection = (ITreeSelection)inputObject; + if (inputSelection.getPaths().length == 1) { + retVal = findDmcInPath(inputSelection.getPaths()[0], dmcType); + } + } else if (inputObject instanceof IStructuredSelection) { + Object rootElement = ((IStructuredSelection)inputObject).getFirstElement(); + if (rootElement instanceof AbstractDMVMLayoutNode.DMVMContext) { + retVal = DMContexts.getAncestorOfType(((DMVMContext)rootElement).getDMC(), dmcType); + } + } else if (inputObject instanceof AbstractDMVMLayoutNode.DMVMContext) { + retVal = DMContexts.getAncestorOfType(((DMVMContext)inputObject).getDMC(), dmcType); + } + } + + return retVal; + } +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProvider.java new file mode 100644 index 00000000000..788b370ea09 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProvider.java @@ -0,0 +1,139 @@ +/******************************************************************************* + * 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.dm; + +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; +import org.eclipse.dd.dsf.concurrent.GetDataDone; +import org.eclipse.dd.dsf.datamodel.IDMEvent; +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousContentAdapter; +import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousLabelAdapter; + +/** + * 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. + *

    + * 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") +abstract public class AbstractDMVMProvider extends AbstractVMProvider +{ + private final DsfSession fSession; + + /** + * It is theoretically possible for a VMProvider to be disposed before it + * has a chance to register itself as event listener. This flag is used + * to avoid removing itself as listener in such situation. + */ + private boolean fRegisteredAsEventListener = false; + + /** + * Constructs the view model provider for given DSF session. The + * constructor is thread-safe to allow VM provider to be constructed + * synchronously when a call to getAdapter() is made on an element + * in a view. + */ + public AbstractDMVMProvider(AbstractVMAdapter adapter, IPresentationContext presentationContext, DsfSession session) { + super(adapter, presentationContext); + fSession = session; + // Add ourselves as listener for DM events events. + try { + session.getExecutor().execute(new Runnable() { + public void run() { + if (DsfSession.isSessionActive(getSession().getId())) { + getSession().addServiceEventListener(AbstractDMVMProvider.this, null); + fRegisteredAsEventListener = true; + } + } + }); + } catch (RejectedExecutionException e) { + // Session shut down, not much we can do but wait to be disposed. + } + } + + /** Called to dispose the provider. */ + public void dispose() { + try { + getSession().getExecutor().execute(new Runnable() { + public void run() { + if (DsfSession.isSessionActive(getSession().getId()) && fRegisteredAsEventListener ) { + fSession.removeServiceEventListener(AbstractDMVMProvider.this); + } + } + }); + } catch (RejectedExecutionException e) { + // Session shut down. + } + super.dispose(); + } + + protected DsfSession getSession() { return fSession; } + + + + /** + * 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 (isDisposed()) return; + + // We're in session's executor thread. Re-dispach to VM Adapter + // executor thread and then call root layout node. + try { + getExecutor().execute(new Runnable() { + public void run() { + if (isDisposed()) return; + + IVMRootLayoutNode rootLayoutNode = getRootLayoutNode(); + if (rootLayoutNode != null && rootLayoutNode.getDeltaFlags(event) != 0) { + rootLayoutNode.createDelta(event, new GetDataDone() { + public void run() { + if (getStatus().isOK()) { + getModelProxy().fireModelChangedNonDispatch(getData()); + } + } + @Override public String toString() { + return "Result of a delta for event: '" + event.toString() + "' in VMP: '" + AbstractDMVMProvider.this + "'" + "\n" + getData().toString(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } + }); + } + }}); + } catch (RejectedExecutionException e) { + // Ignore. This exception could be thrown if the provider is being + // shut down. + } + } +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java index d4feb038cb5..7c212d3734b 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java @@ -86,7 +86,10 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor } static void logException(Throwable t) { - ILog log = DsfPlugin.getDefault().getLog(); + DsfPlugin plugin = DsfPlugin.getDefault(); + if (plugin == null) return; + + ILog log = plugin.getLog(); if (log != null) { log.log(new Status( IStatus.ERROR, DsfPlugin.PLUGIN_ID, -1, "Uncaught exception in DSF executor thread", t)); //$NON-NLS-1$ @@ -222,6 +225,12 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor public TracingWrapperRunnable(Runnable runnable, int offset) { super(offset); fRunnable = runnable; + + // Check if executable wasn't executed already. + if (DEBUG_EXECUTOR && fRunnable instanceof DsfExecutable) { + assert !((DsfExecutable)fRunnable).getSubmitted() : "Executable was previously executed."; //$NON-NLS-1$ + ((DsfExecutable)fRunnable).setSubmitted(); + } } protected Object getExecutable() { return fRunnable; } @@ -229,11 +238,6 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor public void run() { traceExecution(); - // If debugging a DSF exeutable, mark that it was executed. - if (DEBUG_EXECUTOR && fRunnable instanceof DsfExecutable) { - ((DsfExecutable)fRunnable).setExecuted(); - } - // Finally invoke the runnable code. fRunnable.run(); } @@ -251,11 +255,6 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor public T call() throws Exception { traceExecution(); - // If debugging a DSF exeutable, mark that it was executed. - if (DEBUG_EXECUTOR && fCallable instanceof DsfExecutable) { - ((DsfExecutable)fCallable).setExecuted(); - } - // Finally invoke the runnable code. return fCallable.call(); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DoneCollector.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DoneCollector.java index 8fce539f983..e21dc82d494 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DoneCollector.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DoneCollector.java @@ -35,9 +35,8 @@ import org.eclipse.dd.dsf.DsfPlugin; * } * */ -public abstract class DoneCollector extends Done { - private final DsfExecutor fExecutor; - private Map fDones = new HashMap(); +public abstract class DoneCollector extends Done { + private Map fDones = new HashMap(); private int fDoneCounter; /** @@ -47,39 +46,25 @@ public abstract class DoneCollector extends Done { * execution of the last done, and in the same dispatch loop. * */ - public DoneCollector(DsfExecutor executor) { + public DoneCollector() { setStatus(new MultiStatus(DsfPlugin.PLUGIN_ID, 0, "Collective status for set of sub-operations.", null)); //$NON-NLS-1$ - fExecutor = executor; } /** * Adds a new Done callback to this tracker's list. - * @param Service-specific class of the Done callback, to avoid an - * unnecessary cast. + * @param Client-specific class of the Done callback, it's used here to avoid an + * unnecessary cast by the client. * @param done callback object to add to the tracker * @return the done that was just added, it allows this method to be used * inlined in service method calls */ - public V add(V done) { + public T add(T done) { assert !fDones.containsKey(done); fDones.put(done, false); fDoneCounter++; return done; } - /** - * Adds a Done which performs no actions. This is useful if all work - * 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); - } - }); - } - /** * Marks the given Done callback as completed. Client implementations of * the Done callback have to call this method in order for the tracker @@ -88,13 +73,15 @@ public abstract class DoneCollector extends Done { * Note: funniest method signature ever! * @param done */ - public void doneDone(Done done) { + public void doneDone(V done) { ((MultiStatus)getStatus()).merge(done.getStatus()); + assert fDones.containsKey(done); fDones.put(done, true); + assert fDoneCounter > 0; fDoneCounter--; if (fDoneCounter == 0) { assert !fDones.containsValue(false); - fExecutor.execute(this); + run(); } } @@ -104,10 +91,15 @@ public abstract class DoneCollector extends Done { * done callbacks. * @return map of the done callbacks. */ - public Map getDones() { return fDones; } + public Map getDones() { return fDones; } @Override public String toString() { return "Done Collector: " + getStatus().toString(); //$NON-NLS-1$ } + + @Override + protected boolean isExecutionRequired() { + return false; + } } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java index 748aa8d2772..7620478eca9 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java @@ -62,7 +62,7 @@ public class DsfExecutable { * Flag indicating whether this executable was ever executed by an * executor. Used for tracing only. */ - private boolean fExecuted = false; + private boolean fSubmitted = false; @SuppressWarnings("unchecked") public DsfExecutable() { @@ -97,17 +97,31 @@ public class DsfExecutable { } } + boolean getSubmitted() { + return fSubmitted; + } + /** * Marks this executable to indicate that it has been executed by the * executor. To be invoked only by DsfExecutor. */ - void setExecuted() { - fExecuted = true; + void setSubmitted() { + fSubmitted = true; + } + + /** + * Returns whether the runnable/callable is expected to be always executed. + * Overriding classes can implement this method and return false, to avoid + * unnecessary trace output. + * @return true if this runnable is expected to run. + */ + protected boolean isExecutionRequired() { + return true; } @Override protected void finalize() { - if (DEBUG_EXECUTOR && !fExecuted) { + if (DEBUG_EXECUTOR && !fSubmitted && isExecutionRequired()) { StringBuilder traceBuilder = new StringBuilder(); // Record the time diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMContext.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMContext.java index b428ba83337..778295eea21 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMContext.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMContext.java @@ -12,7 +12,6 @@ package org.eclipse.dd.dsf.datamodel; import org.eclipse.core.runtime.PlatformObject; import org.eclipse.dd.dsf.concurrent.Immutable; -import org.eclipse.dd.dsf.service.AbstractDsfService; import org.eclipse.dd.dsf.service.DsfSession; /** @@ -40,12 +39,10 @@ abstract public class AbstractDMContext extends PlatformObjec } /** Convenience constructor */ - public AbstractDMContext(AbstractDsfService service, IDMContext parent) { - this(service.getSession().getId(), - service.getServiceFilter(), - parent == null ? new IDMContext[] {} : new IDMContext[] { parent }); + public AbstractDMContext(IDMService service, IDMContext[] parents) { + this(service.getSession().getId(), service.getServiceFilter(), parents); } - + /** * Should be used by the deriving class to compare the basic context object * information. diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/ServiceDMContext.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/ServiceDMContext.java index 1f71becf043..481abf680f9 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/ServiceDMContext.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/ServiceDMContext.java @@ -10,7 +10,6 @@ *******************************************************************************/ 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 @@ -22,8 +21,8 @@ import org.eclipse.dd.dsf.service.AbstractDsfService; public class ServiceDMContext extends AbstractDMContext { String fServiceDMID; - public ServiceDMContext(AbstractDsfService service, String serviceDMID) { - super(service, null); + public ServiceDMContext(IDMService service, String serviceDMID) { + super(service, new IDMContext[0]); fServiceDMID = serviceDMID; } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java index 77bd7654078..a5b527ac02a 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java @@ -74,10 +74,14 @@ public interface IDsfService { */ final static int INTERNAL_ERROR = 10005; + /** + * Returns the DSF Session that this service belongs to. + */ + DsfSession getSession(); /** * Returns the executor that should be used to call methods of this service. - * @return + * This method is equivalent to calling getSession().getExecutor() */ DsfExecutor getExecutor(); From 1330da73239b6b9f6e9d4db5ba06f733d2755849 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 12 Dec 2006 01:13:58 +0000 Subject: [PATCH 051/834] Fixed RejectedExecutionException. --- .../org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java index 2d1b36ab055..98698e6a429 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java @@ -178,6 +178,8 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { getChildNodesElementOffsets(delta, !calculateOffsets, new GetDataDone>() { public void run() { + if (isDisposed()) return; + final DoneCollector childrenBuildDeltaDoneCollector = new DoneCollector() { public void run() { if (isDisposed()) return; From c5b151520f0ebcacf59b9c72afdac0e013208030 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 12 Dec 2006 01:15:26 +0000 Subject: [PATCH 052/834] Exceptions during shutdown cleanup. --- .../src/org/eclipse/dd/dsf/DsfPlugin.java | 1 - .../dd/dsf/concurrent/DefaultDsfExecutor.java | 40 ++++++------------- .../dd/dsf/service/AbstractDsfService.java | 1 - .../dd/dsf/service/DsfServicesTracker.java | 2 + .../eclipse/dd/dsf/service/DsfSession.java | 2 + 5 files changed, 17 insertions(+), 29 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/DsfPlugin.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/DsfPlugin.java index 1e3f7290dec..6a1fb6e93ab 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/DsfPlugin.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/DsfPlugin.java @@ -53,7 +53,6 @@ public class DsfPlugin extends Plugin { * @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); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java index 7c212d3734b..0306ca368a3 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java @@ -16,8 +16,6 @@ import java.io.PrintStream; import java.util.HashMap; import java.util.Map; import java.util.concurrent.Callable; -import java.util.concurrent.CancellationException; -import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; @@ -61,30 +59,6 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor return Thread.currentThread().equals( ((DsfThreadFactory)getThreadFactory()).fThread ); } - @Override - protected void afterExecute(Runnable r, Throwable t) { - if (r instanceof Future) { - Future future = (Future)r; - try { - /* - * Try to retrieve the value, which should throw exception in - * case when exception was thrown within the Runnable/Callable. - * Must call isDone(), because scheduled futures would block - * on get. - */ - if (future.isDone()) { - future.get(); - } - } catch (InterruptedException e) { // Ignore - } catch (CancellationException e) { // Ignore also - } catch (ExecutionException e) { - if (e.getCause() != null) { - logException(e.getCause()); - } - } - } - } - static void logException(Throwable t) { DsfPlugin plugin = DsfPlugin.getDefault(); if (plugin == null) return; @@ -224,6 +198,7 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor final Runnable fRunnable; public TracingWrapperRunnable(Runnable runnable, int offset) { super(offset); + if (runnable == null) throw new NullPointerException(); fRunnable = runnable; // Check if executable wasn't executed already. @@ -239,7 +214,15 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor traceExecution(); // Finally invoke the runnable code. - fRunnable.run(); + try { + fRunnable.run(); + } catch (RuntimeException e) { + // If an exception was thrown in the Runnable, trace it. + // Because there is no one else to catch it, it is a + // programming error. + logException(e); + throw e; + } } } @@ -247,6 +230,7 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor final Callable fCallable; public TracingWrapperCallable(Callable callable, int offset) { super(offset); + if (callable == null) throw new NullPointerException(); fCallable = callable; } @@ -256,6 +240,8 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor traceExecution(); // Finally invoke the runnable code. + // Note that callables can throw exceptions that can be caught + // by clients that invoked them using ExecutionException. return fCallable.call(); } } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java index b70e857ef65..5cd80de03c2 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java @@ -48,7 +48,6 @@ abstract public class AbstractDsfService /** Properties that this service was registered with */ private String fFilter; - /** * Only constructor, requires a reference to the session that this * service belongs to. diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServicesTracker.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServicesTracker.java index 1253077b32a..91e204b86fa 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServicesTracker.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServicesTracker.java @@ -112,6 +112,8 @@ public class DsfServicesTracker { } } catch(InvalidSyntaxException e) { assert false : "Invalid session ID syntax"; //$NON-NLS-1$ + } catch(IllegalStateException e) { + // Can occur when plugin is shutting down. } return null; } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java index b7eb38ad1d2..393f7246fe1 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java @@ -228,6 +228,8 @@ public class DsfSession /** Returns the owner ID of this session */ public String getOwnerId() { return fOwnerId; } + public boolean isActive() { return DsfSession.isSessionActive(fId); } + /** Returns the ID of this session */ public String getId() { return fId; } From 792bdef0f88e7b6fb4d0b672f396c31bd9a7cd95 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 12 Dec 2006 07:02:45 +0000 Subject: [PATCH 053/834] Added initial implementation of Process IO support (bug# 160040). Refactored service for sending/receiving MI commands to debugger. --- .../launch/StandardLaunchRootLayoutNode.java | 1 + .../register/RegisterLayoutNode.java | 1 + .../dd/dsf/debug/service/IBackEndProcess.java | 47 ------------------- 3 files changed, 2 insertions(+), 47 deletions(-) delete mode 100644 plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBackEndProcess.java diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java index e45c8623912..bd1c1ba75b8 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java @@ -81,6 +81,7 @@ public class StandardLaunchRootLayoutNode extends AbstractVMRootLayoutNode childNodeDeltas, rootDelta, event, new Done() { public void run() { + if (isDisposed()) return; if (propagateError(getExecutor(), done, "Failed to create delta.")); //$NON-NLS-1$ done.setData(viewRootDelta); getExecutor().execute(done); diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java index dfdf80b19fd..4da4a40cd89 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java @@ -52,6 +52,7 @@ public class RegisterLayoutNode extends AbstractDMVMLayoutNode public void run() { if (!getStatus().isOK()) { handleFailedUpdate(update); + return; } fillUpdateWithVMCs(update, getData()); update.done(); diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBackEndProcess.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBackEndProcess.java deleted file mode 100644 index f8a5cfa159e..00000000000 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBackEndProcess.java +++ /dev/null @@ -1,47 +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.service; - -import org.eclipse.dd.dsf.service.IDsfService; - - -/** - * Service representing an external process that is part of the debugger back - * end implementation. Having this service allows UI and other clients - * access to the java.lang.Process object for monitoring. E.g. for displaying - * in Debug view and channeling I/O to the console view. - */ -public interface IBackEndProcess extends IDsfService { - /** - * Optional property identifying the process among other services. - * Since there could be multiple instances of this service running at the - * same time, a service property is needed to allow clients to distinguish - * between them. - */ - static final String PROCESS_ID = "org.eclipse.dsdp.DSF.debug.BackendProcess.PROCESS_ID"; //$NON-NLS-1$ - - /** - * Event indicating that the back end process has terminated. - */ - public interface IExitedEvent {} - - /** - * Returns the instance of the java process object representing the back - * end process. - * @return - */ - Process getProcess(); - - /** - * Returns true if back-end process has exited. - */ - boolean isExited(); -} From 6c6f7978db43b71da1907e5b57d82a61a7e0efae Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 13 Dec 2006 22:01:58 +0000 Subject: [PATCH 054/834] Applied patch on behalf of Randy Rohrback, containing refactored MI commands (bug 159688). --- .../ui/viewmodel/register/RegisterGroupLayoutNode.java | 6 +++--- .../src/org/eclipse/dd/dsf/debug/service/IRegisters.java | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java index f924d815f3b..c6f5e9f362e 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java @@ -14,7 +14,7 @@ import org.eclipse.dd.dsf.concurrent.GetDataDone; import org.eclipse.dd.dsf.datamodel.IDMContext; 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.IRegisters.IRegisterGroupDMData; import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; @@ -23,7 +23,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; @SuppressWarnings("restriction") -public class RegisterGroupLayoutNode extends AbstractDMVMLayoutNode { +public class RegisterGroupLayoutNode extends AbstractDMVMLayoutNode { public RegisterGroupLayoutNode(AbstractVMProvider provider, DsfSession session) { super(provider, session, IRegisters.IRegisterGroupDMContext.class); @@ -53,7 +53,7 @@ public class RegisterGroupLayoutNode extends AbstractDMVMLayoutNode dmContext, IRegisterGroupData dmData, + protected void fillColumnLabel(IDMContext dmContext, IRegisterGroupDMData dmData, String columnId, int idx, ILabelUpdate update) { if (RegisterColumnPresentation.COL_NAME.equals(columnId)) { diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java index d03004c2f7d..57fb46c6b29 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java @@ -22,13 +22,13 @@ import org.eclipse.dd.dsf.datamodel.IDMService; public interface IRegisters extends IDMService { /** Register group context */ - public interface IRegisterGroupDMContext extends IDMContext {} + public interface IRegisterGroupDMContext extends IDMContext {} /** - * Register groups only have a name. Sub groups and registered are retrieved + * Register groups only have a name. Sub groups and registers are retrieved * through the service interface. */ - public interface IRegisterGroupData extends IDMData { + public interface IRegisterGroupDMData extends IDMData { public String getName(); public String getDescription(); } From 750c30a12898eccb7c27c717b5c72e829d7d875c Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 5 Jan 2007 22:27:26 +0000 Subject: [PATCH 055/834] Added expression service (bug# 159696) Fixed updating the launch state upon startup and shutdown. --- .../launch/StandardLaunchRootLayoutNode.java | 69 +++++++++++++++---- .../launch/StandardProcessLayoutNode.java | 8 ++- .../viewmodel/dm/AbstractDMVMLayoutNode.java | 46 ++++++++----- 3 files changed, 93 insertions(+), 30 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java index bd1c1ba75b8..830f2c037e4 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java @@ -38,6 +38,17 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; public class StandardLaunchRootLayoutNode extends AbstractVMRootLayoutNode implements IVMRootLayoutNode { + public static class LaunchesEvent { + public enum Type { ADDED, REMOVED, CHANGED, TERMINATED }; + public final ILaunch[] fLaunches; + public final Type fType; + + public LaunchesEvent(ILaunch[] launches, Type type) { + fLaunches = launches; + fType = type; + } + } + final private ILaunch fLaunch; public StandardLaunchRootLayoutNode(AbstractVMProvider provider, ILaunch launch) { @@ -60,7 +71,21 @@ public class StandardLaunchRootLayoutNode extends AbstractVMRootLayoutNode return IModelDelta.NO_CHANGE; } } - return super.getDeltaFlags(e); + int flags = 0; + if (e instanceof LaunchesEvent) { + LaunchesEvent le = (LaunchesEvent)e; + for (ILaunch launch : le.fLaunches) { + if (fLaunch == launch) { + if (le.fType == LaunchesEvent.Type.CHANGED) { + flags = IModelDelta.STATE | IModelDelta.CONTENT; + } else if (le.fType == LaunchesEvent.Type.TERMINATED) { + flags = IModelDelta.STATE | IModelDelta.CONTENT; + } + } + } + } + + return flags | super.getDeltaFlags(e); } public void createDelta(Object event, final GetDataDone done) { @@ -74,19 +99,37 @@ public class StandardLaunchRootLayoutNode extends AbstractVMRootLayoutNode final VMDelta viewRootDelta = new VMDelta(manager, 0, IModelDelta.NO_CHANGE, launchList.size()); final VMDelta rootDelta = viewRootDelta.addNode(getRootObject(), launchList.indexOf(fLaunch), IModelDelta.NO_CHANGE); - final Map childNodeDeltas = getChildNodesWithDeltas(event); - assert childNodeDeltas.size() != 0 : "Caller should make sure that there are deltas for given event."; //$NON-NLS-1$ - - callChildNodesToBuildDelta( - childNodeDeltas, rootDelta, event, - new Done() { - public void run() { - if (isDisposed()) return; - if (propagateError(getExecutor(), done, "Failed to create delta.")); //$NON-NLS-1$ - done.setData(viewRootDelta); - getExecutor().execute(done); + // Generate delta for launch node. + if (event instanceof LaunchesEvent) { + LaunchesEvent le = (LaunchesEvent)event; + for (ILaunch launch : le.fLaunches) { + if (fLaunch == launch) { + if (le.fType == LaunchesEvent.Type.CHANGED) { + rootDelta.addFlags(IModelDelta.STATE | IModelDelta.CONTENT); + } else if (le.fType == LaunchesEvent.Type.TERMINATED) { + rootDelta.addFlags(IModelDelta.STATE | IModelDelta.CONTENT); + } } - }); + } + } + + // Call the child nodes to generate their delta. + final Map childNodeDeltas = getChildNodesWithDeltas(event); + if (childNodeDeltas.size() != 0) { + callChildNodesToBuildDelta( + childNodeDeltas, rootDelta, event, + new Done() { + public void run() { + if (isDisposed()) return; + if (propagateError(getExecutor(), done, "Failed to create delta.")); //$NON-NLS-1$ + done.setData(viewRootDelta); + getExecutor().execute(done); + } + }); + } else { + done.setData(viewRootDelta); + getExecutor().execute(done); + } } public Object getRootObject() { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessLayoutNode.java index 78f34c3eaa9..3bfbb2ebc3c 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessLayoutNode.java @@ -53,6 +53,10 @@ public class StandardProcessLayoutNode extends AbstractVMLayoutNode { public IVMLayoutNode getLayoutNode() { return StandardProcessLayoutNode.this; } @SuppressWarnings("unchecked") public Object getAdapter(Class adapter) { + Object vmcAdapter = super.getAdapter(adapter); + if (vmcAdapter != null) { + return vmcAdapter; + } return fProcess.getAdapter(adapter); } public String toString() { return "IProcess " + fProcess.toString(); } //$NON-NLS-1$ @@ -67,7 +71,9 @@ public class StandardProcessLayoutNode extends AbstractVMLayoutNode { public boolean isTerminated() { return fProcess.isTerminated(); } public void terminate() throws DebugException { fProcess.terminate(); } - public boolean equals(Object other) { return fProcess.equals(other); } + public boolean equals(Object other) { + return other instanceof VMC && fProcess.equals(((VMC)other).fProcess); + } public int hashCode() { return fProcess.hashCode(); } } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java index 775ecdf61ab..43088d2fa88 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java @@ -175,10 +175,16 @@ abstract public class AbstractDMVMLayoutNode extends Abstract } public void updateHasElements(final IHasChildrenUpdate[] updates) { - getSession().getExecutor().execute(new DsfRunnable() { - public void run() { - updateHasElementsInSessionThread(updates); - }}); + try { + getSession().getExecutor().execute(new DsfRunnable() { + public void run() { + updateHasElementsInSessionThread(updates); + }}); + } catch (RejectedExecutionException e) { + for (IHasChildrenUpdate update : updates) { + handleFailedUpdate(update); + } + } } protected void updateHasElementsInSessionThread(IHasChildrenUpdate[] updates) { @@ -206,12 +212,16 @@ abstract public class AbstractDMVMLayoutNode extends Abstract public void updateElementCount(final IChildrenCountUpdate update) { if (!checkUpdate(update)) return; - getSession().getExecutor().execute(new DsfRunnable() { - public void run() { - // After every dispatch, must check if update still valid. - if (!checkUpdate(update)) return; - updateElementCountInSessionThread(update); - }}); + try { + getSession().getExecutor().execute(new DsfRunnable() { + public void run() { + // After every dispatch, must check if update still valid. + if (!checkUpdate(update)) return; + updateElementCountInSessionThread(update); + }}); + } catch (RejectedExecutionException e) { + handleFailedUpdate(update); + } } protected void updateElementCountInSessionThread(final IChildrenCountUpdate update) { @@ -235,12 +245,16 @@ abstract public class AbstractDMVMLayoutNode extends Abstract public void updateElements(final IChildrenUpdate update) { if (!checkUpdate(update)) return; - getSession().getExecutor().execute(new DsfRunnable() { - public void run() { - // After every dispatch, must check if update still valid. - if (!checkUpdate(update)) return; - updateElementsInSessionThread(update); - }}); + try { + getSession().getExecutor().execute(new DsfRunnable() { + public void run() { + // After every dispatch, must check if update still valid. + if (!checkUpdate(update)) return; + updateElementsInSessionThread(update); + }}); + } catch (RejectedExecutionException e) { + handleFailedUpdate(update); + } } abstract protected void updateElementsInSessionThread(IChildrenUpdate update); From a037a34af243378e5709186534ed9a359dd7bf20 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Sun, 7 Jan 2007 22:06:42 +0000 Subject: [PATCH 056/834] temporarily remove docs from the sdk feature --- features/org.eclipse.dd.dsf.sdk-feature/feature.xml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/features/org.eclipse.dd.dsf.sdk-feature/feature.xml b/features/org.eclipse.dd.dsf.sdk-feature/feature.xml index bc022a4e7ca..cd63d9c30af 100644 --- a/features/org.eclipse.dd.dsf.sdk-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.sdk-feature/feature.xml @@ -31,12 +31,6 @@ version="0.0.0" unpack="false"/> - - Date: Mon, 8 Jan 2007 03:54:52 +0000 Subject: [PATCH 057/834] fixed copyright notice, license --- .../feature.xml | 67 ++++++++++++++++-- .../feature.xml | 12 ++-- .../feature.xml | 67 ++++++++++++++++-- .../feature.xml | 70 +++++++++++++++++-- 4 files changed, 193 insertions(+), 23 deletions(-) diff --git a/features/org.eclipse.dd.dsf.examples-feature/feature.xml b/features/org.eclipse.dd.dsf.examples-feature/feature.xml index caad9397279..1a9087969ea 100644 --- a/features/org.eclipse.dd.dsf.examples-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.examples-feature/feature.xml @@ -4,16 +4,71 @@ label="DSF Examples Feature" version="0.9.0"> - - [Enter Feature Description here.] + + Device Software Development Platform Project +Device Debug +Debug Services Framework +Examples - - [Enter Copyright Description here.] + + Copyright (c) 2006-2007 Wind River Systems and others. +All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html - - [Enter License Description here.] + + ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT +March 17, 2005 + +Usage Of Content + +THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT. + +Applicable Licenses + +Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is provided with this Content and is also available at http://www.eclipse.org/legal/epl-v10.html. For purposes of the EPL, "Program" will mean the Content. + +Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse.org CVS repository ("Repository") in CVS modules ("Modules") and made available as downloadable archives ("Downloads"). + + - Content may be structured and packaged into modules to facilitate delivering, + extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"), + plug-in fragments ("Fragments"), and features ("Features"). + - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive) + in a directory named "plugins". + - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. + Each Feature may be packaged as a sub-directory in a directory named "features". + Within a Feature, files named "feature.xml" may contain a list of the names and version + numbers of the Plug-ins and/or Fragments associated with that Feature. + - Features may also include other Features ("Included Features"). Within a Feature, files + named "feature.xml" may contain a list of the names and version numbers of Included Features. + +Features may also include other Features ("Included Features"). Files named "feature.xml" may contain a list of the names and version numbers of Included Features. + +The terms and conditions governing Plug-ins and Fragments should be contained in files named "about.html" ("Abouts"). The terms and conditions governing Features and Included Features should be contained in files named "license.html" ("Feature Licenses"). Abouts and Feature +Licenses may be located in any directory of a Download or Module including, but not limited to the following locations: + + - The top-level (root) directory + - Plug-in and Fragment directories + - Inside Plug-ins and Fragments packaged as JARs + - Sub-directories of the directory named "src" of certain Plug-ins + - Feature directories + +Note: if a Feature made available by the Eclipse Foundation is installed using the Eclipse Update Manager, you must agree to a license ("Feature Update License") during the installation process. If the Feature contains Included Features, the Feature Update License should either provide you +with the terms and conditions governing the Included Features or inform you where you can locate them. Feature Update Licenses may be found in the "license" property of files named "feature.properties". Such Abouts, Feature Licenses and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your +use of the associated Content in that directory. + +THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO): + + - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html) + +IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License or Feature Update License is provided, please contact the Eclipse Foundation to determine what terms and conditions govern that particular Content. + +Cryptography + +Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to another country, of encryption software. BEFORE using any encryption software, please check the country's laws, +regulations and policies concerning the import, possession, or use, and re-export of encryption software, to see if this is permitted. + +Java and all Java-based trademarks are trademarks of Sun Microsystem diff --git a/features/org.eclipse.dd.dsf.gdb-feature/feature.xml b/features/org.eclipse.dd.dsf.gdb-feature/feature.xml index f5d8adb8b12..ad37ff36d59 100644 --- a/features/org.eclipse.dd.dsf.gdb-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.gdb-feature/feature.xml @@ -4,12 +4,16 @@ label="DSF MI Feature" version="0.9.0"> - - [Enter Feature Description here.] + + Device Software Development Platform Project +Device Debug +Debug Services Framework +GDB-MI Implementation - - [Enter Copyright Description here.] + + Copyright (c) 2006-2007 Wind River Systems and others. +All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html diff --git a/features/org.eclipse.dd.dsf.sdk-feature/feature.xml b/features/org.eclipse.dd.dsf.sdk-feature/feature.xml index cd63d9c30af..41bba3d0def 100644 --- a/features/org.eclipse.dd.dsf.sdk-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.sdk-feature/feature.xml @@ -5,16 +5,71 @@ version="0.9.0" provider-name="Eclipse.org"> - - [Enter Feature Description here.] + + Device Software Development Platform Project +Device Debug +Debug Services Framework +Core SDK - - [Enter Copyright Description here.] + + Copyright (c) 2006-2007 Wind River Systems and others. +All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at - - [Enter License Description here.] + + ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT +March 17, 2005 + +Usage Of Content + +THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT. + +Applicable Licenses + +Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is provided with this Content and is also available at http://www.eclipse.org/legal/epl-v10.html. For purposes of the EPL, "Program" will mean the Content. + +Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse.org CVS repository ("Repository") in CVS modules ("Modules") and made available as downloadable archives ("Downloads"). + + - Content may be structured and packaged into modules to facilitate delivering, + extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"), + plug-in fragments ("Fragments"), and features ("Features"). + - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive) + in a directory named "plugins". + - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. + Each Feature may be packaged as a sub-directory in a directory named "features". + Within a Feature, files named "feature.xml" may contain a list of the names and version + numbers of the Plug-ins and/or Fragments associated with that Feature. + - Features may also include other Features ("Included Features"). Within a Feature, files + named "feature.xml" may contain a list of the names and version numbers of Included Features. + +Features may also include other Features ("Included Features"). Files named "feature.xml" may contain a list of the names and version numbers of Included Features. + +The terms and conditions governing Plug-ins and Fragments should be contained in files named "about.html" ("Abouts"). The terms and conditions governing Features and Included Features should be contained in files named "license.html" ("Feature Licenses"). Abouts and Feature +Licenses may be located in any directory of a Download or Module including, but not limited to the following locations: + + - The top-level (root) directory + - Plug-in and Fragment directories + - Inside Plug-ins and Fragments packaged as JARs + - Sub-directories of the directory named "src" of certain Plug-ins + - Feature directories + +Note: if a Feature made available by the Eclipse Foundation is installed using the Eclipse Update Manager, you must agree to a license ("Feature Update License") during the installation process. If the Feature contains Included Features, the Feature Update License should either provide you +with the terms and conditions governing the Included Features or inform you where you can locate them. Feature Update Licenses may be found in the "license" property of files named "feature.properties". Such Abouts, Feature Licenses and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your +use of the associated Content in that directory. + +THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO): + + - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html) + +IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License or Feature Update License is provided, please contact the Eclipse Foundation to determine what terms and conditions govern that particular Content. + +Cryptography + +Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to another country, of encryption software. BEFORE using any encryption software, please check the country's laws, +regulations and policies concerning the import, possession, or use, and re-export of encryption software, to see if this is permitted. + +Java and all Java-based trademarks are trademarks of Sun Microsystem diff --git a/features/org.eclipse.dd.dsf.test-feature/feature.xml b/features/org.eclipse.dd.dsf.test-feature/feature.xml index 52aaf777329..d829f773fc1 100644 --- a/features/org.eclipse.dd.dsf.test-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.test-feature/feature.xml @@ -2,18 +2,74 @@ + version="0.9.0" + provider-name="Eclipse.org"> - - [Enter Feature Description here.] + + Device Software Development Platform Project +Device Debug +Debug Services Framework +Tests - - [Enter Copyright Description here.] + + Copyright (c) 2006-2007 Wind River Systems and others. +All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html - - [Enter License Description here.] + + ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT +March 17, 2005 + +Usage Of Content + +THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT. + +Applicable Licenses + +Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is provided with this Content and is also available at http://www.eclipse.org/legal/epl-v10.html. For purposes of the EPL, "Program" will mean the Content. + +Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse.org CVS repository ("Repository") in CVS modules ("Modules") and made available as downloadable archives ("Downloads"). + + - Content may be structured and packaged into modules to facilitate delivering, + extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"), + plug-in fragments ("Fragments"), and features ("Features"). + - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive) + in a directory named "plugins". + - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. + Each Feature may be packaged as a sub-directory in a directory named "features". + Within a Feature, files named "feature.xml" may contain a list of the names and version + numbers of the Plug-ins and/or Fragments associated with that Feature. + - Features may also include other Features ("Included Features"). Within a Feature, files + named "feature.xml" may contain a list of the names and version numbers of Included Features. + +Features may also include other Features ("Included Features"). Files named "feature.xml" may contain a list of the names and version numbers of Included Features. + +The terms and conditions governing Plug-ins and Fragments should be contained in files named "about.html" ("Abouts"). The terms and conditions governing Features and Included Features should be contained in files named "license.html" ("Feature Licenses"). Abouts and Feature +Licenses may be located in any directory of a Download or Module including, but not limited to the following locations: + + - The top-level (root) directory + - Plug-in and Fragment directories + - Inside Plug-ins and Fragments packaged as JARs + - Sub-directories of the directory named "src" of certain Plug-ins + - Feature directories + +Note: if a Feature made available by the Eclipse Foundation is installed using the Eclipse Update Manager, you must agree to a license ("Feature Update License") during the installation process. If the Feature contains Included Features, the Feature Update License should either provide you +with the terms and conditions governing the Included Features or inform you where you can locate them. Feature Update Licenses may be found in the "license" property of files named "feature.properties". Such Abouts, Feature Licenses and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your +use of the associated Content in that directory. + +THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO): + + - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html) + +IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License or Feature Update License is provided, please contact the Eclipse Foundation to determine what terms and conditions govern that particular Content. + +Cryptography + +Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to another country, of encryption software. BEFORE using any encryption software, please check the country's laws, +regulations and policies concerning the import, possession, or use, and re-export of encryption software, to see if this is permitted. + +Java and all Java-based trademarks are trademarks of Sun Microsystem From 5e033e7ab4f69f376fc1277c87c4a48ae6abb132 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Fri, 12 Jan 2007 19:24:06 +0000 Subject: [PATCH 058/834] version .qualifier --- features/org.eclipse.dd.dsf.sdk-feature/feature.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/org.eclipse.dd.dsf.sdk-feature/feature.xml b/features/org.eclipse.dd.dsf.sdk-feature/feature.xml index 41bba3d0def..95b3409f0d2 100644 --- a/features/org.eclipse.dd.dsf.sdk-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.sdk-feature/feature.xml @@ -2,7 +2,7 @@ From 5a17ce63c4d9c226472a94949308b23bb8af4dca Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Fri, 12 Jan 2007 20:08:50 +0000 Subject: [PATCH 059/834] .qualifier --- features/org.eclipse.dd.dsf.examples-feature/feature.xml | 2 +- features/org.eclipse.dd.dsf.gdb-feature/feature.xml | 2 +- features/org.eclipse.dd.dsf.test-feature/feature.xml | 2 +- plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF | 2 +- plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF | 2 +- plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/features/org.eclipse.dd.dsf.examples-feature/feature.xml b/features/org.eclipse.dd.dsf.examples-feature/feature.xml index 1a9087969ea..73a89fb3504 100644 --- a/features/org.eclipse.dd.dsf.examples-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.examples-feature/feature.xml @@ -2,7 +2,7 @@ + version="0.9.0.qualifier"> Device Software Development Platform Project diff --git a/features/org.eclipse.dd.dsf.gdb-feature/feature.xml b/features/org.eclipse.dd.dsf.gdb-feature/feature.xml index ad37ff36d59..b0fcf61cac2 100644 --- a/features/org.eclipse.dd.dsf.gdb-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.gdb-feature/feature.xml @@ -2,7 +2,7 @@ + version="0.9.0.qualifier"> Device Software Development Platform Project diff --git a/features/org.eclipse.dd.dsf.test-feature/feature.xml b/features/org.eclipse.dd.dsf.test-feature/feature.xml index d829f773fc1..eaf7a6e9b11 100644 --- a/features/org.eclipse.dd.dsf.test-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.test-feature/feature.xml @@ -2,7 +2,7 @@ diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF index f043727ab9e..ec0c0bf3c98 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-Vendor: %providerName Bundle-SymbolicName: org.eclipse.dd.dsf.debug.ui -Bundle-Version: 0.9.0 +Bundle-Version: 0.9.0.qualifier Bundle-Activator: org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin Bundle-Localization: plugin Require-Bundle: org.eclipse.ui, diff --git a/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF index e438fd1debe..8b4e3330424 100644 --- a/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-Vendor: %providerName Bundle-SymbolicName: org.eclipse.dd.dsf.debug -Bundle-Version: 0.9.0 +Bundle-Version: 0.9.0.qualifier Bundle-Activator: org.eclipse.dd.dsf.debug.DsfDebugPlugin Bundle-Localization: plugin Require-Bundle: org.eclipse.core.runtime, diff --git a/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF index 6070a58d0f0..77125464c5a 100644 --- a/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-Vendor: %providerName Bundle-SymbolicName: org.eclipse.dd.dsf.ui -Bundle-Version: 0.9.0 +Bundle-Version: 0.9.0.qualifier Bundle-Activator: org.eclipse.dd.dsf.ui.DsfUIPlugin Bundle-Localization: plugin Require-Bundle: org.eclipse.ui, From 4ab54fe231569ee20c82845bfaab9baf1f6bceab Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Tue, 23 Jan 2007 17:11:32 +0000 Subject: [PATCH 060/834] this executor utilizes the SWT UI dispatch thread. --- .../ui/concurrent/SWTDispatchDsfExecutor.java | 137 ++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/SWTDispatchDsfExecutor.java diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/SWTDispatchDsfExecutor.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/SWTDispatchDsfExecutor.java new file mode 100644 index 00000000000..71e22929638 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/SWTDispatchDsfExecutor.java @@ -0,0 +1,137 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.dsf.ui.concurrent; + +import java.util.concurrent.Callable; +import java.util.concurrent.Future; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor; +import org.eclipse.swt.widgets.Display; + +public class SWTDispatchDsfExecutor extends DefaultDsfExecutor +{ + + public SWTDispatchDsfExecutor() + { + super(); + } + + private Callable createSWTDispatchCallable(final Callable callable) + { + return new Callable() + { + public V call() throws Exception + { + final Object[] v = new Object[1]; + final Throwable[] e = new Throwable[1]; + + Display.getDefault().syncExec(new Runnable() + { + public void run() + { + try + { + v[0] = callable.call(); + } + catch(Throwable exception) + { + e[0] = exception; + } + } + }); + + if(e[0] instanceof RuntimeException) + throw (RuntimeException) e[0]; + else if(e[0] instanceof Exception) + throw (Exception) e[0]; + + return (V) v[0]; + } + }; + } + + private Runnable createSWTDispatchRunnable(final Runnable runnable) + { + return new Runnable() + { + public void run() + { + final Throwable[] e = new Throwable[1]; + + Display.getDefault().syncExec(new Runnable() + { + public void run() + { + try + { + runnable.run(); + } + catch(Throwable exception) + { + e[0] = exception; + } + } + }); + + if(e[0] instanceof RuntimeException) + throw (RuntimeException) e[0]; + } + }; + } + + @Override + public ScheduledFuture schedule(final Callable callable, long delay, + TimeUnit unit) { + return super.schedule(createSWTDispatchCallable(callable), delay, unit); + } + + @Override + public ScheduledFuture schedule(Runnable command, long delay, + TimeUnit unit) { + return super.schedule(createSWTDispatchRunnable(command), delay, unit); + } + + @Override + public ScheduledFuture scheduleAtFixedRate(Runnable command, + long initialDelay, long period, TimeUnit unit) { + return super.scheduleAtFixedRate(createSWTDispatchRunnable(command), initialDelay, period, unit); + } + + @Override + public ScheduledFuture scheduleWithFixedDelay(Runnable command, + long initialDelay, long delay, TimeUnit unit) { + return super.scheduleWithFixedDelay(createSWTDispatchRunnable(command), initialDelay, delay, unit); + } + + @Override + public void execute(Runnable command) { + super.execute(createSWTDispatchRunnable(command)); + } + + @Override + public Future submit(Callable callable) { + return super.submit(createSWTDispatchCallable(callable)); + } + + @Override + public Future submit(Runnable command, T result) { + return super.submit(createSWTDispatchRunnable(command), result); + } + + @Override + public Future submit(Runnable command) { + return super.submit(createSWTDispatchRunnable(command)); + } + +} From b1a5e0fca5cc8b22de11646cb8da613d9c45e100 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Thu, 1 Feb 2007 20:48:44 +0000 Subject: [PATCH 061/834] added org.eclipse.dd.dsf.ui.concurrent to Export-Package --- plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF index 77125464c5a..ac57942403e 100644 --- a/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF @@ -12,5 +12,6 @@ Require-Bundle: org.eclipse.ui, org.eclipse.debug.ui Eclipse-LazyStart: true Export-Package: org.eclipse.dd.dsf.ui.viewmodel, - org.eclipse.dd.dsf.ui.viewmodel.dm + org.eclipse.dd.dsf.ui.viewmodel.dm, + org.eclipse.dd.dsf.ui.concurrent Bundle-RequiredExecutionEnvironment: J2SE-1.5 From 9d2cde2b8e939bc833d184a6287238b39b6b4aa7 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Fri, 23 Feb 2007 18:44:43 +0000 Subject: [PATCH 062/834] Changes necessary to execute against M5 eclipse. Please search for // FIXME M5 --- .../dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java | 7 ++++++- .../dd/dsf/ui/viewmodel/AbstractVMProvider.java | 12 ++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java index 98698e6a429..eeb94b8bafe 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java @@ -327,7 +327,12 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { } protected class ViewerUpdate implements IViewerUpdate { - final private Done fDone; + + public void cancel() { + // FIXME M5 + } + + final private Done fDone; private boolean fDoneInvoked = false; final private TreePath fTreePath; private IStatus fStatus; diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java index 821b1e1184c..9befc631b76 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java @@ -531,7 +531,12 @@ abstract public class AbstractVMProvider implements IVMProvider } class ViewerUpdate implements IViewerUpdate { - private IStatus fStatus; + + public void cancel() { + // FIXME M5 + } + + private IStatus fStatus; private boolean fDoneInvoked = false; final private Done fDone; final protected IViewerUpdate fClientUpdate; @@ -550,7 +555,10 @@ abstract public class AbstractVMProvider implements IVMProvider public void beginTask(String name, int totalWork) {} public void internalWorked(double work) {} public boolean isCanceled() { return fClientUpdate.isCanceled(); } - public void setCanceled(boolean value) { fClientUpdate.setCanceled(value); } + public void setCanceled(boolean value) { + // FIXME M5 + // fClientUpdate.setCanceled(value); + } public void setTaskName(String name) {} public void subTask(String name) {} public void worked(int work) {} From bd63dcf820aba7f357370490f9841ac9aa6fa3a5 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Fri, 23 Feb 2007 20:01:04 +0000 Subject: [PATCH 063/834] 175239 - features renamed --- features/org.eclipse.dd.dsf.gdb-feature/feature.xml | 2 +- features/org.eclipse.dd.dsf.sdk-feature/feature.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/features/org.eclipse.dd.dsf.gdb-feature/feature.xml b/features/org.eclipse.dd.dsf.gdb-feature/feature.xml index b0fcf61cac2..b20dc9d212d 100644 --- a/features/org.eclipse.dd.dsf.gdb-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.gdb-feature/feature.xml @@ -1,7 +1,7 @@ diff --git a/features/org.eclipse.dd.dsf.sdk-feature/feature.xml b/features/org.eclipse.dd.dsf.sdk-feature/feature.xml index 95b3409f0d2..9eba90e5d9d 100644 --- a/features/org.eclipse.dd.dsf.sdk-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.sdk-feature/feature.xml @@ -1,7 +1,7 @@ From 11aaafc82981f60aecc37d9a1846cf3edd5c53d1 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 21 Mar 2007 23:52:14 +0000 Subject: [PATCH 064/834] Added an example of a view model with a recursive layout node (bug 178692). --- .../launch/StandardLaunchRootLayoutNode.java | 2 +- .../ui/viewmodel/AbstractVMLayoutNode.java | 70 +++++++++++++------ .../dsf/ui/viewmodel/AbstractVMProvider.java | 65 ++++++----------- .../viewmodel/AbstractVMRootLayoutNode.java | 2 +- .../dd/dsf/ui/viewmodel/IVMLayoutNode.java | 24 ++++++- .../dd/dsf/ui/viewmodel/IVMProvider.java | 5 -- .../eclipse/dd/dsf/ui/viewmodel/VMDelta.java | 4 +- .../viewmodel/dm/AbstractDMVMLayoutNode.java | 2 +- 8 files changed, 96 insertions(+), 78 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java index 830f2c037e4..49de1e0b869 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java @@ -114,7 +114,7 @@ public class StandardLaunchRootLayoutNode extends AbstractVMRootLayoutNode } // Call the child nodes to generate their delta. - final Map childNodeDeltas = getChildNodesWithDeltas(event); + final Map childNodeDeltas = getChildNodesWithDeltaFlags(event); if (childNodeDeltas.size() != 0) { callChildNodesToBuildDelta( childNodeDeltas, rootDelta, event, diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java index eeb94b8bafe..2e975953274 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java @@ -60,7 +60,7 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { return fProvider.getExecutor(); } - protected IVMProvider getVMProvider() { + protected AbstractVMProvider getVMProvider() { return fProvider; } @@ -91,17 +91,20 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { return retVal; } - /** - * 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. + /** + * Base implementation that handles calling child layout nodes to build + * the model delta. The child nodes are called with all the elements + * in this node, which could be very inefficient. In order to build delta + * only for specific elements in this node, the class extending + * AbstractVMLayoutNode should override this method. + * @see IVMLayoutNode#buildDelta(Object, VMDelta, int, Done) */ public void buildDelta(final Object event, final VMDelta parentDelta, final int nodeOffset, final Done done) { // Find the child nodes that have deltas for the given event. - final Map childNodeDeltas = getChildNodesWithDeltas(event); + final Map childNodesWithDeltaFlags = getChildNodesWithDeltaFlags(event); // If no child layout nodes have deltas we can stop here. - if (childNodeDeltas.size() == 0) { + if (childNodesWithDeltaFlags.size() == 0) { getExecutor().execute(done); return; } @@ -112,14 +115,14 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { // use the full path from the delta to handle these flags. // Similarly, the index argument is not necessary either. boolean mustGetElements = false; - for (int childDelta : childNodeDeltas.values()) { + for (int childDelta : childNodesWithDeltaFlags.values()) { if ((childDelta & ~IModelDelta.CONTENT & ~IModelDelta.STATE) != 0) { mustGetElements = true; } } if (!mustGetElements) { - callChildNodesToBuildDelta(childNodeDeltas, parentDelta, event, done); + callChildNodesToBuildDelta(childNodesWithDeltaFlags, parentDelta, event, done); } else { // The given child layout nodes have deltas potentially for all elements // from this node. Retrieve all elements and call the child nodes with @@ -147,9 +150,9 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { // For each element from this node, create a new delta, // and then call all the child nodes to build their delta. for (int i = 0; i < getData().size(); i++) { - VMDelta delta = parentDelta.addNode((IVMContext)getData().get(i), nodeOffset + i, IModelDelta.NO_CHANGE); + VMDelta delta = parentDelta.addNode(getData().get(i), nodeOffset + i, IModelDelta.NO_CHANGE); callChildNodesToBuildDelta( - childNodeDeltas, delta, event, + childNodesWithDeltaFlags, delta, event, elementsDeltasDoneCollector.add(new Done() { public void run() { elementsDeltasDoneCollector.doneDone(this); @@ -162,6 +165,17 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { } } + /** + * Calls the specified child layout nodes to build the delta for the given event. + * @param nodes Map of layout nodes to be invoked, and the corresponding delta + * flags that they will generate. This map is generated with a call to + * {@link #getChildNodesWithDeltaFlags(Object)}. + * @param delta The delta object to build on. This delta should have been + * gerated by this node, unless the full delta path is not being calculated + * due to an optimization. + * @param event The event object that the delta is being built for. + * @param done The result token to invoke when the delta is completed. + */ protected void callChildNodesToBuildDelta(final Map nodes, final VMDelta delta, final Object event, final Done done) { assert nodes.size() != 0; @@ -203,6 +217,22 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { }); } + /** + * Calculates the indexes at which the elements of each of the child + * layout nodes begin. These indexes are necessary to correctly + * calculate the deltas for elements in the child nodes. + * @param delta The delta object to build on. This delta should have been + * gerated by this node, unless the full delta path is not being calculated + * due to an optimization. + * @param fakeIt If true, it causes this method to fill the return data + * structure with dummy values. The dummy values indicate that the indexes + * are not known and are acceptable in the delta if the delta flags being + * generated do not require full index information. + * @param done Return token containing the results. The result data is a + * mapping between the child nodes and the indexes at which the child nodes' + * elements begin. There is a special value in the map with a null + * key, which contains the full element count for all the nodes. + */ private void getChildNodesElementOffsets(IModelDelta delta, boolean fakeIt, final GetDataDone> done) { assert getChildLayoutNodes().length != 0; @@ -258,7 +288,7 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { * true to the hasDeltaFlags() test for the given * event. */ - protected Map getChildNodesWithDeltas(Object e) { + protected Map getChildNodesWithDeltaFlags(Object e) { Map nodes = new HashMap(); for (final IVMLayoutNode childNode : getChildLayoutNodes()) { int delta = childNode.getDeltaFlags(e); @@ -328,10 +358,6 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { protected class ViewerUpdate implements IViewerUpdate { - public void cancel() { - // FIXME M5 - } - final private Done fDone; private boolean fDoneInvoked = false; final private TreePath fTreePath; @@ -372,13 +398,8 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { public TreePath getElementPath() { return fTreePath; } public IStatus getStatus() { return fStatus; } public void setStatus(IStatus status) { fStatus = status; } - public void beginTask(String name, int totalWork) {} - public void internalWorked(double work) {} public boolean isCanceled() { return fCancelled; } - public void setCanceled(boolean value) { fCancelled = value; } - public void setTaskName(String name) {} - public void subTask(String name) {} - public void worked(int work) {} + public void cancel() { fCancelled = true; } public void done() { assert !fDoneInvoked; @@ -430,6 +451,11 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { public void setChild(Object child, int offset) { fChildren.add(offset, child); } + + @Override + public String toString() { + return "ElementsUpdate for all elements under parent = " + getElement(); //$NON-NLS-1$ + } } } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java index 9befc631b76..130ce67293a 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java @@ -28,8 +28,6 @@ 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.IDsfService; import org.eclipse.dd.dsf.ui.DsfUIPlugin; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; @@ -90,14 +88,14 @@ abstract public class AbstractVMProvider implements IVMProvider fPresentationContext = presentationContext; } - public IVMAdapter getVMAdapter() { - return fVMAdapter; - } - public IPresentationContext getPresentationContext() { return fPresentationContext; } - + + public AbstractVMAdapter getVMAdapter() { + return fVMAdapter; + } + /** * Sets the root node for this provider. */ @@ -459,30 +457,6 @@ abstract public class AbstractVMProvider implements IVMProvider return false; } - /** - * 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) { - IVMRootLayoutNode rootLayoutNode = getRootLayoutNode(); - - if (rootLayoutNode != null && rootLayoutNode.getDeltaFlags(event) != 0) { - rootLayoutNode.createDelta(event, new GetDataDone() { - public void run() { - if (getStatus().isOK()) { - fModelProxy.fireModelChangedNonDispatch(getData()); - } - } - @Override public String toString() { - return "Result of a delta for event: '" + event.toString() + "' in VMP: '" + AbstractVMProvider.this + "'" + "\n" + getData().toString(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - } - }); - } - } @ThreadSafe protected class ModelProxy extends AbstractModelProxy { @@ -500,10 +474,12 @@ abstract public class AbstractVMProvider implements IVMProvider public boolean isConflicting(ISchedulingRule rule) { return rule == this; } }; + @Override public void installed(Viewer viewer) { fProxyActive++; } + @Override public void dispose() { fProxyActive--; super.dispose(); @@ -518,6 +494,7 @@ abstract public class AbstractVMProvider implements IVMProvider if (fProxyActive <= 0) return; Job job = new Job("Processing view model delta.") { //$NON-NLS-1$ + @Override protected IStatus run(IProgressMonitor monitor) { fireModelChanged(delta); return Status.OK_STATUS; @@ -532,10 +509,6 @@ abstract public class AbstractVMProvider implements IVMProvider class ViewerUpdate implements IViewerUpdate { - public void cancel() { - // FIXME M5 - } - private IStatus fStatus; private boolean fDoneInvoked = false; final private Done fDone; @@ -552,17 +525,11 @@ abstract public class AbstractVMProvider implements IVMProvider public IStatus getStatus() { return fStatus; } public void setStatus(IStatus status) { fStatus = status; } - public void beginTask(String name, int totalWork) {} - public void internalWorked(double work) {} public boolean isCanceled() { return fClientUpdate.isCanceled(); } - public void setCanceled(boolean value) { - // FIXME M5 - // fClientUpdate.setCanceled(value); + public void cancel() { + fClientUpdate.cancel(); } - public void setTaskName(String name) {} - public void subTask(String name) {} - public void worked(int work) {} - + public void done() { assert !fDoneInvoked; fDoneInvoked = true; @@ -583,6 +550,7 @@ abstract public class AbstractVMProvider implements IVMProvider fDone = done; } + @Override public TreePath getElementPath() { return ((IHasChildrenUpdate)fClientUpdate).getElementPath(); } @@ -591,6 +559,7 @@ abstract public class AbstractVMProvider implements IVMProvider fDone.setData(hasChildren); } + @Override public void done() { assert fDone.getData() != null || !fDone.getStatus().isOK(); super.done(); @@ -607,6 +576,7 @@ abstract public class AbstractVMProvider implements IVMProvider fDone = done; } + @Override public TreePath getElementPath() { return fElementPath; } @@ -615,6 +585,7 @@ abstract public class AbstractVMProvider implements IVMProvider fDone.setData(count); } + @Override public void done() { assert fDone.getData() != null || !fDone.getStatus().isOK(); super.done(); @@ -642,6 +613,7 @@ abstract public class AbstractVMProvider implements IVMProvider return fLength; } + @Override public TreePath getElementPath() { return ((IChildrenUpdate)fClientUpdate).getElementPath(); } @@ -652,5 +624,10 @@ abstract public class AbstractVMProvider implements IVMProvider } } + @Override + public String toString() { + return "ElementsUpdate for elements under parent = " + getElement() + ", in range " + getOffset() + " -> " + (getOffset() + getLength()); //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$ + } + } } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMRootLayoutNode.java index 53d5650d917..8bd73da70ed 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMRootLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMRootLayoutNode.java @@ -77,7 +77,7 @@ abstract public class AbstractVMRootLayoutNode extends AbstractVMLayoutNode impl * is the input object into the view. */ public void createDelta(Object event, final GetDataDone done) { - final Map childNodeDeltas = getChildNodesWithDeltas(event); + final Map childNodeDeltas = getChildNodesWithDeltaFlags(event); assert childNodeDeltas.size() != 0 : "Caller should make sure that there are deltas for given event."; //$NON-NLS-1$ // Always create the rootDelta, no matter what delta flags the child nodes have. diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMLayoutNode.java index 883d0e23d0d..b6af2856cd8 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMLayoutNode.java @@ -60,7 +60,8 @@ public interface IVMLayoutNode /** * Retrieves the element objects of this node for the given path in the * viewer, and for the given range of indexes.
    - * Note: the range of children, denoted by ILabelUpdate.getOffset() + * NOTE: update.getOffset() and update.getLength() may return -1. + * The range of children, denoted by ILabelUpdate.getOffset() * and ILabelUpdate.getLength(), may not be specified, in which case these * methods may return -1. This means that all the elements should be * retrieved for this node.
    @@ -89,12 +90,31 @@ public interface IVMLayoutNode * for the given event. * @param event Event to process. * @return IModelDelta flags + * @see #buildDelta(Object, VMDelta, int, Done) * @see IModelDelta */ public int getDeltaFlags(Object event); /** - * Builds model delta information based on the given event. + * Builds model delta information based on the given event. + *

    + * Model deltas, which are used to control the state of elements in the viewer, are + * generated by the layout nodes by recursively calling this method on all the nodes + * in the layout tree. Each node implements two methods: {@link #getDeltaFlags(Object)}, + * and buildDelta(). A parent node which is processing a + * buildDelta operation needs to determine which of its elements are + * affected by a given event, set appropriate flags on these elements, and then + * it needs to call its child nodes with those elements to give the child nodes a + * chance to add onto the delta. + *

    + *

    + * The getDeltaFlags() is a synchronous + * call which tells the parent node whether on not to call the child node's + * buildDelta with the given event. If a child node return + * true, it only indicates that the node may add delta flags, but it + * does not require it to do so. + *

    + * * @param event Event to process. * @param parent Parent model delta node that this object should add delta * data to. diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java index 44b2a3e6504..c8bd7c4d542 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java @@ -16,11 +16,6 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationCont public interface IVMProvider extends IElementContentProvider, IModelProxyFactoryAdapter, IColumnPresentationFactoryAdapter { - /** - * Returns the View Model Adapter that this provider belongs to. - */ - public IVMAdapter getVMAdapter(); - /** * Returns the root layout node that is configured in this provider. * It may return null, if a root node is not yet configured. diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java index 6c524768b3f..906c71e9502 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java @@ -177,7 +177,7 @@ public class VMDelta extends ModelDelta { * @param numChildren the number of children the element has * @return newly created child delta */ - public ModelDelta addNode(Object element, int index, int flags, int numChildren) { + public VMDelta addNode(Object element, int index, int flags, int numChildren) { VMDelta node = new VMDelta(element, index, flags, numChildren); node.setParent(this); addDelta(node); @@ -197,7 +197,7 @@ public class VMDelta extends ModelDelta { * @see org.eclipse.debug.internal.ui.viewers.IModelDelta#getParent() */ @Override - public IModelDelta getParentDelta() { + public VMDelta getParentDelta() { return fParent; } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java index 43088d2fa88..5b35febce0e 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java @@ -388,7 +388,7 @@ abstract public class AbstractDMVMLayoutNode extends Abstract // Create the VM context based on the DM context from the DM event. final IVMContext vmc = new DMVMContext(DMContexts.getAncestorOfType(event.getDMContext(), fDMCClassType)); - final Map childNodeDeltas = getChildNodesWithDeltas(event); + final Map childNodeDeltas = getChildNodesWithDeltaFlags(event); if (childNodeDeltas.size() == 0) { // There are no child nodes with deltas, just return to parent. getExecutor().execute(done); From caa4c1b3550c2c22918ece16c3b5d04ec404fe76 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 23 Mar 2007 17:00:36 +0000 Subject: [PATCH 065/834] Generics warnings cleanup (bug 178689). --- .../dd/dsf/debug/ui/DsfDebugUIPlugin.java | 6 +- .../DebugViewSelectionRootLayoutNode.java | 7 +- .../launch/StackFramesLayoutNode.java | 3 +- .../launch/StandardLaunchRootLayoutNode.java | 5 +- .../launch/StandardProcessLayoutNode.java | 12 ++- .../META-INF/MANIFEST.MF | 3 +- .../eclipse/dd/dsf/debug/DsfDebugPlugin.java | 6 +- .../dd/dsf/debug/service/IModules.java | 2 + .../dsf/debug/service/command/ICommand.java | 36 +++++++++ .../service/command/ICommandControl.java | 80 +++++++++++++++++++ .../service/command/ICommandListener.java | 54 +++++++++++++ .../debug/service/command/ICommandResult.java | 27 +++++++ .../debug/service/command/IEventListener.java | 19 +++++ .../org/eclipse/dd/dsf/ui/DsfUIPlugin.java | 6 +- .../ui/concurrent/SWTDispatchDsfExecutor.java | 3 +- .../ui/viewmodel/AbstractVMLayoutNode.java | 16 ++-- .../dsf/ui/viewmodel/AbstractVMProvider.java | 16 ++-- .../viewmodel/AbstractVMRootLayoutNode.java | 5 +- .../eclipse/dd/dsf/ui/viewmodel/VMDelta.java | 9 ++- .../viewmodel/dm/AbstractDMVMLayoutNode.java | 14 +++- .../ui/viewmodel/dm/AbstractDMVMProvider.java | 1 + .../src/org/eclipse/dd/dsf/DsfPlugin.java | 6 +- .../dd/dsf/concurrent/DefaultDsfExecutor.java | 2 + .../org/eclipse/dd/dsf/concurrent/Done.java | 1 + .../dd/dsf/concurrent/DsfExecutable.java | 1 - .../eclipse/dd/dsf/concurrent/DsfQuery.java | 2 + .../dd/dsf/concurrent/DsfSequence.java | 5 +- .../dd/dsf/concurrent/GetDataDone.java | 1 + .../dd/dsf/concurrent/StackTraceWrapper.java | 1 + .../dd/dsf/datamodel/AbstractDMContext.java | 1 + .../dd/dsf/datamodel/ServiceDMContext.java | 1 + .../dd/dsf/service/DsfServicesTracker.java | 2 + .../eclipse/dd/dsf/service/DsfSession.java | 10 ++- 33 files changed, 318 insertions(+), 45 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommand.java create mode 100644 plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandControl.java create mode 100644 plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandListener.java create mode 100644 plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandResult.java create mode 100644 plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/IEventListener.java diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/DsfDebugUIPlugin.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/DsfDebugUIPlugin.java index f38e404fc17..5f8d59f5f4f 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/DsfDebugUIPlugin.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/DsfDebugUIPlugin.java @@ -25,7 +25,8 @@ public class DsfDebugUIPlugin extends AbstractUIPlugin { * (non-Javadoc) * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) */ - public void start(BundleContext context) throws Exception { + @Override + public void start(BundleContext context) throws Exception { super.start(context); plugin = this; } @@ -34,7 +35,8 @@ public class DsfDebugUIPlugin extends AbstractUIPlugin { * (non-Javadoc) * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) */ - public void stop(BundleContext context) throws Exception { + @Override + public void stop(BundleContext context) throws Exception { plugin = null; super.stop(context); } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewSelectionRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewSelectionRootLayoutNode.java index a147deafe8f..73ba8d9e0e9 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewSelectionRootLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewSelectionRootLayoutNode.java @@ -86,7 +86,7 @@ public class DebugViewSelectionRootLayoutNode extends AbstractVMRootLayoutNode boolean potentialMatchFound = false; boolean matchFound = false; - IDMContext eventDmc = ((IDMEvent)event).getDMContext(); + IDMContext eventDmc = ((IDMEvent)event).getDMContext(); for (IDMContext eventDmcAncestor : DMContexts.toList(eventDmc)) { IDMContext inputDmcAncestor = DMContexts.getAncestorOfType(inputDmc, eventDmcAncestor.getClass()); if (inputDmcAncestor != null) { @@ -129,7 +129,10 @@ public class DebugViewSelectionRootLayoutNode extends AbstractVMRootLayoutNode IStructuredSelection structSelection = (IStructuredSelection)selection; if (structSelection.getFirstElement() instanceof DMVMContext) { - return ((DMVMContext)structSelection.getFirstElement()).getDMC(); + // Correct cast: (AbstractDMVMLayoutNode.DMVMContext) breaks the javac compiler + @SuppressWarnings("unchecked") + DMVMContext vmc = (DMVMContext)structSelection.getFirstElement(); + return vmc.getDMC(); } } return null; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java index 0bd4d240637..348fc14ed89 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java @@ -190,6 +190,7 @@ public class StackFramesLayoutNode extends AbstractDMVMLayoutNode done) { /* * Create the root of the delta. Since the launch object is not at the @@ -121,7 +122,7 @@ public class StandardLaunchRootLayoutNode extends AbstractVMRootLayoutNode new Done() { public void run() { if (isDisposed()) return; - if (propagateError(getExecutor(), done, "Failed to create delta.")); //$NON-NLS-1$ + if (propagateError(getExecutor(), done, "Failed to create delta.")) return; //$NON-NLS-1$ done.setData(viewRootDelta); getExecutor().execute(done); } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessLayoutNode.java index 3bfbb2ebc3c..e65a4ba59c1 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessLayoutNode.java @@ -51,14 +51,18 @@ public class StandardProcessLayoutNode extends AbstractVMLayoutNode { fProcess = process; } + @Override public IVMLayoutNode getLayoutNode() { return StandardProcessLayoutNode.this; } - @SuppressWarnings("unchecked") public Object getAdapter(Class adapter) { + @Override + @SuppressWarnings("unchecked") + public Object getAdapter(Class adapter) { Object vmcAdapter = super.getAdapter(adapter); if (vmcAdapter != null) { return vmcAdapter; } return fProcess.getAdapter(adapter); } + @Override public String toString() { return "IProcess " + fProcess.toString(); } //$NON-NLS-1$ public String getAttribute(String key) { return fProcess.getAttribute(key); } @@ -71,9 +75,11 @@ public class StandardProcessLayoutNode extends AbstractVMLayoutNode { public boolean isTerminated() { return fProcess.isTerminated(); } public void terminate() throws DebugException { fProcess.terminate(); } + @Override public boolean equals(Object other) { return other instanceof VMC && fProcess.equals(((VMC)other).fProcess); } + @Override public int hashCode() { return fProcess.hashCode(); } } @@ -132,7 +138,7 @@ public class StandardProcessLayoutNode extends AbstractVMLayoutNode { } // @see org.eclipse.dd.dsf.ui.viewmodel.IViewModelLayoutNode#retrieveLabel(org.eclipse.dd.dsf.ui.viewmodel.IVMContext, org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor) - public void updateLabel(IVMContext vmc, ILabelRequestMonitor result, String[] columns) { + public void updateLabel(@SuppressWarnings("unused")IVMContext vmc, ILabelRequestMonitor result, @SuppressWarnings("unused") String[] columns) { /* * The implementation of IAdapterFactory that uses this node should not @@ -198,7 +204,7 @@ public class StandardProcessLayoutNode extends AbstractVMLayoutNode { parent.addNode(new VMC((IProcess)event.getSource()), IModelDelta.STATE); } - protected void handleCreate(DebugEvent event, VMDelta parent) { + protected void handleCreate(@SuppressWarnings("unused") DebugEvent event, @SuppressWarnings("unused") VMDelta parent) { // do nothing - Launch change notification handles this } diff --git a/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF index 8b4e3330424..b94b7631e23 100644 --- a/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF @@ -10,5 +10,6 @@ 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 +Export-Package: org.eclipse.dd.dsf.debug.service, + org.eclipse.dd.dsf.debug.service.command Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/DsfDebugPlugin.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/DsfDebugPlugin.java index a0b8f8b600b..7a8cbd969f3 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/DsfDebugPlugin.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/DsfDebugPlugin.java @@ -42,7 +42,8 @@ public class DsfDebugPlugin extends Plugin { * (non-Javadoc) * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext) */ - public void start(BundleContext context) throws Exception { + @Override + 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$ @@ -52,7 +53,8 @@ public class DsfDebugPlugin extends Plugin { * (non-Javadoc) * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext) */ - public void stop(BundleContext context) throws Exception { + @Override + public void stop(BundleContext context) throws Exception { fgPlugin = null; fgBundleContext = null; super.stop(context); diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java index 0c96960a1ec..dd12e4e7914 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java @@ -75,10 +75,12 @@ public interface IModules extends IDMService { this.fOffset = offset; } + @Override public int hashCode() { return fModule.hashCode() + fSection.hashCode() + fOffset.intValue(); } + @Override public boolean equals(Object o) { if (!(o instanceof ModuleSectionOffset)) return false; ModuleSectionOffset mso = (ModuleSectionOffset)o; diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommand.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommand.java new file mode 100644 index 00000000000..0b67c7cc1b3 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommand.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.dsf.debug.service.command; + + +/** + * Command interface for creating and manipulating GDB/MI commands + * for the DSF GDB reference implemenation. The command represents + * the GDB/MI request which will be put on the wire to the GDB + * backend. + */ + +public interface ICommand { + /** + * Takes the supplied command and coalesces it with this one. + * The result is a new third command which represent the two + * original commands. + *
    Note: the result type associated with the resurned command may be + * different than the result type associated with either of the commands + * being coalesced. + * + * @return newly created command, or null if command cannot be coalesced + */ + public ICommand coalesceWith( ICommand command ); +} + + diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandControl.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandControl.java new file mode 100644 index 00000000000..e58f40b77be --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandControl.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * 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.command; + +import org.eclipse.dd.dsf.concurrent.GetDataDone; +import org.eclipse.dd.dsf.service.IDsfService; + +/** + * API for sending commands to the debugger and for receiving command results + * and asynchronous events. + */ +public interface ICommandControl extends IDsfService{ + + /** + * Adds the specified command to the queue of commands to be processed. + * + * @param command Specific command to be processed + * @param done Completion notification handler + * @return None + */ + void queueCommand(ICommand command, GetDataDone done); + + /** + * Removes the specified command from the processor queue. + * + * @param command Specific command to be removed + * @return None + */ + void removeCommand(ICommand command); + + /** + * Attempts to cancel and already sent command. Some versions + * of GDB/MI implement control commands which allow this. The + * GDB/MI standard does not currently allow for this. + * + * @param command Specific command to be removed + * @return None + */ + void cancelCommand(ICommand command); + + /** + * Adds a notification handler for the Command processor. + * + * @param command listener to be added + * @return None + */ + void addCommandListener(ICommandListener listener); + + /** + * Removes a notification handler for the Command processor. + * + * @param command listener to be removed + * @return None + */ + void removeCommandListener(ICommandListener listener); + + /** + * Adds a notification handler for the Event processor. + * + * @param event listener to be added + * @return None + */ + void addEventListener(IEventListener listener); + + /** + * Removes a notification handler for the Event processor. + * + * @param event listener to be removed + * @return None + */ + void removeEventListener(IEventListener listener); +} diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandListener.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandListener.java new file mode 100644 index 00000000000..5a2f8e813a6 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandListener.java @@ -0,0 +1,54 @@ +package org.eclipse.dd.dsf.debug.service.command; + +import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; + +/** + * Synchronous listener to commands being sent and received. + * All the registered listeners will be called in the same + * dispatch cycle as when the result of the command is submitted. + */ + +@ConfinedToDsfExecutor("") +public interface ICommandListener { + /** + * Notifies that the specified command has been added to the Command Queue. + * It has not yet been sent. In this state the command can be examined and + * possibly withdrawn because it has been coalesced with another command. + * + * @return None + * @param command Command which has been added to the Queue + */ + public void commandQueued(ICommand command); + + /** + * Notification that the given command was sent to the debugger. At this + * point the command is no longer in the Command Queue and should not be + * examined. The only thing which can be done is to try and cancel the + * command. + * + * @return None + * @param command + */ + public void commandSent(ICommand command); + + /** + * Notifies that the specified command has been removed from the + * Command Queue. This notification means that the command has + * been removed from the queue and not sent to the backend. The + * user has specifically removed it, perhaps because it has been + * combined with another. Or some state change has occured and + * there is no longer a need to get this particular set of data. + * + * @return None + * @param Command which has been sent to the backend + */ + public void commandRemoved(ICommand command); + + /** + * Notifies that the specified command has been completed. + * + * @return None + * @param Command which has been sent to the backend + */ + public void commandDone(ICommand command, ICommandResult result); +} diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandResult.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandResult.java new file mode 100644 index 00000000000..1504485d4e3 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandResult.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.dsf.debug.service.command; + +public interface ICommandResult { + /** + * Returns an ICommandResult which is a subset command result. The command + * result which is being passed in is from a coalesced command. The result + * which is desired is contained within those results. In this instance we + * are processing the command result from the coalesced command to get our + * command result. + * Note: The type of returned command result must match the type + * associated with the subset command that is passed in the argument. + * + * @return result for this particular command. + */ + public V getSubsetResult( ICommand command ); +} diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/IEventListener.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/IEventListener.java new file mode 100644 index 00000000000..f98ccd72539 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/IEventListener.java @@ -0,0 +1,19 @@ +package org.eclipse.dd.dsf.debug.service.command; + +import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; + +/** + * Synchronous listener for events issued from the debugger. All + * registered listeners will be called in the same dispatch cycle. + */ + +@ConfinedToDsfExecutor("") +public interface IEventListener { + /** + * Notifies that the given asynchronous output was received from the + * debugger. + * @param output output that was received from the debugger. Format + * of the output data is debugger specific. + */ + public void eventReceived(Object output); +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/DsfUIPlugin.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/DsfUIPlugin.java index 164a2f69e1f..bea8083dc93 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/DsfUIPlugin.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/DsfUIPlugin.java @@ -37,7 +37,8 @@ public class DsfUIPlugin extends AbstractUIPlugin { * (non-Javadoc) * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) */ - public void start(BundleContext context) throws Exception { + @Override + public void start(BundleContext context) throws Exception { fgBundleContext = context; super.start(context); } @@ -46,7 +47,8 @@ public class DsfUIPlugin extends AbstractUIPlugin { * (non-Javadoc) * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) */ - public void stop(BundleContext context) throws Exception { + @Override + public void stop(BundleContext context) throws Exception { fgPlugin = null; fgBundleContext = null; super.stop(context); diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/SWTDispatchDsfExecutor.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/SWTDispatchDsfExecutor.java index 71e22929638..3f1e61ec5c6 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/SWTDispatchDsfExecutor.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/SWTDispatchDsfExecutor.java @@ -31,7 +31,8 @@ public class SWTDispatchDsfExecutor extends DefaultDsfExecutor { return new Callable() { - public V call() throws Exception + @SuppressWarnings("unchecked") + public V call() throws Exception { final Object[] v = new Object[1]; final Throwable[] e = new Throwable[1]; diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java index 2e975953274..fd908ca8bf4 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java @@ -412,32 +412,32 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { } protected class ElementsCountUpdate extends ViewerUpdate implements IChildrenCountUpdate { - private final GetDataDone fDone; + private final GetDataDone fElementCountDone; public ElementsCountUpdate(GetDataDone done, IModelDelta delta) { super(done, delta); - fDone = done; + fElementCountDone = done; } public void setChildCount(int numChildren) { - fDone.setData(numChildren); + fElementCountDone.setData(numChildren); } } protected class ElementsUpdate extends ViewerUpdate implements IChildrenUpdate { private final List fChildren = new ArrayList(); - private GetDataDone> fDone; + private GetDataDone> fElementUpdateDone; public ElementsUpdate(GetDataDone> done, IModelDelta delta) { super(done, delta); - fDone = done; - fDone.setData(fChildren); + fElementUpdateDone = done; + fElementUpdateDone.setData(fChildren); } public ElementsUpdate(GetDataDone> done, TreePath path) { super(done, path); - fDone = done; - fDone.setData(fChildren); + fElementUpdateDone = done; + fElementUpdateDone.setData(fChildren); } public int getOffset() { diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java index 130ce67293a..7a27627ef2d 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java @@ -543,11 +543,11 @@ abstract public class AbstractVMProvider implements IVMProvider class HasElementsUpdate extends ViewerUpdate implements IHasChildrenUpdate { - final private GetDataDone fDone; + final private GetDataDone fHasElemsDone; HasElementsUpdate(IHasChildrenUpdate clientUpdate, GetDataDone done) { super(clientUpdate, done); - fDone = done; + fHasElemsDone = done; } @Override @@ -556,24 +556,24 @@ abstract public class AbstractVMProvider implements IVMProvider } public void setHasChilren(boolean hasChildren) { - fDone.setData(hasChildren); + fHasElemsDone.setData(hasChildren); } @Override public void done() { - assert fDone.getData() != null || !fDone.getStatus().isOK(); + assert fHasElemsDone.getData() != null || !fHasElemsDone.getStatus().isOK(); super.done(); } } class ElementsCountUpdate extends ViewerUpdate implements IChildrenCountUpdate { - final private GetDataDone fDone; + final private GetDataDone fCountDone; final private TreePath fElementPath; ElementsCountUpdate(IViewerUpdate clientUpdate, GetDataDone done, TreePath elementPath) { super(clientUpdate, done); fElementPath = elementPath; - fDone = done; + fCountDone = done; } @Override @@ -582,12 +582,12 @@ abstract public class AbstractVMProvider implements IVMProvider } public void setChildCount(int count) { - fDone.setData(count); + fCountDone.setData(count); } @Override public void done() { - assert fDone.getData() != null || !fDone.getStatus().isOK(); + assert fCountDone.getData() != null || !fCountDone.getStatus().isOK(); super.done(); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMRootLayoutNode.java index 8bd73da70ed..253d8c0bfb7 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMRootLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMRootLayoutNode.java @@ -68,7 +68,8 @@ abstract public class AbstractVMRootLayoutNode extends AbstractVMLayoutNode impl * There is no use case for a root node implementing this method, but its * easier to just impelemnt it for sake of uniformity of model. */ - public void updateLabel(IVMContext vmc, ILabelUpdate update) { + public void updateLabel(@SuppressWarnings("unused") + IVMContext vmc, ILabelUpdate update) { update.done(); } @@ -88,7 +89,7 @@ abstract public class AbstractVMRootLayoutNode extends AbstractVMLayoutNode impl new Done() { public void run() { if (isDisposed()) return; - if (propagateError(getExecutor(), done, "Failed to create delta.")); //$NON-NLS-1$ + if (propagateError(getExecutor(), done, "Failed to create delta.")) return; //$NON-NLS-1$ done.setData(rootDelta); getExecutor().execute(done); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java index 906c71e9502..800d163a303 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java @@ -127,7 +127,8 @@ public class VMDelta extends ModelDelta { * @param flags change flags for child * @return newly created child delta */ - public VMDelta addNode(Object element, int flags) { + @Override + public VMDelta addNode(Object element, int flags) { VMDelta node = new VMDelta(element, flags); node.setParent(this); addDelta(node); @@ -144,6 +145,7 @@ public class VMDelta extends ModelDelta { * @param flags change flags * @return newly created child delta */ + @Override public VMDelta addNode(Object element, Object replacement, int flags) { VMDelta node = new VMDelta(element, replacement, flags); node.setParent(this); @@ -160,6 +162,7 @@ public class VMDelta extends ModelDelta { * @param flags change flags * @return newly created child delta */ + @Override public VMDelta addNode(Object element, int index, int flags) { VMDelta node = new VMDelta(element, index, flags); node.setParent(this); @@ -177,6 +180,7 @@ public class VMDelta extends ModelDelta { * @param numChildren the number of children the element has * @return newly created child delta */ + @Override public VMDelta addNode(Object element, int index, int flags, int numChildren) { VMDelta node = new VMDelta(element, index, flags, numChildren); node.setParent(this); @@ -300,6 +304,7 @@ public class VMDelta extends ModelDelta { /* (non-Javadoc) * @see org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta#getChildCount() */ + @Override public int getChildCount() { return fChildCount; } @@ -307,10 +312,12 @@ public class VMDelta extends ModelDelta { /* (non-Javadoc) * @see org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta#accept(org.eclipse.debug.internal.ui.viewers.provisional.IModelDeltaVisitor) */ + @Override public void accept(IModelDeltaVisitor visitor) { doAccept(visitor, 0); } + @Override protected void doAccept(IModelDeltaVisitor visitor, int depth) { if (visitor.visit(this, depth)) { ModelDelta[] childDeltas = getChildDeltas(); diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java index 5b35febce0e..7857722c66b 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java @@ -79,6 +79,7 @@ abstract public class AbstractDMVMLayoutNode extends Abstract * The IAdaptable implementation. If the adapter is the DM context, * return the context, otherwise delegate to IDMContext.getAdapter(). */ + @Override @SuppressWarnings("unchecked") public Object getAdapter(Class adapter) { Object superAdapter = super.getAdapter(adapter); @@ -91,6 +92,7 @@ abstract public class AbstractDMVMLayoutNode extends Abstract } } + @Override public boolean equals(Object other) { if (!(other instanceof AbstractDMVMLayoutNode.DMVMContext)) return false; DMVMContext otherVmc = (DMVMContext)other; @@ -98,10 +100,12 @@ abstract public class AbstractDMVMLayoutNode extends Abstract fDmc.equals(otherVmc.fDmc); } + @Override public int hashCode() { return AbstractDMVMLayoutNode.this.hashCode() + fDmc.hashCode(); } + @Override public String toString() { return fDmc.toString(); } @@ -134,6 +138,7 @@ abstract public class AbstractDMVMLayoutNode extends Abstract } + @Override public void dispose() { fServicesTracker.dispose(); super.dispose(); @@ -339,7 +344,8 @@ abstract public class AbstractDMVMLayoutNode extends Abstract * @see IElementLabelProvider * @see IColumnPresentationFactoryAdapter */ - protected void fillColumnLabel(IDMContext dmContext, V dmData, String columnId, int idx, ILabelUpdate update) { + protected void fillColumnLabel(@SuppressWarnings("unused") IDMContext dmContext, @SuppressWarnings("unused") V dmData, + @SuppressWarnings("unused") String columnId, int idx, ILabelUpdate update) { update.setLabel("", idx); //$NON-NLS-1$ } @@ -347,12 +353,12 @@ abstract public class AbstractDMVMLayoutNode extends Abstract public int getDeltaFlags(Object e) { int flags = 0; if (e instanceof IDMEvent) { - flags = getNodeDeltaFlagsForDMEvent((IDMEvent)e); + flags = getNodeDeltaFlagsForDMEvent((IDMEvent)e); } return flags | super.getDeltaFlags(e); } - protected int getNodeDeltaFlagsForDMEvent(IDMEvent e) { + protected int getNodeDeltaFlagsForDMEvent(@SuppressWarnings("unused") IDMEvent e) { return IModelDelta.NO_CHANGE; } @@ -364,7 +370,7 @@ abstract public class AbstractDMVMLayoutNode extends Abstract if (DsfSession.isSessionActive(getSession().getId())) { getSession().getExecutor().execute(new DsfRunnable() { public void run() { - buildDeltaForDMEvent((IDMEvent)e, parentDelta, nodeOffset, done); + buildDeltaForDMEvent((IDMEvent)e, parentDelta, nodeOffset, done); } }); } else { diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProvider.java index 788b370ea09..9cb1d99330b 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProvider.java @@ -80,6 +80,7 @@ abstract public class AbstractDMVMProvider extends AbstractVMProvider } /** Called to dispose the provider. */ + @Override public void dispose() { try { getSession().getExecutor().execute(new Runnable() { diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/DsfPlugin.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/DsfPlugin.java index 6a1fb6e93ab..b0823212fc7 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/DsfPlugin.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/DsfPlugin.java @@ -42,7 +42,8 @@ public class DsfPlugin extends Plugin { * (non-Javadoc) * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext) */ - public void start(BundleContext context) throws Exception { + @Override + public void start(BundleContext context) throws Exception { fgBundleContext = context; super.start(context); DEBUG = "true".equals(Platform.getDebugOption("org.eclipse.dd.dsf/debug")); //$NON-NLS-1$//$NON-NLS-2$ @@ -52,7 +53,8 @@ public class DsfPlugin extends Plugin { * (non-Javadoc) * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext) */ - public void stop(BundleContext context) throws Exception { + @Override + public void stop(BundleContext context) throws Exception { fgBundleContext = null; super.stop(context); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java index 0306ca368a3..a6e47251fd7 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java @@ -208,6 +208,7 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor } } + @Override protected Object getExecutable() { return fRunnable; } public void run() { @@ -234,6 +235,7 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor fCallable = callable; } + @Override protected Object getExecutable() { return fCallable; } public T call() throws Exception { diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java index 4c07703eeb4..04ef3bf344a 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java @@ -67,6 +67,7 @@ abstract public class Done extends DsfRunnable { return false; } + @Override public String toString() { return "Done: " + getStatus().toString(); //$NON-NLS-1$ } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java index 7620478eca9..24f20df4522 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java @@ -43,7 +43,6 @@ public class DsfExecutable { assert ASSERTIONS_ENABLED = true; DEBUG_EXECUTOR = DsfPlugin.DEBUG && "true".equals( //$NON-NLS-1$ Platform.getDebugOption("org.eclipse.dd.dsf/debug/executor")); //$NON-NLS-1$ - assert ASSERTIONS_ENABLED = true; } /** diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfQuery.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfQuery.java index 014818b5566..01b402ed93e 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfQuery.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfQuery.java @@ -101,10 +101,12 @@ abstract public class DsfQuery extends DsfRunnable return (state & (STATE_DONE | STATE_CANCELLED)) != 0; } + @Override protected int tryAcquireShared(int ignore) { return doIsDone()? 1 : -1; } + @Override protected boolean tryReleaseShared(int ignore) { return true; } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java index e2ba546b311..2b7fda408c0 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java @@ -284,6 +284,7 @@ abstract public class DsfSequence extends DsfRunnable implements Future abortExecution(getStatus()); } } + @Override public String toString() { return "DsfSequence \"" + fTaskName + "\", result for executing step #" + fStepIdx + " = " + getStatus(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } @@ -335,7 +336,7 @@ abstract public class DsfSequence extends DsfRunnable implements Future } else { abortRollBack(getStatus()); } - }; + } @Override public String toString() { return "DsfSequence \"" + fTaskName + "\", result for rolling back step #" + fStepIdx + " = " + getStatus(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ @@ -450,10 +451,12 @@ abstract public class DsfSequence extends DsfRunnable implements Future return (state & (STATE_FINISHED | STATE_CANCELLED | STATE_ABORTED)) != 0; } + @Override protected int tryAcquireShared(int ignore) { return doIsDone()? 1 : -1; } + @Override protected boolean tryReleaseShared(int ignore) { return true; } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/GetDataDone.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/GetDataDone.java index c1e9af9ce8a..bbedc24667e 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/GetDataDone.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/GetDataDone.java @@ -31,6 +31,7 @@ public abstract class GetDataDone extends Done { */ public V getData() { return fData; } + @Override public String toString() { if (getData() != null) { return getData().toString(); diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/StackTraceWrapper.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/StackTraceWrapper.java index aa0e71f4498..c8ff2428661 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/StackTraceWrapper.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/StackTraceWrapper.java @@ -20,6 +20,7 @@ class StackTraceWrapper { StackTraceWrapper(StackTraceElement[] elements) { fStackTraceElements = elements; } + @Override public String toString() { StringBuilder builder = new StringBuilder(fStackTraceElements.length * 30); for (int i = 0; i < fStackTraceElements.length && i < 10; i++) { diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMContext.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMContext.java index 778295eea21..87656319219 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMContext.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMContext.java @@ -103,6 +103,7 @@ abstract public class AbstractDMContext extends PlatformObjec * session is equally important. * @see org.eclipse.runtime.IAdapterManager */ + @Override @SuppressWarnings("unchecked") public Object getAdapter(Class adapterType) { Object retVal = null; diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/ServiceDMContext.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/ServiceDMContext.java index 481abf680f9..f8219488a31 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/ServiceDMContext.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/ServiceDMContext.java @@ -26,6 +26,7 @@ public class ServiceDMContext extends AbstractDMContext fServiceDMID = serviceDMID; } + @Override public String toString() { return baseToString() + fServiceDMID; } } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServicesTracker.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServicesTracker.java index 91e204b86fa..ab794d24d5f 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServicesTracker.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServicesTracker.java @@ -55,6 +55,7 @@ public class DsfServicesTracker { fFilter = filter; } + @Override public boolean equals(Object other) { // I guess this doesn't have to assume fFilter can be null, but oh well. return other instanceof ServiceKey && @@ -64,6 +65,7 @@ public class DsfServicesTracker { (fFilter != null && fFilter.equals(((ServiceKey)other).fFilter))); } + @Override public int hashCode() { return (fClassName == null ? 0 : fClassName.hashCode()) + (fFilter == null ? 0 : fFilter.hashCode()); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java index 393f7246fe1..243a012597a 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java @@ -195,10 +195,12 @@ public class DsfSession fFilter = filter; } + @Override public boolean equals(Object other) { return other instanceof ListenerEntry && fListener.equals(((ListenerEntry)other).fListener); } + @Override public int hashCode() { return fListener.hashCode(); } } @@ -278,6 +280,7 @@ public class DsfSession public void dispatchEvent(final Object event, final Dictionary serviceProperties) { getExecutor().submit(new DsfRunnable() { public void run() { doDispatchEvent(event, serviceProperties);} + @Override public String toString() { return "Event: " + event + ", from service " + serviceProperties; } //$NON-NLS-1$ //$NON-NLS-2$ }); } @@ -317,11 +320,13 @@ public class DsfSession return fAdapters.get(adapterType); } + @Override @ThreadSafe public boolean equals(Object other) { return other instanceof DsfSession && fId.equals(((DsfSession)other).fId); } + @Override @ThreadSafe public int hashCode() { return fId.hashCode(); } @@ -340,11 +345,12 @@ public class DsfSession return ((IDsfService)o1.fListener).getStartupNumber() - ((IDsfService)o2.fListener).getStartupNumber(); } return 1; - }; + } + @Override public boolean equals(Object obj) { return obj == this; - }; + } }); // Build a list of listeners and methods that are registered for this event class. From 1c987b3065feeb20cdeb345c10f19529e014a450 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Mon, 26 Mar 2007 19:53:45 +0000 Subject: [PATCH 066/834] Changed the IExpressions interface so that it uses org.eclipse.cdt.core.IAddress instead of org.eclipse.dd.dsf.debug.service.IAddress. This change is needed to get a clean compile of the Expressions service (which implements the IExpressions interface). --- plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF | 5 +++-- .../src/org/eclipse/dd/dsf/debug/service/IExpressions.java | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF index b94b7631e23..79256f374b0 100644 --- a/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF @@ -7,8 +7,9 @@ Bundle-Version: 0.9.0.qualifier 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 + org.eclipse.debug.core, + org.eclipse.dd.dsf, + org.eclipse.cdt.core Eclipse-LazyStart: true Export-Package: org.eclipse.dd.dsf.debug.service, org.eclipse.dd.dsf.debug.service.command diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java index ee399aadfc8..4c1246b1a19 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java @@ -12,6 +12,7 @@ package org.eclipse.dd.dsf.debug.service; import java.util.Map; +import org.eclipse.cdt.core.IAddress; import org.eclipse.dd.dsf.concurrent.GetDataDone; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMData; From e44c94107f3050224866b899837e4729fa0e6b53 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 28 Mar 2007 22:14:46 +0000 Subject: [PATCH 067/834] Refactored the Done object into a RequestMonitor (bug 177081). --- .../launch/StackFramesLayoutNode.java | 79 +++--- .../launch/StandardLaunchRootLayoutNode.java | 22 +- .../launch/StandardProcessLayoutNode.java | 12 +- .../register/RegisterGroupLayoutNode.java | 18 +- .../register/RegisterLayoutNode.java | 13 +- .../dd/dsf/debug/service/IBreakpoints.java | 6 +- .../dd/dsf/debug/service/IExpressions.java | 10 +- .../eclipse/dd/dsf/debug/service/IMemory.java | 8 +- .../dd/dsf/debug/service/IModules.java | 8 +- .../dsf/debug/service/INativeProcesses.java | 28 +- .../org/eclipse/dd/dsf/debug/service/IOS.java | 16 +- .../dd/dsf/debug/service/IRegisters.java | 12 +- .../dd/dsf/debug/service/IRunControl.java | 14 +- .../dd/dsf/debug/service/ISourceLookup.java | 6 +- .../eclipse/dd/dsf/debug/service/IStack.java | 12 +- .../dd/dsf/debug/service/ISymbols.java | 6 +- .../dd/dsf/debug/service/ITargets.java | 16 +- .../service/command/ICommandControl.java | 6 +- .../dsf/ui/viewmodel/AbstractVMAdapter.java | 7 +- .../ui/viewmodel/AbstractVMLayoutNode.java | 202 +++++++------- .../dsf/ui/viewmodel/AbstractVMProvider.java | 151 ++++++----- .../viewmodel/AbstractVMRootLayoutNode.java | 22 +- .../dd/dsf/ui/viewmodel/IVMLayoutNode.java | 8 +- .../dsf/ui/viewmodel/IVMRootLayoutNode.java | 8 +- .../viewmodel/dm/AbstractDMVMLayoutNode.java | 46 ++-- .../ui/viewmodel/dm/AbstractDMVMProvider.java | 23 +- ...tDataDone.java => DataRequestMonitor.java} | 20 +- .../dd/dsf/concurrent/DefaultDsfExecutor.java | 2 +- .../org/eclipse/dd/dsf/concurrent/Done.java | 74 ----- .../dd/dsf/concurrent/DoneCollector.java | 105 -------- .../dsf/concurrent/MultiRequestMonitor.java | 95 +++++++ .../concurrent/{DsfQuery.java => Query.java} | 18 +- .../dd/dsf/concurrent/RequestMonitor.java | 253 ++++++++++++++++++ .../{DsfSequence.java => Sequence.java} | 75 +++--- .../eclipse/dd/dsf/datamodel/IDMService.java | 11 +- .../dd/dsf/service/AbstractDsfService.java | 10 +- .../eclipse/dd/dsf/service/IDsfService.java | 10 +- 37 files changed, 834 insertions(+), 598 deletions(-) rename plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/{GetDataDone.java => DataRequestMonitor.java} (68%) delete mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java delete mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DoneCollector.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/MultiRequestMonitor.java rename plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/{DsfQuery.java => Query.java} (91%) create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java rename plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/{DsfSequence.java => Sequence.java} (88%) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java index 348fc14ed89..d09e526a29b 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java @@ -12,8 +12,8 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.launch; import java.util.List; -import org.eclipse.dd.dsf.concurrent.Done; -import org.eclipse.dd.dsf.concurrent.GetDataDone; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMEvent; import org.eclipse.dd.dsf.debug.service.IRunControl; @@ -74,8 +74,9 @@ public class StackFramesLayoutNode extends AbstractDMVMLayoutNode() { - public void run() { + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + public void handleCompleted() { if (!getStatus().isOK()) { // Failed to retrieve frames. If we are stepping, we // might still be able to retrieve just the top stack @@ -100,7 +101,7 @@ public class StackFramesLayoutNode extends AbstractDMVMLayoutNode() { public void run() { - if (!getStatus().isOK()) { - handleFailedUpdate(update); - return; - } - - IVMContext topFrameVmc = new DMVMContext(getData()); - - update.setChild(topFrameVmc, 0); - // 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 (fCachedOldFrameVMCs != null && fCachedOldFrameVMCs.length >= 1) { - fCachedOldFrameVMCs[0] = topFrameVmc; - for (int i = 0; i < fCachedOldFrameVMCs.length; i++) update.setChild(fCachedOldFrameVMCs[i], i); - } else { + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + public void handleCompleted() { + if (!getStatus().isOK()) { + handleFailedUpdate(update); + return; + } + + IVMContext topFrameVmc = new DMVMContext(getData()); + update.setChild(topFrameVmc, 0); + // 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 (fCachedOldFrameVMCs != null && fCachedOldFrameVMCs.length >= 1) { + fCachedOldFrameVMCs[0] = topFrameVmc; + for (int i = 0; i < fCachedOldFrameVMCs.length; i++) update.setChild(fCachedOldFrameVMCs[i], i); + } else { + update.setChild(topFrameVmc, 0); + } + update.done(); } - update.done(); - }}); + }); } @Override @@ -220,25 +224,25 @@ public class StackFramesLayoutNode extends AbstractDMVMLayoutNode e, final VMDelta parent, final int nodeOffset, final Done done) { + protected void buildDeltaForDMEvent(final IDMEvent e, final VMDelta parent, final int nodeOffset, final RequestMonitor rm) { if (e instanceof IRunControl.ISuspendedDMEvent) { - buildDeltaForSuspendedEvent((IRunControl.ISuspendedDMEvent)e, parent, nodeOffset, done); + buildDeltaForSuspendedEvent((IRunControl.ISuspendedDMEvent)e, parent, nodeOffset, rm); } else if (e instanceof IRunControl.IResumedDMEvent) { - buildDeltaForResumedEvent((IRunControl.IResumedDMEvent)e, parent, nodeOffset, done); + buildDeltaForResumedEvent((IRunControl.IResumedDMEvent)e, parent, nodeOffset, rm); } else if (e instanceof IStepQueueManager.ISteppingTimedOutEvent) { - buildDeltaForSteppingTimedOutEvent((IStepQueueManager.ISteppingTimedOutEvent)e, parent, nodeOffset, done); + buildDeltaForSteppingTimedOutEvent((IStepQueueManager.ISteppingTimedOutEvent)e, parent, nodeOffset, rm); } else { // Call super-class to build sub-node delta's. - super.buildDeltaForDMEvent(e, parent, nodeOffset, done); + super.buildDeltaForDMEvent(e, parent, nodeOffset, rm); } } - private void buildDeltaForSuspendedEvent(final IRunControl.ISuspendedDMEvent e, final VMDelta parent, final int nodeOffset, final Done done) { + private void buildDeltaForSuspendedEvent(final IRunControl.ISuspendedDMEvent e, final VMDelta parent, final int nodeOffset, final RequestMonitor rm) { IRunControl runControlService = getServicesTracker().getService(IRunControl.class); IStack stackService = getServicesTracker().getService(IStack.class); if (stackService == null || runControlService == null) { // Required services have not initialized yet. Ignore the event. - super.buildDeltaForDMEvent(e, parent, nodeOffset, done); + super.buildDeltaForDMEvent(e, parent, nodeOffset, rm); return; } @@ -255,8 +259,9 @@ public class StackFramesLayoutNode extends AbstractDMVMLayoutNode>() { - public void run() { + new DataRequestMonitor>(getSession().getExecutor(), null) { + @Override + public void handleCompleted() { if (getStatus().isOK() && getData().size() != 0) { parent.addNode( getData().get(0), IModelDelta.SELECT | IModelDelta.STATE); // If second frame is available repaint it, so that a "..." appears. This gives a better @@ -266,18 +271,18 @@ public class StackFramesLayoutNode extends AbstractDMVMLayoutNode done) { + public void createDelta(Object event, final DataRequestMonitor rm) { /* * 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 @@ -115,21 +115,21 @@ public class StandardLaunchRootLayoutNode extends AbstractVMRootLayoutNode } // Call the child nodes to generate their delta. - final Map childNodeDeltas = getChildNodesWithDeltaFlags(event); + Map childNodeDeltas = getChildNodesWithDeltaFlags(event); if (childNodeDeltas.size() != 0) { callChildNodesToBuildDelta( childNodeDeltas, rootDelta, event, - new Done() { - public void run() { + new RequestMonitor(getExecutor(), rm) { + @Override + public void handleOK() { if (isDisposed()) return; - if (propagateError(getExecutor(), done, "Failed to create delta.")) return; //$NON-NLS-1$ - done.setData(viewRootDelta); - getExecutor().execute(done); + rm.setData(viewRootDelta); + rm.done(); } }); } else { - done.setData(viewRootDelta); - getExecutor().execute(done); + rm.setData(viewRootDelta); + rm.done(); } } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessLayoutNode.java index e65a4ba59c1..a8ba47cbeee 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessLayoutNode.java @@ -10,7 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.viewmodel.launch; -import org.eclipse.dd.dsf.concurrent.Done; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMLayoutNode; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; @@ -121,7 +121,7 @@ public class StandardProcessLayoutNode extends AbstractVMLayoutNode { update.done(); } - // @see org.eclipse.dd.dsf.ui.viewmodel.IViewModelLayoutNode#hasElements(org.eclipse.dd.dsf.ui.viewmodel.IVMContext, org.eclipse.dd.dsf.concurrent.GetDataDone) + // @see org.eclipse.dd.dsf.ui.viewmodel.IViewModelLayoutNode#hasElements(org.eclipse.dd.dsf.ui.viewmodel.IVMContext, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) public void updateHasElements(IHasChildrenUpdate[] updates) { for (IHasChildrenUpdate update : updates) { ILaunch launch = findLaunch(update.getElementPath()); @@ -180,7 +180,7 @@ public class StandardProcessLayoutNode extends AbstractVMLayoutNode { } @Override - public void buildDelta(Object e, VMDelta parent, int nodeOffset, Done done) { + public void buildDelta(Object e, VMDelta parent, int nodeOffset, RequestMonitor requestMonitor) { if (e instanceof DebugEvent && ((DebugEvent)e).getSource() instanceof IProcess) { DebugEvent de = (DebugEvent)e; if (de.getKind() == DebugEvent.CHANGE) { @@ -192,11 +192,11 @@ public class StandardProcessLayoutNode extends AbstractVMLayoutNode { } /* * No other node should need to process events related to process. - * Therefore, just invoke done, without calling super.buildDelta(). + * Therefore, just invoke the request monitor without calling super.buildDelta(). */ - getExecutor().execute(done); + requestMonitor.done(); } else { - super.buildDelta(e, parent, nodeOffset, done); + super.buildDelta(e, parent, nodeOffset, requestMonitor); } } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java index c6f5e9f362e..3b95f6a8e81 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java @@ -10,7 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.viewmodel.register; -import org.eclipse.dd.dsf.concurrent.GetDataDone; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext; @@ -38,14 +38,16 @@ public class RegisterGroupLayoutNode extends AbstractDMVMLayoutNode() { public void run() { - if (!getStatus().isOK()) { + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + public void handleCompleted() { + if (!getStatus().isOK()) { + update.done(); + return; + } + fillUpdateWithVMCs(update, getData()); update.done(); - return; - } - fillUpdateWithVMCs(update, getData()); - update.done(); - }}); + }}); } else { handleFailedUpdate(update); } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java index 4da4a40cd89..f2a628d042f 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java @@ -10,8 +10,8 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.viewmodel.register; -import org.eclipse.dd.dsf.concurrent.Done; -import org.eclipse.dd.dsf.concurrent.GetDataDone; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMEvent; import org.eclipse.dd.dsf.debug.service.IRegisters; @@ -48,8 +48,9 @@ public class RegisterLayoutNode extends AbstractDMVMLayoutNode getServicesTracker().getService(IRegisters.class).getRegisters( execDmc, - new GetDataDone() { - public void run() { + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + public void handleCompleted() { if (!getStatus().isOK()) { handleFailedUpdate(update); return; @@ -93,7 +94,7 @@ public class RegisterLayoutNode extends AbstractDMVMLayoutNode } @Override - protected void buildDeltaForDMEvent(IDMEvent e, VMDelta parent, int nodeOffset, Done done) { + protected void buildDeltaForDMEvent(IDMEvent e, VMDelta parent, int nodeOffset, RequestMonitor requestMonitor) { if (e instanceof IRunControl.ISuspendedDMEvent) { // Create a delta that the whole register group has changed. parent.addFlags(IModelDelta.CONTENT); @@ -101,6 +102,6 @@ public class RegisterLayoutNode extends AbstractDMVMLayoutNode if (e instanceof IRegisters.IRegisterChangedDMEvent) { parent.addNode( new DMVMContext(((IRegisters.IRegisterChangedDMEvent)e).getDMContext()), IModelDelta.STATE ); } - super.buildDeltaForDMEvent(e, parent, nodeOffset, done); + super.buildDeltaForDMEvent(e, parent, nodeOffset, requestMonitor); } } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java index 864ac543f7c..7f379669c57 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java @@ -10,7 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.service; -import org.eclipse.dd.dsf.concurrent.GetDataDone; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMData; import org.eclipse.dd.dsf.datamodel.IDMEvent; @@ -44,7 +44,7 @@ public interface IBreakpoints extends IDsfService { public interface IBreakpointHitEvent extends IBreakpointDMEvent {} - public void getAllBreakpoints(IExecutionDMContext execDmc, GetDataDone done); - public void getBreakpoints(IExecutionDMContext execDmc, IBreakpoint platformBp, GetDataDone done); + public void getAllBreakpoints(IExecutionDMContext execDmc, DataRequestMonitor rm); + public void getBreakpoints(IExecutionDMContext execDmc, IBreakpoint platformBp, DataRequestMonitor rm); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java index 4c1246b1a19..6f98089dc56 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java @@ -13,7 +13,7 @@ package org.eclipse.dd.dsf.debug.service; import java.util.Map; import org.eclipse.cdt.core.IAddress; -import org.eclipse.dd.dsf.concurrent.GetDataDone; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMData; import org.eclipse.dd.dsf.datamodel.IDMEvent; @@ -78,16 +78,16 @@ public interface IExpressions extends IDMService { /** * Retrieves the sub-expressions of the given expression. * @param exprCtx Expression context to evaluate. - * @param done The return parameter is an Iterable because it's possible + * @param rm 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(IExpressionDMContext exprCtx, GetDataDone> done); + void getSubExpressions(IExpressionDMContext exprCtx, DataRequestMonitor> rm); /** * For object oriented languages, this method returns the expressions * representing base types of the given expression type. * @param exprContext - * @param done + * @param rm Request completion monitor. */ - void getBaseExpressions(IExpressionDMContext exprContext, GetDataDone done); + void getBaseExpressions(IExpressionDMContext exprContext, DataRequestMonitor rm); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java index 1167a679cae..936df52ee78 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java @@ -10,7 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.service; -import org.eclipse.dd.dsf.concurrent.Done; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.service.IDsfService; /** @@ -37,11 +37,11 @@ public interface IMemory extends IDsfService { /** Writes the given value to the given memory location. */ public void setMemory(IMemoryContext memCtx, IAddress addr, - int word_size, byte[] buf, int offs, int size, int mode, Done done); + int word_size, byte[] buf, int offs, int size, int mode, RequestMonitor requestMonitor); /** Reads memory at the given location */ public void getMemory(IMemoryContext memCtx, IAddress addr, - int word_size, byte[] buf, int offs, int size, int mode, Done done); + int word_size, byte[] buf, int offs, int size, int mode, RequestMonitor requestMonitor); /** * Fill target memory with given pattern. @@ -50,6 +50,6 @@ public interface IMemory extends IDsfService { * there was an error. */ public void fillMemory(IMemoryContext memCtx, IAddress addr, - int word_size, byte[] value, int size, int mode, Done done); + int word_size, byte[] value, int size, int mode, RequestMonitor requestMonitor); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java index dd12e4e7914..1885eafcfac 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java @@ -12,7 +12,7 @@ package org.eclipse.dd.dsf.debug.service; import java.math.BigInteger; -import org.eclipse.dd.dsf.concurrent.GetDataDone; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMData; import org.eclipse.dd.dsf.datamodel.IDMEvent; @@ -134,16 +134,16 @@ public interface IModules extends IDMService { /** * Retreives the list of modules loaded in given symbol context. */ - void getModules(ISymbolDMContext symCtx, GetDataDone done); + void getModules(ISymbolDMContext symCtx, DataRequestMonitor rm); /** * Calculates the line numbers corresponding to the given address. */ - void calcLineInfo(ISymbolDMContext symCtx, IAddress address, GetDataDone done); + void calcLineInfo(ISymbolDMContext symCtx, IAddress address, DataRequestMonitor rm); /** * Calculates the addresses corresponding to the given source file location. */ - void calcAddressInfo(ISymbolDMContext symCtx, String file, int line, int col, GetDataDone done); + void calcAddressInfo(ISymbolDMContext symCtx, String file, int line, int col, DataRequestMonitor rm); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/INativeProcesses.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/INativeProcesses.java index ce585e87ad9..8dcb2349e21 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/INativeProcesses.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/INativeProcesses.java @@ -10,8 +10,8 @@ *******************************************************************************/ 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.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMData; import org.eclipse.dd.dsf.datamodel.IDMEvent; @@ -50,33 +50,35 @@ public interface INativeProcesses extends IDMService { /** * Retrieves the current list of processes running on target. + * @param rm Request completion monitor, to be filled in with array of process contexts. */ - void getRunningProcesses(GetDataDone done); + void getRunningProcesses(DataRequestMonitor rm); /** * Attaches debugger to the given process. */ - void attachDebuggerToProcess(IProcessDMContext procCtx, Done done); + void attachDebuggerToProcess(IProcessDMContext procCtx, RequestMonitor requestMonitor); /** * Starts a new process. * @param file Process image to use for the new process. - * @param done Return token with the process context. + * @param rm Request completion monitor, to be filled in with the process context. */ - void runNewProcess(String file, GetDataDone done); + void runNewProcess(String file, DataRequestMonitor rm); /** * 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. + * @param rm Request completion monitor, to be willed in with the process context. */ - void debugNewProcess(String file, GetDataDone done); + void debugNewProcess(String file, DataRequestMonitor rm); /** * Retrieves the list of processes which are currently under * debugger control. + * @param rm Request completion monitor. */ - void getProcessesBeingDebugged(GetDataDone done); + void getProcessesBeingDebugged(DataRequestMonitor rm); /** * Returns a thread context for given run control execution context. @@ -88,14 +90,14 @@ public interface INativeProcesses extends IDMService { /** * Checks whether the given process or thread can be terminated. * @param thread Thread or process to terminate. - * @param done Return token. + * @param rm Return token. */ - void canTerminate(IThreadDMContext thread, GetDataDone done); + void canTerminate(IThreadDMContext thread, DataRequestMonitor rm); /** * Terminates the selected process or thread. * @param thread Thread or process to terminate. - * @param done Return token. + * @param rm Request completion monitor, indicates success or failure. */ - void terminate(IThreadDMContext thread, Done done); + void terminate(IThreadDMContext thread, RequestMonitor requestMonitor); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IOS.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IOS.java index a1b707b0c6e..9c3150597bb 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IOS.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IOS.java @@ -10,8 +10,8 @@ *******************************************************************************/ 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.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMData; import org.eclipse.dd.dsf.datamodel.IDMService; @@ -81,21 +81,23 @@ public interface IOS extends IDMService { * Retrieves list of OS object types. * @param os OS context. * @param parent Optional parent type. - * @param done Return token. + * @param rm Request completion monitor. */ - public void getObjectTypes(IOSDMContext os, IObjectTypeDMContext parent, GetDataDone done); + public void getObjectTypes(IOSDMContext os, IObjectTypeDMContext parent, DataRequestMonitor rm); /** * Retrieves list of OS objects for given type. * @param os OS context. * @param type The object type. * @param parent Optional parent of the requested objects. - * @param done Return token. + * @param rm Request completion monitor. */ - public void getObjects(IOSDMContext os, IObjectTypeDMContext type, IObjectDMContext parent, GetDataDone done); + public void getObjects(IOSDMContext os, IObjectTypeDMContext type, IObjectDMContext parent, DataRequestMonitor rm); /** * Attaches the debugger to given OS object context. + * @param objectDmc Data Model Context of the OS object to attach to. + * @param rm Request completion monitor. */ - public void attachDebuggerToObject(IObjectDMContext objectDmc, Done done); + public void attachDebuggerToObject(IObjectDMContext objectDmc, RequestMonitor requestMonitor); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java index 57fb46c6b29..ffe2bee47b5 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java @@ -10,7 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.service; -import org.eclipse.dd.dsf.concurrent.GetDataDone; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMData; import org.eclipse.dd.dsf.datamodel.IDMEvent; @@ -100,16 +100,16 @@ public interface IRegisters extends IDMService { * Retrieves the list of register groups. * @param execCtx Execution DMC, this is required. * @param frameCtx Stack frame DMC, this is optional and may be null. - * @param done Return token. + * @param rm Request completion monitor. */ - void getRegisterGroups(IRunControl.IExecutionDMContext execCtx, IStack.IFrameDMContext frameCtx, GetDataDone done); + void getRegisterGroups(IRunControl.IExecutionDMContext execCtx, IStack.IFrameDMContext frameCtx, DataRequestMonitor rm); /** Retrieves list of sub-groups of given register group. */ - void getRegisterSubGroups(IRegisterGroupDMContext groupCtx, GetDataDone done); + void getRegisterSubGroups(IRegisterGroupDMContext groupCtx, DataRequestMonitor rm); /** Retrieves registers in given register group. */ - void getRegisters(IRegisterGroupDMContext groupCtx, GetDataDone done); + void getRegisters(IRegisterGroupDMContext groupCtx, DataRequestMonitor rm); /** Retrieves bit fields for given register */ - void getBitFields(IRegisterDMContext regCtx, GetDataDone done); + void getBitFields(IRegisterDMContext regCtx, DataRequestMonitor rm); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java index 818b35c1487..0d89a134f10 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java @@ -10,8 +10,8 @@ *******************************************************************************/ 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.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMData; import org.eclipse.dd.dsf.datamodel.IDMEvent; @@ -86,7 +86,7 @@ public interface IRunControl extends IDMService /** * Returns execution contexts belonging to the given container context. */ - public void getExecutionContexts(IContainerDMContext c, GetDataDone done); + public void getExecutionContexts(IContainerDMContext c, DataRequestMonitor rm); /* * Run control commands. They all require the IExecutionContext object on @@ -95,12 +95,12 @@ public interface IRunControl extends IDMService boolean canResume(IExecutionDMContext context); boolean canSuspend(IExecutionDMContext context); boolean isSuspended(IExecutionDMContext context); - void resume(IExecutionDMContext context, Done done); - void suspend(IExecutionDMContext context, Done done); + void resume(IExecutionDMContext context, RequestMonitor requestMonitor); + void suspend(IExecutionDMContext context, RequestMonitor requestMonitor); public enum StepType { STEP_OVER, STEP_INTO, STEP_RETURN }; boolean isStepping(IExecutionDMContext context); boolean canStep(IExecutionDMContext context); - void step(IExecutionDMContext context, StepType stepType, Done done); + void step(IExecutionDMContext context, StepType stepType, RequestMonitor requestMonitor); boolean canInstructionStep(IExecutionDMContext context); - void instructionStep(IExecutionDMContext context, StepType stepType, Done done); + void instructionStep(IExecutionDMContext context, StepType stepType, RequestMonitor requestMonitor); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISourceLookup.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISourceLookup.java index 74ddadcd4ce..de58864f456 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISourceLookup.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISourceLookup.java @@ -10,7 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.service; -import org.eclipse.dd.dsf.concurrent.GetDataDone; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.debug.core.sourcelookup.ISourceContainer; @@ -49,10 +49,10 @@ public interface ISourceLookup extends IDsfService { /** * Retrieves the host source object for given debugger path string. */ - void getSource(ISourceLookupContext srcCtx, String debuggerPath, boolean searchDuplicates, GetDataDone done); + void getSource(ISourceLookupContext srcCtx, String debuggerPath, boolean searchDuplicates, DataRequestMonitor rm); /** * Retrieves the debugger path string(s) for given host source object. */ - void getDebuggerPath(ISourceLookupContext srcCtx, Object source, boolean searchDuplicates, GetDataDone done); + void getDebuggerPath(ISourceLookupContext srcCtx, Object source, boolean searchDuplicates, DataRequestMonitor rm); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java index 98ef485c0fd..e938f165046 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java @@ -10,7 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.service; -import org.eclipse.dd.dsf.concurrent.GetDataDone; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMData; import org.eclipse.dd.dsf.datamodel.IDMService; @@ -65,7 +65,7 @@ public interface IStack extends IDMService { * Retrieves list of stack frames for the given execution context. Request * will fail if the stack frame data is not available. */ - void getFrames(IRunControl.IExecutionDMContext execContext, GetDataDone done); + void getFrames(IRunControl.IExecutionDMContext execContext, DataRequestMonitor rm); /** * Retrieves the top stack frame for the given execution context. @@ -74,17 +74,17 @@ public interface IStack extends IDMService { * is often included in the stopped event. Also for some UI functionality, * such as setpping, only top stack frame is often needed. * @param execContext - * @param done + * @param rm */ - void getTopFrame(IRunControl.IExecutionDMContext execContext, GetDataDone done); + void getTopFrame(IRunControl.IExecutionDMContext execContext, DataRequestMonitor rm); /** * Retrieves variables which were arguments to the stack frame's function. */ - void getArguments(IFrameDMContext frameCtx, GetDataDone done); + void getArguments(IFrameDMContext frameCtx, DataRequestMonitor rm); /** * Retrieves variables local to the stack frame. */ - void getLocals(IFrameDMContext frameCtx, GetDataDone done); + void getLocals(IFrameDMContext frameCtx, DataRequestMonitor rm); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISymbols.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISymbols.java index 446915da89d..94da90b32c4 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISymbols.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISymbols.java @@ -10,7 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.service; -import org.eclipse.dd.dsf.concurrent.GetDataDone; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMData; import org.eclipse.dd.dsf.datamodel.IDMEvent; @@ -47,8 +47,8 @@ public interface ISymbols extends IDMService { /** * Retrieves the list of symbols. * @param symCtx Symbols context to retrieve symbols for. - * @param done Return token. The return value is an iterator (rather than + * @param rm Request completion monitor. The return value is an iterator (rather than * array) since there could be a very large number of symbols returned. */ - public void getSymbols(IModules.ISymbolDMContext symCtx, GetDataDone> done); + public void getSymbols(IModules.ISymbolDMContext symCtx, DataRequestMonitor> rm); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ITargets.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ITargets.java index c6740dea672..8108979fdad 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ITargets.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ITargets.java @@ -10,8 +10,8 @@ *******************************************************************************/ 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.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMData; import org.eclipse.dd.dsf.datamodel.IDMEvent; @@ -41,12 +41,12 @@ public interface ITargets extends IDMService { public interface ICoreStateChangedDMEvent extends IDMEvent {} - public void getTargets(GetDataDone done); - public void getCores(ITargetDMContext target, GetDataDone done); + public void getTargets(DataRequestMonitor requestMonitor); + public void getCores(ITargetDMContext target, DataRequestMonitor requestMonitor); - 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); + public void connectTarget(ITargetDMContext targetDmc, RequestMonitor requestMonitor); + public void disconnectTarget(ITargetDMContext targetDmc, RequestMonitor requestMonitor); + public void connectCore(ITargetDMContext targetDmc, RequestMonitor requestMonitor); + public void disconnectCore(ITargetDMContext targetDmc, RequestMonitor requestMonitor); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandControl.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandControl.java index e58f40b77be..bf4effb9962 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandControl.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandControl.java @@ -10,7 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.service.command; -import org.eclipse.dd.dsf.concurrent.GetDataDone; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.service.IDsfService; /** @@ -23,10 +23,10 @@ public interface ICommandControl extends IDsfService{ * Adds the specified command to the queue of commands to be processed. * * @param command Specific command to be processed - * @param done Completion notification handler + * @param rm Request completion monitor * @return None */ - void queueCommand(ICommand command, GetDataDone done); + void queueCommand(ICommand command, DataRequestMonitor rm); /** * Removes the specified command from the processor queue. diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java index 163e67a9593..a4ecedef72f 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java @@ -13,13 +13,12 @@ package org.eclipse.dd.dsf.ui.viewmodel; import java.util.Collections; import java.util.HashMap; import java.util.Map; -import java.util.concurrent.Executor; -import java.util.concurrent.ExecutorService; import java.util.concurrent.RejectedExecutionException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.service.IDsfService; @@ -41,7 +40,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; @SuppressWarnings("restriction") abstract public class AbstractVMAdapter implements IVMAdapter { - private final ExecutorService fExecutor; + private final DsfExecutor fExecutor; private boolean fDisposed; private final Map fViewModelProviders = @@ -64,7 +63,7 @@ abstract public class AbstractVMAdapter implements IVMAdapter * and the layout nodes. * @return */ - public Executor getExecutor() { + public DsfExecutor getExecutor() { return fExecutor; } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java index fd908ca8bf4..e749e482e9e 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java @@ -15,13 +15,13 @@ import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; -import java.util.concurrent.Executor; import java.util.concurrent.RejectedExecutionException; import org.eclipse.core.runtime.IStatus; -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.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.MultiRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactoryAdapter; @@ -56,7 +56,7 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { /** * Accessor method for sub-classes. */ - protected Executor getExecutor() { + protected DsfExecutor getExecutor() { return fProvider.getExecutor(); } @@ -97,15 +97,15 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { * in this node, which could be very inefficient. In order to build delta * only for specific elements in this node, the class extending * AbstractVMLayoutNode should override this method. - * @see IVMLayoutNode#buildDelta(Object, VMDelta, int, Done) + * @see IVMLayoutNode#buildDelta(Object, VMDelta, int, RequestMonitor) */ - public void buildDelta(final Object event, final VMDelta parentDelta, final int nodeOffset, final Done done) { + public void buildDelta(final Object event, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) { // Find the child nodes that have deltas for the given event. final Map childNodesWithDeltaFlags = getChildNodesWithDeltaFlags(event); // If no child layout nodes have deltas we can stop here. if (childNodesWithDeltaFlags.size() == 0) { - getExecutor().execute(done); + requestMonitor.done(); return; } @@ -122,30 +122,33 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { } if (!mustGetElements) { - callChildNodesToBuildDelta(childNodesWithDeltaFlags, parentDelta, event, done); + callChildNodesToBuildDelta(childNodesWithDeltaFlags, parentDelta, event, requestMonitor); } else { // 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. updateElements(new ElementsUpdate( - new GetDataDone>() { - public void run() { + new DataRequestMonitor>(getExecutor(), null) { + @Override + protected void handleCompleted() { if (fDisposed) return; // Check for an empty list of elements. If it's empty then we // don't have to call the children nodes, so return here. // No need to propagate error, there's no means or need to display it. if (!getStatus().isOK() || getData().size() == 0) { - getExecutor().execute(done); + requestMonitor.done(); return; } - final DoneCollector elementsDeltasDoneCollector = new DoneCollector() { - public void run() { - if (isDisposed()) return; - getExecutor().execute(done); - } - }; + final MultiRequestMonitor elementsDeltasMultiRequestMon = + new MultiRequestMonitor(getExecutor(), null) { + @Override + protected void handleCompleted() { + if (isDisposed()) return; + requestMonitor.done(); + } + }; // For each element from this node, create a new delta, // and then call all the child nodes to build their delta. @@ -153,9 +156,10 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { VMDelta delta = parentDelta.addNode(getData().get(i), nodeOffset + i, IModelDelta.NO_CHANGE); callChildNodesToBuildDelta( childNodesWithDeltaFlags, delta, event, - elementsDeltasDoneCollector.add(new Done() { - public void run() { - elementsDeltasDoneCollector.doneDone(this); + elementsDeltasMultiRequestMon.add(new RequestMonitor(getExecutor(), null) { + @Override + protected void handleCompleted() { + elementsDeltasMultiRequestMon.requestMonitorDone(this); } })); } @@ -174,9 +178,9 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { * gerated by this node, unless the full delta path is not being calculated * due to an optimization. * @param event The event object that the delta is being built for. - * @param done The result token to invoke when the delta is completed. + * @param requestMonitor The result token to invoke when the delta is completed. */ - protected void callChildNodesToBuildDelta(final Map nodes, final VMDelta delta, final Object event, final Done done) { + protected void callChildNodesToBuildDelta(final Map nodes, final VMDelta delta, final Object event, final RequestMonitor requestMonitor) { assert nodes.size() != 0; // Check if any of the child nodes are will generate IModelDelta.SELECT or @@ -190,31 +194,37 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { } } - getChildNodesElementOffsets(delta, !calculateOffsets, new GetDataDone>() { - public void run() { - if (isDisposed()) return; - - final DoneCollector childrenBuildDeltaDoneCollector = new DoneCollector() { - public void run() { - if (isDisposed()) return; - getExecutor().execute(done); + getChildNodesElementOffsets( + delta, !calculateOffsets, + new DataRequestMonitor>(getExecutor(), null) { + @Override + protected void handleCompleted() { + if (isDisposed()) return; + + final MultiRequestMonitor childrenBuildDeltaDoneCollector = + new MultiRequestMonitor(getExecutor(), null) { + @Override + protected void handleCompleted() { + if (isDisposed()) return; + requestMonitor.done(); + } + }; + + // Set the total count of number of children in the parent delta. + delta.setChildCount(getData().get(null)); + + for (IVMLayoutNode node : nodes.keySet()) { + node.buildDelta( + event, delta, getData().get(node), + childrenBuildDeltaDoneCollector.add(new RequestMonitor(getExecutor(), null) { + @Override + protected void handleCompleted() { + childrenBuildDeltaDoneCollector.requestMonitorDone(this); + }}) + ); } - }; - - // Set the total count of number of children in the parent delta. - delta.setChildCount(getData().get(null)); - - for (IVMLayoutNode node : nodes.keySet()) { - node.buildDelta( - event, delta, getData().get(node), - childrenBuildDeltaDoneCollector.add(new Done() { - public void run() { - childrenBuildDeltaDoneCollector.doneDone(this); - }}) - ); } - } - }); + }); } /** @@ -228,43 +238,50 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { * structure with dummy values. The dummy values indicate that the indexes * are not known and are acceptable in the delta if the delta flags being * generated do not require full index information. - * @param done Return token containing the results. The result data is a + * @param rm Return token containing the results. The result data is a * mapping between the child nodes and the indexes at which the child nodes' * elements begin. There is a special value in the map with a null * key, which contains the full element count for all the nodes. */ - private void getChildNodesElementOffsets(IModelDelta delta, boolean fakeIt, final GetDataDone> done) { + private void getChildNodesElementOffsets(IModelDelta delta, boolean fakeIt, final DataRequestMonitor> rm) { assert getChildLayoutNodes().length != 0; if (!fakeIt) { final Integer[] counts = new Integer[getChildLayoutNodes().length]; - final DoneCollector childrenCountDoneCollector = new DoneCollector() { - public void run() { - if (isDisposed()) return; - if (propagateError(getExecutor(), done, "")) return; //$NON-NLS-1$ - Map data = new HashMap(); - int offset = 0; - for (int i = 0; i < getChildLayoutNodes().length; i++) { - data.put(getChildLayoutNodes()[i], offset); - offset += counts[i]; + final MultiRequestMonitor childrenCountMultiRequestMon = + new MultiRequestMonitor(getExecutor(), rm) { + @Override + protected void handleCompleted() { + if (isDisposed()) return; + super.handleCompleted(); } - // As the final value, put the total count in the return map, with null key. - data.put(null, offset); - done.setData(data); - getExecutor().execute(done); - } - }; + @Override + protected void handleOK() { + Map data = new HashMap(); + int offset = 0; + for (int i = 0; i < getChildLayoutNodes().length; i++) { + data.put(getChildLayoutNodes()[i], offset); + offset += counts[i]; + } + // As the final value, put the total count in the return map, with null key. + data.put(null, offset); + rm.setData(data); + rm.done(); + } + }; for (int i = 0; i < getChildLayoutNodes().length; i++) { final int nodeIndex = i; getChildLayoutNodes()[i].updateElementCount( new ElementsCountUpdate( - childrenCountDoneCollector.add(new GetDataDone() { - public void run() { - counts[nodeIndex] = getData(); - childrenCountDoneCollector.doneDone(this); - } - }), + childrenCountMultiRequestMon.add( + new DataRequestMonitor(getExecutor(), null) { + @Override + protected void handleCompleted() { + counts[nodeIndex] = getData(); + childrenCountMultiRequestMon.requestMonitorDone(this); + } + }), delta) ); } @@ -274,8 +291,8 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { data.put(getChildLayoutNodes()[i], -1); } data.put(null, -1); - done.setData(data); - getExecutor().execute(done); + rm.setData(data); + rm.done(); } } @@ -358,14 +375,13 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { protected class ViewerUpdate implements IViewerUpdate { - final private Done fDone; - private boolean fDoneInvoked = false; + final private RequestMonitor fRequestMonitor; final private TreePath fTreePath; private IStatus fStatus; private boolean fCancelled = false; - public ViewerUpdate(Done done, IModelDelta delta) { - fDone = done; + public ViewerUpdate(RequestMonitor requestMonitor, IModelDelta delta) { + fRequestMonitor = requestMonitor; List elementList = new LinkedList(); IModelDelta listDelta = delta; elementList.add(0, listDelta.getElement()); @@ -376,8 +392,8 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { fTreePath = new TreePath(elementList.toArray()); } - public ViewerUpdate(Done done, TreePath path) { - fDone = done; + public ViewerUpdate(RequestMonitor requestMonitor, TreePath path) { + fRequestMonitor = requestMonitor; fTreePath = path; } @@ -402,42 +418,40 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { public void cancel() { fCancelled = true; } public void done() { - assert !fDoneInvoked; - fDoneInvoked = true; try { - getExecutor().execute(fDone); + fRequestMonitor.done(); } catch (RejectedExecutionException e) { } } } protected class ElementsCountUpdate extends ViewerUpdate implements IChildrenCountUpdate { - private final GetDataDone fElementCountDone; + private final DataRequestMonitor fElementCountRequestMonitor; - public ElementsCountUpdate(GetDataDone done, IModelDelta delta) { - super(done, delta); - fElementCountDone = done; + public ElementsCountUpdate(DataRequestMonitor rm, IModelDelta delta) { + super(rm, delta); + fElementCountRequestMonitor = rm; } public void setChildCount(int numChildren) { - fElementCountDone.setData(numChildren); + fElementCountRequestMonitor.setData(numChildren); } } protected class ElementsUpdate extends ViewerUpdate implements IChildrenUpdate { private final List fChildren = new ArrayList(); - private GetDataDone> fElementUpdateDone; + private DataRequestMonitor> fElementUpdateRequestMonitor; - public ElementsUpdate(GetDataDone> done, IModelDelta delta) { - super(done, delta); - fElementUpdateDone = done; - fElementUpdateDone.setData(fChildren); + public ElementsUpdate(DataRequestMonitor> rm, IModelDelta delta) { + super(rm, delta); + fElementUpdateRequestMonitor = rm; + fElementUpdateRequestMonitor.setData(fChildren); } - public ElementsUpdate(GetDataDone> done, TreePath path) { - super(done, path); - fElementUpdateDone = done; - fElementUpdateDone.setData(fChildren); + public ElementsUpdate(DataRequestMonitor> rm, TreePath path) { + super(rm, path); + fElementUpdateRequestMonitor = rm; + fElementUpdateRequestMonitor.setData(fChildren); } public int getOffset() { diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java index 7a27627ef2d..227365734e7 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java @@ -14,7 +14,6 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.concurrent.Executor; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.atomic.AtomicReference; @@ -24,9 +23,10 @@ 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.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.MultiRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.DsfUIPlugin; @@ -131,7 +131,7 @@ abstract public class AbstractVMProvider implements IVMProvider /** * Convenience method to access the View Model's executor. */ - public Executor getExecutor() { return fVMAdapter.getExecutor(); } + public DsfExecutor getExecutor() { return fVMAdapter.getExecutor(); } public void update(IHasChildrenUpdate[] updates) { @@ -175,13 +175,14 @@ abstract public class AbstractVMProvider implements IVMProvider final IHasChildrenUpdate update = updates[i]; for (int j = 0; j < node.getChildLayoutNodes().length; j++) { - final DoneCollector> hasChildrenDoneCollector = - new DoneCollector>() { - public void run() { - // Status is OK, only if all dones are OK. + final MultiRequestMonitor> hasChildrenMultiRequestMon = + new MultiRequestMonitor>(getExecutor(), null) { + @Override + protected void handleCompleted() { + // Status is OK, only if all request monitors are OK. if (getStatus().isOK()) { boolean isContainer = false; - for (GetDataDone hasElementsDone : getDones().keySet()) { + for (DataRequestMonitor hasElementsDone : getRequestMonitors().keySet()) { isContainer |= hasElementsDone.getStatus().isOK() && hasElementsDone.getData().booleanValue(); } @@ -193,11 +194,13 @@ abstract public class AbstractVMProvider implements IVMProvider elementsUpdates[j][i] = new HasElementsUpdate( update, - hasChildrenDoneCollector.add(new GetDataDone() { - public void run() { - hasChildrenDoneCollector.doneDone(this); - } - })); + hasChildrenMultiRequestMon.add( + new DataRequestMonitor(getExecutor(), null) { + @Override + protected void handleCompleted() { + hasChildrenMultiRequestMon.requestMonitorDone(this); + } + })); } } @@ -213,8 +216,9 @@ abstract public class AbstractVMProvider implements IVMProvider getChildrenCountsForNode( update, update.getElementPath(), - new GetDataDone() { - public void run() { + new DataRequestMonitor(getExecutor(), null) { + @Override + protected void handleCompleted() { if (getStatus().isOK()) { int numChildren = 0; for (Integer count : getData()) { @@ -234,8 +238,9 @@ abstract public class AbstractVMProvider implements IVMProvider for (final IChildrenUpdate update : updates) { getChildrenCountsForNode( update, update.getElementPath(), - new GetDataDone() { - public void run() { + new DataRequestMonitor(getExecutor(), null) { + @Override + protected void handleCompleted() { if (!getStatus().isOK()) { update.done(); return; @@ -247,16 +252,16 @@ abstract public class AbstractVMProvider implements IVMProvider } - private void getChildrenCountsForNode(IViewerUpdate update, TreePath elementPath, final GetDataDone done) { + private void getChildrenCountsForNode(IViewerUpdate update, TreePath elementPath, final DataRequestMonitor rm) { if (isDisposed()) return; // Get the VM Context for last element in path. final IVMLayoutNode layoutNode = getLayoutNodeObject(update.getElement()); if (layoutNode == null) { // Stale update. Just ignore. - done.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, - "Stale update.", null)); //$NON-NLS-1$ - getExecutor().execute(done); + rm.setStatus(new Status( + IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Stale update.", null)); //$NON-NLS-1$ + rm.done(); return; } @@ -265,21 +270,25 @@ abstract public class AbstractVMProvider implements IVMProvider // If parent element's layout node has no children, just mark done and // return. if (childNodes.length == 0) { - done.setData(new Integer[0]); - getExecutor().execute(done); + rm.setData(new Integer[0]); + rm.done(); return; } // Get the mapping of all the counts. final Integer[] counts = new Integer[childNodes.length]; - final DoneCollector childrenCountDoneCollector = - new DoneCollector() { - public void run() { - if (fDisposed) return; - if (propagateError(getExecutor(), done, "")) return; //$NON-NLS-1$ - done.setData(counts); - getExecutor().execute(done); + final MultiRequestMonitor childrenCountMultiReqMon = + new MultiRequestMonitor(getExecutor(), rm) { + @Override + protected void handleCompleted() { + if (!fDisposed) super.handleCompleted(); + } + + @Override + protected void handleOK() { + rm.setData(counts); + rm.done(); } }; @@ -288,15 +297,19 @@ abstract public class AbstractVMProvider implements IVMProvider childNodes[i].updateElementCount( new ElementsCountUpdate( update, - childrenCountDoneCollector.add(new GetDataDone() { - public void run() { - if (getStatus().isOK()) { - assert getData() != null; + childrenCountMultiReqMon.add( + new DataRequestMonitor(getExecutor(), null) { + @Override + protected void handleOK() { counts[nodeIndex] = getData(); - } - childrenCountDoneCollector.doneDone(this); - } - }), + } + + @Override + protected void handleCompleted() { + super.handleCompleted(); + childrenCountMultiReqMon.requestMonitorDone(this); + } + }), elementPath) ); } @@ -309,10 +322,12 @@ abstract public class AbstractVMProvider implements IVMProvider if (!update.isCanceled()) update.done(); } - // Create the done collector to mark update when querying all children nodes is finished. - final DoneCollector elementsDoneCollector = - new DoneCollector() { - public void run() { + // Create the multi request monitor to mark update when querying all + // children nodes is finished. + final MultiRequestMonitor elementsMultiRequestMon = + new MultiRequestMonitor(getExecutor(), null) { + @Override + protected void handleCompleted() { if (!update.isCanceled()) update.done(); } }; @@ -336,9 +351,10 @@ abstract public class AbstractVMProvider implements IVMProvider layoutNodes[i].updateElements( new ElementsUpdate( update, - elementsDoneCollector.add(new Done() { - public void run() { - elementsDoneCollector.doneDone(this); + elementsMultiRequestMon.add(new RequestMonitor(getExecutor(), null) { + @Override + protected void handleCompleted() { + elementsMultiRequestMon.requestMonitorDone(this); } }), nodeStartIdx, elementsStartIdx, elementsEndIdx - elementsStartIdx) @@ -347,7 +363,7 @@ abstract public class AbstractVMProvider implements IVMProvider } // Guard against invalid queries. - if (elementsDoneCollector.getDones().isEmpty()) { + if (elementsMultiRequestMon.getRequestMonitors().isEmpty()) { update.done(); } @@ -510,12 +526,11 @@ abstract public class AbstractVMProvider implements IVMProvider class ViewerUpdate implements IViewerUpdate { private IStatus fStatus; - private boolean fDoneInvoked = false; - final private Done fDone; + final private RequestMonitor fRequestMonitor; final protected IViewerUpdate fClientUpdate; - public ViewerUpdate(IViewerUpdate clientUpdate, Done done) { - fDone = done; + public ViewerUpdate(IViewerUpdate clientUpdate, RequestMonitor requestMonitor) { + fRequestMonitor = requestMonitor; fClientUpdate = clientUpdate; } @@ -531,10 +546,8 @@ abstract public class AbstractVMProvider implements IVMProvider } public void done() { - assert !fDoneInvoked; - fDoneInvoked = true; try { - getExecutor().execute(fDone); + fRequestMonitor.done(); } catch (RejectedExecutionException e) { // Ignore } } @@ -543,11 +556,11 @@ abstract public class AbstractVMProvider implements IVMProvider class HasElementsUpdate extends ViewerUpdate implements IHasChildrenUpdate { - final private GetDataDone fHasElemsDone; + final private DataRequestMonitor fHasElemsRequestMonitor; - HasElementsUpdate(IHasChildrenUpdate clientUpdate, GetDataDone done) { - super(clientUpdate, done); - fHasElemsDone = done; + HasElementsUpdate(IHasChildrenUpdate clientUpdate, DataRequestMonitor rm) { + super(clientUpdate, rm); + fHasElemsRequestMonitor = rm; } @Override @@ -556,24 +569,24 @@ abstract public class AbstractVMProvider implements IVMProvider } public void setHasChilren(boolean hasChildren) { - fHasElemsDone.setData(hasChildren); + fHasElemsRequestMonitor.setData(hasChildren); } @Override public void done() { - assert fHasElemsDone.getData() != null || !fHasElemsDone.getStatus().isOK(); + assert fHasElemsRequestMonitor.getData() != null || !fHasElemsRequestMonitor.getStatus().isOK(); super.done(); } } class ElementsCountUpdate extends ViewerUpdate implements IChildrenCountUpdate { - final private GetDataDone fCountDone; + final private DataRequestMonitor fCountRequestMonitor; final private TreePath fElementPath; - ElementsCountUpdate(IViewerUpdate clientUpdate, GetDataDone done, TreePath elementPath) { - super(clientUpdate, done); + ElementsCountUpdate(IViewerUpdate clientUpdate, DataRequestMonitor rm, TreePath elementPath) { + super(clientUpdate, rm); fElementPath = elementPath; - fCountDone = done; + fCountRequestMonitor = rm; } @Override @@ -582,12 +595,12 @@ abstract public class AbstractVMProvider implements IVMProvider } public void setChildCount(int count) { - fCountDone.setData(count); + fCountRequestMonitor.setData(count); } @Override public void done() { - assert fCountDone.getData() != null || !fCountDone.getStatus().isOK(); + assert fCountRequestMonitor.getData() != null || !fCountRequestMonitor.getStatus().isOK(); super.done(); } @@ -598,8 +611,8 @@ abstract public class AbstractVMProvider implements IVMProvider private final int fOffset; private final int fLength; - ElementsUpdate(IChildrenUpdate clientUpdate, Done done, int clientOffset, int offset, int length) { - super(clientUpdate, done); + ElementsUpdate(IChildrenUpdate clientUpdate, RequestMonitor requestMonitor, int clientOffset, int offset, int length) { + super(clientUpdate, requestMonitor); fClientOffset = clientOffset; fOffset = offset; fLength = length; diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMRootLayoutNode.java index 253d8c0bfb7..a7dfdc82e33 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMRootLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMRootLayoutNode.java @@ -12,8 +12,8 @@ package org.eclipse.dd.dsf.ui.viewmodel; import java.util.Map; -import org.eclipse.dd.dsf.concurrent.Done; -import org.eclipse.dd.dsf.concurrent.GetDataDone; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; @@ -77,7 +77,7 @@ abstract public class AbstractVMRootLayoutNode extends AbstractVMLayoutNode impl * 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 done) { + public void createDelta(Object event, final DataRequestMonitor rm) { final Map childNodeDeltas = getChildNodesWithDeltaFlags(event); assert childNodeDeltas.size() != 0 : "Caller should make sure that there are deltas for given event."; //$NON-NLS-1$ @@ -86,12 +86,16 @@ abstract public class AbstractVMRootLayoutNode extends AbstractVMLayoutNode impl callChildNodesToBuildDelta( childNodeDeltas, rootDelta, event, - new Done() { - public void run() { - if (isDisposed()) return; - if (propagateError(getExecutor(), done, "Failed to create delta.")) return; //$NON-NLS-1$ - done.setData(rootDelta); - getExecutor().execute(done); + new RequestMonitor(getExecutor(), rm) { + @Override + protected void handleCompleted() { + if (!isDisposed()) super.handleCompleted(); + } + + @Override + public void handleOK() { + rm.setData(rootDelta); + rm.done(); } }); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMLayoutNode.java index b6af2856cd8..d21487c7192 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMLayoutNode.java @@ -11,7 +11,7 @@ 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.RequestMonitor; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; @@ -90,7 +90,7 @@ public interface IVMLayoutNode * for the given event. * @param event Event to process. * @return IModelDelta flags - * @see #buildDelta(Object, VMDelta, int, Done) + * @see #buildDelta(Object, VMDelta, int, RequestMonitor) * @see IModelDelta */ public int getDeltaFlags(Object event); @@ -120,10 +120,10 @@ public interface IVMLayoutNode * data to. * @param nodeOffset The offset of the first element in this node. This offset * depends on the elements returned by the siblings of this layout node. - * @param done Return token, which notifies the caller that the calculation is + * @param requestMonitor Return token, which notifies the caller that the calculation is * complete. */ - public void buildDelta(Object event, VMDelta parent, int nodeOffset, Done done); + public void buildDelta(Object event, VMDelta parent, int nodeOffset, RequestMonitor requestMonitor); /** * Releases the resources held by this node. diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMRootLayoutNode.java index 500ff56c64f..34398603e7a 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMRootLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMRootLayoutNode.java @@ -10,7 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.dsf.ui.viewmodel; -import org.eclipse.dd.dsf.concurrent.GetDataDone; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; /** @@ -30,11 +30,11 @@ public interface IVMRootLayoutNode extends IVMLayoutNode{ public Object getRootObject(); /** - * Version of the {@link IVMLayoutNode#buildDelta(Object, ViewModelDelta, org.eclipse.dd.dsf.concurrent.Done)} + * Version of the {@link IVMLayoutNode#buildDelta(Object, ViewModelDelta, org.eclipse.dd.dsf.concurrent.RequestMonitor)} * 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. + * @param rm Result notification, contains the root of the delta. */ - public void createDelta(Object event, GetDataDone done); + public void createDelta(Object event, DataRequestMonitor rm); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java index 7857722c66b..df94f0e020c 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java @@ -16,9 +16,9 @@ import java.util.concurrent.RejectedExecutionException; 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.RequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfRunnable; -import org.eclipse.dd.dsf.concurrent.GetDataDone; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; @@ -198,8 +198,9 @@ abstract public class AbstractDMVMLayoutNode extends Abstract updateElementsInSessionThread( new ElementsUpdate( - new GetDataDone>() { - public void run() { + new DataRequestMonitor>(getSession().getExecutor(), null) { + @Override + protected void handleCompleted() { if (!checkUpdate(update)) return; if (getStatus().isOK()) { update.setHasChilren(getData().size() != 0); @@ -232,8 +233,9 @@ abstract public class AbstractDMVMLayoutNode extends Abstract protected void updateElementCountInSessionThread(final IChildrenCountUpdate update) { updateElementsInSessionThread( new ElementsUpdate( - new GetDataDone>() { - public void run() { + new DataRequestMonitor>(getSession().getExecutor(), null) { + @Override + protected void handleCompleted() { if (!checkUpdate(update)) return; if (getStatus().isOK()) { update.setChildCount(getData().size()); @@ -296,8 +298,9 @@ abstract public class AbstractDMVMLayoutNode extends Abstract ((IDMService)getServicesTracker().getService(null, vmc.getDMC().getServiceFilter())).getModelData( dmc, - new GetDataDone() { - public void run() { + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + protected void handleCompleted() { /* * Check that the request was evaluated and data is still * valid. The request could fail if the state of the @@ -363,22 +366,22 @@ abstract public class AbstractDMVMLayoutNode extends Abstract } @Override - public void buildDelta(final Object e, final VMDelta parentDelta, final int nodeOffset, final Done done) { + public void buildDelta(final Object e, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) { if (e instanceof IDMEvent) { // Call handler for Data Model events. But check to make sure // that session is still active. if (DsfSession.isSessionActive(getSession().getId())) { getSession().getExecutor().execute(new DsfRunnable() { public void run() { - buildDeltaForDMEvent((IDMEvent)e, parentDelta, nodeOffset, done); + buildDeltaForDMEvent((IDMEvent)e, parentDelta, nodeOffset, requestMonitor); } }); } else { if (isDisposed()) return; - getExecutor().execute(done); + requestMonitor.done(); } } else { - super.buildDelta(e, parentDelta, nodeOffset, done); + super.buildDelta(e, parentDelta, nodeOffset, requestMonitor); } } @@ -387,7 +390,7 @@ abstract public class AbstractDMVMLayoutNode extends Abstract * a context of the type tracked by this node, then this base implementation * will only create a delta node for this one element. */ - protected void buildDeltaForDMEvent(final IDMEvent event, final VMDelta parentDelta, final int nodeOffset, final Done done) { + protected void buildDeltaForDMEvent(final IDMEvent event, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) { IDMContext dmc = DMContexts.getAncestorOfType(event.getDMContext(), fDMCClassType); if (dmc != null) { @@ -397,7 +400,7 @@ abstract public class AbstractDMVMLayoutNode extends Abstract final Map childNodeDeltas = getChildNodesWithDeltaFlags(event); if (childNodeDeltas.size() == 0) { // There are no child nodes with deltas, just return to parent. - getExecutor().execute(done); + requestMonitor.done(); return; } @@ -416,15 +419,16 @@ abstract public class AbstractDMVMLayoutNode extends Abstract // Calculate the index of this node by retrieving all the // elements and then finding the DMC that the event is for. updateElements(new ElementsUpdate( - new GetDataDone>() { - public void run() { + new DataRequestMonitor>(getExecutor(), null) { + @Override + protected void handleCompleted() { if (isDisposed()) return; // Check for an empty list of elements. If it's empty then we // don't have to call the children nodes, so return here. // No need to propagate error, there's no means or need to display it. if (!getStatus().isOK()) { - getExecutor().execute(done); + requestMonitor.done(); return; } @@ -435,23 +439,23 @@ abstract public class AbstractDMVMLayoutNode extends Abstract } if (i == getData().size()) { // Element not found, no need to generate the delta. - getExecutor().execute(done); + requestMonitor.done(); } VMDelta delta = parentDelta.addNode(vmc, nodeOffset + i, IModelDelta.NO_CHANGE); - callChildNodesToBuildDelta(childNodeDeltas, delta, event, done); + callChildNodesToBuildDelta(childNodeDeltas, delta, event, requestMonitor); } }, parentDelta)); } else { VMDelta delta = parentDelta.addNode(vmc, IModelDelta.NO_CHANGE); - callChildNodesToBuildDelta(childNodeDeltas, delta, event, done); + callChildNodesToBuildDelta(childNodeDeltas, delta, event, requestMonitor); } } else { // The for this node was not found in the event. Call the // super-class to resort to the default behavior which may add a // delta node for every element in this node. - super.buildDelta(event, parentDelta, nodeOffset, done); + super.buildDelta(event, parentDelta, nodeOffset, requestMonitor); } } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProvider.java index 9cb1d99330b..990892a5d1a 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProvider.java @@ -13,7 +13,7 @@ package org.eclipse.dd.dsf.ui.viewmodel.dm; import java.util.concurrent.RejectedExecutionException; import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; -import org.eclipse.dd.dsf.concurrent.GetDataDone; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMEvent; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfSession; @@ -120,16 +120,19 @@ abstract public class AbstractDMVMProvider extends AbstractVMProvider IVMRootLayoutNode rootLayoutNode = getRootLayoutNode(); if (rootLayoutNode != null && rootLayoutNode.getDeltaFlags(event) != 0) { - rootLayoutNode.createDelta(event, new GetDataDone() { - public void run() { - if (getStatus().isOK()) { - getModelProxy().fireModelChangedNonDispatch(getData()); + rootLayoutNode.createDelta( + event, + new DataRequestMonitor(getExecutor(), null) { + @Override + public void handleCompleted() { + if (getStatus().isOK()) { + getModelProxy().fireModelChangedNonDispatch(getData()); + } } - } - @Override public String toString() { - return "Result of a delta for event: '" + event.toString() + "' in VMP: '" + AbstractDMVMProvider.this + "'" + "\n" + getData().toString(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - } - }); + @Override public String toString() { + return "Result of a delta for event: '" + event.toString() + "' in VMP: '" + AbstractDMVMProvider.this + "'" + "\n" + getData().toString(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } + }); } }}); } catch (RejectedExecutionException e) { diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/GetDataDone.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DataRequestMonitor.java similarity index 68% rename from plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/GetDataDone.java rename to plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DataRequestMonitor.java index bbedc24667e..754e5dd4175 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/GetDataDone.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DataRequestMonitor.java @@ -10,26 +10,32 @@ *******************************************************************************/ package org.eclipse.dd.dsf.concurrent; + /** - * Asynchronous method callback which returns a data object (in addition to - * the base class's getStatus(). - * @param + * Request monitor that allows data to be returned to the request initiator. + * + * @param V The type of the data object that this monitor handles. */ -public abstract class GetDataDone extends Done { +public abstract class DataRequestMonitor extends RequestMonitor { + /** Data object reference */ private V fData; + public DataRequestMonitor(DsfExecutor executor, RequestMonitor parentRequestMonitor) { + super(executor, parentRequestMonitor); + } + /** * Sets the data object to specified value. To be called by the * asynchronous method implementor. * @param data Data value to set. */ - public void setData(V data) { fData = data; } + public synchronized void setData(V data) { fData = data; } /** * Returns the data value, null if not set. */ - public V getData() { return fData; } + public synchronized V getData() { return fData; } @Override public String toString() { @@ -38,5 +44,5 @@ public abstract class GetDataDone extends Done { } else { return super.toString(); } - } + } } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java index a6e47251fd7..b5f5a240a53 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java @@ -92,7 +92,7 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor } /** - * This map is used by DsfRunnable/DsfQuery/DsfCallable to track by which executor + * This map is used by DsfRunnable/Query/DsfCallable to track by which executor * an executable object was created. *
    Note: Only used when tracing. */ diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java deleted file mode 100644 index 04ef3bf344a..00000000000 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Done.java +++ /dev/null @@ -1,74 +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.concurrent; - -import java.util.concurrent.Executor; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.MultiStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.DsfPlugin; - -/** - * Base class for DSF service method-completion callbacks. By default - * all callbacks that indicate a complition of a method contain the status - * of the result. - *
    NOTE: Access to the status data is not synchronized, so - * clients have to make sure that access to this object is thread safe if - * it's used outside of the caller's dispatch thread. - */ -@ConfinedToDsfExecutor("") -abstract public class Done extends DsfRunnable { - private IStatus fStatus = Status.OK_STATUS; - - /** Sets the status of the called method. */ - public void setStatus(IStatus status) { fStatus = status; } - - /** Returns the status of the completed method. */ - public IStatus getStatus() { return fStatus; } - - /** - * Convenience method for setting the status using a status object of a - * sub-command. - * @param pluginId plugin id of the invoked method - * @param code status code - * @param message message to include - * @param subStatus status object to base the Done status on - */ - public void setErrorStatus(String pluginId, int code, String message, final IStatus subStatus) { - MultiStatus status = new MultiStatus(pluginId, code, message, null); - status.merge(subStatus); - fStatus = status; - } - - /** - * Convenience method which checks for error in done, and propagates it - * to caller's client done. - * @return Returns true if there was an error that was propagated and - * the caller can stop processing result. - */ - protected boolean propagateError(Executor executor, Done clientDone, String message) { - if (clientDone.getStatus().getSeverity() == IStatus.CANCEL) { - return true; - } - if (!getStatus().isOK()) { - clientDone.setErrorStatus(DsfPlugin.PLUGIN_ID, getStatus().getCode(), message, getStatus()); - executor.execute(clientDone); - return true; - } - return false; - } - - @Override - public String toString() { - return "Done: " + getStatus().toString(); //$NON-NLS-1$ - } -} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DoneCollector.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DoneCollector.java deleted file mode 100644 index e21dc82d494..00000000000 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DoneCollector.java +++ /dev/null @@ -1,105 +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.concurrent; - -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.core.runtime.MultiStatus; -import org.eclipse.dd.dsf.DsfPlugin; - -/** - * Utility class to collect multiple done (callback) results of commands - * that are initiated simultaneously. The usage is as follows: - *
    - *     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, doneCollector.addDone(new Done() {
    - *             public void run() {
    - *                 System.out.println(Integer.toString(i) + " complete");
    - *                 doneCollector.doneDone(this);
    - *             }
    - *         }));
    - *     }
    - * 
    - */ -public abstract class DoneCollector extends Done { - private Map fDones = new HashMap(); - private int fDoneCounter; - - /** - * No-arg constructor. - *
    - * Note: this runnable will be executed following - * execution of the last done, and in the same dispatch loop. - * - */ - public DoneCollector() { - setStatus(new MultiStatus(DsfPlugin.PLUGIN_ID, 0, "Collective status for set of sub-operations.", null)); //$NON-NLS-1$ - } - - /** - * Adds a new Done callback to this tracker's list. - * @param Client-specific class of the Done callback, it's used here to avoid an - * unnecessary cast by the client. - * @param done callback object to add to the tracker - * @return the done that was just added, it allows this method to be used - * inlined in service method calls - */ - public T add(T done) { - assert !fDones.containsKey(done); - fDones.put(done, false); - fDoneCounter++; - return done; - } - - /** - * Marks the given Done callback as completed. Client implementations of - * the Done callback have to call this method in order for the tracker - * to complete. - *
    - * Note: funniest method signature ever! - * @param done - */ - public void doneDone(V done) { - ((MultiStatus)getStatus()).merge(done.getStatus()); - assert fDones.containsKey(done); - fDones.put(done, true); - assert fDoneCounter > 0; - fDoneCounter--; - if (fDoneCounter == 0) { - assert !fDones.containsValue(false); - run(); - } - } - - /** - * Returns the map of Done callbacks. Access to this data is provided - * in case overriding classes need access to the collected data in the - * done callbacks. - * @return map of the done callbacks. - */ - public Map getDones() { return fDones; } - - @Override - public String toString() { - return "Done Collector: " + getStatus().toString(); //$NON-NLS-1$ - } - - @Override - protected boolean isExecutionRequired() { - return false; - } -} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/MultiRequestMonitor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/MultiRequestMonitor.java new file mode 100644 index 00000000000..37bb9fdbf9b --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/MultiRequestMonitor.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.concurrent; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.dd.dsf.DsfPlugin; + +/** + * Utility class to collect multiple request monitor results of commands + * that are initiated simultaneously. The usage is as follows: + *
    + *     final MultiRequestMonitor multiRequestMon = new MultiRequestMonitor(fExecutor, null) { 
    + *         public void handleCompleted() {
    + *             System.out.println("All complete, errors=" + !getStatus().isOK());
    + *         }
    + *     };
    + *     
    + *     for (int i = 0; i < 10; i++) {
    + *         service.call(i, multiRequestMon.addRequestMonitor(
    + *             new RequestMonitor(fExecutor, null) {
    + *                 public void handleCompleted() {
    + *                     System.out.println(Integer.toString(i) + " complete");
    + *                     multiRequestMon.requestMonitorDone(this);
    + *                }
    + *             }));
    + *     }
    + * 
    + */ +public abstract class MultiRequestMonitor extends RequestMonitor { + private Map fRequestMonitors = new HashMap(); + private int fDoneCounter; + + public MultiRequestMonitor(DsfExecutor executor, RequestMonitor parentRequestMonitor) { + super(executor, parentRequestMonitor); + setStatus(new MultiStatus(DsfPlugin.PLUGIN_ID, 0, "Collective status for set of sub-operations.", null)); //$NON-NLS-1$ + } + + /** + * Adds a new RequestMonitor callback to this tracker's list. + * @param Client-specific class of the RequestMonitor callback, it's used here to avoid an + * unnecessary cast by the client. + * @param rm Request monitor object to add to the tracker + * @return The request monitor that was just added, it allows this method to be used + * inlined in service method calls + */ + public T add(T rm) { + assert !fRequestMonitors.containsKey(rm); + fRequestMonitors.put(rm, false); + fDoneCounter++; + return rm; + } + + /** + * Marks the given RequestMonitor callback as completed. Client implementations of + * the RequestMonitor callback have to call this method in order for the tracker + * to complete. + *
    + * @param requestMonitor + */ + public void requestMonitorDone(V requestMonitor) { + ((MultiStatus)getStatus()).merge(requestMonitor.getStatus()); + assert fRequestMonitors.containsKey(requestMonitor); + fRequestMonitors.put(requestMonitor, true); + assert fDoneCounter > 0; + fDoneCounter--; + if (fDoneCounter == 0) { + assert !fRequestMonitors.containsValue(false); + super.done(); + } + } + + /** + * Returns the map of RequestMonitor callbacks. Access to this data is provided + * in case overriding classes need access to the collected data in the + * request monitors. + * @return map of the request monitors + */ + public Map getRequestMonitors() { return fRequestMonitors; } + + @Override + public String toString() { + return "Multi-RequestMonitor: " + getStatus().toString(); //$NON-NLS-1$ + } +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfQuery.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Query.java similarity index 91% rename from plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfQuery.java rename to plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Query.java index 01b402ed93e..c85c99fb010 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfQuery.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Query.java @@ -30,12 +30,19 @@ import org.eclipse.core.runtime.CoreException; * @see java.util.concurrent.Callable */ @ThreadSafe -abstract public class DsfQuery extends DsfRunnable +abstract public class Query extends DsfRunnable implements Future { /** The synchronization object for this query */ - final Sync fSync = new Sync(); + private final Sync fSync = new Sync(); + /** The executor that is used to complete the asynchronous operation of this query */ + private final DsfExecutor fExecutor; + + public Query(DsfExecutor executor) { + fExecutor = executor; + } + public V get() throws InterruptedException, ExecutionException { return fSync.doGet(); } public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { @@ -59,13 +66,14 @@ abstract public class DsfQuery extends DsfRunnable fSync.doSetException(t); } - abstract protected void execute(GetDataDone done); + abstract protected void execute(DataRequestMonitor rm); public void run() { if (fSync.doRun()) { try { - execute(new GetDataDone() { - public void run() { + execute(new DataRequestMonitor(fExecutor, null) { + @Override + public void handleCompleted() { if (getStatus().isOK()) fSync.doSet(getData()); else fSync.doSetException(new CoreException(getStatus())); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java new file mode 100644 index 00000000000..09c895fa17e --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java @@ -0,0 +1,253 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.concurrent; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.DsfPlugin; +import org.eclipse.dd.dsf.service.IDsfService; + +/** + * Used to monitor the result of an asynchronous request. Because of the + * asynchronous nature of DSF code, a very large number of methods needs to + * signal the result of an operation through a call-back. This class is the base + * class for such call backs. + *

    + * The intended use of this class, is that a client who is calling an asynchronous + * method, will sub-class RequestMonitor, and implement the method {@link #handleCompleted()}, + * or any of the other handle... methods, in order to interpret the + * results of the request. The object implementing the asynchronous method is required + * to call the {@link #done()} method on the request monitor object that it received + * as an argument. + *

    + *

    + * This class handles an optional "parent" request monitor. If a parent monitor is + * specified, it will automatically be invoked by this monitor when the request is + * completed. The parent option is useful when implementing a method which is + * asynchronous (and accepts a request monitor as an argument) and which itself calls + * another asynchronous method to complete its operation. For example, in the request + * monitor implementation below, the implementation only needs to override + * handleOK(), because the base implementation will handle notifying the + * parent rm in case the getIngredients() call fails. + *

    + *     public void createCupCakes(final DataRequestMonitor rm) {
    + *         getIngredients(new DataRequestMonitor(fExecutor, rm) {
    + *                 public void handleOK() {
    + *                     rm.setData( new CupCake(getData().getFlour(), getData().getSugar(), 
    + *                                             getData().getBakingPowder()));
    + *                     rm.done();  
    + *                 }
    + *             });
    + *     }
    + * 
    + *

    + */ +@ConfinedToDsfExecutor("") +public class RequestMonitor { + public static final IStatus STATUS_CANCEL = new Status(IStatus.CANCEL, DsfPlugin.PLUGIN_ID, "Request canceled"); //$NON-NLS-1$ + + /** + * The executor that will be used in order to invoke the handler of the results + * of the request. + */ + private final DsfExecutor fExecutor; + + /** + * The request monitor which was used to call into the method that created this + * monitor. + */ + private final RequestMonitor fParentRequestMonitor; + + /** + * Status + */ + private IStatus fStatus = Status.OK_STATUS; + private boolean fCanceled = false; + private boolean fDone = false; + + /** + * Constructor with an optional parent monitor. + * @param executor This executor will be used to invoke the runnable that + * will allow processing the completion code of this request monitor. + * @param parentRequestMonitor The optional parent request monitor to be invoked by + * default when this request completes. Parameter may be null. + */ + public RequestMonitor(DsfExecutor executor, RequestMonitor parentRequestMonitor) { + fExecutor = executor; + fParentRequestMonitor = parentRequestMonitor; + } + + /** + * Sets the status of the result of the request. If status is OK, this + * method does not need to be called. + */ + public synchronized void setStatus(IStatus status) { fStatus = status; } + + /** Returns the status of the completed method. */ + public synchronized IStatus getStatus() { + return fStatus; + } + + /** + * Sets this request as canceled. The operation may still be carried out + * as it is up to the implementation of the asynchronous operation + * to cancel the operation. + * @param canceled Flag indicating whether to cancel. + */ + public synchronized void setCanceled(boolean canceled) { + if (fParentRequestMonitor != null) { + fParentRequestMonitor.setCanceled(canceled); + } else { + fCanceled = canceled; + } + } + + /** + * Returns whether the request was canceled. Even if the request is + * canceled by the client, the implementor handling the request should + * still call {@link #done()} in order to complete handling + * of the request monitor. + */ + public synchronized boolean isCanceled() { + if (fParentRequestMonitor != null) { + return fParentRequestMonitor.isCanceled(); + } else { + return fCanceled; + } + } + + /** + * Marks this request as completed. Once this method is called, the + * monitor submits a runnable to the DSF Executor to call the + * handle... methods. + *

    + * Note: This method should be called once and only once, for every request + * issued. Even if the request was canceled. + *

    + */ + public synchronized void done() { + if (fDone) { + throw new IllegalStateException("RequestMonitor: " + this + ", done() method called more than once"); //$NON-NLS-1$//$NON-NLS-2$ + } + fDone = true; + fExecutor.execute(new DsfRunnable() { + public void run() { + RequestMonitor.this.handleCompleted(); + } + @Override + public String toString() { + return "Completed: " + RequestMonitor.this.toString(); //$NON-NLS-1$ + } + }); + } + + /** + * Convenience method for setting the status using a status object of a + * sub-command. + * @param pluginId plugin id of the invoked method + * @param code status code + * @param message message to include + * @param subStatus status object to base the RequestMonitor status on + */ + public void setMultiStatus(String pluginId, int code, String message, final IStatus subStatus) { + MultiStatus status = new MultiStatus(pluginId, code, message, null); + status.merge(subStatus); + fStatus = status; + } + + @Override + public String toString() { + return "RequestMonitor: " + getStatus().toString(); //$NON-NLS-1$ + } + + /** + * Default handler for the completion of a request. The implementation + * calls {@link #handleOK()} if the request succeded, and calls + * {@link #handleErrorOrCancel()} or cancel otherwise. + *
    + * Note: Sub-classes may override this method. + */ + protected void handleCompleted() { + if (getStatus().isOK()) { + handleOK(); + } else { + handleErrorOrCancel(); + } + } + + /** + * Default handler for a successful the completion of a request. If this + * monitor has a parent monitor that was configured by the constructor, that + * parent monitor is notified. Otherwise this method does nothing. + * {@link #handleErrorOrCancel()} or cancel otherwise. + *
    + * Note: Sub-classes may override this method. + */ + protected void handleOK() { + if (fParentRequestMonitor != null) { + fParentRequestMonitor.done(); + } + } + + /** + * The default implementation of a cancellation or an error result of a + * request. The implementation delegates to {@link #handleCancel()} and + * {@link #handleError()} as needed. + *
    + * Note: Sub-classes may override this method. + */ + protected void handleErrorOrCancel() { + assert !getStatus().isOK(); + if (isCanceled()) { + handleCancel(); + } else { + if (getStatus().getCode() == IStatus.CANCEL) { + DsfPlugin.getDefault().getLog().log(new Status( + IStatus.ERROR, DsfPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Request monitor: '" + this + "' resulted in a cancel status: " + getStatus() + ", even though the request is not set to cancel.", null)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + handleError(); + } + } + + /** + * The default implementation of an error result of a request. If this + * monitor has a parent monitor that was configured by the constructor, that + * parent monitor is configured with a new error status containing this error. + * Otherwise the error is logged. + *
    + * Note: Sub-classes may override this method. + */ + protected void handleError() { + if (fParentRequestMonitor != null) { + fParentRequestMonitor.setMultiStatus(DsfPlugin.PLUGIN_ID, getStatus().getCode(), "Failed: " + toString(), getStatus()); //$NON-NLS-1$ + fParentRequestMonitor.done(); + } else { + MultiStatus logStatus = new MultiStatus(DsfPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Request for monitor: '" + this + "' resulted in an error.", null); //$NON-NLS-1$ //$NON-NLS-2$ + logStatus.merge(getStatus()); + DsfPlugin.getDefault().getLog().log(logStatus); + } + } + + /** + * Default handler for a canceled the completion of a request. If this + * monitor has a parent monitor that was configured by the constructor, that + * parent monitor is notified. Otherwise this method does nothing. + *
    + * Note: Sub-classes may override this method. + */ + protected void handleCancel() { + if (fParentRequestMonitor != null) { + fParentRequestMonitor.setMultiStatus(DsfPlugin.PLUGIN_ID, getStatus().getCode(), "Canceled: " + toString(), getStatus()); //$NON-NLS-1$ + fParentRequestMonitor.done(); + } + } +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Sequence.java similarity index 88% rename from plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java rename to plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Sequence.java index 2b7fda408c0..4e9e99bfd14 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfSequence.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Sequence.java @@ -33,13 +33,13 @@ import org.eclipse.dd.dsf.DsfPlugin; * because for example result of one command is used as input into another * command. The typical DSF pattern of solving this problem is the following: *
  • - *
    1. original caller passes a Done callback to a method and invokes it + *
    1. original caller passes a RequestMonitor callback to a method and invokes it *
    2. the method is executed by a subsystem *
    3. when the method is finished it calls another method and passes * the original callback to it *
    4. steps 2-3 are repeated number of times *
    5. when the last method in a chain is executed, it submits the original - * Done callback + * RequestMonitor callback *
  • *

    * This pattern is very useful in itself, but it proves very difficult to follow @@ -49,40 +49,40 @@ import org.eclipse.dd.dsf.DsfPlugin; * this problem by containing this pattern in a single class. */ @ThreadSafe -abstract public class DsfSequence extends DsfRunnable implements Future { +abstract public class Sequence extends DsfRunnable implements Future { /** * The abstract class that each step has to implement. */ abstract public static class Step { - private DsfSequence fSequence; + private Sequence fSequence; /** * Sets the sequence that this step belongs to. It is only accessible * by the sequence itself, and is not meant to be called by sequence * sub-classes. */ - void setSequence(DsfSequence sequence) { fSequence = sequence; } + void setSequence(Sequence sequence) { fSequence = sequence; } /** Returns the sequence that this step is running in. */ - public DsfSequence getSequence() { return fSequence; } + public Sequence getSequence() { return fSequence; } /** * Executes the next step. Overriding classes should perform the * work in this method. - * @param done Result token to submit to executor when step is finished. + * @param rm Result token to submit to executor when step is finished. */ - public void execute(Done done) { - getSequence().getExecutor().execute(done); + public void execute(RequestMonitor rm) { + rm.done(); } /** * Roll back gives the step implementation a chance to undo the * operation that was performed by execute(). - * @param done Result token to submit to executor when rolling back the step is finished. + * @param rm Result token to submit to executor when rolling back the step is finished. */ - public void rollBack(Done done) { - getSequence().getExecutor().execute(done); + public void rollBack(RequestMonitor rm) { + rm.done(); } /** @@ -107,7 +107,7 @@ abstract public class DsfSequence extends DsfRunnable implements Future * thread. Otherwise, the {@link Future#get()} method is the appropriate * method of retrieving the result. */ - final private Done fDone; + final private RequestMonitor fRequestMonitor; /** Status indicating the success/failure of the test. Used internally only. */ @ConfinedToDsfExecutor("getExecutor") @@ -127,13 +127,13 @@ abstract public class DsfSequence extends DsfRunnable implements Future /** Convenience constructor with limited arguments. */ - public DsfSequence(DsfExecutor executor) { + public Sequence(DsfExecutor executor) { this(executor, new NullProgressMonitor(), "", "", null); //$NON-NLS-1$ //$NON-NLS-2$ } /** Convenience constructor with limited arguments. */ - public DsfSequence(DsfExecutor executor, Done done) { - this(executor, new NullProgressMonitor(), "", "", done); //$NON-NLS-1$ //$NON-NLS-2$ + public Sequence(DsfExecutor executor, RequestMonitor rm) { + this(executor, new NullProgressMonitor(), "", "", rm); //$NON-NLS-1$ //$NON-NLS-2$ } /** @@ -147,13 +147,12 @@ abstract public class DsfSequence extends DsfRunnable implements Future * @param Result that will be submitted to executor when sequence is finished. Can be null if calling from * non-executor thread and using {@link Future#get()} method to wait for the sequence result. */ - - public DsfSequence(DsfExecutor executor, IProgressMonitor pm, String taskName, String rollbackTaskName, Done done) { + public Sequence(DsfExecutor executor, IProgressMonitor pm, String taskName, String rollbackTaskName, RequestMonitor rm) { fExecutor = executor; fProgressMonitor = pm; fTaskName = taskName; fRollbackTaskName = rollbackTaskName; - fDone = done; + fRequestMonitor = rm; } /** @@ -173,11 +172,9 @@ abstract public class DsfSequence extends DsfRunnable implements Future public DsfExecutor getExecutor() { return fExecutor; } /** - * Returns the Done callback that is registered with the Sequence - * @param doneQC callback that will be submitted when sequence completes, - * null if there is no callback configured + * Returns the RequestMonitor callback that is registered with the Sequence */ - public Done getDone() { return fDone; } + public RequestMonitor getRequestMonitor() { return fRequestMonitor; } /** * The get method blocks until sequence is complete, but always returns null. @@ -270,9 +267,10 @@ abstract public class DsfSequence extends DsfRunnable implements Future // Proceed with executing next step. fCurrentStepIdx = nextStepIndex; try { - getSteps()[fCurrentStepIdx].execute(new Done() { + getSteps()[fCurrentStepIdx].execute(new RequestMonitor(fExecutor, null) { final private int fStepIdx = fCurrentStepIdx; - public void run() { + @Override + public void handleCompleted() { // Check if we're still the correct step. assert fStepIdx == fCurrentStepIdx; @@ -286,7 +284,7 @@ abstract public class DsfSequence extends DsfRunnable implements Future } @Override public String toString() { - return "DsfSequence \"" + fTaskName + "\", result for executing step #" + fStepIdx + " = " + getStatus(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + return "Sequence \"" + fTaskName + "\", result for executing step #" + fStepIdx + " = " + getStatus(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } }); } catch(Throwable t) { @@ -298,7 +296,7 @@ abstract public class DsfSequence extends DsfRunnable implements Future */ abortExecution(new Status( IStatus.ERROR, DsfPlugin.PLUGIN_ID, 0, - "Unhandled exception when executing DsfSequence " + this + ", step #" + fCurrentStepIdx, //$NON-NLS-1$ //$NON-NLS-2$ + "Unhandled exception when executing Sequence " + this + ", step #" + fCurrentStepIdx, //$NON-NLS-1$ //$NON-NLS-2$ t)); /* @@ -323,9 +321,10 @@ abstract public class DsfSequence extends DsfRunnable implements Future // Proceed with rolling back given step. fCurrentStepIdx = stepIdx; try { - getSteps()[fCurrentStepIdx].rollBack(new Done() { + getSteps()[fCurrentStepIdx].rollBack(new RequestMonitor(fExecutor, null) { final private int fStepIdx = fCurrentStepIdx; - public void run() { + @Override + public void handleCompleted() { // Check if we're still the correct step. assert fStepIdx == fCurrentStepIdx; @@ -339,7 +338,7 @@ abstract public class DsfSequence extends DsfRunnable implements Future } @Override public String toString() { - return "DsfSequence \"" + fTaskName + "\", result for rolling back step #" + fStepIdx + " = " + getStatus(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + return "Sequence \"" + fTaskName + "\", result for rolling back step #" + fStepIdx + " = " + getStatus(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } }); } catch(Throwable t) { @@ -351,7 +350,7 @@ abstract public class DsfSequence extends DsfRunnable implements Future */ abortRollBack(new Status( IStatus.ERROR, DsfPlugin.PLUGIN_ID, 0, - "Unhandled exception when rolling back DsfSequence " + this + ", step #" + fCurrentStepIdx, //$NON-NLS-1$ //$NON-NLS-2$ + "Unhandled exception when rolling back Sequence " + this + ", step #" + fCurrentStepIdx, //$NON-NLS-1$ //$NON-NLS-2$ t)); /* @@ -371,8 +370,8 @@ abstract public class DsfSequence extends DsfRunnable implements Future fProgressMonitor.subTask(fRollbackTaskName); } fStatus = new Status(IStatus.CANCEL, DsfPlugin.PLUGIN_ID, -1, "Sequence \"" + fTaskName + "\" cancelled.", null); //$NON-NLS-1$ //$NON-NLS-2$ - if (fDone != null) { - fDone.setStatus(fStatus); + if (fRequestMonitor != null) { + fRequestMonitor.setStatus(fStatus); } /* @@ -395,8 +394,8 @@ abstract public class DsfSequence extends DsfRunnable implements Future fProgressMonitor.subTask(fRollbackTaskName); } fStatus = error; - if (fDone != null) { - fDone.setStatus(error); + if (fRequestMonitor != null) { + fRequestMonitor.setStatus(error); } fSync.doAbort(new CoreException(error)); @@ -424,15 +423,15 @@ abstract public class DsfSequence extends DsfRunnable implements Future newStatus.merge(fStatus); fStatus = newStatus; - if (fDone != null) { - fDone.setStatus(newStatus); + if (fRequestMonitor != null) { + fRequestMonitor.setStatus(newStatus); } finish(); } private void finish() { - if (fDone != null) getExecutor().submit(fDone); + if (fRequestMonitor != null) fRequestMonitor.done(); fSync.doFinish(); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMService.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMService.java index 895dca5bbd0..4f494895533 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMService.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMService.java @@ -10,7 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.dsf.datamodel; -import org.eclipse.dd.dsf.concurrent.GetDataDone; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.service.IDsfService; /** @@ -27,11 +27,16 @@ public interface IDMService extends IDsfService, IDMData { * service are changed. */ 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. + * + * @param The Data Model Data type that is to be retrieved. + * @param dmc Data Model Context for the data model data object to be retrieved. + * @param rm Request completion monitor to be filled in with the Data Model Data. */ - void getModelData(IDMContext dmc, GetDataDone done); + void getModelData(IDMContext dmc, DataRequestMonitor rm); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java index 5cd80de03c2..0c4bc5f8f2c 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java @@ -14,7 +14,7 @@ import java.util.Arrays; import java.util.Dictionary; import java.util.Enumeration; -import org.eclipse.dd.dsf.concurrent.Done; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfExecutor; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; @@ -66,16 +66,16 @@ abstract public class AbstractDsfService public int getStartupNumber() { return fStartupNumber; } - public void initialize(Done done) { + public void initialize(RequestMonitor rm) { fTracker = new DsfServicesTracker(getBundleContext(), fSession.getId()); fStartupNumber = fSession.getAndIncrementServiceStartupCounter(); - getExecutor().submit(done); + rm.done(); } - public void shutdown(Done done) { + public void shutdown(RequestMonitor rm) { fTracker.dispose(); fTracker = null; - getExecutor().submit(done); + rm.done(); } /** Returns the session object for this service */ diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java index a5b527ac02a..be934f81ee1 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java @@ -13,7 +13,7 @@ package org.eclipse.dd.dsf.service; import java.util.Dictionary; import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; -import org.eclipse.dd.dsf.concurrent.Done; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfExecutor; /** @@ -107,15 +107,15 @@ public interface IDsfService { * logic, if this service depends on other services, the implementaion should * assume that these services are already present, and if they are not, the * initializaiton should fail. - * @param done callback to be submitted when the initialization is complete + * @param requestMonitor callback to be submitted when the initialization is complete */ - void initialize(Done done); + void initialize(RequestMonitor requestMonitor); /** * Performs shutdown and de-registration of the given service. - * @param done callback to be submitted when shutdown is complete + * @param requestMonitor callback to be submitted when shutdown is complete */ - void shutdown(Done done); + void shutdown(RequestMonitor requestMonitor); /** * Returns the startup order number of this service among services in the same session. From 7d59d57f7291a761f3deba6fa4cbc5cbe0f512c8 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Mon, 2 Apr 2007 20:18:00 +0000 Subject: [PATCH 068/834] Fixed M6 buld (bug 177371). Created abstract equals() and hashCode() methods for DM and VM contexts (bug 180276). --- .../ui/viewmodel/AbstractVMLayoutNode.java | 28 +++++++++++++++---- .../dsf/ui/viewmodel/AbstractVMProvider.java | 11 ++++---- .../dd/dsf/ui/viewmodel/IVMAdapter.java | 6 ++-- .../dd/dsf/ui/viewmodel/IVMProvider.java | 6 ++-- .../viewmodel/dm/AbstractDMVMLayoutNode.java | 8 +++--- .../dd/dsf/datamodel/AbstractDMContext.java | 27 ++++++++++++++++-- .../dd/dsf/datamodel/ServiceDMContext.java | 16 ++++++++--- 7 files changed, 74 insertions(+), 28 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java index e749e482e9e..a9b5463c5d6 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java @@ -24,12 +24,12 @@ import org.eclipse.dd.dsf.concurrent.MultiRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactoryAdapter; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactoryAdapter; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; import org.eclipse.jface.viewers.TreePath; @@ -344,7 +344,17 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { update.done(); } - public static class AbstractVMContext implements IVMContext { + /** + * Implementation of basic View Model Context node functionality. The main + * purpose of the VMC wrapper is to re-direct adapter queries to the IVMAdapter + * and the layout node that the given context was created by. + *

    + * Note: Deriving classes must override the Object.equals/hashCode methods. + * This is because the VMC objects are just wrappers that are created + * by the view model on demand, so the equals methods must use the object + * being wrapped by the VMC to perform a meaningful comparison. + */ + abstract public static class AbstractVMContext implements IVMContext { protected final IVMAdapter fVMAdapter; protected final IVMLayoutNode fLayoutNode; @@ -359,8 +369,8 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { * IAdapter implementation returns the IVMAdapter instance for the * interfaces that are actually implemented by the VM Adapter. These * should at least include {@link IElementContentProvider}, - * {@link IModelProxyFactoryAdapter}, and - * {@link IColumnPresentationFactoryAdapter}. + * {@link IModelProxyFactory}, and + * {@link IColumnPresentationFactory}. */ @SuppressWarnings("unchecked") public Object getAdapter(Class adapter) { @@ -371,6 +381,14 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { } return null; } + + /** Deriving classes must override. */ + @Override + abstract public boolean equals(Object obj); + + /** Deriving classes must override. */ + @Override + abstract public int hashCode(); } protected class ViewerUpdate implements IViewerUpdate { diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java index 227365734e7..27515202f9a 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java @@ -33,7 +33,7 @@ import org.eclipse.dd.dsf.ui.DsfUIPlugin; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactoryAdapter; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory; import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy; @@ -42,7 +42,6 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; import org.eclipse.debug.internal.ui.viewers.provisional.AbstractModelProxy; import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousContentAdapter; import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousLabelAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.IColumnEditorFactoryAdapter; import org.eclipse.jface.viewers.TreePath; import org.eclipse.jface.viewers.Viewer; @@ -392,11 +391,11 @@ abstract public class AbstractVMProvider implements IVMProvider * the tree/table, so the VMProvider must be configured to own the root element * in the view in order for this setting to be effective. *

    - * Note: since the IColumnEditorFactoryAdapter interface is synchronous, and since + * Note: since the IColumnEditorFactory interface is synchronous, and since * column info is fairly static, this method is thread-safe, and it will * not be called on the executor thread. * - * @see IColumnPresentationFactoryAdapter#createColumnPresentation(IPresentationContext, Object) + * @see IColumnPresentationFactory#createColumnPresentation(IPresentationContext, Object) */ public IColumnPresentation createColumnPresentation(IPresentationContext context, Object element) { return null; @@ -411,11 +410,11 @@ abstract public class AbstractVMProvider implements IVMProvider * the tree/table, so the VMProvider must be configured to own the root element * in the view in order for this setting to be effective. *

    - * Note: since the IColumnEditorFactoryAdapter interface is synchronous, and since + * Note: since the IColumnEditorFactory interface is synchronous, and since * column info is fairly static, this method is thread-safe, and it will * not be called on the executor thread. * - * @see IColumnEditorFactoryAdapter#getColumnEditorId(IPresentationContext, Object) + * @see IColumnEditorFactory#getColumnEditorId(IPresentationContext, Object) */ public String getColumnPresentationId(IPresentationContext context, Object element) { return null; diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMAdapter.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMAdapter.java index 2d1c9dfaa05..85d5e3abadd 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMAdapter.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMAdapter.java @@ -1,9 +1,9 @@ package org.eclipse.dd.dsf.ui.viewmodel; import org.eclipse.dd.dsf.concurrent.ThreadSafe; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactoryAdapter; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactoryAdapter; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory; /** * The View Model adapter handles the layout of a given data model within a @@ -14,6 +14,6 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactor @ThreadSafe @SuppressWarnings("restriction") public interface IVMAdapter - extends IElementContentProvider, IModelProxyFactoryAdapter, IColumnPresentationFactoryAdapter + extends IElementContentProvider, IModelProxyFactory, IColumnPresentationFactory { } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java index c8bd7c4d542..8228dea5a4d 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java @@ -1,9 +1,9 @@ package org.eclipse.dd.dsf.ui.viewmodel; import org.eclipse.dd.dsf.concurrent.ThreadSafe; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactoryAdapter; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactoryAdapter; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; /** @@ -14,7 +14,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationCont @ThreadSafe @SuppressWarnings("restriction") public interface IVMProvider - extends IElementContentProvider, IModelProxyFactoryAdapter, IColumnPresentationFactoryAdapter + extends IElementContentProvider, IModelProxyFactory, IColumnPresentationFactory { /** * Returns the root layout node that is configured in this provider. diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java index df94f0e020c..c6fd3cfe9cb 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java @@ -16,10 +16,10 @@ import java.util.concurrent.RejectedExecutionException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMData; @@ -36,7 +36,7 @@ import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactoryAdapter; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; @@ -345,7 +345,7 @@ abstract public class AbstractDMVMLayoutNode extends Abstract * @param update Update object to fill information to * * @see IElementLabelProvider - * @see IColumnPresentationFactoryAdapter + * @see IColumnPresentationFactory */ protected void fillColumnLabel(@SuppressWarnings("unused") IDMContext dmContext, @SuppressWarnings("unused") V dmData, @SuppressWarnings("unused") String columnId, int idx, ILabelUpdate update) { diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMContext.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMContext.java index 87656319219..a68690c9277 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMContext.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMContext.java @@ -15,9 +15,17 @@ import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.dsf.service.DsfSession; /** - * 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. + * Base implementation of the IDMContext interface. There are two pieces of + * functionality here:
    + * 1) The {@link #getAdapter(Class)} implementation which retrieves model + * adapters registered with the session.
    + * 2) Methods to help compare DM Contexts.
    + *

    + * Note: The {@link #equals(Object)} and {@link #hashCode()} methods are + * made abstract to force the deriving classes to provide a proper + * implementation. Data Model Context objects are meant to be used as handles, + * therefore a proper equals implementation is critical. + *

    * @param Data Model data type that this context is for. */ @Immutable @@ -117,4 +125,17 @@ abstract public class AbstractDMContext extends PlatformObjec return retVal; } + /** + * Deriving classes must implement proper equals and hashCode operations + * based on context data. + */ + @Override + abstract public boolean equals(Object obj); + + /** + * Deriving classes must implement proper equals and hashCode operations + * based on context data. + */ + @Override + abstract public int hashCode(); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/ServiceDMContext.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/ServiceDMContext.java index f8219488a31..89de05e027a 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/ServiceDMContext.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/ServiceDMContext.java @@ -12,11 +12,9 @@ package org.eclipse.dd.dsf.datamodel; /** - * The Data Model Context representing the owner service. The service DM Context + * The Data Model Context representing the owner service, which is returned by + * {@link IDMService#getServiceContext()} methods. The service DM Context * should be the parent of all contexts originating from the given service. - *

    - * Note: there should be only one instance of ServiceContext per service, so there - * is no need to implement the equals() methods. */ public class ServiceDMContext extends AbstractDMContext { String fServiceDMID; @@ -29,4 +27,14 @@ public class ServiceDMContext extends AbstractDMContext @Override public String toString() { return baseToString() + fServiceDMID; } + @Override + public boolean equals(Object obj) { + return obj instanceof ServiceDMContext && fServiceDMID.equals(((ServiceDMContext)obj).fServiceDMID); + } + + @Override + public int hashCode() { + return fServiceDMID.hashCode(); + } + } From c923b48ecc692a6a5b938194b64476c3a7d142c7 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 5 Apr 2007 16:15:50 +0000 Subject: [PATCH 069/834] Fixed javac compiler error. --- .../src/org/eclipse/dd/dsf/debug/service/command/ICommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommand.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommand.java index 0b67c7cc1b3..1e6a2520705 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommand.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommand.java @@ -30,7 +30,7 @@ public interface ICommand { * * @return newly created command, or null if command cannot be coalesced */ - public ICommand coalesceWith( ICommand command ); + public ICommand coalesceWith( ICommand command ); } From 43c359cb486f5c2ab31f928adbeead73de9bd969 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Thu, 5 Apr 2007 19:07:11 +0000 Subject: [PATCH 070/834] Fixed licensing and update URLs. --- .../feature.xml | 7 +- .../feature.xml | 108 +++++++++++++- .../feature.xml | 137 ++++++++++++------ .../feature.xml | 4 + .../META-INF/MANIFEST.MF | 4 +- .../META-INF/MANIFEST.MF | 4 +- .../META-INF/MANIFEST.MF | 4 +- .../org.eclipse.dd.dsf/META-INF/MANIFEST.MF | 6 +- 8 files changed, 214 insertions(+), 60 deletions(-) diff --git a/features/org.eclipse.dd.dsf.examples-feature/feature.xml b/features/org.eclipse.dd.dsf.examples-feature/feature.xml index 73a89fb3504..413bbdd4a22 100644 --- a/features/org.eclipse.dd.dsf.examples-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.examples-feature/feature.xml @@ -2,7 +2,8 @@ + version="0.9.0.qualifier" + provider-name="Eclipse.org"> Device Software Development Platform Project @@ -71,6 +72,10 @@ regulations and policies concerning the import, possession, or use, and re-expor Java and all Java-based trademarks are trademarks of Sun Microsystem + + + + diff --git a/features/org.eclipse.dd.dsf.gdb-feature/feature.xml b/features/org.eclipse.dd.dsf.gdb-feature/feature.xml index b20dc9d212d..11eaf9477c5 100644 --- a/features/org.eclipse.dd.dsf.gdb-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.gdb-feature/feature.xml @@ -2,7 +2,8 @@ + version="0.9.0.qualifier" + provider-name="Eclipse.org"> Device Software Development Platform Project @@ -13,13 +14,112 @@ GDB-MI Implementation Copyright (c) 2006-2007 Wind River Systems and others. -All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html +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 - - [Enter License Description here.] + + ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT +March 17, 2005 +Usage Of Content +THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, +INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY +"CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS +OF THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE +AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING +THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED +BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE +LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. +IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT +AND THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS +OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE +THE CONTENT. +Applicable Licenses +Unless otherwise indicated, all Content made available by the +Eclipse Foundation is provided to you under the terms and conditions +of the Eclipse Public License Version 1.0 ("EPL"). A copy of +the EPL is provided with this Content and is also available at +http://www.eclipse.org/legal/epl-v10.html. For purposes of the +EPL, "Program" will mean the Content. +Content includes, but is not limited to, source code, object +code, documentation and other files maintained in the Eclipse.org +CVS repository ("Repository") in CVS modules ("Modules") and +made available as downloadable archives ("Downloads"). +- Content may be structured and packaged into modules to facilitate +delivering, +extending, and upgrading the Content. Typical modules may include +plug-ins ("Plug-ins"), +plug-in fragments ("Fragments"), and features ("Features"). +- Each Plug-in or Fragment may be packaged as a sub-directory +or JAR (Java? ARchive) +in a directory named "plugins". +- A Feature is a bundle of one or more Plug-ins and/or Fragments +and associated material. +Each Feature may be packaged as a sub-directory in a directory +named "features". +Within a Feature, files named "feature.xml" may contain a list +of the names and version +numbers of the Plug-ins and/or Fragments associated with that +Feature. +- Features may also include other Features ("Included Features"). +Within a Feature, files +named "feature.xml" may contain a list of the names and version +numbers of Included Features. +Features may also include other Features ("Included Features"). +Files named "feature.xml" may contain a list of the names and +version numbers of Included Features. +The terms and conditions governing Plug-ins and Fragments should +be contained in files named "about.html" ("Abouts"). The terms +and conditions governing Features and Included Features should +be contained in files named "license.html" ("Feature Licenses"). +Abouts and Feature +Licenses may be located in any directory of a Download or Module +including, but not limited to the following locations: +- The top-level (root) directory +- Plug-in and Fragment directories +- Inside Plug-ins and Fragments packaged as JARs +- Sub-directories of the directory named "src" of certain Plug-ins +- Feature directories +Note: if a Feature made available by the Eclipse Foundation is +installed using the Eclipse Update Manager, you must agree to +a license ("Feature Update License") during the installation +process. If the Feature contains Included Features, the Feature +Update License should either provide you +with the terms and conditions governing the Included Features +or inform you where you can locate them. Feature Update Licenses +may be found in the "license" property of files named "feature.properties". +Such Abouts, Feature Licenses and Feature Update Licenses contain +the terms and conditions (or references to such terms and conditions) +that govern your +use of the associated Content in that directory. +THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY +REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS +AND CONDITIONS. SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE +(BUT ARE NOT LIMITED TO): +- Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html) +IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS +PRIOR TO USE OF THE CONTENT. If no About, Feature License or +Feature Update License is provided, please contact the Eclipse +Foundation to determine what terms and conditions govern that +particular Content. +Cryptography +Content may contain encryption software. The country in which +you are currently may have restrictions on the import, possession, +and use, and/or re-export to another country, of encryption software. +BEFORE using any encryption software, please check the country's +laws, +regulations and policies concerning the import, possession, or +use, and re-export of encryption software, to see if this is +permitted. +Java and all Java-based trademarks are trademarks of Sun Microsystem + + + + diff --git a/features/org.eclipse.dd.dsf.sdk-feature/feature.xml b/features/org.eclipse.dd.dsf.sdk-feature/feature.xml index 9eba90e5d9d..a3985f89786 100644 --- a/features/org.eclipse.dd.dsf.sdk-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.sdk-feature/feature.xml @@ -17,61 +17,106 @@ Core SDK 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 - + ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT March 17, 2005 - Usage Of Content - -THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT. - +THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, +INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY +"CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS +OF THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE +AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING +THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED +BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE +LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. +IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT +AND THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS +OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE +THE CONTENT. Applicable Licenses - -Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is provided with this Content and is also available at http://www.eclipse.org/legal/epl-v10.html. For purposes of the EPL, "Program" will mean the Content. - -Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse.org CVS repository ("Repository") in CVS modules ("Modules") and made available as downloadable archives ("Downloads"). - - - Content may be structured and packaged into modules to facilitate delivering, - extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"), - plug-in fragments ("Fragments"), and features ("Features"). - - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive) - in a directory named "plugins". - - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. - Each Feature may be packaged as a sub-directory in a directory named "features". - Within a Feature, files named "feature.xml" may contain a list of the names and version - numbers of the Plug-ins and/or Fragments associated with that Feature. - - Features may also include other Features ("Included Features"). Within a Feature, files - named "feature.xml" may contain a list of the names and version numbers of Included Features. - -Features may also include other Features ("Included Features"). Files named "feature.xml" may contain a list of the names and version numbers of Included Features. - -The terms and conditions governing Plug-ins and Fragments should be contained in files named "about.html" ("Abouts"). The terms and conditions governing Features and Included Features should be contained in files named "license.html" ("Feature Licenses"). Abouts and Feature -Licenses may be located in any directory of a Download or Module including, but not limited to the following locations: - - - The top-level (root) directory - - Plug-in and Fragment directories - - Inside Plug-ins and Fragments packaged as JARs - - Sub-directories of the directory named "src" of certain Plug-ins - - Feature directories - -Note: if a Feature made available by the Eclipse Foundation is installed using the Eclipse Update Manager, you must agree to a license ("Feature Update License") during the installation process. If the Feature contains Included Features, the Feature Update License should either provide you -with the terms and conditions governing the Included Features or inform you where you can locate them. Feature Update Licenses may be found in the "license" property of files named "feature.properties". Such Abouts, Feature Licenses and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your +Unless otherwise indicated, all Content made available by the +Eclipse Foundation is provided to you under the terms and conditions +of the Eclipse Public License Version 1.0 ("EPL"). A copy of +the EPL is provided with this Content and is also available at +http://www.eclipse.org/legal/epl-v10.html. For purposes of the +EPL, "Program" will mean the Content. +Content includes, but is not limited to, source code, object +code, documentation and other files maintained in the Eclipse.org +CVS repository ("Repository") in CVS modules ("Modules") and +made available as downloadable archives ("Downloads"). +- Content may be structured and packaged into modules to facilitate +delivering, +extending, and upgrading the Content. Typical modules may include +plug-ins ("Plug-ins"), +plug-in fragments ("Fragments"), and features ("Features"). +- Each Plug-in or Fragment may be packaged as a sub-directory +or JAR (Java? ARchive) +in a directory named "plugins". +- A Feature is a bundle of one or more Plug-ins and/or Fragments +and associated material. +Each Feature may be packaged as a sub-directory in a directory +named "features". +Within a Feature, files named "feature.xml" may contain a list +of the names and version +numbers of the Plug-ins and/or Fragments associated with that +Feature. +- Features may also include other Features ("Included Features"). +Within a Feature, files +named "feature.xml" may contain a list of the names and version +numbers of Included Features. +Features may also include other Features ("Included Features"). +Files named "feature.xml" may contain a list of the names and +version numbers of Included Features. +The terms and conditions governing Plug-ins and Fragments should +be contained in files named "about.html" ("Abouts"). The terms +and conditions governing Features and Included Features should +be contained in files named "license.html" ("Feature Licenses"). +Abouts and Feature +Licenses may be located in any directory of a Download or Module +including, but not limited to the following locations: +- The top-level (root) directory +- Plug-in and Fragment directories +- Inside Plug-ins and Fragments packaged as JARs +- Sub-directories of the directory named "src" of certain Plug-ins +- Feature directories +Note: if a Feature made available by the Eclipse Foundation is +installed using the Eclipse Update Manager, you must agree to +a license ("Feature Update License") during the installation +process. If the Feature contains Included Features, the Feature +Update License should either provide you +with the terms and conditions governing the Included Features +or inform you where you can locate them. Feature Update Licenses +may be found in the "license" property of files named "feature.properties". +Such Abouts, Feature Licenses and Feature Update Licenses contain +the terms and conditions (or references to such terms and conditions) +that govern your use of the associated Content in that directory. - -THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO): - - - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html) - -IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License or Feature Update License is provided, please contact the Eclipse Foundation to determine what terms and conditions govern that particular Content. - +THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY +REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS +AND CONDITIONS. SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE +(BUT ARE NOT LIMITED TO): +- Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html) +IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS +PRIOR TO USE OF THE CONTENT. If no About, Feature License or +Feature Update License is provided, please contact the Eclipse +Foundation to determine what terms and conditions govern that +particular Content. Cryptography - -Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to another country, of encryption software. BEFORE using any encryption software, please check the country's laws, -regulations and policies concerning the import, possession, or use, and re-export of encryption software, to see if this is permitted. - +Content may contain encryption software. The country in which +you are currently may have restrictions on the import, possession, +and use, and/or re-export to another country, of encryption software. +BEFORE using any encryption software, please check the country's +laws, +regulations and policies concerning the import, possession, or +use, and re-export of encryption software, to see if this is +permitted. Java and all Java-based trademarks are trademarks of Sun Microsystem + + + + diff --git a/features/org.eclipse.dd.dsf.test-feature/feature.xml b/features/org.eclipse.dd.dsf.test-feature/feature.xml index eaf7a6e9b11..d8a1d0e8111 100644 --- a/features/org.eclipse.dd.dsf.test-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.test-feature/feature.xml @@ -72,6 +72,10 @@ regulations and policies concerning the import, possession, or use, and re-expor Java and all Java-based trademarks are trademarks of Sun Microsystem + + + + diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF index ec0c0bf3c98..595e44d0eed 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF @@ -1,7 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 -Bundle-Name: %pluginName -Bundle-Vendor: %providerName +Bundle-Name: org.eclipse.dd.dsf.debug.ui +Bundle-Vendor: Eclipse.org Bundle-SymbolicName: org.eclipse.dd.dsf.debug.ui Bundle-Version: 0.9.0.qualifier Bundle-Activator: org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin diff --git a/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF index 79256f374b0..b8e58513963 100644 --- a/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF @@ -1,7 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 -Bundle-Name: %pluginName -Bundle-Vendor: %providerName +Bundle-Name: org.eclipse.dd.dsf.debug +Bundle-Vendor: Eclipse.org Bundle-SymbolicName: org.eclipse.dd.dsf.debug Bundle-Version: 0.9.0.qualifier Bundle-Activator: org.eclipse.dd.dsf.debug.DsfDebugPlugin diff --git a/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF index ac57942403e..60600c4b70e 100644 --- a/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF @@ -1,7 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 -Bundle-Name: %pluginName -Bundle-Vendor: %providerName +Bundle-Name: org.eclipse.dd.dsf.ui +Bundle-Vendor: Eclipse.org Bundle-SymbolicName: org.eclipse.dd.dsf.ui Bundle-Version: 0.9.0.qualifier Bundle-Activator: org.eclipse.dd.dsf.ui.DsfUIPlugin diff --git a/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF index 3f616f08a98..650915a13a3 100644 --- a/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF @@ -1,9 +1,9 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 -Bundle-Name: %pluginName -Bundle-Vendor: %providerName +Bundle-Name: org.eclipse.dd.dsf +Bundle-Vendor: Eclipse.org Bundle-SymbolicName: org.eclipse.dd.dsf -Bundle-Version: 0.9.0 +Bundle-Version: 0.9.0.qualifier Bundle-Activator: org.eclipse.dd.dsf.DsfPlugin Bundle-Localization: plugin Require-Bundle: org.eclipse.core.runtime From 8f6d74188f2835beb43729c31cba3d1925a0da75 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Thu, 5 Apr 2007 21:49:59 +0000 Subject: [PATCH 071/834] plugin names --- plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF | 2 +- plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF | 2 +- plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF | 2 +- plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF index 595e44d0eed..36de5b827d1 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF @@ -1,6 +1,6 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 -Bundle-Name: org.eclipse.dd.dsf.debug.ui +Bundle-Name: Debug Services Framework Debug UI Bundle-Vendor: Eclipse.org Bundle-SymbolicName: org.eclipse.dd.dsf.debug.ui Bundle-Version: 0.9.0.qualifier diff --git a/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF index b8e58513963..d15f4f53dbd 100644 --- a/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF @@ -1,6 +1,6 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 -Bundle-Name: org.eclipse.dd.dsf.debug +Bundle-Name: Debug Services Framework Debug Bundle-Vendor: Eclipse.org Bundle-SymbolicName: org.eclipse.dd.dsf.debug Bundle-Version: 0.9.0.qualifier diff --git a/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF index 60600c4b70e..b1e95a31747 100644 --- a/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF @@ -1,6 +1,6 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 -Bundle-Name: org.eclipse.dd.dsf.ui +Bundle-Name: Debug Services Framework UI Bundle-Vendor: Eclipse.org Bundle-SymbolicName: org.eclipse.dd.dsf.ui Bundle-Version: 0.9.0.qualifier diff --git a/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF index 650915a13a3..e02419404ab 100644 --- a/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF @@ -1,6 +1,6 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 -Bundle-Name: org.eclipse.dd.dsf +Bundle-Name: Debug Services Framework Core Bundle-Vendor: Eclipse.org Bundle-SymbolicName: org.eclipse.dd.dsf Bundle-Version: 0.9.0.qualifier From 3de10f8d2b53259561a0aa759287b47cbd8e73ba Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Fri, 6 Apr 2007 14:34:51 +0000 Subject: [PATCH 072/834] Fixed NPE Bugzilla 181315. Reference layoutNode which is known to be stale. --- .../src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java index 27515202f9a..58a6fa3bbc6 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java @@ -319,6 +319,7 @@ abstract public class AbstractVMProvider implements IVMProvider if (layoutNode == null) { // Stale update. Just ignore. if (!update.isCanceled()) update.done(); + return; } // Create the multi request monitor to mark update when querying all From 4c76a8df1e1e4fa976f4b9488b899e0d11b306e6 Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Thu, 19 Apr 2007 14:31:31 +0000 Subject: [PATCH 073/834] Created the initial formatting interface for Bugzilla 179778. Updated the IRegisters interface for Bugzilla 183188 and added required interface methods to the MI Register implementation ( all indicated not yet implemented ) which are now required by the updated IRegiisters interface. Also updated the Register View VM to handle the new events which were also added in IRegisters. --- .../register/RegisterGroupLayoutNode.java | 28 ++++++++ .../register/RegisterLayoutNode.java | 23 ++---- .../dsf/debug/service/IFormattedValues.java | 72 +++++++++++++++++++ .../dd/dsf/debug/service/IRegisters.java | 58 +++++++++++++-- 4 files changed, 159 insertions(+), 22 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java index 3b95f6a8e81..384e5fd7b69 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java @@ -11,16 +11,21 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.register; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.datamodel.IDMEvent; import org.eclipse.dd.dsf.debug.service.IRegisters; +import org.eclipse.dd.dsf.debug.service.IRunControl; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMData; import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; @SuppressWarnings("restriction") public class RegisterGroupLayoutNode extends AbstractDMVMLayoutNode { @@ -66,4 +71,27 @@ public class RegisterGroupLayoutNode extends AbstractDMVMLayoutNode e) { + if (e instanceof IRunControl.ISuspendedDMEvent) { + return IModelDelta.CONTENT; + }else if (e instanceof IRegisters.IRegistersChangedDMEvent) { + return IModelDelta.CONTENT; + } + return IModelDelta.NO_CHANGE; + } + + @Override + protected void buildDeltaForDMEvent(IDMEvent e, VMDelta parent, int nodeOffset, RequestMonitor rm) { + if (e instanceof IRunControl.ISuspendedDMEvent) { + // Create a delta that the whole register group has changed. + parent.addFlags(IModelDelta.CONTENT); + } + if (e instanceof IRegisters.IRegistersChangedDMEvent) { + parent.addNode( new DMVMContext(((IRegisters.IRegistersChangedDMEvent)e).getDMContext()), IModelDelta.STATE ); + } + + super.buildDeltaForDMEvent(e, parent, nodeOffset, rm); + } } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java index f2a628d042f..5021006acdc 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java @@ -10,8 +10,8 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.viewmodel.register; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMEvent; import org.eclipse.dd.dsf.debug.service.IRegisters; @@ -21,7 +21,6 @@ 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.ui.viewmodel.AbstractVMProvider; -import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; @@ -31,8 +30,6 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; @SuppressWarnings("restriction") public class RegisterLayoutNode extends AbstractDMVMLayoutNode { - public IVMContext[] fCachedRegisterVMCs; - public RegisterLayoutNode(AbstractVMProvider provider, DsfSession session) { super(provider, session, IRegisters.IRegisterDMContext.class); } @@ -70,16 +67,7 @@ public class RegisterLayoutNode extends AbstractDMVMLayoutNode } else if (RegisterColumnPresentation.COL_VALUE.equals(columnId)) { update.setLabel(dmData.getHexValue(), idx); } else if (RegisterColumnPresentation.COL_DESCRIPTION.equals(columnId)) { - String size = dmData.getDescription(); - String value = dmData.getHexValue(); - if ("".equals(size)) { //$NON-NLS-1$ - if ( value.contains( "uint64" ) ) { //$NON-NLS-1$ - size = "64 bit register" ; //$NON-NLS-1$ - } else if ( value.contains( "v4_float" ) ) { //$NON-NLS-1$ - size = "128 bit register" ; //$NON-NLS-1$ - } - } - update.setLabel(size, idx); + update.setLabel(dmData.getDescription(), idx); } } @@ -89,12 +77,12 @@ public class RegisterLayoutNode extends AbstractDMVMLayoutNode return IModelDelta.CONTENT; } else if (e instanceof IRegisters.IRegisterChangedDMEvent) { return IModelDelta.STATE; - } + } return IModelDelta.NO_CHANGE; } @Override - protected void buildDeltaForDMEvent(IDMEvent e, VMDelta parent, int nodeOffset, RequestMonitor requestMonitor) { + protected void buildDeltaForDMEvent(IDMEvent e, VMDelta parent, int nodeOffset, RequestMonitor rm) { if (e instanceof IRunControl.ISuspendedDMEvent) { // Create a delta that the whole register group has changed. parent.addFlags(IModelDelta.CONTENT); @@ -102,6 +90,7 @@ public class RegisterLayoutNode extends AbstractDMVMLayoutNode if (e instanceof IRegisters.IRegisterChangedDMEvent) { parent.addNode( new DMVMContext(((IRegisters.IRegisterChangedDMEvent)e).getDMContext()), IModelDelta.STATE ); } - super.buildDeltaForDMEvent(e, parent, nodeOffset, requestMonitor); + + super.buildDeltaForDMEvent(e, parent, nodeOffset, rm); } } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java new file mode 100644 index 00000000000..80fc136846b --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java @@ -0,0 +1,72 @@ +/* + * IFormattedValuesService.java + * Created on Apr 16, 2007 + * + * Copyright 2007 Wind River Systems Inc. All rights reserved. +*/ +package org.eclipse.dd.dsf.debug.service; + +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.datamodel.IDMData; +import org.eclipse.dd.dsf.datamodel.IDMService; + +public interface IFormattedValues extends IDMService { + + /** Marker interface for a DMC that has a formatted value. */ + public interface IDataDMContext extends IDMContext {} + + /** + * These strings represent the standard known formats for any bit stream + * which needs to be formatted. These ID's as well as others which may be + * specifically available from the backend are what is returned from the + * getID() method. + */ + public final static String HEX_FORMAT = "HEX.Format" ; //$NON-NLS-1$ + public final static String OCTAL_FORMAT = "OCTAL.Format" ; //$NON-NLS-1$ + public final static String BINARY_FORMAT = "BINARY.Format" ; //$NON-NLS-1$ + public final static String NATURAL_FORMAT = "NATURAL.Format" ; //$NON-NLS-1$ + + /** + * DMC that represents a value with specific format. The format ID can be + * persisted and used for comparison. + */ + public interface IValueDMContext extends IDMContext + { + public String getID(); + } + + /** + * DM Data returned when a formatted value DMC is evaluated. It contains + * only the properly formatted string. + * + * @param includePrefix Should the resulting formatted string contain the + * typical prefix ( if any exists for this format - e.g. 0x, 0b, 0 ). + * @param leadingZeros Should the resulting formatted string contain leading 0's. + */ + public interface IValueDMData extends IDMData { + String getFormattedValue(); + } + + /** + * Retrieves the available formats that the given data is available in. + * This method is asynchronous because the service may need to retrieve + * information from the back end in order to determine what formats are + * available for the given data context. + * + * @param dmc Context for which to retrieve available formatted values. + * @param formatIDs Currently supported format IDs. + */ + public void getAvailableFormattedValues(IDataDMContext dmc, DataRequestMonitor formatIDs); + + /** + * Retrieves the available formats that the given data is available in. + * This method is asynchronous because the service may need to retrieve + * information from the back end in order to determine what formats are + * available for the given data context. + * + * @param dmc Context for which to retrieve a IValueDMContext. + * @param formatId Defines format to be supplied from the returned context. + */ + public IValueDMContext getFormattedValue(IDataDMContext dmc, String formatId); +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java index ffe2bee47b5..7113a38c512 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java @@ -11,6 +11,7 @@ package org.eclipse.dd.dsf.debug.service; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMData; import org.eclipse.dd.dsf.datamodel.IDMEvent; @@ -20,13 +21,19 @@ import org.eclipse.dd.dsf.datamodel.IDMService; * Service for accessing register data. */ public interface IRegisters extends IDMService { + + /** Event indicating groups have changed. */ + public interface IGroupsChangedDMEvent extends IDMEvent {} /** Register group context */ public interface IRegisterGroupDMContext extends IDMContext {} + /** Event indicating registers in a group have changed. */ + public interface IRegistersChangedDMEvent extends IDMEvent {} + /** - * Register groups only have a name. Sub groups and registers are retrieved - * through the service interface. + * Register groups only have a name and description. Sub groups and registers are + * retrieved through the service interface. */ public interface IRegisterGroupDMData extends IDMData { public String getName(); @@ -55,6 +62,9 @@ public interface IRegisters extends IDMService { /** Bit field context */ public interface IBitFieldDMContext extends IDMContext {} + /** Event indicating register value changed. */ + public interface IBitFieldChangedDMEvent extends IDMEvent {} + /** * Bitfield data, big groups and mnemonics are retrieved at the same * time as rest of bit field data @@ -104,12 +114,50 @@ public interface IRegisters extends IDMService { */ void getRegisterGroups(IRunControl.IExecutionDMContext execCtx, IStack.IFrameDMContext frameCtx, DataRequestMonitor rm); - /** Retrieves list of sub-groups of given register group. */ + /** + * Retrieves list of sub-groups of given register group. + * @param groupCtx Group DMC, this is required. + * @param rm Request completion monitor. + */ void getRegisterSubGroups(IRegisterGroupDMContext groupCtx, DataRequestMonitor rm); - /** Retrieves registers in given register group. */ + /** + * Retrieves registers in given register group. + * @param groupCtx Group DMC, this is required. + * @param rm Request completion monitor. + */ void getRegisters(IRegisterGroupDMContext groupCtx, DataRequestMonitor rm); - /** Retrieves bit fields for given register */ + /** + * Retrieves bit fields for given register + * @param regCtx Register DMC, this is required. + * @param rm Request completion monitor. + */ void getBitFields(IRegisterDMContext regCtx, DataRequestMonitor rm); + + /** + * Writes a register value for a given register to the target + * @param regCtx Register DMC, this is required. + * @param regValue Value of the register to be written. + * @param formatId Format of the value to be written. + * @param rm Request completion monitor. + */ + void writeRegister(IRegisterDMContext regCtx, String regValue, String formatId, RequestMonitor rm); + + /** + * Writes a bit field value for a given bit field to the target + * @param bitFieldCtx Bit field DMC, this is required. + * @param bitFieldValue Value of the bit field to be written. + * @param formatId Format of the value to be written. + * @param rm Request completion monitor. + */ + void writeBitField(IBitFieldDMContext bitFieldCtx, String bitFieldValue, String formatId, RequestMonitor rm); + + /** + * Writes a bit field value for a given bit field to the target + * @param bitFieldCtx Bit field DMC, this is required. + * @param mnemonic Mnemonic which represents the value to be written. + * @param rm Request completion monitor. + */ + void writeBitField(IBitFieldDMContext bitFieldCtx, IMnemonic mnemonic, RequestMonitor rm); } From 2c84b29d1d77ea9768facae594ec29ef981a864b Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 20 Apr 2007 18:11:02 +0000 Subject: [PATCH 074/834] Checked in patch for bug 183400, and cleaned up TODOs. --- .../dd/dsf/debug/service/IExpressions.java | 198 +++++++++++++++--- 1 file changed, 165 insertions(+), 33 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java index 6f98089dc56..7f4049a9992 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java @@ -20,74 +20,206 @@ import org.eclipse.dd.dsf.datamodel.IDMEvent; import org.eclipse.dd.dsf.datamodel.IDMService; /** - * Expressions service provides access to the debugger's expression evaluator. - * This service has dependencies on the Modules service, RunControl service, and - * Stack service, as all may be used to provide context for an expression to be - * evaluated. + * Expressions service provides access to the debugger's expression evaluator. This service has + * dependencies on the Modules service, RunControl service, and Stack service, as all may be used to + * provide context for an expression to be evaluated. */ 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. + /** + * Expression context. Since some expressions have children, expression contexts can be have an + * arbitrary number of parents of type ExpressionContext. */ public interface IExpressionDMContext extends IDMContext { String getExpression(); } /** - * Expression data. It is based pretty closely on what DFW's info-retrieve - * node for expressions. + * This is the model data interface that corresponds to IExpressionDMContext. */ - public interface IExpressionDMData extends IDMData { + interface IExpressionDMData extends IDMData { + // These static fields define the possible return values of method getTypeId(). QUESTION: Why can't + // these have type int? + + final static String TYPEID_UNKNOWN = "TYPEID_UNKNOWN"; //$NON-NLS-1$ + final static String TYPEID_INTEGER = "TYPEID_INTEGER"; //$NON-NLS-1$ + final static String TYPEID_CHAR = "TYPEID_CHAR"; //$NON-NLS-1$ + final static String TYPEID_FLOAT = "TYPEID_FLOAT"; //$NON-NLS-1$ + final static String TYPEID_DOUBLE = "TYPEID_DOUBLE"; //$NON-NLS-1$ + final static String TYPEID_OPAQUE = "TYPEID_OPAQUE"; //$NON-NLS-1$ + + /** + * This enumerates the possible basic types that an expression can have. + * + * @see Method getBasicType(). + */ + enum BasicType { + unknown, // Unknown type. + basic, // Scalar type (e.g., int, short, float). + pointer, // Pointer to anything. + array, // Array of anything. + composite, // Struct, union, or class. + enumeration, // Enumeration. + function // Function. + } + + /** + * ISSUE: Should this method be named getExpression() instead? + * + * @return The original expression string that was supplied to IExpressions.createExpression(). + */ String getName(); - public enum BasicType { basic, pointer, array, composite, enumeration, function } + + /** + * @return A BasicType enumerator describing the basic type of an expression. + */ BasicType getBasicType(); + + /** + * @return The source code type of this expression. This is a string such as "struct Foo", "short", + * "int *", "mytypedef", "(int *)[]", "enum Bar". If the debugger backend cannot supply + * this information, this method returns "" (the angle brackets are there just in + * case there is a type named "UNKNOWN" in the application). + */ String getTypeName(); + + /** + * This method needs to be defined. For now, this returns the empty string. + */ String getEncoding(); + + /** + * @return One of the TYPEID_* static field values defined by this interface. + */ String getTypeId(); + + /** + * @return The number of bits in the value of the expression. For a bit field, this is the number + * of bits in the field. For other types, this is 8 times the number of bytes in the value. + */ int getBitCount(); + + /** + * @return A string containing the value of the expression in a format that is natural for its type. + * For example, type "char" is shown as a single-quoted character, type "int" (and its cousins) + * is shown in decimal, type "unsigned int" (and its cousins) and pointers are shown in hex, + * floating point values are shown in non-scientific notation. + */ String getNaturalValue(); + + /** + * @return A string containing the hexadecimal representation of the expression value. If the + * expression value is not convertable to an integer, this returns "UNKNOWN". + */ String getHexValue(); + + /** + * @return A string containing the octal representation of the expression value. If the + * expression value is not convertable to an integer, this returns "UNKNOWN". + */ String getOctalValue(); + + /** + * @return A string containing the binary representation of the expression value. If the + * expression value is not convertable to an integer, this returns "UNKNOWN". + */ String getBinaryValue(); + + /** + * @return A string containing the value of the expression as returned by the debugger backend. + */ String getStringValue(); + + /** + * @return An IAddress object representing the memory address of the value of the expression (if it + * has one). Non-lvalues do not have memory addresses (e.g., "x + 5"). When the expression + * has no address, this method returns an IAddress object on which isZero() returns true. + * ISSUE: It would be nice if there was a method IAddress.isValid() which could return false + * in this case. + */ IAddress getAddress(); + + /** + * @return A Map in which the keys are strings that are the names of enumerators in the enumeration + * that is the value of this expression and the values are the integer values of the + * enumerators. If the expression type is not an enumeration, this returns an empty Map. + */ + Map getEnumerations(); + + /** + * This method needs to be defined. + */ IRegisters.IRegisterDMContext getRegister(); - Map getEnumerations(); } /** - * Event indicating that a given expression is changed. If an expression - * is changed, it's implied that all the children of that expression are - * changed too. + * Event indicating that a given expression is changed. If an expression is changed, it's implied that all + * the children of that expression are changed too. */ - public interface IExpressionChangedDMEvent extends IDMEvent {} + interface IExpressionChangedDMEvent extends IDMEvent {} /** - * Returns the context for the specified expression. - * @param symCtx Symbol context in which to evaluate the expression. This parameter is required and cannot be null. - * @param execCtx Optional execution context for the evaluation. Can be null. - * @param frameCtx Optional stack frame context for the evaluation. Can be null. - * @param expression Expression to evaluate. - * @return Expression context. + * Returns the data model context object for the specified expression in the context of the symbols + * specified by symbolsDmc. + * + * @param symbolsDmc: Symbol context in which to evaluate the expression. This parameter can be null if + * there is no symbol context available. + * + * @param expression: The expression to evaluate. + * + * @return An expression data model context object that must be passed to getModelData() to obtain the + * value of the expression. */ - IExpressionDMContext createExpression(IModules.ISymbolDMContext symCtx, IRunControl.IExecutionDMContext execDmc, IStack.IFrameDMContext frameDmc, String expression); - + IExpressionDMContext createExpression(IModules.ISymbolDMContext symbolsDmc, String expression); + /** - * Retrieves the sub-expressions of the given expression. - * @param exprCtx Expression context to evaluate. - * @param rm The return parameter is an Iterable because it's possible - * that the sub-expressions as members of an array which could be very large. + * Returns the data model context object for the specified expression in the context of the thread + * specified by execDmc. + * + * @param execDmc: Optional execution context for the evaluation. This parameter cannot be null. If + * there is no execution context available, the client should instead call + * createExpression(ISymbolDMContext, String). + * + * @param expression: The expression to evaluate. + * + * @return An expression data model context object that must be passed to getModelData() to obtain the + * value of the expression. + */ + IExpressionDMContext createExpression(IRunControl.IExecutionDMContext execDmc, String expression); + + /** + * Returns the data model context object for the specified expression in the context of the stack frame + * specified by frameDmc. + * + * @param frameDmc: Optional stack frame context for the evaluation. This parameter cannot be null. If + * there is no stack frame context available, the client should instead call + * createExpression(ISymbolDMContext, String) or createExpression(IExecutionDMContext, String). + * + * @param expression: The expression to evaluate. + * + * @return An expression data model context object that must be passed to getModelData() to obtain the + * value of the expression. + */ + IExpressionDMContext createExpression(IStack.IFrameDMContext frameDmc, String expression); + + /** + * Retrieves the sub-expressions of the given expression. Sub-expressions are fields of a struct, union, + * or class, the enumerators of an enumeration, and the element of an array. + * + * @param exprCtx: The data model context representing an expression. + * + * @param rm: 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(IExpressionDMContext exprCtx, DataRequestMonitor> rm); /** - * For object oriented languages, this method returns the expressions - * representing base types of the given expression type. - * @param exprContext - * @param rm Request completion monitor. + * For object oriented languages, this method returns the expressions representing base types of + * the given expression type. + * + * @param exprContext: The data model context representing an expression. + * + * @param rm: Request completion monitor. */ void getBaseExpressions(IExpressionDMContext exprContext, DataRequestMonitor rm); } From c7ea21be28ac070b2ac8b5caa6227da3e7955415 Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Wed, 25 Apr 2007 16:20:15 +0000 Subject: [PATCH 075/834] IFormattedValues.java 1.) Changed the names somewhat to be a little more distinctive when used in other code. 2.) Created FormattedValueDMContext class instead of requiring addition interfaces to be done by the users. IRegisters.java 1.) Changed to support IFormattedValues 2.) Removed INumericalValue interface RegisterLayoutNode.java 1.) Changed to use IFormattedValues data style. 2.) Added additional overriden method updateLabelInSessionThread to deal with the additional level of abstraction to get the data. 3.) Completed the event handling. MIRegisters.java 1.) Changed to use the new IRegisters.java formatted data interfaces. 2.) Add getModelData routines for IRegisterDMContext - this is untested at this point. I will test it shortly. --- .../register/RegisterLayoutNode.java | 184 ++++++++++++++++-- .../dsf/debug/service/IFormattedValues.java | 82 +++++--- .../dd/dsf/debug/service/IRegisters.java | 28 +-- 3 files changed, 234 insertions(+), 60 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java index 5021006acdc..77c05d42d19 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java @@ -12,14 +12,19 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.register; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMEvent; +import org.eclipse.dd.dsf.datamodel.IDMService; +import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.dd.dsf.debug.service.IRegisters; import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData; +import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterChangedDMEvent; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMData; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext; import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; @@ -34,6 +39,168 @@ public class RegisterLayoutNode extends AbstractDMVMLayoutNode super(provider, session, IRegisters.IRegisterDMContext.class); } + /** + * Private data access routine which performs the extra level of data access needed to + * get the formatted data value for a specific register. + */ + private void updateFormattedRegisterValue(final ILabelUpdate update, final int labelIndex, final IRegisterDMContext dmc) + { + final IRegisters regService = getServicesTracker().getService(IRegisters.class); + /* + * PREFPAGE : We are using a default format until the preference page is created + * + * First select the format to be used. This involves checking so see that the preference + * page format is supported by the register service. If the format is not supported then + * we will pick the first available format. + */ + + final String preferencePageFormatId = IFormattedValues.HEX_FORMAT; + + regService.getAvailableFormattedValues( + dmc, + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + public void handleCompleted() { + if (!getStatus().isOK()) { + handleFailedUpdate(update); + return; + } + + /* + * See if the desired format is supported. + */ + String[] formatIds = getData(); + String finalFormatId = IFormattedValues.HEX_FORMAT; + boolean requestedFormatIsSupported = false; + + for ( String fId : formatIds ) { + if ( preferencePageFormatId.equals(fId) ) { + /* + * Desired format is supported. + */ + finalFormatId = preferencePageFormatId; + requestedFormatIsSupported = true; + break; + } + } + + if ( ! requestedFormatIsSupported ) { + /* + * Desired format is not supported. If there are any formats supported + * then use the first available. + */ + if ( formatIds.length != 0 ) { + finalFormatId = formatIds[0]; + } + else { + /* + * Register service does not support any format. + */ + handleFailedUpdate(update); + return; + } + } + + /* + * Format has been validated. Get the formatted value. + */ + FormattedValueDMContext valueDmc = regService.getFormattedValue(dmc, finalFormatId); + + regService.getModelData( + valueDmc, + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + public void handleCompleted() { + if (!getStatus().isOK()) { + handleFailedUpdate(update); + return; + } + + /* + * Fill the label/column with the properly formatted data value. + */ + update.setLabel(getData().getFormattedValue(), labelIndex); + update.done(); + } + } + ); + } + } + ); + } + + /* + * We override the Abstract method because we now need to perform an extra level of data fetch + * to get the formatted value represenatation of the register. Before we obtained the data from + * the IDMData returned for the Register DMC. Now basically the level of information returned + * is attribute information and the formatted value requires a separate transaction. + * + * @see org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode#updateLabelInSessionThread(org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate[]) + */ + @Override + protected void updateLabelInSessionThread(ILabelUpdate[] updates) { + for (final ILabelUpdate update : updates) { + + final IRegisterDMContext dmc = findDmcInPath(update.getElementPath(), IRegisters.IRegisterDMContext.class); + + ((IDMService)getServicesTracker().getService(null, dmc.getServiceFilter())).getModelData( + dmc, + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + protected void handleCompleted() { + /* + * Check that the request was evaluated and data is still + * valid. The request could fail if the state of the + * service changed during the request, but the view model + * has not been updated yet. + */ + if (!getStatus().isOK() || !getData().isValid()) { + assert getStatus().isOK() || + getStatus().getCode() != IDsfService.INTERNAL_ERROR || + getStatus().getCode() != IDsfService.NOT_SUPPORTED; + handleFailedUpdate(update); + return; + } + + /* + * If columns are configured, extract the selected values for each + * understood column. First we fill all of those columns which can + * be filled without the extra data mining. We also note if we do + * have to datamine. Any columns need to set the processing flag + * so we know we have further work to do. If there are more columns + * which need data extraction they need to be added in both "for" + * loops. + */ + String[] localColumns = update.getPresentationContext().getColumns(); + if (localColumns == null) localColumns = new String[] { null }; + + boolean weAreExtractingFormattedData = false; + + for (int idx = 0; idx < localColumns.length; idx++) { + if (RegisterColumnPresentation.COL_NAME.equals(localColumns[idx])) { + update.setLabel(getData().getName(), idx); + } else if (RegisterColumnPresentation.COL_VALUE.equals(localColumns[idx])) { + weAreExtractingFormattedData = true; + } else if (RegisterColumnPresentation.COL_DESCRIPTION.equals(localColumns[idx])) { + update.setLabel(getData().getDescription(), idx); + } + } + + if ( ! weAreExtractingFormattedData ) { + update.done(); + } else { + for (int idx = 0; idx < localColumns.length; idx++) { + if (RegisterColumnPresentation.COL_VALUE.equals(localColumns[idx])) { + updateFormattedRegisterValue(update, idx, dmc); + } + } + } + } + } + ); + } + } + @Override protected void updateElementsInSessionThread(final IChildrenUpdate update) { final IRegisterGroupDMContext execDmc = findDmcInPath(update.getElementPath(), IRegisterGroupDMContext.class); @@ -58,19 +225,6 @@ public class RegisterLayoutNode extends AbstractDMVMLayoutNode }); } - @Override - protected void fillColumnLabel(IDMContext dmContext, IRegisterDMData dmData, String columnId, - int idx, ILabelUpdate update) - { - if (RegisterColumnPresentation.COL_NAME.equals(columnId)) { - update.setLabel(dmData.getName(), idx); - } else if (RegisterColumnPresentation.COL_VALUE.equals(columnId)) { - update.setLabel(dmData.getHexValue(), idx); - } else if (RegisterColumnPresentation.COL_DESCRIPTION.equals(columnId)) { - update.setLabel(dmData.getDescription(), idx); - } - } - @Override protected int getNodeDeltaFlagsForDMEvent(IDMEvent e) { if (e instanceof IRunControl.ISuspendedDMEvent) { @@ -88,7 +242,7 @@ public class RegisterLayoutNode extends AbstractDMVMLayoutNode parent.addFlags(IModelDelta.CONTENT); } if (e instanceof IRegisters.IRegisterChangedDMEvent) { - parent.addNode( new DMVMContext(((IRegisters.IRegisterChangedDMEvent)e).getDMContext()), IModelDelta.STATE ); + parent.addNode( new DMVMContext(((IRegisterChangedDMEvent)e).getDMContext()), IModelDelta.STATE ); } super.buildDeltaForDMEvent(e, parent, nodeOffset, rm); diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java index 80fc136846b..b092e37f43a 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java @@ -7,6 +7,7 @@ package org.eclipse.dd.dsf.debug.service; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.datamodel.AbstractDMContext; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMData; import org.eclipse.dd.dsf.datamodel.IDMService; @@ -14,7 +15,7 @@ import org.eclipse.dd.dsf.datamodel.IDMService; public interface IFormattedValues extends IDMService { /** Marker interface for a DMC that has a formatted value. */ - public interface IDataDMContext extends IDMContext {} + public interface IFormattedDataDMContext extends IDMContext {} /** * These strings represent the standard known formats for any bit stream @@ -27,27 +28,6 @@ public interface IFormattedValues extends IDMService { public final static String BINARY_FORMAT = "BINARY.Format" ; //$NON-NLS-1$ public final static String NATURAL_FORMAT = "NATURAL.Format" ; //$NON-NLS-1$ - /** - * DMC that represents a value with specific format. The format ID can be - * persisted and used for comparison. - */ - public interface IValueDMContext extends IDMContext - { - public String getID(); - } - - /** - * DM Data returned when a formatted value DMC is evaluated. It contains - * only the properly formatted string. - * - * @param includePrefix Should the resulting formatted string contain the - * typical prefix ( if any exists for this format - e.g. 0x, 0b, 0 ). - * @param leadingZeros Should the resulting formatted string contain leading 0's. - */ - public interface IValueDMData extends IDMData { - String getFormattedValue(); - } - /** * Retrieves the available formats that the given data is available in. * This method is asynchronous because the service may need to retrieve @@ -55,9 +35,9 @@ public interface IFormattedValues extends IDMService { * available for the given data context. * * @param dmc Context for which to retrieve available formatted values. - * @param formatIDs Currently supported format IDs. + * @param rm Completion monitor returns an array of support formatIds. */ - public void getAvailableFormattedValues(IDataDMContext dmc, DataRequestMonitor formatIDs); + public void getAvailableFormattedValues(IFormattedDataDMContext dmc, DataRequestMonitor rm); /** * Retrieves the available formats that the given data is available in. @@ -68,5 +48,57 @@ public interface IFormattedValues extends IDMService { * @param dmc Context for which to retrieve a IValueDMContext. * @param formatId Defines format to be supplied from the returned context. */ - public IValueDMContext getFormattedValue(IDataDMContext dmc, String formatId); + public FormattedValueDMContext getFormattedValue(IFormattedDataDMContext dmc, String formatId); + + /** + * DMC that represents a value with specific format. The format ID can be + * persisted and used for comparison. + */ + + public static class FormattedValueDMContext extends AbstractDMContext + { + private final String fFormatID; + + public FormattedValueDMContext(IDMService service, IDMContext parent, String formatId) { + super(service, new IDMContext[] { parent }); + fFormatID = formatId; + } + + public FormattedValueDMContext(String sessionId, String filter, IDMContext parent, String formatId) { + super(sessionId, filter, new IDMContext[] { parent }); + fFormatID = formatId; + } + + public String getFormatID() { + return fFormatID; + } + + @Override + public boolean equals(Object obj) { + return baseEquals(obj) && ((FormattedValueDMContext)obj).getFormatID().equals(getFormatID()); + } + + @Override + public int hashCode() { + return baseHashCode() + getFormatID().hashCode(); + } + } + + public static class FormattedValueDMData implements IDMData { + + private final String fValue; + + public FormattedValueDMData(String value) { + fValue = value; + } + + public String getFormattedValue() { + return fValue; + } + + public boolean isValid() { + return true; + } + + } } \ No newline at end of file diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java index 7113a38c512..7725b253332 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java @@ -12,21 +12,19 @@ package org.eclipse.dd.dsf.debug.service; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMData; import org.eclipse.dd.dsf.datamodel.IDMEvent; -import org.eclipse.dd.dsf.datamodel.IDMService; /** * Service for accessing register data. */ -public interface IRegisters extends IDMService { +public interface IRegisters extends IFormattedValues { /** Event indicating groups have changed. */ public interface IGroupsChangedDMEvent extends IDMEvent {} /** Register group context */ - public interface IRegisterGroupDMContext extends IDMContext {} + public interface IRegisterGroupDMContext extends IFormattedDataDMContext {} /** Event indicating registers in a group have changed. */ public interface IRegistersChangedDMEvent extends IDMEvent {} @@ -41,13 +39,13 @@ public interface IRegisters extends IDMService { } /** Register context */ - public interface IRegisterDMContext extends IDMContext {} + public interface IRegisterDMContext extends IFormattedDataDMContext {} /** Event indicating register value changed. */ public interface IRegisterChangedDMEvent extends IDMEvent {} /** Register information */ - public interface IRegisterDMData extends IDMData, INumericalValue { + public interface IRegisterDMData extends IDMData { String getName(); String getDescription(); boolean isReadable(); @@ -60,7 +58,7 @@ public interface IRegisters extends IDMService { } /** Bit field context */ - public interface IBitFieldDMContext extends IDMContext {} + public interface IBitFieldDMContext extends IFormattedDataDMContext {} /** Event indicating register value changed. */ public interface IBitFieldChangedDMEvent extends IDMEvent {} @@ -69,7 +67,7 @@ public interface IRegisters extends IDMService { * Bitfield data, big groups and mnemonics are retrieved at the same * time as rest of bit field data */ - public interface IBitFieldDMData extends IDMData, INumericalValue { + public interface IBitFieldDMData extends IDMData { String getName(); String getDescription(); boolean isReadable(); @@ -81,6 +79,7 @@ public interface IRegisters extends IDMService { boolean isZeroBitLeftMost(); IBitGroup[] getBitGroup(); IMnemonic[] getMnemonics(); + IMnemonic getCurrentMnemonicValue(); } /** Bit group definition */ @@ -90,22 +89,11 @@ public interface IRegisters extends IDMService { } /** Bit field mnemonic */ - public interface IMnemonic extends INumericalValue { + public interface IMnemonic { String getShortName(); String getLongName(); } - /** - * Common interface for describing a number value for various register - * data objects - */ - public interface INumericalValue { - String getNaturalValue(); - String getHexValue(); - String getOctalValue(); - String getBinaryValue(); - } - /** * Retrieves the list of register groups. * @param execCtx Execution DMC, this is required. From 126c61affe458525e689a3ab5e75d31809e806f9 Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Tue, 1 May 2007 19:26:32 +0000 Subject: [PATCH 076/834] IAddress.java - fixed comment header IFormattedValues.java - fixed comment header DsfDebugUIPlugin.java - added getContextBundle SyncRegisterDataAccess.java - new helper sync register data access class --- .../dd/dsf/debug/ui/DsfDebugUIPlugin.java | 13 + .../register/SyncRegisterDataAccess.java | 803 ++++++++++++++++++ .../dd/dsf/debug/service/IAddress.java | 11 + .../dsf/debug/service/IFormattedValues.java | 17 +- 4 files changed, 838 insertions(+), 6 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/DsfDebugUIPlugin.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/DsfDebugUIPlugin.java index 5f8d59f5f4f..ccab5fcab18 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/DsfDebugUIPlugin.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/DsfDebugUIPlugin.java @@ -14,6 +14,9 @@ public class DsfDebugUIPlugin extends AbstractUIPlugin { // The shared instance private static DsfDebugUIPlugin plugin; + + // BundleContext of this plugin + private static BundleContext fgBundleContext; /** * The constructor @@ -29,6 +32,7 @@ public class DsfDebugUIPlugin extends AbstractUIPlugin { public void start(BundleContext context) throws Exception { super.start(context); plugin = this; + fgBundleContext = context; } /* @@ -50,6 +54,15 @@ public class DsfDebugUIPlugin extends AbstractUIPlugin { return plugin; } + /** + * Returns the bundle context + * + * @return the bundle context + */ + public static BundleContext getBundleContext() { + return fgBundleContext; + } + /** * Returns an image descriptor for the image file at the given * plug-in relative path diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java new file mode 100644 index 00000000000..0c2811fd097 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java @@ -0,0 +1,803 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.dsf.debug.ui.viewmodel.register; + +import java.util.concurrent.ExecutionException; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.Query; +import org.eclipse.dd.dsf.concurrent.ThreadSafeAndProhibitedFromDsfExecutor; +import org.eclipse.dd.dsf.debug.service.IRegisters; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.IFormattedDataDMContext; +import org.eclipse.dd.dsf.debug.service.IRegisters.IBitFieldDMContext; +import org.eclipse.dd.dsf.debug.service.IRegisters.IBitFieldDMData; +import org.eclipse.dd.dsf.debug.service.IRegisters.IMnemonic; +import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext; +import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMData; +import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.util.tracker.ServiceTracker; + +@ThreadSafeAndProhibitedFromDsfExecutor("") +public class SyncRegisterDataAccess { + + /** + * Need to use the OSGi service tracker here (instead of DsfServiceTracker), + * because we're accessing it in non-dispatch thread. DsfServiceTracker is + * not thread-safe. + */ + private ServiceTracker fServiceTracker; + + private synchronized IRegisters getService(String filter) { + + if (fServiceTracker == null) { + try { + fServiceTracker = new ServiceTracker(DsfDebugUIPlugin + .getBundleContext(), DsfDebugUIPlugin.getBundleContext() + .createFilter(filter), null); + fServiceTracker.open(); + } catch (InvalidSyntaxException e) { + assert false : "Invalid filter in DMC: " + filter; //$NON-NLS-1$ + return null; + } + } else { + /* + * All of the DMCs that this cell modifier is invoked for should + * originate from the same service. This assertion checks this + * assumption by comparing the service reference in the tracker to + * the filter string in the DMC. + */ + try { + assert DsfDebugUIPlugin.getBundleContext().createFilter(filter) + .match(fServiceTracker.getServiceReference()); + } catch (InvalidSyntaxException e) { + } + } + return (IRegisters) fServiceTracker.getService(); + } + + public void dispose() { + if ( fServiceTracker != null ) { + fServiceTracker.close(); + } + } + + public class GetBitFieldValueQuery extends Query { + + private IBitFieldDMContext fDmc; + + public GetBitFieldValueQuery(DsfExecutor executor, IBitFieldDMContext dmc) { + super(executor); + fDmc = dmc; + } + + @Override + protected void execute(final DataRequestMonitor rm) { + /* + * Guard agains the session being disposed. If session is disposed + * it could mean that the executor is shut-down, which in turn could + * mean that we can't complete the RequestMonitor argument. in that + * case, cancel to notify waiting thread. + */ + final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); + if (session == null) { + cancel(false); + return; + } + + IRegisters service = getService(fDmc.getServiceFilter()); + if (service == null) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service not available", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + service.getModelData(fDmc, new DataRequestMonitor(session.getExecutor(), rm) { + @Override + protected void handleCompleted() { + /* + * We're in another dispatch, so we must guard against + * executor shutdown again. + */ + if (!DsfSession.isSessionActive(session.getId())) { + GetBitFieldValueQuery.this.cancel(false); + return; + } + super.handleCompleted(); + } + + @Override + protected void handleOK() { + /* + * All good set return value. + */ + rm.setData(getData()); + rm.done(); + } + }); + } + } + + public IBitFieldDMContext getBitFieldDMC(Object element) { + if (element instanceof IAdaptable) { + return (IBitFieldDMContext) ((IAdaptable) element).getAdapter(IBitFieldDMContext.class); + } + return null; + } + + public IBitFieldDMData readBitField(Object element) { + /* + * Get the DMC and the session. If element is not an register DMC, or + * session is stale, then bail out. + */ + IBitFieldDMContext dmc = getBitFieldDMC(element); + if (dmc == null) return null; + DsfSession session = DsfSession.getSession(dmc.getSessionId()); + if (session == null) return null; + + /* + * Create the query to request the value from service. Note: no need to + * guard agains RejectedExecutionException, because + * DsfSession.getSession() above would only return an active session. + */ + GetBitFieldValueQuery query = new GetBitFieldValueQuery(session.getExecutor(), dmc); + session.getExecutor().execute(query); + + /* + * Now we have the data, go and get it. Since the call is completed now + * the ".get()" will not suspend it will immediately return with the + * data. + */ + try { + return query.get(); + } catch (InterruptedException e) { + assert false; + return null; + } catch (ExecutionException e) { + return null; + } + } + + public class SetBitFieldValueQuery extends Query { + + private IBitFieldDMContext fDmc; + private String fValue; + private String fFormatId; + + public SetBitFieldValueQuery(DsfExecutor executor, IBitFieldDMContext dmc, String value, String formatId) { + super(executor); + fDmc = dmc; + fValue = value; + fFormatId = formatId; + } + + @Override + protected void execute(final DataRequestMonitor rm) { + /* + * We're in another dispatch, so we must guard against executor + * shutdown again. + */ + final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); + if (session == null) { + cancel(false); + return; + } + + /* + * Guard against a disposed service + */ + IRegisters service = getService(fDmc.getServiceFilter()); + if (service == null) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + /* + * Write the bit field using a string/format style. + */ + service.writeBitField( + fDmc, + fValue, + fFormatId, + new DataRequestMonitor(session.getExecutor(), rm) { + @Override + protected void handleCompleted() { + /* + * We're in another dispatch, so we must guard + * against executor shutdown again. + */ + if (!DsfSession.isSessionActive(session.getId())) { + SetBitFieldValueQuery.this.cancel(false); + return; + } + super.handleCompleted(); + } + + @Override + protected void handleOK() { + /* + * All good set return value. + */ + rm.setData(new Object()); + rm.done(); + } + } + ); + } + } + + public void writeBitField(Object element, String value, String formatId) { + + /* + * Get the DMC and the session. If element is not an register DMC, or + * session is stale, then bail out. + */ + IBitFieldDMContext dmc = getBitFieldDMC(element); + if (dmc == null) return; + DsfSession session = DsfSession.getSession(dmc.getSessionId()); + if (session == null) return; + + /* + * Create the query to write the value to the service. Note: no need to + * guard agains RejectedExecutionException, because + * DsfSession.getSession() above would only return an active session. + */ + SetBitFieldValueQuery query = new SetBitFieldValueQuery(session.getExecutor(), dmc, value, formatId); + session.getExecutor().execute(query); + + /* + * Now we have the data, go and get it. Since the call is completed now + * the ".get()" will not suspend it will immediately return with the + * data. + */ + try { + /* + * Return value is irrelevant, any error would come through with an + * exception. + */ + query.get(); + } catch (InterruptedException e) { + assert false; + } catch (ExecutionException e) { + assert false; + /* + * View must be shutting down, no need to show erro dialog. + */ + } + } + + public class SetBitFieldValueMnemonicQuery extends Query { + + IBitFieldDMContext fDmc; + + IMnemonic fMnemonic; + + public SetBitFieldValueMnemonicQuery(DsfExecutor executor, IBitFieldDMContext dmc, IMnemonic mnemonic) { + super(executor); + fDmc = dmc; + fMnemonic = mnemonic; + } + + @Override + protected void execute(final DataRequestMonitor rm) { + /* + * We're in another dispatch, so we must guard against executor + * shutdown again. + */ + final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); + if (session == null) { + cancel(false); + return; + } + + /* + * Guard against a disposed service + */ + IRegisters service = getService(fDmc.getServiceFilter()); + if (service == null) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + /* + * Write the bit field using the mnemonic style. + */ + service.writeBitField( + fDmc, + fMnemonic, + new DataRequestMonitor(session.getExecutor(), rm) { + @Override + protected void handleCompleted() { + /* + * We're in another dispatch, so we must guard + * against executor shutdown again. + */ + if (!DsfSession.isSessionActive(session.getId())) { + SetBitFieldValueMnemonicQuery.this.cancel(false); + return; + } + super.handleCompleted(); + } + + @Override + protected void handleOK() { + /* + * All good set return value. + */ + rm.setData(new Object()); + rm.done(); + } + } + ); + } + } + + public void writeBitField(Object element, IMnemonic mnemonic) { + + /* + * Get the DMC and the session. If element is not an register DMC, or + * session is stale, then bail out. + */ + IBitFieldDMContext dmc = getBitFieldDMC(element); + if (dmc == null) return; + DsfSession session = DsfSession.getSession(dmc.getSessionId()); + if (session == null) return; + + /* + * Create the query to write the value to the service. Note: no need to + * guard agains RejectedExecutionException, because + * DsfSession.getSession() above would only return an active session. + */ + SetBitFieldValueMnemonicQuery query = new SetBitFieldValueMnemonicQuery( session.getExecutor(), dmc, mnemonic); + session.getExecutor().execute(query); + + /* + * Now we have the data, go and get it. Since the call is completed now + * the ".get()" will not suspend it will immediately return with the + * data. + */ + try { + /* + * Return value is irrelevant, any error would come through with an + * exception. + */ + query.get(); + } catch (InterruptedException e) { + assert false; + } catch (ExecutionException e) { + /* + * View must be shutting down, no need to show erro dialog. + */ + } + } + + public IRegisterDMContext getRegisterDMC(Object element) { + if (element instanceof IAdaptable) { + return (IRegisterDMContext) ((IAdaptable) element).getAdapter(IRegisterDMContext.class); + } + return null; + } + + public IFormattedDataDMContext getFormattedDMC(Object element) { + if (element instanceof IAdaptable) { + return (IFormattedDataDMContext) ((IAdaptable) element).getAdapter(IFormattedDataDMContext.class); + } + return null; + } + + public class GetRegisterValueQuery extends Query { + + IRegisterDMContext fDmc; + + public GetRegisterValueQuery(DsfExecutor executor, IRegisterDMContext dmc) { + super(executor); + fDmc = dmc; + } + + @Override + protected void execute(final DataRequestMonitor rm) { + /* + * Guard agains the session being disposed. If session is disposed + * it could mean that the executor is shut-down, which in turn could + * mean that we can't complete the RequestMonitor argument. in that + * case, cancel to notify waiting thread. + */ + final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); + if (session == null) { + cancel(false); + return; + } + + IRegisters service = getService(fDmc.getServiceFilter()); + if (service == null) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service not available", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + service.getModelData(fDmc, new DataRequestMonitor( session.getExecutor(), rm) { + @Override + protected void handleCompleted() { + /* + * We're in another dispatch, so we must guard against + * executor shutdown again. + */ + if (!DsfSession.isSessionActive(session.getId())) { + GetRegisterValueQuery.this.cancel(false); + return; + } + super.handleCompleted(); + } + + @Override + protected void handleOK() { + /* + * All good set return value. + */ + rm.setData(getData()); + rm.done(); + } + }); + } + } + + public IRegisterDMData readRegister(Object element) { + /* + * Get the DMC and the session. If element is not an register DMC, or + * session is stale, then bail out. + */ + IRegisterDMContext dmc = getRegisterDMC(element); + if (dmc == null) return null; + DsfSession session = DsfSession.getSession(dmc.getSessionId()); + if (session == null) return null; + + /* + * Create the query to request the value from service. Note: no need to + * guard agains RejectedExecutionException, because + * DsfSession.getSession() above would only return an active session. + */ + GetRegisterValueQuery query = new GetRegisterValueQuery(session.getExecutor(), dmc); + session.getExecutor().execute(query); + + /* + * Now we have the data, go and get it. Since the call is completed now + * the ".get()" will not suspend it will immediately return with the + * data. + */ + try { + return query.get(); + } catch (InterruptedException e) { + assert false; + return null; + } catch (ExecutionException e) { + return null; + } + } + + public class SetRegisterValueQuery extends Query { + + private IRegisterDMContext fDmc; + private String fValue; + private String fFormatId; + + public SetRegisterValueQuery(DsfExecutor executor, IRegisterDMContext dmc, String value, String formatId) { + super(executor); + fDmc = dmc; + fValue = value; + fFormatId = formatId; + } + + @Override + protected void execute(final DataRequestMonitor rm) { + /* + * We're in another dispatch, so we must guard against executor + * shutdown again. + */ + final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); + if (session == null) { + cancel(false); + return; + } + + /* + * Guard against a disposed service + */ + IRegisters service = getService(fDmc.getServiceFilter()); + if (service == null) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + /* + * The interface does not currently have a write function. It needs + * to and now would seem to be the time to add it. + */ + /* + * Write the bit field using a string/format style. + */ + service.writeRegister( + fDmc, + fValue, + fFormatId, + new DataRequestMonitor(session.getExecutor(), rm) { + @Override + protected void handleCompleted() { + /* + * We're in another dispatch, so we must guard + * against executor shutdown again. + */ + if (!DsfSession.isSessionActive(session.getId())) { + SetRegisterValueQuery.this.cancel(false); + return; + } + super.handleCompleted(); + } + + @Override + protected void handleOK() { + /* + * All good set return value. + */ + rm.setData(new Object()); + rm.done(); + } + } + ); + } + } + + public void writeRegister(Object element, String value, + String formatId) { + + /* + * Get the DMC and the session. If element is not an register DMC, or + * session is stale, then bail out. + */ + IRegisterDMContext dmc = getRegisterDMC(element); + if (dmc == null) return; + DsfSession session = DsfSession.getSession(dmc.getSessionId()); + if (session == null) return; + + /* + * Create the query to write the value to the service. Note: no need to + * guard agains RejectedExecutionException, because + * DsfSession.getSession() above would only return an active session. + */ + SetRegisterValueQuery query = new SetRegisterValueQuery(session.getExecutor(), dmc, value, formatId); + session.getExecutor().execute(query); + + /* + * Now we have the data, go and get it. Since the call is completed now + * the ".get()" will not suspend it will immediately return with the + * data. + */ + try { + /* + * Return value is irrelevant, any error would come through with an + * exception. + */ + query.get(); + } catch (InterruptedException e) { + assert false; + } catch (ExecutionException e) { + /* + * View must be shutting down, no need to show erro dialog. + */ + } + } + + public class GetSupportFormatsValueQuery extends Query { + + IFormattedDataDMContext fDmc; + + public GetSupportFormatsValueQuery(DsfExecutor executor, IFormattedDataDMContext dmc) { + super(executor); + fDmc = dmc; + } + + @Override + protected void execute(final DataRequestMonitor rm) { + /* + * We're in another dispatch, so we must guard against executor + * shutdown again. + */ + final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); + if (session == null) { + cancel(false); + return; + } + + /* + * Guard against a disposed service + */ + IRegisters service = getService(fDmc.getServiceFilter()); + if (service == null) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + /* + * Write the bit field using a string/format style. + */ + service.getAvailableFormattedValues( + fDmc, + new DataRequestMonitor(session.getExecutor(), rm) { + @Override + protected void handleCompleted() { + /* + * We're in another dispatch, so we must + * guard against executor shutdown again. + */ + if (!DsfSession.isSessionActive(session.getId())) { + GetSupportFormatsValueQuery.this.cancel(false); + return; + } + super.handleCompleted(); + } + + @Override + protected void handleOK() { + /* + * All good set return value. + */ + rm.setData(new Object()); + rm.done(); + } + } + ); + } + } + + public String[] getSupportedFormats(Object element) { + + /* + * Get the DMC and the session. If element is not an register DMC, or + * session is stale, then bail out. + */ + IFormattedDataDMContext dmc = getFormattedDMC(element); + if (dmc == null) return null; + DsfSession session = DsfSession.getSession(dmc.getSessionId()); + if (session == null) return null; + + /* + * Create the query to write the value to the service. Note: no need to + * guard agains RejectedExecutionException, because + * DsfSession.getSession() above would only return an active session. + */ + GetSupportFormatsValueQuery query = new GetSupportFormatsValueQuery( session.getExecutor(), dmc); + session.getExecutor().execute(query); + + /* + * Now we have the data, go and get it. Since the call is completed now + * the ".get()" will not suspend it will immediately return with the + * data. + */ + try { + return (String[]) query.get(); + } catch (InterruptedException e) { + assert false; + return null; + } catch (ExecutionException e) { + return null; + } + } + + public class GetFormattedValueValueQuery extends Query { + + private IFormattedDataDMContext fDmc; + private String fFormatId; + + public GetFormattedValueValueQuery(DsfExecutor executor, IFormattedDataDMContext dmc, String formatId) { + super(executor); + fDmc = dmc; + fFormatId = formatId; + } + + @Override + protected void execute(final DataRequestMonitor rm) { + /* + * We're in another dispatch, so we must guard against executor + * shutdown again. + */ + final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); + if (session == null) { + cancel(false); + return; + } + + /* + * Guard against a disposed service + */ + IRegisters service = getService(fDmc.getServiceFilter()); + if (service == null) { + rm .setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + /* + * Convert to the proper formatting DMC then go get the formatted value. + */ + + FormattedValueDMContext formDmc = service.getFormattedValue(fDmc, fFormatId); + + service.getModelData(formDmc, new DataRequestMonitor( session.getExecutor(), rm) { + @Override + protected void handleCompleted() { + /* + * We're in another dispatch, so we must guard against executor shutdown again. + */ + if (!DsfSession.isSessionActive(session.getId())) { + GetFormattedValueValueQuery.this.cancel(false); + return; + } + super.handleCompleted(); + } + + @Override + protected void handleOK() { + /* + * All good set return value. + */ + rm.setData(getData().getFormattedValue()); + rm.done(); + } + }); + } + } + + public String getFormattedValue(Object element, String formatId) { + + /* + * Get the DMC and the session. If element is not an register DMC, or + * session is stale, then bail out. + */ + IFormattedDataDMContext dmc = getFormattedDMC(element); + if (dmc == null) return null; + DsfSession session = DsfSession.getSession(dmc.getSessionId()); + if (session == null) return null; + + /* + * Create the query to write the value to the service. Note: no need to + * guard agains RejectedExecutionException, because + * DsfSession.getSession() above would only return an active session. + */ + GetFormattedValueValueQuery query = new GetFormattedValueValueQuery(session.getExecutor(), dmc, formatId); + session.getExecutor().execute(query); + + /* + * Now we have the data, go and get it. Since the call is completed now + * the ".get()" will not suspend it will immediately return with the + * data. + */ + try { + return (String) query.get(); + } catch (InterruptedException e) { + assert false; + return null; + } catch (ExecutionException e) { + return null; + } + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IAddress.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IAddress.java index 2f630505e4e..9faabd84e31 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IAddress.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IAddress.java @@ -1,3 +1,14 @@ +/******************************************************************************* + * 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; /** diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java index b092e37f43a..7b2d1e3b0e1 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java @@ -1,9 +1,14 @@ -/* - * IFormattedValuesService.java - * Created on Apr 16, 2007 - * - * Copyright 2007 Wind River Systems Inc. All rights reserved. -*/ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ + package org.eclipse.dd.dsf.debug.service; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; From 995cd3177c070702678c3777a713d3dfc29c124e Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 2 May 2007 17:57:15 +0000 Subject: [PATCH 077/834] Added a protected createVMContext() to allow sub-classes to supply own VMC implementation. --- .../dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java index c6fd3cfe9cb..d85a0937d1d 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java @@ -478,9 +478,13 @@ abstract public class AbstractDMVMLayoutNode extends Abstract int startIdx = update.getOffset() != -1 ? update.getOffset() : 0; int endIdx = update.getLength() != -1 ? startIdx + update.getLength() : dmcs.length; for (int i = startIdx; i < endIdx; i++) { - update.setChild(new DMVMContext(dmcs[i]), i); + update.setChild(createVMContext(dmcs[i]), i); } } + + protected IVMContext createVMContext(IDMContext dmc) { + return new DMVMContext(dmc); + } /** * Searches for a DMC of given type in the tree patch contained in given From da03d03830ea2fa973422bd3341311e90ddbceb7 Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Wed, 2 May 2007 19:49:34 +0000 Subject: [PATCH 078/834] Commiting patch submitted by Fran Litterio, Bugzilla 179778. Updated the expression interface and default implementation to support new formatted numbering. --- .../dd/dsf/debug/service/IExpressions.java | 25 +++---------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java index 7f4049a9992..ec01bf9e7d1 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java @@ -14,7 +14,6 @@ import java.util.Map; import org.eclipse.cdt.core.IAddress; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -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; @@ -24,13 +23,13 @@ import org.eclipse.dd.dsf.datamodel.IDMService; * dependencies on the Modules service, RunControl service, and Stack service, as all may be used to * provide context for an expression to be evaluated. */ -public interface IExpressions extends IDMService { +public interface IExpressions extends IDMService, IFormattedValues { /** * Expression context. Since some expressions have children, expression contexts can be have an * arbitrary number of parents of type ExpressionContext. */ - public interface IExpressionDMContext extends IDMContext { + public interface IExpressionDMContext extends IFormattedDataDMContext { String getExpression(); } @@ -51,7 +50,7 @@ public interface IExpressions extends IDMService { /** * This enumerates the possible basic types that an expression can have. * - * @see Method getBasicType(). + * @see getBasicType(). */ enum BasicType { unknown, // Unknown type. @@ -107,24 +106,6 @@ public interface IExpressions extends IDMService { */ String getNaturalValue(); - /** - * @return A string containing the hexadecimal representation of the expression value. If the - * expression value is not convertable to an integer, this returns "UNKNOWN". - */ - String getHexValue(); - - /** - * @return A string containing the octal representation of the expression value. If the - * expression value is not convertable to an integer, this returns "UNKNOWN". - */ - String getOctalValue(); - - /** - * @return A string containing the binary representation of the expression value. If the - * expression value is not convertable to an integer, this returns "UNKNOWN". - */ - String getBinaryValue(); - /** * @return A string containing the value of the expression as returned by the debugger backend. */ From 810d315bbfe7b266ec1dbbc8a1bd11a351eca001 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Sat, 5 May 2007 00:12:37 +0000 Subject: [PATCH 079/834] Added expression view model implementation (bug 185635). --- .../META-INF/MANIFEST.MF | 7 +- .../org.eclipse.dd.dsf.debug.ui/plugin.xml | 5 + .../DebugViewSelectionRootLayoutNode.java | 32 +- .../debug/ui/viewmodel/IDebugVMConstants.java | 13 + .../IFormattedValuePreferenceStore.java | 20 ++ .../viewmodel/IFormattedValueVMContext.java | 20 ++ .../ui/viewmodel/SetDefaultFormatDecimal.java | 47 +++ .../ui/viewmodel/SetDefaultFormatHex.java | 52 +++ .../AbstractExpressionLayoutNode.java | 310 ++++++++++++++++++ .../ExpressionColumnPresentation.java | 75 +++++ .../ExpressionManagerLayoutNode.java | 293 +++++++++++++++++ .../expression/ExpressionVMProvider.java | 123 +++++++ .../expression/IExpressionLayoutNode.java | 31 ++ .../expression/IExpressionVMContext.java | 19 ++ .../expression/MessagesForExpressionVM.java | 24 ++ .../WatchExpressionCellModifier.java | 66 ++++ .../expression/WatchExpressionDelegate.java | 33 ++ .../viewmodel/expression/messages.properties | 7 + .../launch/StackFramesLayoutNode.java | 2 +- .../launch/StandardLaunchRootLayoutNode.java | 2 +- .../register/RegisterColumnPresentation.java | 33 +- .../register/RegisterGroupLayoutNode.java | 233 ++++++++++++- .../register/RegisterLayoutNode.java | 238 +++++++++++++- .../register/RegisterVMProvider.java | 10 +- .../register/SyncRegisterDataAccess.java | 100 +++++- .../viewmodel/variable/LocalsLayoutNode.java | 94 ++++++ .../variable/MessagesForVariablesVM.java | 21 ++ .../variable/VariableColumnPresentation.java | 69 ++++ .../variable/VariableVMProvider.java | 44 +++ .../ui/viewmodel/variable/messages.properties | 3 + .../ui/viewmodel/AbstractVMLayoutNode.java | 24 +- .../dsf/ui/viewmodel/AbstractVMProvider.java | 235 ++++--------- .../ui/viewmodel/VMElementsCountUpdate.java | 41 +++ .../dd/dsf/ui/viewmodel/VMElementsUpdate.java | 77 +++++ .../dsf/ui/viewmodel/VMHasElementsUpdate.java | 40 +++ .../dd/dsf/ui/viewmodel/VMViewerUpdate.java | 54 +++ .../viewmodel/dm/AbstractDMVMLayoutNode.java | 4 +- .../ui/viewmodel/dm/AbstractDMVMProvider.java | 32 +- .../concurrent/CountingRequestMonitor.java | 61 ++++ .../dd/dsf/concurrent/DataRequestMonitor.java | 2 +- .../dsf/concurrent/MultiRequestMonitor.java | 36 +- 41 files changed, 2351 insertions(+), 281 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/IDebugVMConstants.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/IFormattedValuePreferenceStore.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/IFormattedValueVMContext.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/SetDefaultFormatDecimal.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/SetDefaultFormatHex.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionLayoutNode.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionColumnPresentation.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerLayoutNode.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionLayoutNode.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionVMContext.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/MessagesForExpressionVM.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/WatchExpressionCellModifier.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/WatchExpressionDelegate.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/messages.properties create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/LocalsLayoutNode.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/MessagesForVariablesVM.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableColumnPresentation.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/messages.properties create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMElementsCountUpdate.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMElementsUpdate.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMHasElementsUpdate.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/CountingRequestMonitor.java diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF index 36de5b827d1..63fc553607d 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Debug Services Framework Debug UI Bundle-Vendor: Eclipse.org -Bundle-SymbolicName: org.eclipse.dd.dsf.debug.ui +Bundle-SymbolicName: org.eclipse.dd.dsf.debug.ui; singleton:=true Bundle-Version: 0.9.0.qualifier Bundle-Activator: org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin Bundle-Localization: plugin @@ -17,7 +17,10 @@ Require-Bundle: org.eclipse.ui, org.eclipse.dd.dsf.debug Eclipse-LazyStart: true Export-Package: + org.eclipse.dd.dsf.debug.ui, org.eclipse.dd.dsf.debug.ui.viewmodel, + org.eclipse.dd.dsf.debug.ui.viewmodel.expression, + org.eclipse.dd.dsf.debug.ui.viewmodel.launch, org.eclipse.dd.dsf.debug.ui.viewmodel.register, - org.eclipse.dd.dsf.debug.ui.viewmodel.launch + org.eclipse.dd.dsf.debug.ui.viewmodel.variable Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml index 33ca93ceb1b..614503dc5b9 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml +++ b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml @@ -1,5 +1,10 @@ + + + diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewSelectionRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewSelectionRootLayoutNode.java index 73ba8d9e0e9..0128ffaad5e 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewSelectionRootLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewSelectionRootLayoutNode.java @@ -20,8 +20,6 @@ import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode.DMVMContext; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.ui.DebugUITools; -import org.eclipse.debug.ui.contexts.DebugContextEvent; -import org.eclipse.debug.ui.contexts.IDebugContextListener; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.ui.IWorkbenchWindow; @@ -39,25 +37,14 @@ import org.eclipse.ui.IWorkbenchWindow; */ @SuppressWarnings("restriction") public class DebugViewSelectionRootLayoutNode extends AbstractVMRootLayoutNode - implements IVMRootLayoutNode, IDebugContextListener + implements IVMRootLayoutNode { - private ISelection fSelection; - + private final IWorkbenchWindow fWindow; public DebugViewSelectionRootLayoutNode(AbstractVMProvider provider) { super(provider); - IWorkbenchWindow activeWindow = DsfDebugUIPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow(); - if (activeWindow != null) { - fSelection = DebugUITools.getDebugContextManager().getContextService(activeWindow).getActiveContext(); - } - DebugUITools.getDebugContextManager().addDebugContextListener(this); + fWindow = DsfDebugUIPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow(); } - @Override - public void dispose() { - DebugUITools.getDebugContextManager().removeDebugContextListener(this); - super.dispose(); - } - /** * If the input object is a Data Model context, and the event is a DMC event. * Then we can filter the event to make sure that the view does not @@ -109,22 +96,19 @@ public class DebugViewSelectionRootLayoutNode extends AbstractVMRootLayoutNode * @return */ public ISelection getSelection() { - return fSelection; + return DebugUITools.getDebugContextManager().getContextService(fWindow).getActiveContext(); } public Object getRootObject() { - if (fSelection instanceof IStructuredSelection) { - return ((IStructuredSelection)fSelection).getFirstElement(); + ISelection selection = getSelection(); + if (selection instanceof IStructuredSelection) { + return ((IStructuredSelection)selection).getFirstElement(); } return null; } - public void debugContextChanged(DebugContextEvent event) { - fSelection = event.getContext(); - } - private IDMContext getSelectedDMC() { - Object selection = fSelection; + Object selection = getSelection(); if (selection instanceof IStructuredSelection) { IStructuredSelection structSelection = (IStructuredSelection)selection; if (structSelection.getFirstElement() instanceof DMVMContext) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/IDebugVMConstants.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/IDebugVMConstants.java new file mode 100644 index 00000000000..3b0b9432139 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/IDebugVMConstants.java @@ -0,0 +1,13 @@ +package org.eclipse.dd.dsf.debug.ui.viewmodel; + +import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; + +public interface IDebugVMConstants { + public static final String ID = DsfDebugUIPlugin.PLUGIN_ID + ".VARIABLES_COLUMN_PRESENTATION_ID"; //$NON-NLS-1$ + public static final String COLUMN_ID__NAME = DsfDebugUIPlugin.PLUGIN_ID + ".COLUMN_ID__NAME"; //$NON-NLS-1$ + public static final String COLUMN_ID__TYPE = DsfDebugUIPlugin.PLUGIN_ID + ".COLUMN_ID__TYPE"; //$NON-NLS-1$ + public static final String COLUMN_ID__VALUE = DsfDebugUIPlugin.PLUGIN_ID + ".COLUMN_ID__VALUE"; //$NON-NLS-1$ + public static final String COLUMN_ID__DESCRIPTION = DsfDebugUIPlugin.PLUGIN_ID + ".COLUMN_ID__DESCRIPTION"; //$NON-NLS-1$ + public static final String COLUMN_ID__EXPRESSION = DsfDebugUIPlugin.PLUGIN_ID + ".COLUMN_ID__EXPRESSION"; //$NON-NLS-1$ + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/IFormattedValuePreferenceStore.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/IFormattedValuePreferenceStore.java new file mode 100644 index 00000000000..99e1343e771 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/IFormattedValuePreferenceStore.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel; + +/** + * + */ +public interface IFormattedValuePreferenceStore { + public String getDefaultFormatId(); + + public void setDefaultFormatId(String id); +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/IFormattedValueVMContext.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/IFormattedValueVMContext.java new file mode 100644 index 00000000000..3b38afb2f54 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/IFormattedValueVMContext.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel; + +import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; + +/** + * + */ +public interface IFormattedValueVMContext extends IVMContext { + IFormattedValuePreferenceStore getPreferenceStore(); +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/SetDefaultFormatDecimal.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/SetDefaultFormatDecimal.java new file mode 100644 index 00000000000..6ba564344e6 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/SetDefaultFormatDecimal.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel; + +import org.eclipse.dd.dsf.debug.service.IFormattedValues; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IViewActionDelegate; +import org.eclipse.ui.IViewPart; + +/** + * + */ +public class SetDefaultFormatDecimal implements IViewActionDelegate { + + private IFormattedValueVMContext fFormattedValueVMC; + + public void init(IViewPart view) { + } + + public void run(IAction action) { + if (fFormattedValueVMC != null) { + fFormattedValueVMC.getPreferenceStore().setDefaultFormatId(IFormattedValues.NATURAL_FORMAT); + } + } + + public void selectionChanged(IAction action, ISelection selection) { + fFormattedValueVMC = null; + if (selection instanceof IStructuredSelection) { + Object element = ((IStructuredSelection)selection).getFirstElement(); + if (element instanceof IFormattedValueVMContext) { + fFormattedValueVMC = ((IFormattedValueVMContext)element); + } + } + action.setEnabled(fFormattedValueVMC != null); + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/SetDefaultFormatHex.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/SetDefaultFormatHex.java new file mode 100644 index 00000000000..984abaf9c09 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/SetDefaultFormatHex.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.dd.dsf.debug.service.IFormattedValues; +import org.eclipse.dd.dsf.ui.viewmodel.IVMAdapter; +import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; +import org.eclipse.debug.ui.AbstractDebugView; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IViewActionDelegate; +import org.eclipse.ui.IViewPart; + +/** + * + */ +public class SetDefaultFormatHex implements IViewActionDelegate { + + private IFormattedValueVMContext fFormattedValueVMC; + + public void init(IViewPart view) { + } + + public void run(IAction action) { + if (fFormattedValueVMC != null) { + fFormattedValueVMC.getPreferenceStore().setDefaultFormatId(IFormattedValues.HEX_FORMAT); + } + } + + public void selectionChanged(IAction action, ISelection selection) { + fFormattedValueVMC = null; + if (selection instanceof IStructuredSelection) { + Object element = ((IStructuredSelection)selection).getFirstElement(); + if (element instanceof IFormattedValueVMContext) { + fFormattedValueVMC = ((IFormattedValueVMContext)element); + } + } + action.setEnabled(fFormattedValueVMC != null); + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionLayoutNode.java new file mode 100644 index 00000000000..ffacf21203f --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionLayoutNode.java @@ -0,0 +1,310 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; + +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; +import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.MultiRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.datamodel.IDMData; +import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; +import org.eclipse.dd.dsf.ui.viewmodel.VMElementsUpdate; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; +import org.eclipse.debug.core.model.IExpression; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.jface.viewers.TreePath; + +/** + * + */ +@SuppressWarnings("restriction") +public abstract class AbstractExpressionLayoutNode extends AbstractDMVMLayoutNode + implements IExpressionLayoutNode +{ + + public AbstractExpressionLayoutNode(AbstractVMProvider provider, DsfSession session, Class> dmcClassType) { + super(provider, session, dmcClassType); + } + + public void getElementForExpression(final IChildrenUpdate update, final String expressionText, final IExpression expression) { + final int exprLength = getExpressionLength(expressionText); + if (exprLength < 0) { + update.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Invalid expression", null)); //$NON-NLS-1$ + update.done(); + return; + } + + final String nodeExpressionText = exprLength > 0 ? expressionText.substring(0, exprLength) : expressionText; + + getElementForExpressionPart( + update, nodeExpressionText, + new DataRequestMonitor(getExecutor(), null) { + @Override + protected void handleOK() { + /** + * If the current expression is the whole expression from the argument, + * return the VMC. Otherwise, call the child nodes to continue evaluating + * the expression. + */ + if (exprLength == expressionText.length()) { + Object element = getData(); + associateExpression(element, expression); + update.setChild(element, 0); + update.done(); + } else { + getVMContextForExpressionFromChildNodes( + update, getData(), expressionText.substring(exprLength), expression); + } + } + + @Override + protected void handleErrorOrCancel() { + update.setStatus(getStatus()); + update.done(); + } + }); + } + + protected void getElementForExpressionPart(final IChildrenUpdate update, final String expressionPartText, final DataRequestMonitor rm) { + updateElements(new VMElementsUpdate( + update, -1, -1, + new DataRequestMonitor>(getSession().getExecutor(), rm) { + @Override + protected void handleOK() { + if (getData().size() == 0) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "No contexts", null)); //$NON-NLS-1$ + rm.done(); + } else { + final List elements = getData(); + + final MultiRequestMonitor> multiRm = new MultiRequestMonitor>(getExecutor(), rm) { + @Override + protected void handleOK() { + boolean foundMatchingContext = false; + for (int i = 0; i < getRequestMonitors().size(); i++) { + if (getRequestMonitors().get(i).getData()) { + rm.setData(elements.get(i)); + foundMatchingContext = true; + break; + } + } + if (!foundMatchingContext) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Context not found", null)); //$NON-NLS-1$ + } + rm.done(); + } + }; + + for (Object element : elements) { + testContextForExpression( + element, expressionPartText, + multiRm.add( + new DataRequestMonitor(getExecutor(), null) { + @Override + protected void handleCompleted() { + multiRm.requestMonitorDone(this); + } + })); + } + } + } + + @Override + protected void handleErrorOrCancel() { + update.setStatus(getStatus()); + update.done(); + } + }) + ); + } + + + @ConfinedToDsfExecutor("#getSession#getExecutor") + protected abstract void testContextForExpression(Object element, final String expression, final DataRequestMonitor rm); + protected abstract void associateExpression(Object element, IExpression expression); + + protected void getVMContextForExpressionFromChildNodes(final IChildrenUpdate update, Object parentElement, String childExpression, IExpression expression) { + IChildrenUpdate childUpdate = new ChildExpressionElementUpdate( + update, update.getElementPath().createChildPath(parentElement), + new DataRequestMonitor>(getExecutor(), null) { + @Override + protected void handleOK() { + update.setChild(getData().get(0), 0); + update.done(); + } + @Override + protected void handleErrorOrCancel() { + update.setStatus(getStatus()); + update.done(); + } + }); + + + for (int i = 0; i < getChildLayoutNodes().length; i++) { + if (getChildLayoutNodes()[i] instanceof IExpressionLayoutNode) { + IExpressionLayoutNode childNode = (IExpressionLayoutNode)getChildLayoutNodes()[i]; + if (childNode.getExpressionLength(childExpression) > 0) { + // The child node will call update.done(); + childNode.getElementForExpression(childUpdate, childExpression, expression); + return; + } + } + } + + // If we didn't find a matching child node in the for loop above, return an error. + update.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Invalid expression", null)); //$NON-NLS-1$ + update.done(); + + } + + public int getDeltaFlagsForExpression(String expressionText, Object event) { + int exprLength = getExpressionLength(expressionText); + if (exprLength >= 0) { + if (exprLength == expressionText.length()) { + return getDeltaFlags(event); + } else { + int retVal = getDeltaFlagsForExpressionPart(event); + String childExpression = expressionText.substring(exprLength); + for (int i = 0; i < getChildLayoutNodes().length; i++) { + if (getChildLayoutNodes()[i] instanceof IExpressionLayoutNode) { + IExpressionLayoutNode exprNode = (IExpressionLayoutNode)getChildLayoutNodes()[i]; + if (exprNode.getExpressionLength(childExpression) > 0) { + // The child node will call update.done(); + retVal |= exprNode.getDeltaFlagsForExpression(childExpression, event); + } + } + } + return retVal; + } + } + + return IModelDelta.NO_CHANGE; + } + + protected abstract int getDeltaFlagsForExpressionPart(Object event); + + public void buildDeltaForExpression(final IExpression expression, final int elementIdx, final String expressionText, final Object event, final VMDelta parentDelta, final TreePath path, final RequestMonitor rm) + { + // Find the expression part that belong to this node. If expression + // is not recognized, do nothing. + final int exprLength = getExpressionLength(expressionText); + if (exprLength < 0) { + rm.done(); + return; + } + + final String nodeExpressionText = exprLength > 0 ? expressionText.substring(0, exprLength) : expressionText; + + getElementForExpressionPart( + new ElementsUpdate(new DataRequestMonitor>(getExecutor(), null), path), + nodeExpressionText, + new DataRequestMonitor(getExecutor(), null) { + @Override + protected void handleOK() { + if (exprLength == expressionText.length()) { + associateExpression(getData(), expression); + buildDeltaForExpressionElement(getData(), elementIdx, event, parentDelta, rm); + } else { + TreePath newPath = path.createChildPath(getData()); + callChildExpressionNodesToBuildDelta( + expression, elementIdx, expressionText.substring(exprLength), event, parentDelta, newPath, rm); + } + } + + @Override + protected void handleErrorOrCancel() { + // There is no matching element for given expression. That's OK, it just + // means that the expression is invalid. + rm.done(); + } + }); + } + + protected void buildDeltaForExpressionElement(Object element, int elementIdx, Object event, VMDelta parentDelta, final RequestMonitor rm) + { + // Find the child nodes that have deltas for the given event. + final Map childNodesWithDeltaFlags = getChildNodesWithDeltaFlags(event); + + // If no child layout nodes have deltas we can stop here. + if (childNodesWithDeltaFlags.size() == 0) { + rm.done(); + return; + } + + callChildNodesToBuildDelta( + childNodesWithDeltaFlags, parentDelta.addNode(element, elementIdx, IModelDelta.NO_CHANGE), event, rm); + } + + protected void callChildExpressionNodesToBuildDelta(IExpression expression, int elementIdx, String expressionRemainder, Object event, VMDelta parentDelta, TreePath path, final RequestMonitor rm) + { + final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), null) { + @Override + protected void handleCompleted() { + rm.done(); + } + }; + + int childRmCount = 0; + + for (int i = 0; i < getChildLayoutNodes().length; i++) { + if (getChildLayoutNodes()[i] instanceof IExpressionLayoutNode) { + IExpressionLayoutNode childNode = (IExpressionLayoutNode)getChildLayoutNodes()[i]; + if (childNode.getExpressionLength(expressionRemainder) > 0 && + childNode.getDeltaFlagsForExpression(expressionRemainder, event) != IModelDelta.NO_CHANGE) + { + childNode.buildDeltaForExpression( + expression, elementIdx, expressionRemainder, event, parentDelta, path, rm); + childRmCount++; + // The child node will call update.done(); + } + } + } + + if (childRmCount > 0) { + countingRm.setCount(childRmCount); + } else { + countingRm.done(); + } + } + + + class ChildExpressionElementUpdate extends VMElementsUpdate { + private final TreePath fPath; + + ChildExpressionElementUpdate(IChildrenUpdate clientUpdate, TreePath path, DataRequestMonitor> rm) { + super(clientUpdate, 0, 1, rm); + fPath = path; + } + + @Override + public Object getElement() { + return fPath.getLastSegment(); + } + + @Override + public TreePath getElementPath() { + return fPath; + } + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionColumnPresentation.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionColumnPresentation.java new file mode 100644 index 00000000000..b2945554a57 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionColumnPresentation.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; + +import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.jface.resource.ImageDescriptor; + +/** + * + */ +@SuppressWarnings("restriction") +public class ExpressionColumnPresentation implements IColumnPresentation { + + public static final String ID = DsfDebugUIPlugin.PLUGIN_ID + ".REGISTERS_COLUMN_PRESENTATION_ID"; //$NON-NLS-1$ + + public void init(IPresentationContext context) { + } + + public void dispose() { + } + + // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getAvailableColumns() + public String[] getAvailableColumns() { + return new String[] { IDebugVMConstants.COLUMN_ID__EXPRESSION, IDebugVMConstants.COLUMN_ID__NAME, IDebugVMConstants.COLUMN_ID__TYPE, IDebugVMConstants.COLUMN_ID__VALUE, IDebugVMConstants.COLUMN_ID__DESCRIPTION, }; + } + + // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getHeader(java.lang.String) + public String getHeader(String id) { + if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(id)) { + return MessagesForExpressionVM.ExpressionColumnPresentation_expression; + } else if (IDebugVMConstants.COLUMN_ID__NAME.equals(id)) { + return MessagesForExpressionVM.ExpressionColumnPresentation_name; + } else if (IDebugVMConstants.COLUMN_ID__TYPE.equals(id)) { + return MessagesForExpressionVM.ExpressionColumnPresentation_type; + } else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(id)) { + return MessagesForExpressionVM.ExpressionColumnPresentation_value; + } else if (IDebugVMConstants.COLUMN_ID__DESCRIPTION.equals(id)) { + return MessagesForExpressionVM.ExpressionColumnPresentation_description; + } + return null; + } + + // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getId() + public String getId() { + return ID; + } + + public ImageDescriptor getImageDescriptor(String id) { + return null; + } + + + + // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getInitialColumns() + public String[] getInitialColumns() { + return new String[] { IDebugVMConstants.COLUMN_ID__EXPRESSION, IDebugVMConstants.COLUMN_ID__VALUE }; + } + + // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#isOptional() + public boolean isOptional() { + return true; + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerLayoutNode.java new file mode 100644 index 00000000000..f8adf60a30b --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerLayoutNode.java @@ -0,0 +1,293 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; +import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.ExpressionVMProvider.ExpressionsChangedEvent; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; +import org.eclipse.dd.dsf.ui.viewmodel.VMElementsUpdate; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.IExpressionManager; +import org.eclipse.debug.core.model.IExpression; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementEditor; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.debug.ui.IDebugUIConstants; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ICellModifier; +import org.eclipse.jface.viewers.TextCellEditor; +import org.eclipse.swt.widgets.Composite; + +@SuppressWarnings("restriction") +public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode + implements IElementLabelProvider, IElementEditor +{ + + private class InvalidExpressionVMC extends AbstractVMContext { + final IExpression fExpression; + + public InvalidExpressionVMC(IExpression expression) { + super(getVMProvider().getVMAdapter(), ExpressionManagerLayoutNode.this); + fExpression = expression; + } + + @Override + @SuppressWarnings("unchecked") + public Object getAdapter(Class adapter) { + if (adapter.isAssignableFrom(fExpression.getClass())) { + return fExpression; + } else { + return super.getAdapter(adapter); + } + } + + @Override + public boolean equals(Object obj) { + return obj instanceof InvalidExpressionVMC && ((InvalidExpressionVMC)obj).fExpression.equals(fExpression); + } + + @Override + public int hashCode() { + return fExpression.hashCode(); + } + } + + private IExpressionLayoutNode[] fExpressionNodes = new IExpressionLayoutNode[0]; + private IExpressionManager fManager = DebugPlugin.getDefault().getExpressionManager(); + private WatchExpressionCellModifier fWatchExpressionCellModifier = new WatchExpressionCellModifier(); + + public ExpressionManagerLayoutNode(AbstractVMProvider provider) { + super(provider); + } + + public void updateHasElements(IHasChildrenUpdate[] updates) { + for (int i = 0; i < updates.length; i++) { + updates[i].setHasChilren(fManager.getExpressions().length != 0); + updates[i].done(); + } + } + + public void updateElementCount(IChildrenCountUpdate update) { + update.setChildCount(fManager.getExpressions().length); + update.done(); + } + + public void updateElements(final IChildrenUpdate update) { + final IExpression[] expressions = fManager.getExpressions(); + + final CountingRequestMonitor multiRm = new CountingRequestMonitor(getExecutor(), null) { + @Override + protected void handleCompleted() { + update.done(); + } + }; + + int expressionRmCount = 0; + + for (int i = update.getOffset(); i < update.getOffset() + update.getLength() && i < expressions.length; i++) { + + // Check the array boundries as the expression manager could change asynchronously. + // The expression manager change should lead to a refresh in the view. + if (i > expressions.length) { + continue; + } + + final String expressionText = expressions[i].getExpressionText(); + final int expressionIdx = i; + final IExpression expression = expressions[i]; + IExpressionLayoutNode expressionNode = findNodeForExpression(expressionText); + if (expressionNode == null) { + update.setChild(new InvalidExpressionVMC(expression), i); + } else { + expressionRmCount++; + VMElementsUpdate expressionElementUpdate = new VMElementsUpdate( + update, 0, 1, + new DataRequestMonitor>(getExecutor(), multiRm) { + @Override + protected void handleOK() { + update.setChild(getData().get(0), expressionIdx); + multiRm.done(); + } + + @Override + protected void handleError() { + update.setChild(new InvalidExpressionVMC(expression), expressionIdx); + multiRm.done(); + } + }); + expressionNode.getElementForExpression(expressionElementUpdate, expressionText, expression); + } + } + + if (expressionRmCount > 0) { + multiRm.setCount(expressionRmCount); + } else { + multiRm.done(); + } + } + + public void update(ILabelUpdate[] updates) { + for (ILabelUpdate update : updates) { + if (update.getElement() instanceof InvalidExpressionVMC) { + updateInvalidExpressionVMCLabel(update, (InvalidExpressionVMC) update.getElement()); + } else { + update.done(); + } + } + } + + private void updateInvalidExpressionVMCLabel(ILabelUpdate update, InvalidExpressionVMC vmc) { + String[] columnIds = update.getColumnIds() != null ? + update.getColumnIds() : new String[] { IDebugVMConstants.COLUMN_ID__NAME }; + + for (int i = 0; i < columnIds.length; i++) { + if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(columnIds[i])) { + update.setLabel(vmc.fExpression.getExpressionText(), i); + update.setImageDescriptor(DebugUITools.getImageDescriptor( IDebugUIConstants.IMG_OBJS_EXPRESSION ), i); + } else if (IDebugVMConstants.COLUMN_ID__NAME.equals(columnIds[i])) { + update.setLabel(vmc.fExpression.getExpressionText(), i); + update.setImageDescriptor(DebugUITools.getImageDescriptor( IDebugUIConstants.IMG_OBJS_EXPRESSION ), i); + } else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(columnIds[i])) { + update.setLabel(MessagesForExpressionVM.ExpressionManagerLayoutNode__invalidExpression_valueColumn_label, i); + } else { + update.setLabel("", i); //$NON-NLS-1$ + } + } + + + update.done(); + } + + private IExpressionLayoutNode findNodeForExpression(String expressionText) { + for (IExpressionLayoutNode node : fExpressionNodes) { + if (node.getExpressionLength(expressionText) > 0) { + return node; + } + } + return null; + } + + @Override + public void setChildNodes(IVMLayoutNode[] childNodes) { + throw new UnsupportedOperationException("This node does not support children."); //$NON-NLS-1$ + } + + public void setExpressionLayoutNodes(IExpressionLayoutNode[] nodes) { + fExpressionNodes = nodes; + } + + @Override + public void dispose() { + + for (IExpressionLayoutNode exprNode : fExpressionNodes) { + exprNode.dispose(); + } + super.dispose(); + } + + /** + * If any of the children nodes have delta flags, that means that this + * node has to generate a delta as well. + */ + @Override + public int getDeltaFlags(Object event) { + int retVal = 0; + + // Add a flag if the list of expressions has changed. + if (event instanceof ExpressionsChangedEvent) { + retVal |= IModelDelta.CONTENT; + } + + for (IExpressionLayoutNode node : fExpressionNodes) { + retVal |= node.getDeltaFlags(event); + } + + return retVal; + } + + @Override + public void buildDelta(final Object event, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) { + // Add a flag if the list of expressions has changed. + if (event instanceof ExpressionsChangedEvent) { + parentDelta.addFlags(IModelDelta.CONTENT); + } + + CountingRequestMonitor multiRm = new CountingRequestMonitor(getExecutor(), requestMonitor); + int buildDeltaForExpressionCallCount = 0; + + IExpression[] expressions = fManager.getExpressions(); + for (int i = 0; i < expressions.length; i++ ) { + String expressionText = expressions[i].getExpressionText(); + IExpressionLayoutNode node = findNodeForExpression(expressionText); + if (node == null) continue; + + int flags = node.getDeltaFlagsForExpression(expressionText, event); + + // If the given node has no delta flags, skip it. + if (flags == IModelDelta.NO_CHANGE) continue; + + node.buildDeltaForExpression(expressions[i], i + nodeOffset, expressionText, event, parentDelta, + getTreePathFromDelta(parentDelta), + new RequestMonitor(getExecutor(), multiRm)); + buildDeltaForExpressionCallCount++; + } + + if (buildDeltaForExpressionCallCount != 0) { + multiRm.setCount(buildDeltaForExpressionCallCount); + } else { + requestMonitor.done(); + } + } + + /** + * Convenience method that returns the child layout nodes which return + * true to the hasDeltaFlags() test for the given + * event. + */ + protected Map getExpressionsWithDeltaFlags(String expressionText, Object e) { + Map nodes = new HashMap(); + for (final IExpressionLayoutNode node : fExpressionNodes) { + int delta = node.getDeltaFlagsForExpression(expressionText, e); + if (delta != IModelDelta.NO_CHANGE) { + nodes.put(node, delta); + } + } + return nodes; + } + + + public CellEditor getCellEditor(IPresentationContext context, String columnId, Object element, Composite parent) { + if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(columnId)) { + return new TextCellEditor(parent); + } + return null; + } + + public ICellModifier getCellModifier(IPresentationContext context, Object element) { + return fWatchExpressionCellModifier; + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java new file mode 100644 index 00000000000..2348cc3c41a --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java @@ -0,0 +1,123 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; + +import org.eclipse.dd.dsf.debug.ui.viewmodel.DebugViewSelectionRootLayoutNode; +import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterGroupLayoutNode; +import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterLayoutNode; +import org.eclipse.dd.dsf.debug.ui.viewmodel.register.SyncRegisterDataAccess; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; +import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.IExpressionsListener; +import org.eclipse.debug.core.model.IExpression; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; + +/** + * + */ +@SuppressWarnings("restriction") +public class ExpressionVMProvider extends AbstractDMVMProvider + implements IExpressionsListener +{ + public static class ExpressionsChangedEvent { + enum Type {ADDED, CHANGED, REMOVED} + public final Type fType; + public final IExpression[] fExpressions; + public ExpressionsChangedEvent(Type type, IExpression[] expressions) { + fType = type; + fExpressions = expressions; + } + } + + public ExpressionVMProvider(AbstractVMAdapter adapter, IPresentationContext context, DsfSession session) { + super(adapter, context, session); + + // The VM provider has to handle all events that result in model deltas. + // Add the provider as listener to expression changes events. + DebugPlugin.getDefault().getExpressionManager().addExpressionListener(this); + + configureLayout(); + } + + protected void configureLayout() { + SyncRegisterDataAccess syncDataAccess = new SyncRegisterDataAccess(); + + // Configure the layout nodes + IVMRootLayoutNode debugViewSelectionNode = new DebugViewSelectionRootLayoutNode(this); + ExpressionManagerLayoutNode expressionManagerNode = new ExpressionManagerLayoutNode(this); + debugViewSelectionNode.setChildNodes(new IVMLayoutNode[] {expressionManagerNode}); + IExpressionLayoutNode registerGroupNode = new RegisterGroupLayoutNode(this, getSession(), syncDataAccess); + expressionManagerNode.setExpressionLayoutNodes(new IExpressionLayoutNode[] { registerGroupNode }); + IVMLayoutNode registerNode = new RegisterLayoutNode(this, getSession(), syncDataAccess); + registerGroupNode.setChildNodes(new IVMLayoutNode[] { registerNode }); + setRootLayoutNode(debugViewSelectionNode); + } + + @Override + public void dispose() { + DebugPlugin.getDefault().getExpressionManager().removeExpressionListener(this); + super.dispose(); + } + + @Override + public IColumnPresentation createColumnPresentation(IPresentationContext context, Object element) { + return new ExpressionColumnPresentation(); + } + + @Override + public String getColumnPresentationId(IPresentationContext context, Object element) { + return ExpressionColumnPresentation.ID; + } + + /** + * Override this operation to avoid the standard test of isOurLayoutNode(), + * which does not take into account {@link ExpressionManagerLayoutNode.setExpressionLayoutNodes} + * nodes. + */ + @Override + protected IVMLayoutNode getLayoutNodeForElement(Object element) { + /* + * First check to see if the parent object is the root object of the + * hierarchy. If that's the case, then retrieve the correcponding + * root VMC from the root node, and pass this root vmc to the root's + * child layout nodes. + */ + IVMRootLayoutNode rootLayoutNode = getRootLayoutNode(); + if (rootLayoutNode == null) { + return null; + } + else if (element.equals(rootLayoutNode.getRootObject())) { + return rootLayoutNode; + } + else if (element instanceof IVMContext){ + return ((IVMContext)element).getLayoutNode(); + } + return null; + } + + public void expressionsAdded(IExpression[] expressions) { + handleEvent(new ExpressionsChangedEvent(ExpressionsChangedEvent.Type.ADDED, expressions)); + } + + public void expressionsChanged(IExpression[] expressions) { + handleEvent(new ExpressionsChangedEvent(ExpressionsChangedEvent.Type.CHANGED, expressions)); + } + + public void expressionsRemoved(IExpression[] expressions) { + handleEvent(new ExpressionsChangedEvent(ExpressionsChangedEvent.Type.REMOVED, expressions)); + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionLayoutNode.java new file mode 100644 index 00000000000..ea30c602a42 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionLayoutNode.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; + +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; +import org.eclipse.debug.core.model.IExpression; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.jface.viewers.TreePath; + +/** + * + */ +@SuppressWarnings("restriction") +public interface IExpressionLayoutNode extends IVMLayoutNode { + int getExpressionLength(String expression); + void getElementForExpression(IChildrenUpdate update, String expressionText, IExpression expression); + + int getDeltaFlagsForExpression(String expressionText, Object event); + void buildDeltaForExpression(IExpression expression, int elementIdx, String expressionText, Object event, + VMDelta parentDelta, TreePath path, RequestMonitor rm); +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionVMContext.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionVMContext.java new file mode 100644 index 00000000000..73d6a53f155 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionVMContext.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; + +import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; + +/** + * + */ +public interface IExpressionVMContext extends IVMContext { +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/MessagesForExpressionVM.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/MessagesForExpressionVM.java new file mode 100644 index 00000000000..6b943864783 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/MessagesForExpressionVM.java @@ -0,0 +1,24 @@ +package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; + +import org.eclipse.osgi.util.NLS; + +public class MessagesForExpressionVM extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.dd.dsf.debug.ui.viewmodel.expression.messages"; //$NON-NLS-1$ + + public static String ExpressionColumnPresentation_expression; + public static String ExpressionColumnPresentation_name; + public static String ExpressionColumnPresentation_type; + public static String ExpressionColumnPresentation_value; + public static String ExpressionColumnPresentation_description; + + public static String ExpressionManagerLayoutNode__invalidExpression_nameColumn_label; + public static String ExpressionManagerLayoutNode__invalidExpression_valueColumn_label; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, MessagesForExpressionVM.class); + } + + private MessagesForExpressionVM() { + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/WatchExpressionCellModifier.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/WatchExpressionCellModifier.java new file mode 100644 index 00000000000..a66ccef945f --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/WatchExpressionCellModifier.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.dd.dsf.concurrent.ThreadSafeAndProhibitedFromDsfExecutor; +import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; +import org.eclipse.debug.core.model.IWatchExpression; +import org.eclipse.jface.viewers.ICellModifier; + +/** + * + */ +@SuppressWarnings("restriction") +@ThreadSafeAndProhibitedFromDsfExecutor("") +public class WatchExpressionCellModifier implements ICellModifier { + + /** + * Constructor for the modifier requires a valid DSF session in order to + * initialize the service tracker. + * @param session DSF session this modifier will use. + */ + public WatchExpressionCellModifier() { + } + + public boolean canModify(Object element, String property) { + return IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(property) && getWatchExpression(element) != null; + } + + public Object getValue(Object element, String property) { + if (!IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(property)) return ""; //$NON-NLS-1$ + + IWatchExpression expression = getWatchExpression(element); + + if (expression != null) { + return expression.getExpressionText(); + } + return ""; //$NON-NLS-1$ + } + + + public void modify(Object element, String property, Object value) { + if (!IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(property)) return; + + IWatchExpression expression = getWatchExpression(element); + if (expression != null && value instanceof String) { + expression.setExpressionText((String)value); + } + } + + private IWatchExpression getWatchExpression(Object element) { + if (element instanceof IAdaptable) { + return (IWatchExpression)((IAdaptable)element).getAdapter(IWatchExpression.class); + } + return null; + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/WatchExpressionDelegate.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/WatchExpressionDelegate.java new file mode 100644 index 00000000000..0d0bd695dc7 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/WatchExpressionDelegate.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; + +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.model.IDebugElement; +import org.eclipse.debug.core.model.IValue; +import org.eclipse.debug.core.model.IWatchExpressionDelegate; +import org.eclipse.debug.core.model.IWatchExpressionListener; +import org.eclipse.debug.core.model.IWatchExpressionResult; + +/** + * + */ +public class WatchExpressionDelegate implements IWatchExpressionDelegate { + public void evaluateExpression(final String expression, IDebugElement context, IWatchExpressionListener listener) { + listener.watchEvaluationFinished(new IWatchExpressionResult() { + public String[] getErrorMessages() { return new String[0]; } + public DebugException getException() { return null; } + public String getExpressionText() { return expression; } + public IValue getValue() { return null; } + public boolean hasErrors() { return false; } + }); + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/messages.properties b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/messages.properties new file mode 100644 index 00000000000..9c940b5d501 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/messages.properties @@ -0,0 +1,7 @@ +ExpressionColumnPresentation_expression=Expression +ExpressionColumnPresentation_name=Name +ExpressionColumnPresentation_type=Type +ExpressionColumnPresentation_value=Value +ExpressionColumnPresentation_description=Description +ExpressionManagerLayoutNode__invalidExpression_nameColumn_label=Invalid expression +ExpressionManagerLayoutNode__invalidExpression_valueColumn_label=Invalid expression diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java index d09e526a29b..6968cc8d6b6 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java @@ -12,8 +12,8 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.launch; import java.util.List; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMEvent; import org.eclipse.dd.dsf.debug.service.IRunControl; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java index e471686c7b4..38f3a669992 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java @@ -66,7 +66,7 @@ public class StandardLaunchRootLayoutNode extends AbstractVMRootLayoutNode return IModelDelta.NO_CHANGE; } else if (de.getSource() instanceof IDebugElement && - !((IDebugElement)de.getSource()).getLaunch().equals(fLaunch) ) + !fLaunch.equals(((IDebugElement)de.getSource()).getLaunch())) { return IModelDelta.NO_CHANGE; } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterColumnPresentation.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterColumnPresentation.java index 779980b0586..b7c15157661 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterColumnPresentation.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterColumnPresentation.java @@ -11,6 +11,7 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.register; import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.jface.resource.ImageDescriptor; @@ -22,28 +23,25 @@ import org.eclipse.jface.resource.ImageDescriptor; public class RegisterColumnPresentation implements IColumnPresentation { public static final String ID = DsfDebugUIPlugin.PLUGIN_ID + ".REGISTERS_COLUMN_PRESENTATION_ID"; //$NON-NLS-1$ - public static final String COL_NAME = ID + ".COL_NAME"; //$NON-NLS-1$ - public static final String COL_VALUE = ID + ".COL_VALUE"; //$NON-NLS-1$ - public static final String COL_DESCRIPTION = ID + ".COL_DESCRIPTION"; //$NON-NLS-1$ - - // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#init(org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext) - public void init(IPresentationContext context) {} - // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#dispose() - public void dispose() {} + public void init(IPresentationContext context) { + } + + public void dispose() { + } // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getAvailableColumns() public String[] getAvailableColumns() { - return new String[] { COL_NAME, COL_VALUE, COL_DESCRIPTION }; + return new String[] { IDebugVMConstants.COLUMN_ID__NAME, IDebugVMConstants.COLUMN_ID__VALUE, IDebugVMConstants.COLUMN_ID__DESCRIPTION, }; } // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getHeader(java.lang.String) public String getHeader(String id) { - if (COL_NAME.equals(id)) { + if (IDebugVMConstants.COLUMN_ID__NAME.equals(id)) { return MessagesForRegisterVM.RegisterColumnPresentation_name; - } else if (COL_VALUE.equals(id)) { + } else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(id)) { return MessagesForRegisterVM.RegisterColumnPresentation_value; - } else if (COL_DESCRIPTION.equals(id)) { + } else if (IDebugVMConstants.COLUMN_ID__DESCRIPTION.equals(id)) { return MessagesForRegisterVM.RegisterColumnPresentation_description; } return null; @@ -53,17 +51,18 @@ public class RegisterColumnPresentation implements IColumnPresentation { public String getId() { return ID; } - - // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getImageDescriptor(java.lang.String) + public ImageDescriptor getImageDescriptor(String id) { return null; - } + } + + // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getInitialColumns() public String[] getInitialColumns() { - return new String[] { COL_NAME, COL_VALUE }; + return new String[] { IDebugVMConstants.COLUMN_ID__NAME, IDebugVMConstants.COLUMN_ID__VALUE, IDebugVMConstants.COLUMN_ID__DESCRIPTION }; } - + // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#isOptional() public boolean isOptional() { return true; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java index 384e5fd7b69..2ad13d9885b 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java @@ -10,30 +10,144 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.viewmodel.register; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMEvent; +import org.eclipse.dd.dsf.datamodel.IDMService; import org.eclipse.dd.dsf.debug.service.IRegisters; import org.eclipse.dd.dsf.debug.service.IRunControl; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMData; import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; +import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.AbstractExpressionLayoutNode; +import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionCellModifier; import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.model.IDebugTarget; +import org.eclipse.debug.core.model.IExpression; +import org.eclipse.debug.core.model.IValue; +import org.eclipse.debug.core.model.IVariable; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementEditor; import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapterExtension; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ICellModifier; +import org.eclipse.jface.viewers.TextCellEditor; +import org.eclipse.jface.viewers.TreePath; +import org.eclipse.swt.widgets.Composite; @SuppressWarnings("restriction") -public class RegisterGroupLayoutNode extends AbstractDMVMLayoutNode { +public class RegisterGroupLayoutNode extends AbstractExpressionLayoutNode + implements IElementEditor +{ - public RegisterGroupLayoutNode(AbstractVMProvider provider, DsfSession session) { - super(provider, session, IRegisters.IRegisterGroupDMContext.class); + protected class RegisterGroupVMC extends DMVMContext + implements IVariable + { + private IExpression fExpression; + public RegisterGroupVMC(IDMContext dmc) { + super(dmc); + } + + public void setExpression(IExpression expression) { + fExpression = expression; + } + + @Override + @SuppressWarnings("unchecked") + public Object getAdapter(Class adapter) { + if (fExpression != null && adapter.isAssignableFrom(fExpression.getClass())) { + return fExpression; + } else if (adapter.isAssignableFrom(IWatchExpressionFactoryAdapterExtension.class)) { + return fRegisterGroupExpressionFactory; + } else { + return super.getAdapter(adapter); + } + } + + @Override + public boolean equals(Object other) { + if (other instanceof RegisterGroupVMC && super.equals(other)) { + RegisterGroupVMC otherGroup = (RegisterGroupVMC)other; + return (otherGroup.fExpression == null && fExpression == null) || + (otherGroup.fExpression != null && otherGroup.fExpression.equals(fExpression)); + } + return false; + } + + @Override + public int hashCode() { + return super.hashCode() + (fExpression != null ? fExpression.hashCode() : 0); + } + + public String getName() throws DebugException { return toString(); } + public String getReferenceTypeName() throws DebugException { return ""; } //$NON-NLS-1$ + public IValue getValue() throws DebugException { return null; } + public boolean hasValueChanged() throws DebugException { return false; } + public void setValue(IValue value) throws DebugException {} + public void setValue(String expression) throws DebugException {} + public boolean supportsValueModification() { return false; } + public boolean verifyValue(IValue value) throws DebugException { return false; } + public boolean verifyValue(String expression) throws DebugException { return false; } + public IDebugTarget getDebugTarget() { return null;} + public ILaunch getLaunch() { return null; } + public String getModelIdentifier() { return DsfDebugUIPlugin.PLUGIN_ID; } } + protected class RegisterGroupExpressionFactory implements IWatchExpressionFactoryAdapterExtension { + + public boolean canCreateWatchExpression(IVariable variable) { + return variable instanceof RegisterGroupVMC; + } + + public String createWatchExpression(IVariable variable) throws CoreException { + RegisterGroupVMC registerVmc = ((RegisterGroupVMC)variable); + + StringBuffer exprBuf = new StringBuffer(); + IRegisterGroupDMContext groupDmc = + DMContexts.getAncestorOfType(registerVmc.getDMC(), IRegisterGroupDMContext.class); + IRegisterGroupDMData groupData = fSyncRegisterDataAccess.readRegisterGroup(groupDmc); + if (groupData != null) { + exprBuf.append("$$\""); //$NON-NLS-1$ + exprBuf.append(groupData.getName()); + exprBuf.append('"'); + return exprBuf.toString(); + } + + return null; + } + } + + final private SyncRegisterDataAccess fSyncRegisterDataAccess; + final protected RegisterGroupExpressionFactory fRegisterGroupExpressionFactory = new RegisterGroupExpressionFactory(); + private WatchExpressionCellModifier fWatchExpressionCellModifier = new WatchExpressionCellModifier(); + + public RegisterGroupLayoutNode(AbstractVMProvider provider, DsfSession session, SyncRegisterDataAccess syncDataAccess) { + super(provider, session, IRegisters.IRegisterGroupDMContext.class); + fSyncRegisterDataAccess = syncDataAccess; + } + + protected SyncRegisterDataAccess getSyncRegisterDataAccess() { + return fSyncRegisterDataAccess; + } + + @Override protected void updateElementsInSessionThread(final IChildrenUpdate update) { if (!checkService(IRegisters.class, null, update)) return; @@ -59,16 +173,30 @@ public class RegisterGroupLayoutNode extends AbstractDMVMLayoutNode dmc) { + return new RegisterGroupVMC(dmc); + } + + @Override protected void fillColumnLabel(IDMContext dmContext, IRegisterGroupDMData dmData, String columnId, int idx, ILabelUpdate update) { - if (RegisterColumnPresentation.COL_NAME.equals(columnId)) { + if (IDebugVMConstants.COLUMN_ID__NAME.equals(columnId)) { update.setLabel(dmData.getName(), idx); - } else if (RegisterColumnPresentation.COL_VALUE.equals(columnId)) { + } else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(columnId)) { update.setLabel("", idx); //$NON-NLS-1$ - } else if (RegisterColumnPresentation.COL_DESCRIPTION.equals(columnId)) { + } else if (IDebugVMConstants.COLUMN_ID__DESCRIPTION.equals(columnId)) { update.setLabel(dmData.getDescription(), idx); + } else if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(columnId)) { + IVMContext vmc = (IVMContext)update.getElement(); + IExpression expression = (IExpression)vmc.getAdapter(IExpression.class); + if (expression != null) { + update.setLabel(expression.getExpressionText(), idx); + } else { + update.setLabel(dmData.getName(), idx); + } } } @@ -89,9 +217,100 @@ public class RegisterGroupLayoutNode extends AbstractDMVMLayoutNode 0) { + return secondQuoteIdx + 1; + } + } + return -1; + } + + @Override + protected int getDeltaFlagsForExpressionPart(Object event) { + if (event instanceof IRunControl.ISuspendedDMEvent) { + return IModelDelta.CONTENT; + } + + return IModelDelta.NO_CHANGE; + } + + @Override + public void buildDeltaForExpression(final IExpression expression, final int elementIdx, final String expressionText, final Object event, final VMDelta parentDelta, final TreePath path, final RequestMonitor rm) + { + if (event instanceof IRunControl.ISuspendedDMEvent) { + // Mark the partent delta indicating that elements were added and/or removed. + parentDelta.addFlags(IModelDelta.CONTENT); + } + + super.buildDeltaForExpression(expression, elementIdx, expressionText, event, parentDelta, path, rm); + } + + @Override + protected void buildDeltaForExpressionElement(Object element, int elementIdx, Object event, VMDelta parentDelta, final RequestMonitor rm) + { + if (event instanceof IRegisters.IRegistersChangedDMEvent) { + parentDelta.addNode(element, IModelDelta.STATE); + } + + super.buildDeltaForExpressionElement(element, elementIdx, event, parentDelta, rm); + } + + @Override + protected void testContextForExpression(Object element, final String expression, final DataRequestMonitor rm) { + if (!(element instanceof AbstractDMVMLayoutNode.DMVMContext)) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ + rm.done(); + return; + } + final IRegisterGroupDMContext dmc = DMContexts.getAncestorOfType(((DMVMContext)element).getDMC(), IRegisterGroupDMContext.class); + if (dmc == null) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + ((IDMService)getServicesTracker().getService(null, dmc.getServiceFilter())).getModelData( + dmc, + new DataRequestMonitor(getSession().getExecutor(), rm) { + @Override + protected void handleOK() { + int startIdx = "$$\"".length(); //$NON-NLS-1$ + int endIdx = expression.indexOf('"', startIdx); + String groupName = expression.substring(startIdx, endIdx); + if (groupName.equals(getData().getName())) { + rm.setData(Boolean.TRUE); + } else { + rm.setData(Boolean.FALSE); + } + rm.done(); + } + }); + } + + @Override + protected void associateExpression(Object element, IExpression expression) { + if (element instanceof RegisterGroupVMC) { + ((RegisterGroupVMC)element).setExpression(expression); + } + } + + public CellEditor getCellEditor(IPresentationContext context, String columnId, Object element, Composite parent) { + if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(columnId)) { + return new TextCellEditor(parent); + } + return null; + } + + public ICellModifier getCellModifier(IPresentationContext context, Object element) { + return fWatchExpressionCellModifier; + } + } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java index 77c05d42d19..0f55510b8b0 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java @@ -10,8 +10,13 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.viewmodel.register; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMEvent; import org.eclipse.dd.dsf.datamodel.IDMService; import org.eclipse.dd.dsf.debug.service.IFormattedValues; @@ -23,20 +28,137 @@ import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterChangedDMEvent; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMData; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext; +import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMData; +import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; +import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.AbstractExpressionLayoutNode; +import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionCellModifier; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.model.IDebugTarget; +import org.eclipse.debug.core.model.IExpression; +import org.eclipse.debug.core.model.IValue; +import org.eclipse.debug.core.model.IVariable; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementEditor; import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapterExtension; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ICellModifier; +import org.eclipse.jface.viewers.TextCellEditor; +import org.eclipse.jface.viewers.TreePath; +import org.eclipse.swt.widgets.Composite; @SuppressWarnings("restriction") -public class RegisterLayoutNode extends AbstractDMVMLayoutNode { +public class RegisterLayoutNode extends AbstractExpressionLayoutNode + implements IElementEditor +{ + protected class RegisterVMC extends DMVMContext + implements IVariable + { + private IExpression fExpression; + public RegisterVMC(IDMContext dmc) { + super(dmc); + } + + public void setExpression(IExpression expression) { + fExpression = expression; + } + + @Override + @SuppressWarnings("unchecked") + public Object getAdapter(Class adapter) { + if (fExpression != null && adapter.isAssignableFrom(fExpression.getClass())) { + return fExpression; + } else if (adapter.isAssignableFrom(IWatchExpressionFactoryAdapterExtension.class)) { + return fRegisterExpressionFactory; + } else { + return super.getAdapter(adapter); + } + } - public RegisterLayoutNode(AbstractVMProvider provider, DsfSession session) { + @Override + public boolean equals(Object other) { + if (other instanceof RegisterVMC && super.equals(other)) { + RegisterVMC otherReg = (RegisterVMC)other; + return (otherReg.fExpression == null && fExpression == null) || + (otherReg.fExpression != null && otherReg.fExpression.equals(fExpression)); + } + return false; + } + + @Override + public int hashCode() { + return super.hashCode() + (fExpression != null ? fExpression.hashCode() : 0); + } + + public String getName() throws DebugException { return toString(); } + public String getReferenceTypeName() throws DebugException { return ""; } //$NON-NLS-1$ + public IValue getValue() throws DebugException { return null; } + public boolean hasValueChanged() throws DebugException { return false; } + public void setValue(IValue value) throws DebugException {} + public void setValue(String expression) throws DebugException {} + public boolean supportsValueModification() { return false; } + public boolean verifyValue(IValue value) throws DebugException { return false; } + public boolean verifyValue(String expression) throws DebugException { return false; } + public IDebugTarget getDebugTarget() { return null;} + public ILaunch getLaunch() { return null; } + public String getModelIdentifier() { return DsfDebugUIPlugin.PLUGIN_ID; } + } + + protected class RegisterExpressionFactory implements IWatchExpressionFactoryAdapterExtension { + + public boolean canCreateWatchExpression(IVariable variable) { + return variable instanceof RegisterVMC; + } + + public String createWatchExpression(IVariable variable) throws CoreException { + RegisterVMC registerVmc = ((RegisterVMC)variable); + + StringBuffer exprBuf = new StringBuffer(); + IRegisterGroupDMContext groupDmc = + DMContexts.getAncestorOfType(registerVmc.getDMC(), IRegisterGroupDMContext.class); + if (groupDmc != null) { + IRegisterGroupDMData groupData = fSyncRegisterDataAccess.readRegisterGroup(groupDmc); + if (groupData != null) { + exprBuf.append("$$\""); //$NON-NLS-1$ + exprBuf.append(groupData.getName()); + exprBuf.append('"'); + } + } + + IRegisterDMContext registerDmc = + DMContexts.getAncestorOfType(registerVmc.getDMC(), IRegisterDMContext.class); + IRegisterDMData regData = fSyncRegisterDataAccess.readRegister(registerDmc); + if (regData != null) { + exprBuf.append('$'); + exprBuf.append(regData.getName()); + return exprBuf.toString(); + } + + return null; + } + } + + private WatchExpressionCellModifier fWatchExpressionCellModifier = new WatchExpressionCellModifier(); + final protected RegisterExpressionFactory fRegisterExpressionFactory = new RegisterExpressionFactory(); + final private SyncRegisterDataAccess fSyncRegisterDataAccess; + + public RegisterLayoutNode(AbstractVMProvider provider, DsfSession session, SyncRegisterDataAccess syncDataAccess) { super(provider, session, IRegisters.IRegisterDMContext.class); + fSyncRegisterDataAccess = syncDataAccess; + } + + protected SyncRegisterDataAccess getSyncRegisterDataAccess() { + return fSyncRegisterDataAccess; } /** @@ -177,12 +299,20 @@ public class RegisterLayoutNode extends AbstractDMVMLayoutNode boolean weAreExtractingFormattedData = false; for (int idx = 0; idx < localColumns.length; idx++) { - if (RegisterColumnPresentation.COL_NAME.equals(localColumns[idx])) { + if (IDebugVMConstants.COLUMN_ID__NAME.equals(localColumns[idx])) { update.setLabel(getData().getName(), idx); - } else if (RegisterColumnPresentation.COL_VALUE.equals(localColumns[idx])) { + } else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(localColumns[idx])) { weAreExtractingFormattedData = true; - } else if (RegisterColumnPresentation.COL_DESCRIPTION.equals(localColumns[idx])) { + } else if (IDebugVMConstants.COLUMN_ID__DESCRIPTION.equals(localColumns[idx])) { update.setLabel(getData().getDescription(), idx); + } else if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(localColumns[idx])) { + IVMContext vmc = (IVMContext)update.getElement(); + IExpression expression = (IExpression)vmc.getAdapter(IExpression.class); + if (expression != null) { + update.setLabel(expression.getExpressionText(), idx); + } else { + update.setLabel(getData().getName(), idx); //$NON-NLS-1$ + } } } @@ -190,7 +320,7 @@ public class RegisterLayoutNode extends AbstractDMVMLayoutNode update.done(); } else { for (int idx = 0; idx < localColumns.length; idx++) { - if (RegisterColumnPresentation.COL_VALUE.equals(localColumns[idx])) { + if (IDebugVMConstants.COLUMN_ID__VALUE.equals(localColumns[idx])) { updateFormattedRegisterValue(update, idx, dmc); } } @@ -225,6 +355,11 @@ public class RegisterLayoutNode extends AbstractDMVMLayoutNode }); } + @Override + protected IVMContext createVMContext(IDMContext dmc) { + return new RegisterVMC(dmc); + } + @Override protected int getNodeDeltaFlagsForDMEvent(IDMEvent e) { if (e instanceof IRunControl.ISuspendedDMEvent) { @@ -247,4 +382,95 @@ public class RegisterLayoutNode extends AbstractDMVMLayoutNode super.buildDeltaForDMEvent(e, parent, nodeOffset, rm); } + + public int getExpressionLength(String expression) { + if (expression.charAt(0) == '$' && Character.isLetterOrDigit(expression.charAt(1))) { + int length = 1; + while( length < expression.length() && Character.isLetterOrDigit(expression.charAt(length)) ) { + length++; + } + return length; + } else { + return -1; + } + } + + @Override + protected void testContextForExpression(Object element, final String expression, final DataRequestMonitor rm) { + if (!(element instanceof AbstractDMVMLayoutNode.DMVMContext)) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ + rm.done(); + return; + } + final IRegisterDMContext dmc = DMContexts.getAncestorOfType(((DMVMContext)element).getDMC(), IRegisterDMContext.class); + if (dmc == null) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + ((IDMService)getServicesTracker().getService(null, dmc.getServiceFilter())).getModelData( + dmc, + new DataRequestMonitor(getSession().getExecutor(), rm) { + @Override + protected void handleOK() { + String regName = expression.substring(1); + if (regName.equals(getData().getName())) { + rm.setData(Boolean.TRUE); + } else { + rm.setData(Boolean.FALSE); + } + rm.done(); + } + }); + } + + @Override + protected void associateExpression(Object element, IExpression expression) { + if (element instanceof RegisterVMC) { + ((RegisterVMC)element).setExpression(expression); + } + } + + @Override + protected int getDeltaFlagsForExpressionPart(Object event) { + if (event instanceof IRunControl.ISuspendedDMEvent) { + return IModelDelta.CONTENT; + } + + return IModelDelta.NO_CHANGE; + } + + @Override + public void buildDeltaForExpression(final IExpression expression, final int elementIdx, final String expressionText, final Object event, final VMDelta parentDelta, final TreePath path, final RequestMonitor rm) + { + if (event instanceof IRunControl.ISuspendedDMEvent) { + // Mark the partent delta indicating that elements were added and/or removed. + parentDelta.addFlags(IModelDelta.CONTENT); + } + + super.buildDeltaForExpression(expression, elementIdx, expressionText, event, parentDelta, path, rm); + } + + @Override + protected void buildDeltaForExpressionElement(Object element, int elementIdx, Object event, VMDelta parentDelta, final RequestMonitor rm) + { + if (event instanceof IRegisters.IRegisterChangedDMEvent) { + parentDelta.addNode(element, IModelDelta.STATE); + } + + super.buildDeltaForExpressionElement(element, elementIdx, event, parentDelta, rm); + } + + + public CellEditor getCellEditor(IPresentationContext context, String columnId, Object element, Composite parent) { + if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(columnId)) { + return new TextCellEditor(parent); + } + return null; + } + + public ICellModifier getCellModifier(IPresentationContext context, Object element) { + return fWatchExpressionCellModifier; + } } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java index f40284a2fc2..11bad015335 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java @@ -23,13 +23,17 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationCont * */ @SuppressWarnings("restriction") -public class RegisterVMProvider extends AbstractDMVMProvider { +public class RegisterVMProvider extends AbstractDMVMProvider +{ public RegisterVMProvider(AbstractVMAdapter adapter, IPresentationContext context, DsfSession session) { super(adapter, context, session); + + SyncRegisterDataAccess syncDataAccess = new SyncRegisterDataAccess(); + IVMRootLayoutNode debugViewSelection = new DebugViewSelectionRootLayoutNode(this); - IVMLayoutNode registerGroupNode = new RegisterGroupLayoutNode(this, getSession()); + IVMLayoutNode registerGroupNode = new RegisterGroupLayoutNode(this, getSession(), syncDataAccess); debugViewSelection.setChildNodes(new IVMLayoutNode[] { registerGroupNode }); - IVMLayoutNode registerNode = new RegisterLayoutNode(this, getSession()); + IVMLayoutNode registerNode = new RegisterLayoutNode(this, getSession(), syncDataAccess); registerGroupNode.setChildNodes(new IVMLayoutNode[] { registerNode }); setRootLayoutNode(debugViewSelection); } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java index 0c2811fd097..63c901c1787 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java @@ -29,6 +29,8 @@ import org.eclipse.dd.dsf.debug.service.IRegisters.IBitFieldDMData; import org.eclipse.dd.dsf.debug.service.IRegisters.IMnemonic; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMData; +import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext; +import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMData; import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; @@ -390,6 +392,13 @@ public class SyncRegisterDataAccess { } } + public IRegisterGroupDMContext getRegisterGroupDMC(Object element) { + if (element instanceof IAdaptable) { + return (IRegisterGroupDMContext) ((IAdaptable) element).getAdapter(IRegisterGroupDMContext.class); + } + return null; + } + public IRegisterDMContext getRegisterDMC(Object element) { if (element instanceof IAdaptable) { return (IRegisterDMContext) ((IAdaptable) element).getAdapter(IRegisterDMContext.class); @@ -399,10 +408,99 @@ public class SyncRegisterDataAccess { public IFormattedDataDMContext getFormattedDMC(Object element) { if (element instanceof IAdaptable) { - return (IFormattedDataDMContext) ((IAdaptable) element).getAdapter(IFormattedDataDMContext.class); + return (IFormattedDataDMContext) ((IAdaptable) element).getAdapter(IFormattedDataDMContext.class); } return null; } + + public class GetRegisterGroupValueQuery extends Query { + + IRegisterGroupDMContext fDmc; + + public GetRegisterGroupValueQuery(DsfExecutor executor, IRegisterGroupDMContext dmc) { + super(executor); + fDmc = dmc; + } + + @Override + protected void execute(final DataRequestMonitor rm) { + /* + * Guard agains the session being disposed. If session is disposed + * it could mean that the executor is shut-down, which in turn could + * mean that we can't complete the RequestMonitor argument. in that + * case, cancel to notify waiting thread. + */ + final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); + if (session == null) { + cancel(false); + return; + } + + IRegisters service = getService(fDmc.getServiceFilter()); + if (service == null) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service not available", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + service.getModelData(fDmc, new DataRequestMonitor( session.getExecutor(), rm) { + @Override + protected void handleCompleted() { + /* + * We're in another dispatch, so we must guard against + * executor shutdown again. + */ + if (!DsfSession.isSessionActive(session.getId())) { + GetRegisterGroupValueQuery.this.cancel(false); + return; + } + super.handleCompleted(); + } + + @Override + protected void handleOK() { + /* + * All good set return value. + */ + rm.setData(getData()); + rm.done(); + } + }); + } + } + + public IRegisterGroupDMData readRegisterGroup(Object element) { + /* + * Get the DMC and the session. If element is not an register DMC, or + * session is stale, then bail out. + */ + IRegisterGroupDMContext dmc = getRegisterGroupDMC(element); + if (dmc == null) return null; + DsfSession session = DsfSession.getSession(dmc.getSessionId()); + if (session == null) return null; + + /* + * Create the query to request the value from service. Note: no need to + * guard agains RejectedExecutionException, because + * DsfSession.getSession() above would only return an active session. + */ + GetRegisterGroupValueQuery query = new GetRegisterGroupValueQuery(session.getExecutor(), dmc); + session.getExecutor().execute(query); + + /* + * Now we have the data, go and get it. Since the call is completed now + * the ".get()" will not suspend it will immediately return with the + * data. + */ + try { + return query.get(); + } catch (InterruptedException e) { + assert false; + return null; + } catch (ExecutionException e) { + return null; + } + } public class GetRegisterValueQuery extends Query { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/LocalsLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/LocalsLayoutNode.java new file mode 100644 index 00000000000..4c171f3b0e4 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/LocalsLayoutNode.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel.variable; + +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.datamodel.IDMEvent; +import org.eclipse.dd.dsf.debug.service.IRegisters; +import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.IStack; +import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; +import org.eclipse.dd.dsf.debug.service.IStack.IVariableDMContext; +import org.eclipse.dd.dsf.debug.service.IStack.IVariableDMData; +import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; + +@SuppressWarnings("restriction") +public class LocalsLayoutNode extends AbstractDMVMLayoutNode { + + public LocalsLayoutNode(AbstractVMProvider provider, DsfSession session) { + super(provider, session, IStack.IVariableDMContext.class); + } + + @Override + protected void updateElementsInSessionThread(final IChildrenUpdate update) { + if (!checkService(IRegisters.class, null, update)) return; + + final IFrameDMContext frameDmc = findDmcInPath(update.getElementPath(), IFrameDMContext.class) ; + + if (frameDmc != null) { + getServicesTracker().getService(IStack.class).getArguments( + frameDmc, + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + public void handleCompleted() { + if (!getStatus().isOK()) { + update.done(); + return; + } + fillUpdateWithVMCs(update, getData()); + update.done(); + }}); + } else { + handleFailedUpdate(update); + } + + } + + @Override + protected void fillColumnLabel(IDMContext dmContext, IVariableDMData dmData, + String columnId, int idx, ILabelUpdate update) + { + if (IDebugVMConstants.COLUMN_ID__NAME.equals(columnId)) { + update.setLabel(dmData.getName(), idx); + } else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(columnId)) { + update.setLabel(dmData.getValue(), idx); + } else { + update.setLabel("", idx); //$NON-NLS-1$ + } + } + + @Override + protected int getNodeDeltaFlagsForDMEvent(IDMEvent e) { + if (e instanceof IRunControl.ISuspendedDMEvent) { + return IModelDelta.CONTENT; + } + return IModelDelta.NO_CHANGE; + } + + @Override + protected void buildDeltaForDMEvent(IDMEvent e, VMDelta parent, int nodeOffset, RequestMonitor rm) { + if (e instanceof IRunControl.ISuspendedDMEvent) { + // Create a delta that the whole register group has changed. + parent.addFlags(IModelDelta.CONTENT); + } + + super.buildDeltaForDMEvent(e, parent, nodeOffset, rm); + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/MessagesForVariablesVM.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/MessagesForVariablesVM.java new file mode 100644 index 00000000000..9f2f0febf91 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/MessagesForVariablesVM.java @@ -0,0 +1,21 @@ +package org.eclipse.dd.dsf.debug.ui.viewmodel.variable; + +import org.eclipse.osgi.util.NLS; + +public class MessagesForVariablesVM extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.dd.dsf.debug.ui.viewmodel.variable.messages"; //$NON-NLS-1$ + + public static String VariableColumnPresentation_name; + + public static String VariableColumnPresentation_type; + + public static String VariableColumnPresentation_value; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, MessagesForVariablesVM.class); + } + + private MessagesForVariablesVM() { + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableColumnPresentation.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableColumnPresentation.java new file mode 100644 index 00000000000..fd5cfd52ccd --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableColumnPresentation.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel.variable; + +import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.jface.resource.ImageDescriptor; + +/** + * + */ +@SuppressWarnings("restriction") +public class VariableColumnPresentation implements IColumnPresentation { + public static final String ID = DsfDebugUIPlugin.PLUGIN_ID + ".VARIABLES_COLUMN_PRESENTATION_ID"; //$NON-NLS-1$ + + // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#init(org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext) + public void init(IPresentationContext context) {} + + // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#dispose() + public void dispose() {} + + // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getAvailableColumns() + public String[] getAvailableColumns() { + return new String[] { IDebugVMConstants.COLUMN_ID__NAME, IDebugVMConstants.COLUMN_ID__TYPE, IDebugVMConstants.COLUMN_ID__VALUE }; + } + + // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getHeader(java.lang.String) + public String getHeader(String id) { + if (IDebugVMConstants.COLUMN_ID__NAME.equals(id)) { + return MessagesForVariablesVM.VariableColumnPresentation_name; + } else if (IDebugVMConstants.COLUMN_ID__TYPE.equals(id)) { + return MessagesForVariablesVM.VariableColumnPresentation_type; + } else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(id)) { + return MessagesForVariablesVM.VariableColumnPresentation_value; + } + return null; + } + + // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getId() + public String getId() { + return ID; + } + + // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getImageDescriptor(java.lang.String) + public ImageDescriptor getImageDescriptor(String id) { + return null; + } + + // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getInitialColumns() + public String[] getInitialColumns() { + return new String[] { IDebugVMConstants.COLUMN_ID__NAME, IDebugVMConstants.COLUMN_ID__TYPE, IDebugVMConstants.COLUMN_ID__VALUE }; + } + + // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#isOptional() + public boolean isOptional() { + return true; + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java new file mode 100644 index 00000000000..559ee8ba034 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel.variable; + +import org.eclipse.dd.dsf.debug.ui.viewmodel.DebugViewSelectionRootLayoutNode; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; +import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; + +/** + * + */ +@SuppressWarnings("restriction") +public class VariableVMProvider extends AbstractDMVMProvider { + public VariableVMProvider(AbstractVMAdapter adapter, IPresentationContext context, DsfSession session) { + super(adapter, context, session); + IVMRootLayoutNode debugViewSelectionNode = new DebugViewSelectionRootLayoutNode(this); + IVMLayoutNode localsNode = new LocalsLayoutNode(this, getSession()); + debugViewSelectionNode.setChildNodes(new IVMLayoutNode[] { localsNode }); + setRootLayoutNode(debugViewSelectionNode); + } + + @Override + public IColumnPresentation createColumnPresentation(IPresentationContext context, Object element) { + return new VariableColumnPresentation(); + } + + @Override + public String getColumnPresentationId(IPresentationContext context, Object element) { + return VariableColumnPresentation.ID; + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/messages.properties b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/messages.properties new file mode 100644 index 00000000000..d67d7e56fd7 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/messages.properties @@ -0,0 +1,3 @@ +VariableColumnPresentation_name=Name +VariableColumnPresentation_type=Type +VariableColumnPresentation_value=Value diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java index a9b5463c5d6..09dc3ac517b 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java @@ -82,10 +82,19 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { /** * If any of the children nodes have delta flags, that means that this * node has to generate a delta as well. + *

    Note: If a child node has a IModelDelta.CONTENT delta + * flag, it means that this flag will be added to this node's element. + * To allow for optimization change the child's IModelDelta.CONTENT + * flag into a IModelDelta.STATE flag. */ public int getDeltaFlags(Object e) { int retVal = 0; for (IVMLayoutNode childNode : getChildLayoutNodes()) { + int childNodeDeltaFlags = childNode.getDeltaFlags(e); + if ((childNodeDeltaFlags | IModelDelta.CONTENT) != 0) { + childNodeDeltaFlags &= ~IModelDelta.CONTENT; + childNodeDeltaFlags |= IModelDelta.STATE; + } retVal |= childNode.getDeltaFlags(e); } return retVal; @@ -116,7 +125,7 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { // Similarly, the index argument is not necessary either. boolean mustGetElements = false; for (int childDelta : childNodesWithDeltaFlags.values()) { - if ((childDelta & ~IModelDelta.CONTENT & ~IModelDelta.STATE) != 0) { + if ((childDelta & ~IModelDelta.STATE) != 0) { mustGetElements = true; } } @@ -391,6 +400,17 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { abstract public int hashCode(); } + protected TreePath getTreePathFromDelta(IModelDelta delta) { + List elementList = new LinkedList(); + IModelDelta listDelta = delta; + elementList.add(0, listDelta.getElement()); + while (listDelta.getParentDelta() != null) { + elementList.add(0, listDelta.getElement()); + listDelta = listDelta.getParentDelta(); + } + return new TreePath(elementList.toArray()); + } + protected class ViewerUpdate implements IViewerUpdate { final private RequestMonitor fRequestMonitor; @@ -486,7 +506,7 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { @Override public String toString() { - return "ElementsUpdate for all elements under parent = " + getElement(); //$NON-NLS-1$ + return "VMElementsUpdate for all elements under parent = " + getElement(); //$NON-NLS-1$ } } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java index 58a6fa3bbc6..d8ade10a314 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java @@ -42,8 +42,6 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; import org.eclipse.debug.internal.ui.viewers.provisional.AbstractModelProxy; import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousContentAdapter; import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousLabelAdapter; -import org.eclipse.jface.viewers.TreePath; -import org.eclipse.jface.viewers.Viewer; /** * View model provider implements the asynchronous view model functionality for @@ -66,7 +64,7 @@ abstract public class AbstractVMProvider implements IVMProvider { private final AbstractVMAdapter fVMAdapter; private final IPresentationContext fPresentationContext; - private final ModelProxy fModelProxy = new ModelProxy(); + private ModelProxy fModelProxy = new ModelProxy(); private boolean fDisposed = false; /** @@ -106,7 +104,7 @@ abstract public class AbstractVMProvider implements IVMProvider } } - protected ModelProxy getModelProxy() { + protected synchronized ModelProxy getModelProxy() { return fModelProxy; } @@ -138,7 +136,7 @@ abstract public class AbstractVMProvider implements IVMProvider Map> nodeUpdatesMap = new HashMap>(); for (IHasChildrenUpdate update : updates) { // Get the VM Context for last element in path. - IVMLayoutNode layoutNode = getLayoutNodeObject(update.getElement()); + IVMLayoutNode layoutNode = getLayoutNodeForElement(update.getElement()); if (layoutNode == null) { // Stale update, most likely as a result of the layout nodes being // changed. Just ignore it. @@ -167,8 +165,8 @@ abstract public class AbstractVMProvider implements IVMProvider return; } - HasElementsUpdate[][] elementsUpdates = - new HasElementsUpdate[node.getChildLayoutNodes().length][updates.length]; + VMHasElementsUpdate[][] elementsUpdates = + new VMHasElementsUpdate[node.getChildLayoutNodes().length][updates.length]; for (int i = 0; i < updates.length; i ++) { final IHasChildrenUpdate update = updates[i]; @@ -181,7 +179,7 @@ abstract public class AbstractVMProvider implements IVMProvider // Status is OK, only if all request monitors are OK. if (getStatus().isOK()) { boolean isContainer = false; - for (DataRequestMonitor hasElementsDone : getRequestMonitors().keySet()) { + for (DataRequestMonitor hasElementsDone : getRequestMonitors()) { isContainer |= hasElementsDone.getStatus().isOK() && hasElementsDone.getData().booleanValue(); } @@ -191,7 +189,7 @@ abstract public class AbstractVMProvider implements IVMProvider } }; - elementsUpdates[j][i] = new HasElementsUpdate( + elementsUpdates[j][i] = new VMHasElementsUpdate( update, hasChildrenMultiRequestMon.add( new DataRequestMonitor(getExecutor(), null) { @@ -214,7 +212,7 @@ abstract public class AbstractVMProvider implements IVMProvider if (update.isCanceled()) continue; getChildrenCountsForNode( - update, update.getElementPath(), + update, new DataRequestMonitor(getExecutor(), null) { @Override protected void handleCompleted() { @@ -236,7 +234,7 @@ abstract public class AbstractVMProvider implements IVMProvider public void update(IChildrenUpdate[] updates) { for (final IChildrenUpdate update : updates) { getChildrenCountsForNode( - update, update.getElementPath(), + update, new DataRequestMonitor(getExecutor(), null) { @Override protected void handleCompleted() { @@ -251,11 +249,11 @@ abstract public class AbstractVMProvider implements IVMProvider } - private void getChildrenCountsForNode(IViewerUpdate update, TreePath elementPath, final DataRequestMonitor rm) { + private void getChildrenCountsForNode(IViewerUpdate update, final DataRequestMonitor rm) { if (isDisposed()) return; // Get the VM Context for last element in path. - final IVMLayoutNode layoutNode = getLayoutNodeObject(update.getElement()); + final IVMLayoutNode layoutNode = getLayoutNodeForElement(update.getElement()); if (layoutNode == null) { // Stale update. Just ignore. rm.setStatus(new Status( @@ -294,7 +292,7 @@ abstract public class AbstractVMProvider implements IVMProvider for (int i = 0; i < childNodes.length; i++) { final int nodeIndex = i; childNodes[i].updateElementCount( - new ElementsCountUpdate( + new VMElementsCountUpdate( update, childrenCountMultiReqMon.add( new DataRequestMonitor(getExecutor(), null) { @@ -308,14 +306,13 @@ abstract public class AbstractVMProvider implements IVMProvider super.handleCompleted(); childrenCountMultiReqMon.requestMonitorDone(this); } - }), - elementPath) + })) ); } } private void updateChildrenWithCounts(final IChildrenUpdate update, Integer[] nodeElementCounts) { - final IVMLayoutNode layoutNode = getLayoutNodeObject(update.getElement()); + final IVMLayoutNode layoutNode = getLayoutNodeForElement(update.getElement()); if (layoutNode == null) { // Stale update. Just ignore. if (!update.isCanceled()) update.done(); @@ -347,18 +344,22 @@ abstract public class AbstractVMProvider implements IVMProvider if (updateStartIdx <= nodeEndIdx && updateEndIdx > nodeStartIdx) { final int elementsStartIdx = Math.max(updateStartIdx - nodeStartIdx, 0); final int elementsEndIdx = Math.min(updateEndIdx - nodeStartIdx, nodeElementCounts[i]); - - layoutNodes[i].updateElements( - new ElementsUpdate( - update, - elementsMultiRequestMon.add(new RequestMonitor(getExecutor(), null) { - @Override - protected void handleCompleted() { - elementsMultiRequestMon.requestMonitorDone(this); - } - }), - nodeStartIdx, elementsStartIdx, elementsEndIdx - elementsStartIdx) - ); + final int elementsLength = elementsEndIdx - elementsStartIdx; + if (elementsLength > 0) { + layoutNodes[i].updateElements( + new VMElementsUpdate( + update, elementsStartIdx, elementsLength, + elementsMultiRequestMon.add(new DataRequestMonitor>(getExecutor(), null) { + @Override + protected void handleCompleted() { + for (int i = 0; i < elementsLength; i++) { + update.setChild(getData().get(i), elementsStartIdx + nodeStartIdx + i); + } + elementsMultiRequestMon.requestMonitorDone(this); + } + })) + ); + } } } @@ -378,6 +379,9 @@ abstract public class AbstractVMProvider implements IVMProvider if (getRootLayoutNode() != null && element.equals(getRootLayoutNode().getRootObject())) { + synchronized(this) { + fModelProxy = new ModelProxy(); + } return fModelProxy; } return null; @@ -429,7 +433,7 @@ abstract public class AbstractVMProvider implements IVMProvider * @return parent VMC, if null it indicates that the object did not originate * from this view or is stale. */ - private IVMLayoutNode getLayoutNodeObject(Object element) { + protected IVMLayoutNode getLayoutNodeForElement(Object element) { /* * First check to see if the parent object is the root object of the * hierarchy. If that's the case, then retrieve the correcponding @@ -474,14 +478,39 @@ abstract public class AbstractVMProvider implements IVMProvider } + protected void handleEvent(final Object event) { + // We're in session's executor thread. Re-dispach to VM Adapter + // executor thread and then call root layout node. + try { + getExecutor().execute(new Runnable() { + public void run() { + if (isDisposed()) return; + + IVMRootLayoutNode rootLayoutNode = getRootLayoutNode(); + if (rootLayoutNode != null && rootLayoutNode.getDeltaFlags(event) != 0) { + rootLayoutNode.createDelta( + event, + new DataRequestMonitor(getExecutor(), null) { + @Override + public void handleCompleted() { + if (getStatus().isOK()) { + getModelProxy().fireModelChangedNonDispatch(getData()); + } + } + @Override public String toString() { + return "Result of a delta for event: '" + event.toString() + "' in VMP: '" + AbstractVMProvider.this + "'" + "\n" + getData().toString(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } + }); + } + }}); + } catch (RejectedExecutionException e) { + // Ignore. This exception could be thrown if the provider is being + // shut down. + } + } + @ThreadSafe protected class ModelProxy extends AbstractModelProxy { - /** - * Counter for whether the model proxy is currently installed in the viewer. - * Data model events are processed only if the model proxy is active. - */ - private int fProxyActive = 0; - /** * Scheduling rule for running the update jobs. */ @@ -490,25 +519,12 @@ abstract public class AbstractVMProvider implements IVMProvider public boolean isConflicting(ISchedulingRule rule) { return rule == this; } }; - @Override - public void installed(Viewer viewer) { - fProxyActive++; - } - - @Override - public void dispose() { - fProxyActive--; - super.dispose(); - } - /** * Fires given delta using a job. Processing the delta on the dispatch * thread can lead to dead-locks. * @param delta */ public void fireModelChangedNonDispatch(final IModelDelta delta) { - if (fProxyActive <= 0) return; - Job job = new Job("Processing view model delta.") { //$NON-NLS-1$ @Override protected IStatus run(IProgressMonitor monitor) { @@ -522,125 +538,4 @@ abstract public class AbstractVMProvider implements IVMProvider } } - - class ViewerUpdate implements IViewerUpdate { - - private IStatus fStatus; - final private RequestMonitor fRequestMonitor; - final protected IViewerUpdate fClientUpdate; - - public ViewerUpdate(IViewerUpdate clientUpdate, RequestMonitor requestMonitor) { - fRequestMonitor = requestMonitor; - fClientUpdate = clientUpdate; - } - - public Object getElement() { return fClientUpdate.getElement(); } - public TreePath getElementPath() { return fClientUpdate.getElementPath(); } - public IPresentationContext getPresentationContext() { return fClientUpdate.getPresentationContext(); } - - public IStatus getStatus() { return fStatus; } - public void setStatus(IStatus status) { fStatus = status; } - public boolean isCanceled() { return fClientUpdate.isCanceled(); } - public void cancel() { - fClientUpdate.cancel(); - } - - public void done() { - try { - fRequestMonitor.done(); - } catch (RejectedExecutionException e) { // Ignore - } - } - - } - - class HasElementsUpdate extends ViewerUpdate implements IHasChildrenUpdate { - - final private DataRequestMonitor fHasElemsRequestMonitor; - - HasElementsUpdate(IHasChildrenUpdate clientUpdate, DataRequestMonitor rm) { - super(clientUpdate, rm); - fHasElemsRequestMonitor = rm; - } - - @Override - public TreePath getElementPath() { - return ((IHasChildrenUpdate)fClientUpdate).getElementPath(); - } - - public void setHasChilren(boolean hasChildren) { - fHasElemsRequestMonitor.setData(hasChildren); - } - - @Override - public void done() { - assert fHasElemsRequestMonitor.getData() != null || !fHasElemsRequestMonitor.getStatus().isOK(); - super.done(); - } - } - - class ElementsCountUpdate extends ViewerUpdate implements IChildrenCountUpdate { - final private DataRequestMonitor fCountRequestMonitor; - final private TreePath fElementPath; - - ElementsCountUpdate(IViewerUpdate clientUpdate, DataRequestMonitor rm, TreePath elementPath) { - super(clientUpdate, rm); - fElementPath = elementPath; - fCountRequestMonitor = rm; - } - - @Override - public TreePath getElementPath() { - return fElementPath; - } - - public void setChildCount(int count) { - fCountRequestMonitor.setData(count); - } - - @Override - public void done() { - assert fCountRequestMonitor.getData() != null || !fCountRequestMonitor.getStatus().isOK(); - super.done(); - } - - } - - class ElementsUpdate extends ViewerUpdate implements IChildrenUpdate { - private final int fClientOffset; - private final int fOffset; - private final int fLength; - - ElementsUpdate(IChildrenUpdate clientUpdate, RequestMonitor requestMonitor, int clientOffset, int offset, int length) { - super(clientUpdate, requestMonitor); - fClientOffset = clientOffset; - fOffset = offset; - fLength = length; - } - - public int getOffset() { - return fOffset; - } - - public int getLength() { - return fLength; - } - - @Override - public TreePath getElementPath() { - return ((IChildrenUpdate)fClientUpdate).getElementPath(); - } - - public void setChild(Object child, int offset) { - if (offset >= fOffset && offset < (fOffset + fLength)) { - ((IChildrenUpdate)fClientUpdate).setChild(child, fClientOffset + offset); - } - } - - @Override - public String toString() { - return "ElementsUpdate for elements under parent = " + getElement() + ", in range " + getOffset() + " -> " + (getOffset() + getLength()); //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$ - } - - } } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMElementsCountUpdate.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMElementsCountUpdate.java new file mode 100644 index 00000000000..8c599f90e10 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMElementsCountUpdate.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel; + +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; + +/** + * Helper class implementation of an update object to use with IElementContentProvider. + * @see IElementContentProvider + */ +@SuppressWarnings("restriction") +public class VMElementsCountUpdate extends VMViewerUpdate implements IChildrenCountUpdate { + final private DataRequestMonitor fCountRequestMonitor; + + public VMElementsCountUpdate(IViewerUpdate clientUpdate, DataRequestMonitor rm) { + super(clientUpdate, rm); + fCountRequestMonitor = rm; + } + + public void setChildCount(int count) { + fCountRequestMonitor.setData(count); + } + + @Override + public void done() { + assert fCountRequestMonitor.getData() != null || !fCountRequestMonitor.getStatus().isOK(); + super.done(); + } + +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMElementsUpdate.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMElementsUpdate.java new file mode 100644 index 00000000000..4966402314e --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMElementsUpdate.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; + +/** + * Helper class implementation of an update object to use with IElementContentProvider. + * @see IElementContentProvider + */ +@SuppressWarnings("restriction") +public class VMElementsUpdate extends VMViewerUpdate implements IChildrenUpdate { + private final int fOffset; + private final int fLength; + private final List fElements; + + public VMElementsUpdate(IChildrenUpdate clientUpdate, int offset, int length, DataRequestMonitor> requestMonitor) { + super(clientUpdate, requestMonitor); + fOffset = offset; + fLength = length; + fElements = length > 0 ? new ArrayList(length) : new ArrayList(); + } + + public int getOffset() { + return fOffset; + } + + public int getLength() { + return fLength; + } + + public void setChild(Object element, int offset) { + // Calculate the index in array based on configured offset. + int idx = offset - (fOffset > 0 ? fOffset : 0); + + // To make sure that index is in valid range. + if (idx < 0 || (fLength > 0 && idx >= fLength)) return; + + // Increase the list size if needed. + ensureElementsSize(idx + 1); + + // Finally set the element in elements list. + fElements.set(idx, element); + } + + private void ensureElementsSize(int size) { + while (fElements.size() < size) { + fElements.add(null); + } + } + + @Override + public String toString() { + return "VMElementsUpdate for elements under parent = " + getElement() + ", in range " + getOffset() + " -> " + (getOffset() + getLength()); //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$ + } + + @Override + public void done() { + @SuppressWarnings("unchecked") + DataRequestMonitor> rm = (DataRequestMonitor>)fRequestMonitor; + rm.setData(fElements); + super.done(); + } +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMHasElementsUpdate.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMHasElementsUpdate.java new file mode 100644 index 00000000000..2153473ff11 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMHasElementsUpdate.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel; + +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; + +/** + * Helper class implementation of an update object to use with IElementContentProvider. + * @see IElementContentProvider + */ +@SuppressWarnings("restriction") +public class VMHasElementsUpdate extends VMViewerUpdate implements IHasChildrenUpdate { + + final private DataRequestMonitor fHasElemsRequestMonitor; + + public VMHasElementsUpdate(IHasChildrenUpdate clientUpdate, DataRequestMonitor rm) { + super(clientUpdate, rm); + fHasElemsRequestMonitor = rm; + } + + public void setHasChilren(boolean hasChildren) { + fHasElemsRequestMonitor.setData(hasChildren); + } + + @Override + public void done() { + assert fHasElemsRequestMonitor.getData() != null || !fHasElemsRequestMonitor.getStatus().isOK(); + super.done(); + } +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java new file mode 100644 index 00000000000..6512fb3ec4d --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel; + +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; +import org.eclipse.jface.viewers.TreePath; + +/** + * Helper class implementation of an update object to use with IElementContentProvider. + * @see IElementContentProvider + */ +@SuppressWarnings("restriction") +public class VMViewerUpdate implements IViewerUpdate { + final protected RequestMonitor fRequestMonitor; + final protected IViewerUpdate fClientUpdate; + + public VMViewerUpdate(IViewerUpdate clientUpdate, RequestMonitor requestMonitor) { + fRequestMonitor = requestMonitor; + fClientUpdate = clientUpdate; + } + + public Object getElement() { return fClientUpdate.getElement(); } + public TreePath getElementPath() { return fClientUpdate.getElementPath(); } + public IPresentationContext getPresentationContext() { return fClientUpdate.getPresentationContext(); } + + public IStatus getStatus() { return fRequestMonitor.getStatus(); } + public void setStatus(IStatus status) { fRequestMonitor.setStatus(status); } + public boolean isCanceled() { return fClientUpdate.isCanceled(); } + public void cancel() { + fClientUpdate.cancel(); + } + + public void done() { + try { + fRequestMonitor.done(); + } catch (RejectedExecutionException e) { // Ignore + } + } + +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java index d85a0937d1d..250c5dabfa0 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java @@ -452,9 +452,9 @@ abstract public class AbstractDMVMLayoutNode extends Abstract callChildNodesToBuildDelta(childNodeDeltas, delta, event, requestMonitor); } } else { - // The for this node was not found in the event. Call the + // The DMC for this node was not found in the event. Call the // super-class to resort to the default behavior which may add a - // delta node for every element in this node. + // delta for every element in this node. super.buildDelta(event, parentDelta, nodeOffset, requestMonitor); } } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProvider.java index 990892a5d1a..2391170d2db 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProvider.java @@ -13,15 +13,12 @@ package org.eclipse.dd.dsf.ui.viewmodel.dm; import java.util.concurrent.RejectedExecutionException; import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMEvent; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; -import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousContentAdapter; @@ -111,33 +108,6 @@ abstract public class AbstractDMVMProvider extends AbstractVMProvider public void eventDispatched(final IDMEvent event) { if (isDisposed()) return; - // We're in session's executor thread. Re-dispach to VM Adapter - // executor thread and then call root layout node. - try { - getExecutor().execute(new Runnable() { - public void run() { - if (isDisposed()) return; - - IVMRootLayoutNode rootLayoutNode = getRootLayoutNode(); - if (rootLayoutNode != null && rootLayoutNode.getDeltaFlags(event) != 0) { - rootLayoutNode.createDelta( - event, - new DataRequestMonitor(getExecutor(), null) { - @Override - public void handleCompleted() { - if (getStatus().isOK()) { - getModelProxy().fireModelChangedNonDispatch(getData()); - } - } - @Override public String toString() { - return "Result of a delta for event: '" + event.toString() + "' in VMP: '" + AbstractDMVMProvider.this + "'" + "\n" + getData().toString(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - } - }); - } - }}); - } catch (RejectedExecutionException e) { - // Ignore. This exception could be thrown if the provider is being - // shut down. - } + handleEvent(event); } } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/CountingRequestMonitor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/CountingRequestMonitor.java new file mode 100644 index 00000000000..6e6220f4a25 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/CountingRequestMonitor.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.concurrent; + +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.dd.dsf.DsfPlugin; + +/** + * Utility class to collect multiple request monitor results of commands + * that are initiated simultaneously. The usage is as follows: + *
    + *     final MultiRequestMonitor multiRequestMon = new MultiRequestMonitor(fExecutor, null) { 
    + *         public void handleCompleted() {
    + *             System.out.println("All complete, errors=" + !getStatus().isOK());
    + *         }
    + *     };
    + *     
    + *     for (int i = 0; i < 10; i++) {
    + *         service.call(i, multiRequestMon.addRequestMonitor(
    + *             new RequestMonitor(fExecutor, null) {
    + *                 public void handleCompleted() {
    + *                     System.out.println(Integer.toString(i) + " complete");
    + *                     multiRequestMon.requestMonitorDone(this);
    + *                }
    + *             }));
    + *     }
    + * 
    + */ +public class CountingRequestMonitor extends RequestMonitor { + private int fDoneCounter; + + public CountingRequestMonitor(DsfExecutor executor, RequestMonitor parentRequestMonitor) { + super(executor, parentRequestMonitor); + setStatus(new MultiStatus(DsfPlugin.PLUGIN_ID, 0, "Collective status for set of sub-operations.", null)); //$NON-NLS-1$ + } + + public void setCount(int count) { + fDoneCounter = count; + } + + @Override + public synchronized void done() { + fDoneCounter--; + if (fDoneCounter <= 0) { + super.done(); + } + } + + @Override + public String toString() { + return "Multi-RequestMonitor: " + getStatus().toString(); //$NON-NLS-1$ + } +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DataRequestMonitor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DataRequestMonitor.java index 754e5dd4175..9cfe5a24e2f 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DataRequestMonitor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DataRequestMonitor.java @@ -16,7 +16,7 @@ package org.eclipse.dd.dsf.concurrent; * * @param V The type of the data object that this monitor handles. */ -public abstract class DataRequestMonitor extends RequestMonitor { +public class DataRequestMonitor extends RequestMonitor { /** Data object reference */ private V fData; diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/MultiRequestMonitor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/MultiRequestMonitor.java index 37bb9fdbf9b..e084cdd3a5a 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/MultiRequestMonitor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/MultiRequestMonitor.java @@ -11,6 +11,8 @@ package org.eclipse.dd.dsf.concurrent; import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; import java.util.Map; import org.eclipse.core.runtime.MultiStatus; @@ -37,8 +39,9 @@ import org.eclipse.dd.dsf.DsfPlugin; * } * */ -public abstract class MultiRequestMonitor extends RequestMonitor { - private Map fRequestMonitors = new HashMap(); +public class MultiRequestMonitor extends RequestMonitor { + private List fRequestMonitorList = new LinkedList(); + private Map fStatusMap = new HashMap(); private int fDoneCounter; public MultiRequestMonitor(DsfExecutor executor, RequestMonitor parentRequestMonitor) { @@ -55,8 +58,9 @@ public abstract class MultiRequestMonitor extends Requ * inlined in service method calls */ public T add(T rm) { - assert !fRequestMonitors.containsKey(rm); - fRequestMonitors.put(rm, false); + assert !fStatusMap.containsKey(rm); + fRequestMonitorList.add(rm); + fStatusMap.put(rm, false); fDoneCounter++; return rm; } @@ -70,23 +74,29 @@ public abstract class MultiRequestMonitor extends Requ */ public void requestMonitorDone(V requestMonitor) { ((MultiStatus)getStatus()).merge(requestMonitor.getStatus()); - assert fRequestMonitors.containsKey(requestMonitor); - fRequestMonitors.put(requestMonitor, true); + assert fStatusMap.containsKey(requestMonitor); + fStatusMap.put(requestMonitor, true); assert fDoneCounter > 0; fDoneCounter--; if (fDoneCounter == 0) { - assert !fRequestMonitors.containsValue(false); + assert !fStatusMap.containsValue(false); super.done(); } } - + /** - * Returns the map of RequestMonitor callbacks. Access to this data is provided - * in case overriding classes need access to the collected data in the - * request monitors. - * @return map of the request monitors + * Returns the list of requested monitors, sorted in order as they were added. */ - public Map getRequestMonitors() { return fRequestMonitors; } + public List getRequestMonitors() { + return fRequestMonitorList; + } + + /** + * Returns true if given monitor is finished. + */ + public boolean isRequestMonitorDone(V rm) { + return fStatusMap.get(rm); + } @Override public String toString() { From b5503f43ae766477719fef03547fbefa892c8890 Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Tue, 8 May 2007 18:02:45 +0000 Subject: [PATCH 080/834] Completed the functionality on the register view so there is full support for GROUPS/REGISTERS/BITFIELDS if the underlying service supports it. This included editing as well. This is based on Pawel's latest update with the Expressions view support. Randy --- .../META-INF/MANIFEST.MF | 1 + .../expression/ExpressionVMProvider.java | 16 +- .../IFormattedValuePreferenceStore.java | 2 +- .../IFormattedValueVMContext.java | 2 +- .../formatsupport/SetDefaultFormatBinary.java | 47 ++ .../SetDefaultFormatHex.java | 7 +- .../SetDefaultFormatNatural.java} | 4 +- .../formatsupport/SetDefaultFormatOctal.java | 47 ++ .../RegisterBitFieldLayoutCellModifier.java | 153 +++++ .../register/RegisterBitFieldLayoutNode.java | 560 ++++++++++++++++++ .../register/RegisterLayoutNode.java | 66 ++- .../RegisterLayoutValueCellModifier.java | 113 ++++ .../register/RegisterVMProvider.java | 51 +- 13 files changed, 1027 insertions(+), 42 deletions(-) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/{ => formatsupport}/IFormattedValuePreferenceStore.java (91%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/{ => formatsupport}/IFormattedValueVMContext.java (92%) create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatBinary.java rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/{ => formatsupport}/SetDefaultFormatHex.java (83%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/{SetDefaultFormatDecimal.java => formatsupport/SetDefaultFormatNatural.java} (92%) create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatOctal.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutCellModifier.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutValueCellModifier.java diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF index 63fc553607d..015e3211a95 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF @@ -20,6 +20,7 @@ Export-Package: org.eclipse.dd.dsf.debug.ui, org.eclipse.dd.dsf.debug.ui.viewmodel, org.eclipse.dd.dsf.debug.ui.viewmodel.expression, + org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport, org.eclipse.dd.dsf.debug.ui.viewmodel.launch, org.eclipse.dd.dsf.debug.ui.viewmodel.register, org.eclipse.dd.dsf.debug.ui.viewmodel.variable diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java index 2348cc3c41a..9b82c745d9b 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java @@ -10,7 +10,9 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; +import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.dd.dsf.debug.ui.viewmodel.DebugViewSelectionRootLayoutNode; +import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePreferenceStore; import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterGroupLayoutNode; import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterLayoutNode; import org.eclipse.dd.dsf.debug.ui.viewmodel.register.SyncRegisterDataAccess; @@ -31,8 +33,10 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationCont */ @SuppressWarnings("restriction") public class ExpressionVMProvider extends AbstractDMVMProvider - implements IExpressionsListener + implements IExpressionsListener, IFormattedValuePreferenceStore { + private String fDefaultFormatId = IFormattedValues.HEX_FORMAT; + public static class ExpressionsChangedEvent { enum Type {ADDED, CHANGED, REMOVED} public final Type fType; @@ -62,7 +66,7 @@ public class ExpressionVMProvider extends AbstractDMVMProvider debugViewSelectionNode.setChildNodes(new IVMLayoutNode[] {expressionManagerNode}); IExpressionLayoutNode registerGroupNode = new RegisterGroupLayoutNode(this, getSession(), syncDataAccess); expressionManagerNode.setExpressionLayoutNodes(new IExpressionLayoutNode[] { registerGroupNode }); - IVMLayoutNode registerNode = new RegisterLayoutNode(this, getSession(), syncDataAccess); + IVMLayoutNode registerNode = new RegisterLayoutNode(this, this, getSession(), syncDataAccess); registerGroupNode.setChildNodes(new IVMLayoutNode[] { registerNode }); setRootLayoutNode(debugViewSelectionNode); } @@ -120,4 +124,12 @@ public class ExpressionVMProvider extends AbstractDMVMProvider public void expressionsRemoved(IExpression[] expressions) { handleEvent(new ExpressionsChangedEvent(ExpressionsChangedEvent.Type.REMOVED, expressions)); } + + public String getDefaultFormatId() { + return fDefaultFormatId; + } + + public void setDefaultFormatId(String id) { + fDefaultFormatId = id; + } } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/IFormattedValuePreferenceStore.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/IFormattedValuePreferenceStore.java similarity index 91% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/IFormattedValuePreferenceStore.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/IFormattedValuePreferenceStore.java index 99e1343e771..f7b14c4b33f 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/IFormattedValuePreferenceStore.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/IFormattedValuePreferenceStore.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel; +package org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport; /** * diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/IFormattedValueVMContext.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/IFormattedValueVMContext.java similarity index 92% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/IFormattedValueVMContext.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/IFormattedValueVMContext.java index 3b38afb2f54..fb74d6aeeaa 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/IFormattedValueVMContext.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/IFormattedValueVMContext.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel; +package org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatBinary.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatBinary.java new file mode 100644 index 00000000000..f945ab4a8e0 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatBinary.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport; + +import org.eclipse.dd.dsf.debug.service.IFormattedValues; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IViewActionDelegate; +import org.eclipse.ui.IViewPart; + +/** + * + */ +public class SetDefaultFormatBinary implements IViewActionDelegate { + + private IFormattedValueVMContext fFormattedValueVMC; + + public void init(IViewPart view) { + } + + public void run(IAction action) { + if (fFormattedValueVMC != null) { + fFormattedValueVMC.getPreferenceStore().setDefaultFormatId(IFormattedValues.BINARY_FORMAT); + } + } + + public void selectionChanged(IAction action, ISelection selection) { + fFormattedValueVMC = null; + if (selection instanceof IStructuredSelection) { + Object element = ((IStructuredSelection)selection).getFirstElement(); + if (element instanceof IFormattedValueVMContext) { + fFormattedValueVMC = ((IFormattedValueVMContext)element); + } + } + action.setEnabled(fFormattedValueVMC != null); + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/SetDefaultFormatHex.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatHex.java similarity index 83% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/SetDefaultFormatHex.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatHex.java index 984abaf9c09..edfb9d85be9 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/SetDefaultFormatHex.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatHex.java @@ -8,14 +8,9 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel; +package org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport; -import org.eclipse.core.runtime.IAdaptable; import org.eclipse.dd.dsf.debug.service.IFormattedValues; -import org.eclipse.dd.dsf.ui.viewmodel.IVMAdapter; -import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; -import org.eclipse.debug.ui.AbstractDebugView; import org.eclipse.jface.action.IAction; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/SetDefaultFormatDecimal.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatNatural.java similarity index 92% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/SetDefaultFormatDecimal.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatNatural.java index 6ba564344e6..52498992215 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/SetDefaultFormatDecimal.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatNatural.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel; +package org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport; import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.jface.action.IAction; @@ -20,7 +20,7 @@ import org.eclipse.ui.IViewPart; /** * */ -public class SetDefaultFormatDecimal implements IViewActionDelegate { +public class SetDefaultFormatNatural implements IViewActionDelegate { private IFormattedValueVMContext fFormattedValueVMC; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatOctal.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatOctal.java new file mode 100644 index 00000000000..67641c4d511 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatOctal.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport; + +import org.eclipse.dd.dsf.debug.service.IFormattedValues; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IViewActionDelegate; +import org.eclipse.ui.IViewPart; + +/** + * + */ +public class SetDefaultFormatOctal implements IViewActionDelegate { + + private IFormattedValueVMContext fFormattedValueVMC; + + public void init(IViewPart view) { + } + + public void run(IAction action) { + if (fFormattedValueVMC != null) { + fFormattedValueVMC.getPreferenceStore().setDefaultFormatId(IFormattedValues.OCTAL_FORMAT); + } + } + + public void selectionChanged(IAction action, ISelection selection) { + fFormattedValueVMC = null; + if (selection instanceof IStructuredSelection) { + Object element = ((IStructuredSelection)selection).getFirstElement(); + if (element instanceof IFormattedValueVMContext) { + fFormattedValueVMC = ((IFormattedValueVMContext)element); + } + } + action.setEnabled(fFormattedValueVMC != null); + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutCellModifier.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutCellModifier.java new file mode 100644 index 00000000000..5bb899dfda6 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutCellModifier.java @@ -0,0 +1,153 @@ +/* + * BitFieldLayoutCellModifier.java + * Created on Apr 3, 2007 + * + * Copyright 2007 Wind River Systems Inc. All rights reserved. + */ +package org.eclipse.dd.dsf.debug.ui.viewmodel.register; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.dd.dsf.debug.service.IFormattedValues; +import org.eclipse.dd.dsf.debug.service.IRegisters.IBitFieldDMContext; +import org.eclipse.dd.dsf.debug.service.IRegisters.IBitFieldDMData; +import org.eclipse.dd.dsf.debug.service.IRegisters.IMnemonic; +import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; +import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionCellModifier; +import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePreferenceStore; + +public class RegisterBitFieldLayoutCellModifier extends WatchExpressionCellModifier { + + public static enum BitFieldEditorStyle { NOTHING, BITFIELDCOMBO, BITFIELDTEXT } + + private BitFieldEditorStyle fStyle; + private IBitFieldDMData fBitFieldData = null; + private Object fElement = null; + private SyncRegisterDataAccess fDataAccess = null; + private IFormattedValuePreferenceStore fFormatPrefStore; + + public RegisterBitFieldLayoutCellModifier( IFormattedValuePreferenceStore formatPrefStore, BitFieldEditorStyle style, SyncRegisterDataAccess access ) { + fStyle = style; + fDataAccess = access; + fFormatPrefStore = formatPrefStore; + } + + /* + * Used to make sure we are dealing with a valid register. + */ + private IBitFieldDMContext getBitFieldDMC(Object element) { + if (element instanceof IAdaptable) { + return (IBitFieldDMContext)((IAdaptable)element).getAdapter(IBitFieldDMContext.class); + } + return null; + } + + @Override + public boolean canModify(Object element, String property) { + + /* + * If we're in the column value, modify the register data. + * Otherwise, call the super-class to edit the watch expression. + */ + if ( IDebugVMConstants.COLUMN_ID__VALUE.equals(property) ) { + /* + * Make sure we are are dealing with a valid set of information. + */ + if ( getBitFieldDMC(element) == null ) return false; + + fElement = element; + + /* + * We need to read the register in order to get the attributes. + */ + fBitFieldData = fDataAccess.readBitField(element); + + if ( ( fBitFieldData != null ) && ( ! fBitFieldData.isWriteable() ) ) return false; + + return true ; + } else { + return super.canModify(element, property); + } + } + + @Override + public Object getValue(Object element, String property) { + /* + * If we're in the column value, modify the register data. + * Otherwise, call the super-class to edit the watch expression. + */ + if ( IDebugVMConstants.COLUMN_ID__VALUE.equals(property) ) { + /* + * Make sure we are working on the editable areas. + */ + if ( element != fElement ) return false; + + if ( fStyle == BitFieldEditorStyle.BITFIELDTEXT ) { + + /* + * We let the Model provider supply the current format. + */ + String value = fDataAccess.getFormattedValue(fElement, fFormatPrefStore.getDefaultFormatId()); + + if ( value == null ) { value = "..."; } //$NON-NLS-1$ + + return value; + } + else { + /* + * This is a COMBO BOX. So we need to take the value of the bitfield and + * compare it to the associated mnemonic values to see which mnemonic is + * representing the current value. At this point the Bitfield Model data + * has already been established since the "canModify()" method is called + * first by the flexible hierarchy proxies. + */ + IMnemonic curMnemonic = fBitFieldData.getCurrentMnemonicValue(); + + int index = 0 ; + for ( IMnemonic mnemonic : fBitFieldData.getMnemonics() ) { + if ( mnemonic.equals( curMnemonic ) ) { + return new Integer( index ); + } + index ++; + } + + return null; + } + } else { + return super.getValue(element, property); + } + } + + @Override + public void modify(Object element, String property, Object value) { + /* + * If we're in the column value, modify the register data. + * Otherwise, call the super-class to edit the watch expression. + */ + if ( IDebugVMConstants.COLUMN_ID__VALUE.equals(property) ) { + if ( fStyle == BitFieldEditorStyle.BITFIELDTEXT ) { + if (value instanceof String) { + /* + * We let the Model provider supply the current format. + */ + fDataAccess.writeBitField(element, (String) value, IFormattedValues.HEX_FORMAT); + } + } + else { + if (value instanceof Integer) { + /* + * Get the integer value corresponding to the selected entry. + */ + Integer val = (Integer) value; + + /* + * Write the bit field using the selected mnemonic. + */ + fDataAccess.writeBitField(element, fBitFieldData.getMnemonics()[val.intValue()]); + } + } + } else { + super.modify(element, property, value); + } + } +} + diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java new file mode 100644 index 00000000000..77a3fa7aa7d --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java @@ -0,0 +1,560 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel.register; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.datamodel.IDMEvent; +import org.eclipse.dd.dsf.datamodel.IDMService; +import org.eclipse.dd.dsf.debug.service.IFormattedValues; +import org.eclipse.dd.dsf.debug.service.IRegisters; +import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData; +import org.eclipse.dd.dsf.debug.service.IRegisters.IBitFieldChangedDMEvent; +import org.eclipse.dd.dsf.debug.service.IRegisters.IBitFieldDMContext; +import org.eclipse.dd.dsf.debug.service.IRegisters.IBitFieldDMData; +import org.eclipse.dd.dsf.debug.service.IRegisters.IMnemonic; +import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext; +import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMData; +import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext; +import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMData; +import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent; +import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; +import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.AbstractExpressionLayoutNode; +import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePreferenceStore; +import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValueVMContext; +import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterBitFieldLayoutCellModifier.BitFieldEditorStyle; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.model.IDebugTarget; +import org.eclipse.debug.core.model.IExpression; +import org.eclipse.debug.core.model.IValue; +import org.eclipse.debug.core.model.IVariable; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementEditor; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapterExtension; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ComboBoxCellEditor; +import org.eclipse.jface.viewers.ICellModifier; +import org.eclipse.jface.viewers.TextCellEditor; +import org.eclipse.jface.viewers.TreePath; +import org.eclipse.swt.widgets.Composite; + +@SuppressWarnings("restriction") +public class RegisterBitFieldLayoutNode extends AbstractExpressionLayoutNode implements IElementEditor { + + protected class BitFieldVMC extends DMVMContext + implements IVariable, IFormattedValueVMContext + { + private IExpression fExpression; + public BitFieldVMC(IDMContext dmc) { + super(dmc); + } + + public IFormattedValuePreferenceStore getPreferenceStore() { + return fFormattedPrefStore; + } + + public void setExpression(IExpression expression) { + fExpression = expression; + } + + @Override + @SuppressWarnings("unchecked") + public Object getAdapter(Class adapter) { + if (fExpression != null && adapter.isAssignableFrom(fExpression.getClass())) { + return fExpression; + } else if (adapter.isAssignableFrom(IWatchExpressionFactoryAdapterExtension.class)) { + return fBitFieldExpressionFactory; + } else { + return super.getAdapter(adapter); + } + } + + @Override + public boolean equals(Object other) { + if (other instanceof BitFieldVMC && super.equals(other)) { + BitFieldVMC otherBitField = (BitFieldVMC)other; + return (otherBitField.fExpression == null && fExpression == null) || + (otherBitField.fExpression != null && otherBitField.fExpression.equals(fExpression)); + } + return false; + } + + @Override + public int hashCode() { + return super.hashCode() + (fExpression != null ? fExpression.hashCode() : 0); + } + + public String getName() throws DebugException { return toString(); } + public String getReferenceTypeName() throws DebugException { return ""; } //$NON-NLS-1$ + public IValue getValue() throws DebugException { return null; } + public boolean hasValueChanged() throws DebugException { return false; } + public void setValue(IValue value) throws DebugException {} + public void setValue(String expression) throws DebugException {} + public boolean supportsValueModification() { return false; } + public boolean verifyValue(IValue value) throws DebugException { return false; } + public boolean verifyValue(String expression) throws DebugException { return false; } + public IDebugTarget getDebugTarget() { return null;} + public ILaunch getLaunch() { return null; } + public String getModelIdentifier() { return DsfDebugUIPlugin.PLUGIN_ID; } + } + + protected class BitFieldExpressionFactory implements IWatchExpressionFactoryAdapterExtension { + + public boolean canCreateWatchExpression(IVariable variable) { + return variable instanceof BitFieldVMC; + } + + public String createWatchExpression(IVariable variable) throws CoreException { + BitFieldVMC bitFieldVmc = ((BitFieldVMC)variable); + + StringBuffer exprBuf = new StringBuffer(); + IRegisterGroupDMContext groupDmc = + DMContexts.getAncestorOfType(bitFieldVmc.getDMC(), IRegisterGroupDMContext.class); + if (groupDmc != null) { + IRegisterGroupDMData groupData = fDataAccess.readRegisterGroup(groupDmc); + if (groupData != null) { + exprBuf.append("$$\""); //$NON-NLS-1$ + exprBuf.append(groupData.getName()); + exprBuf.append('"'); + } + } + + IRegisterDMContext registerDmc = + DMContexts.getAncestorOfType(bitFieldVmc.getDMC(), IRegisterDMContext.class); + if (registerDmc != null) { + IRegisterDMData regData = fDataAccess.readRegister(registerDmc); + if (regData != null) { + exprBuf.append('$'); + exprBuf.append(regData.getName()); + } + } + + IBitFieldDMContext bitFieldDmc = + DMContexts.getAncestorOfType(bitFieldVmc.getDMC(), IBitFieldDMContext.class); + if (bitFieldDmc != null) { + IBitFieldDMData bitFieldData = fDataAccess.readBitField(bitFieldDmc); + if (bitFieldData != null) { + exprBuf.append('.'); + exprBuf.append(bitFieldData.getName()); + } + } + + return exprBuf.toString(); + } + } + + private SyncRegisterDataAccess fDataAccess = null; + final protected BitFieldExpressionFactory fBitFieldExpressionFactory = new BitFieldExpressionFactory(); + private final IFormattedValuePreferenceStore fFormattedPrefStore; + + public RegisterBitFieldLayoutNode(IFormattedValuePreferenceStore prefStore, AbstractVMProvider provider, DsfSession session, SyncRegisterDataAccess access) { + super(provider, session, IRegisters.IBitFieldDMContext.class); + fDataAccess = access; + fFormattedPrefStore = prefStore; + } + + /** + * Private data access routine which performs the extra level of data access needed to + * get the formatted data value for a specific register. + */ + private void updateFormattedRegisterValue(final ILabelUpdate update, final int labelIndex, final IBitFieldDMContext dmc) + { + final IRegisters regService = getServicesTracker().getService(IRegisters.class); + + /* + * First select the format to be used. This involves checking so see that the preference + * page format is supported by the register service. If the format is not supported then + * we will pick the first available format. + */ + final String preferencePageFormatId = fFormattedPrefStore.getDefaultFormatId(); + + regService.getAvailableFormattedValues( + dmc, + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + public void handleCompleted() { + if (!getStatus().isOK()) { + handleFailedUpdate(update); + return; + } + + /* + * See if the desired format is supported. + */ + String[] formatIds = getData(); + String finalFormatId = IFormattedValues.HEX_FORMAT; + boolean requestedFormatIsSupported = false; + + for ( String fId : formatIds ) { + if ( preferencePageFormatId.equals(fId) ) { + /* + * Desired format is supported. + */ + finalFormatId = preferencePageFormatId; + requestedFormatIsSupported = true; + break; + } + } + + if ( ! requestedFormatIsSupported ) { + /* + * Desired format is not supported. If there are any formats supported + * then use the first available. + */ + if ( formatIds.length != 0 ) { + finalFormatId = formatIds[0]; + } + else { + /* + * Register service does not support any format. + */ + handleFailedUpdate(update); + return; + } + } + + /* + * Format has been validated. Get the formatted value. + */ + FormattedValueDMContext valueDmc = regService.getFormattedValue(dmc, finalFormatId); + + regService.getModelData( + valueDmc, + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + public void handleCompleted() { + if (!getStatus().isOK()) { + handleFailedUpdate(update); + return; + } + + /* + * Fill the label/column with the properly formatted data value. + */ + update.setLabel(getData().getFormattedValue() , labelIndex); + update.done(); + } + } + ); + } + } + ); + } + + /* + * We override the Abstract method because we now need to perform an extra level of data fetch + * to get the formatted value represenatation of the register. Before we obtained the data from + * the IDMData returned for the Register DMC. Now basically the level of information returned + * is attribute information and the formatted value requires a separate transaction. + * + * @see org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode#updateLabelInSessionThread(org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate[]) + */ + @Override + protected void updateLabelInSessionThread(ILabelUpdate[] updates) { + for (final ILabelUpdate update : updates) { + + final IBitFieldDMContext dmc = findDmcInPath(update.getElementPath(), IRegisters.IBitFieldDMContext.class); + + ((IDMService)getServicesTracker().getService(null, dmc.getServiceFilter())).getModelData( + dmc, + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + protected void handleCompleted() { + /* + * Check that the request was evaluated and data is still + * valid. The request could fail if the state of the + * service changed during the request, but the view model + * has not been updated yet. + */ + if (!getStatus().isOK() || !getData().isValid()) { + assert getStatus().isOK() || + getStatus().getCode() != IDsfService.INTERNAL_ERROR || + getStatus().getCode() != IDsfService.NOT_SUPPORTED; + handleFailedUpdate(update); + return; + } + + /* + * If columns are configured, extract the selected values for each + * understood column. First we fill all of those columns which can + * be filled without the extra data mining. We also note if we do + * have to datamine. Any columns need to set the processing flag + * so we know we have further work to do. If there are more columns + * which need data extraction they need to be added in both "for" + * loops. + */ + String[] localColumns = update.getPresentationContext().getColumns(); + if (localColumns == null) localColumns = new String[] { null }; + + boolean weAreExtractingFormattedData = false; + + for (int idx = 0; idx < localColumns.length; idx++) { + if (IDebugVMConstants.COLUMN_ID__NAME.equals(localColumns[idx])) { + update.setLabel(getData().getName(), idx); + } else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(localColumns[idx])) { + weAreExtractingFormattedData = true; + } else if (IDebugVMConstants.COLUMN_ID__DESCRIPTION.equals(localColumns[idx])) { + update.setLabel(getData().getDescription(), idx); + } else if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(localColumns[idx])) { + IVMContext vmc = (IVMContext)update.getElement(); + IExpression expression = (IExpression)vmc.getAdapter(IExpression.class); + if (expression != null) { + update.setLabel(expression.getExpressionText(), idx); + } else { + update.setLabel(getData().getName(), idx); + } + } + } + + if ( ! weAreExtractingFormattedData ) { + update.done(); + } else { + for (int idx = 0; idx < localColumns.length; idx++) { + if (IDebugVMConstants.COLUMN_ID__VALUE.equals(localColumns[idx])) { + updateFormattedRegisterValue(update, idx, dmc); + } + } + } + } + } + ); + } + } + + @Override + protected void updateElementsInSessionThread(final IChildrenUpdate update) { + final IRegisterDMContext regDmc = findDmcInPath(update.getElementPath(), IRegisterDMContext.class); + + if (regDmc == null) { + handleFailedUpdate(update); + return; + } + + getServicesTracker().getService(IRegisters.class).getBitFields( + regDmc, + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + protected void handleErrorOrCancel() { + handleFailedUpdate(update); + } + + @Override + protected void handleOK() { + fillUpdateWithVMCs(update, getData()); + update.done(); + } + }); + } + + @Override + protected IVMContext createVMContext(IDMContext dmc) { + return new BitFieldVMC(dmc); + } + + @Override + protected int getNodeDeltaFlagsForDMEvent(IDMEvent e) { + if (e instanceof IRunControl.ISuspendedDMEvent) { + return IModelDelta.CONTENT; + } else if (e instanceof IRegisters.IBitFieldChangedDMEvent) { + return IModelDelta.STATE; + } + return IModelDelta.NO_CHANGE; + } + + @Override + protected void buildDeltaForDMEvent(IDMEvent e, VMDelta parent, int nodeOffset, RequestMonitor rm) { + if (e instanceof IRunControl.ISuspendedDMEvent) { + // Create a delta that the whole register group has changed. + parent.addFlags(IModelDelta.CONTENT); + } + if (e instanceof IRegisters.IBitFieldChangedDMEvent) { + parent.addNode( createVMContext(((IRegisters.IBitFieldChangedDMEvent)e).getDMContext()), IModelDelta.STATE ); + } + + super.buildDeltaForDMEvent(e, parent, nodeOffset, rm); + } + + public CellEditor getCellEditor(IPresentationContext context, String columnId, Object element, Composite parent) { + + if (IDebugVMConstants.COLUMN_ID__VALUE.equals(columnId)) { + /* + * In order to decide what kind of editor to present we need to know if there are + * mnemonics which can be used to represent the values. If there are then we will + * create a Combo editor for them. Otherwise we will just make a normal text cell + * editor. If there are bit groups then the modifier will check the size of the + * value being entered. + */ + IBitFieldDMData bitFieldData = fDataAccess.readBitField(element); + + if ( bitFieldData != null && bitFieldData.isWriteable() ) { + + IMnemonic[] mnemonics = bitFieldData.getMnemonics(); + + if ( mnemonics != null && mnemonics.length != 0 ) { + + /* + * Create the list of readable dropdown selections. + */ + String[] StringValues = new String[ mnemonics.length ]; + + int idx = 0 ; + for ( IMnemonic mnemonic : mnemonics ) { + StringValues[ idx ++ ] = mnemonic.getLongName(); + } + + /* + * Not we are complex COMBO and return the right editor. + */ + return new ComboBoxCellEditor(parent, StringValues); + } + else { + /* + * Text editor even if we need to clamp the value entered. + */ + return new TextCellEditor(parent); + } + } + } else if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(columnId)) { + return new TextCellEditor(parent); + } + return null; + } + + public ICellModifier getCellModifier(IPresentationContext context, Object element) { + + /* + * In order to decide what kind of modifier to present we need to know if there + * are mnemonics which can be used to represent the values. + */ + IBitFieldDMData bitFieldData = fDataAccess.readBitField(element); + + if ( bitFieldData != null && bitFieldData.isWriteable() ) { + + IMnemonic[] mnemonics = bitFieldData.getMnemonics(); + + if ( mnemonics != null && mnemonics.length != 0 ) { + /* + * Note we are complex COMBO and return the right editor. + */ + return new RegisterBitFieldLayoutCellModifier( fFormattedPrefStore, BitFieldEditorStyle.BITFIELDCOMBO, fDataAccess ); + } + else { + /* + * Text editor even if we need to clamp the value entered. + */ + return new RegisterBitFieldLayoutCellModifier( fFormattedPrefStore, BitFieldEditorStyle.BITFIELDTEXT, fDataAccess ); + } + } + else { + return null; + } + } + + @Override + protected void testContextForExpression(Object element, final String expression, final DataRequestMonitor rm) { + if (!(element instanceof AbstractDMVMLayoutNode.DMVMContext)) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + final IBitFieldDMContext dmc = DMContexts.getAncestorOfType(((DMVMContext)element).getDMC(), IBitFieldDMContext.class); + if (dmc == null) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + ((IDMService)getServicesTracker().getService(null, dmc.getServiceFilter())).getModelData( + dmc, + new DataRequestMonitor(getSession().getExecutor(), rm) { + @Override + protected void handleOK() { + String bitFieldName = expression.substring(1); + if (bitFieldName.equals(getData().getName())) { + rm.setData(Boolean.TRUE); + } else { + rm.setData(Boolean.FALSE); + } + rm.done(); + } + }); + } + + public int getExpressionLength(String expression) { + if (expression.charAt(0) == '.' && Character.isLetterOrDigit(expression.charAt(1))) { + int length = 1; + while( length < expression.length() && Character.isLetterOrDigit(expression.charAt(length)) ) { + length++; + } + return length; + } else { + return -1; + } + } + + @Override + protected void associateExpression(Object element, IExpression expression) { + if (element instanceof BitFieldVMC) { + ((BitFieldVMC)element).setExpression(expression); + } + } + + @Override + protected int getDeltaFlagsForExpressionPart(Object event) { + if (event instanceof IRunControl.ISuspendedDMEvent) { + return IModelDelta.CONTENT; + } + + return IModelDelta.NO_CHANGE; + } + + @Override + public void buildDeltaForExpression(final IExpression expression, final int elementIdx, final String expressionText, final Object event, final VMDelta parentDelta, final TreePath path, final RequestMonitor rm) + { + if (event instanceof ISuspendedDMEvent) { + // Mark the partent delta indicating that elements were added and/or removed. + parentDelta.addFlags(IModelDelta.CONTENT); + } else if (event instanceof IRegisters.IRegisterChangedDMEvent) { + parentDelta.addFlags(IModelDelta.CONTENT); + } + + super.buildDeltaForExpression(expression, elementIdx, expressionText, event, parentDelta, path, rm); + } + + @Override + protected void buildDeltaForExpressionElement(Object element, int elementIdx, Object event, VMDelta parentDelta, final RequestMonitor rm) + { + if (event instanceof IBitFieldChangedDMEvent) { + parentDelta.addNode(element, IModelDelta.STATE); + } + + super.buildDeltaForExpressionElement(element, elementIdx, event, parentDelta, rm); + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java index 0f55510b8b0..9af7cfcc0c0 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java @@ -32,7 +32,8 @@ import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMData; import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.AbstractExpressionLayoutNode; -import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionCellModifier; +import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePreferenceStore; +import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValueVMContext; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; @@ -59,20 +60,20 @@ import org.eclipse.swt.widgets.Composite; @SuppressWarnings("restriction") public class RegisterLayoutNode extends AbstractExpressionLayoutNode - implements IElementEditor + implements IElementEditor { protected class RegisterVMC extends DMVMContext - implements IVariable + implements IVariable, IFormattedValueVMContext { private IExpression fExpression; public RegisterVMC(IDMContext dmc) { super(dmc); } - + public void setExpression(IExpression expression) { fExpression = expression; } - + @Override @SuppressWarnings("unchecked") public Object getAdapter(Class adapter) { @@ -90,16 +91,20 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode dmc) { return new RegisterVMC(dmc); } - + @Override protected int getNodeDeltaFlagsForDMEvent(IDMEvent e) { if (e instanceof IRunControl.ISuspendedDMEvent) { @@ -467,10 +473,22 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode Date: Tue, 8 May 2007 21:46:40 +0000 Subject: [PATCH 081/834] Fixed update problem in Debug view and expression view (bug 186041). --- .../AbstractExpressionLayoutNode.java | 2 +- .../dsf/ui/viewmodel/AbstractVMProvider.java | 46 ++++++++++++------- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionLayoutNode.java index ffacf21203f..6f686cc0b8e 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionLayoutNode.java @@ -89,7 +89,7 @@ public abstract class AbstractExpressionLayoutNode extends Ab protected void getElementForExpressionPart(final IChildrenUpdate update, final String expressionPartText, final DataRequestMonitor rm) { updateElements(new VMElementsUpdate( update, -1, -1, - new DataRequestMonitor>(getSession().getExecutor(), rm) { + new DataRequestMonitor>(getExecutor(), rm) { @Override protected void handleOK() { if (getData().size() == 0) { diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java index d8ade10a314..2372de3e1e3 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java @@ -161,34 +161,46 @@ abstract public class AbstractVMProvider implements IVMProvider if (node.getChildLayoutNodes().length == 0) { for (IHasChildrenUpdate update : updates) { update.setHasChilren(false); + update.done(); } return; } + // Create a matrix of element updates: + // The first dimension "i" is the list of children updates that came from the viewer. + // For each of these updates, there are "j" number of elment updates corresponding + // to the number of child layout nodes in this node. + // Each children update from the viewer is complete when all the child layout nodes + // fill in their elements update. + // Once the matrix is constructed, the child layout nodes are given the list of updates + // equal to the updates requested by the viewer. VMHasElementsUpdate[][] elementsUpdates = new VMHasElementsUpdate[node.getChildLayoutNodes().length][updates.length]; for (int i = 0; i < updates.length; i ++) { final IHasChildrenUpdate update = updates[i]; + + final MultiRequestMonitor> hasChildrenMultiRequestMon = + new MultiRequestMonitor>(getExecutor(), null) { + @Override + protected void handleCompleted() { + // Status is OK, only if all request monitors are OK. + if (getStatus().isOK()) { + boolean isContainer = false; + for (DataRequestMonitor hasElementsDone : getRequestMonitors()) { + isContainer |= hasElementsDone.getStatus().isOK() && + hasElementsDone.getData().booleanValue(); + } + update.setHasChilren(isContainer); + } else { + update.setStatus(getStatus()); + } + update.done(); + } + }; + for (int j = 0; j < node.getChildLayoutNodes().length; j++) { - final MultiRequestMonitor> hasChildrenMultiRequestMon = - new MultiRequestMonitor>(getExecutor(), null) { - @Override - protected void handleCompleted() { - // Status is OK, only if all request monitors are OK. - if (getStatus().isOK()) { - boolean isContainer = false; - for (DataRequestMonitor hasElementsDone : getRequestMonitors()) { - isContainer |= hasElementsDone.getStatus().isOK() && - hasElementsDone.getData().booleanValue(); - } - update.setHasChilren(isContainer); - update.done(); - } - } - }; - elementsUpdates[j][i] = new VMHasElementsUpdate( update, hasChildrenMultiRequestMon.add( From f719fd899c48d211ae545acbf32115a2895ada4f Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Wed, 9 May 2007 14:15:24 +0000 Subject: [PATCH 082/834] Added GROUP and REGISTER icons in the appropriate layout nodes. --- .../debug/ui/viewmodel/register/RegisterGroupLayoutNode.java | 3 +++ .../dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java | 3 +++ 2 files changed, 6 insertions(+) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java index 2ad13d9885b..5ae69def30d 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java @@ -40,11 +40,13 @@ import org.eclipse.debug.core.model.IDebugTarget; import org.eclipse.debug.core.model.IExpression; import org.eclipse.debug.core.model.IValue; import org.eclipse.debug.core.model.IVariable; +import org.eclipse.debug.internal.ui.DebugPluginImages; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementEditor; import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapterExtension; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.ICellModifier; @@ -185,6 +187,7 @@ public class RegisterGroupLayoutNode extends AbstractExpressionLayoutNode Date: Wed, 9 May 2007 21:24:17 +0000 Subject: [PATCH 083/834] Applied patch from Fran Litterio for Bugzilla 186256. Initial implementation of the variables view for Open Source. --- .../viewmodel/variable/LocalsLayoutNode.java | 94 ----- .../variable/VariableLocalsLayoutNode.java | 341 ++++++++++++++++++ .../VariableSubExpressionsLayoutNode.java | 297 +++++++++++++++ .../variable/VariableVMProvider.java | 50 ++- 4 files changed, 671 insertions(+), 111 deletions(-) delete mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/LocalsLayoutNode.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLocalsLayoutNode.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableSubExpressionsLayoutNode.java diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/LocalsLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/LocalsLayoutNode.java deleted file mode 100644 index 4c171f3b0e4..00000000000 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/LocalsLayoutNode.java +++ /dev/null @@ -1,94 +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.ui.viewmodel.variable; - -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.datamodel.IDMEvent; -import org.eclipse.dd.dsf.debug.service.IRegisters; -import org.eclipse.dd.dsf.debug.service.IRunControl; -import org.eclipse.dd.dsf.debug.service.IStack; -import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; -import org.eclipse.dd.dsf.debug.service.IStack.IVariableDMContext; -import org.eclipse.dd.dsf.debug.service.IStack.IVariableDMData; -import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; -import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; -import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; - -@SuppressWarnings("restriction") -public class LocalsLayoutNode extends AbstractDMVMLayoutNode { - - public LocalsLayoutNode(AbstractVMProvider provider, DsfSession session) { - super(provider, session, IStack.IVariableDMContext.class); - } - - @Override - protected void updateElementsInSessionThread(final IChildrenUpdate update) { - if (!checkService(IRegisters.class, null, update)) return; - - final IFrameDMContext frameDmc = findDmcInPath(update.getElementPath(), IFrameDMContext.class) ; - - if (frameDmc != null) { - getServicesTracker().getService(IStack.class).getArguments( - frameDmc, - new DataRequestMonitor(getSession().getExecutor(), null) { - @Override - public void handleCompleted() { - if (!getStatus().isOK()) { - update.done(); - return; - } - fillUpdateWithVMCs(update, getData()); - update.done(); - }}); - } else { - handleFailedUpdate(update); - } - - } - - @Override - protected void fillColumnLabel(IDMContext dmContext, IVariableDMData dmData, - String columnId, int idx, ILabelUpdate update) - { - if (IDebugVMConstants.COLUMN_ID__NAME.equals(columnId)) { - update.setLabel(dmData.getName(), idx); - } else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(columnId)) { - update.setLabel(dmData.getValue(), idx); - } else { - update.setLabel("", idx); //$NON-NLS-1$ - } - } - - @Override - protected int getNodeDeltaFlagsForDMEvent(IDMEvent e) { - if (e instanceof IRunControl.ISuspendedDMEvent) { - return IModelDelta.CONTENT; - } - return IModelDelta.NO_CHANGE; - } - - @Override - protected void buildDeltaForDMEvent(IDMEvent e, VMDelta parent, int nodeOffset, RequestMonitor rm) { - if (e instanceof IRunControl.ISuspendedDMEvent) { - // Create a delta that the whole register group has changed. - parent.addFlags(IModelDelta.CONTENT); - } - - super.buildDeltaForDMEvent(e, parent, nodeOffset, rm); - } -} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLocalsLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLocalsLayoutNode.java new file mode 100644 index 00000000000..8e26c2754f8 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLocalsLayoutNode.java @@ -0,0 +1,341 @@ +/** + * Copyright (c) 2006 Wind River Systems and others. All rights reserved. This program and + * the accompanying materials are made available under the terms of the Eclipse Public + * License v1.0 which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Wind River Systems - initial API and implementation + */ + +package org.eclipse.dd.dsf.debug.ui.viewmodel.variable; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.MultiRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.IDMEvent; +import org.eclipse.dd.dsf.datamodel.IDMService; +import org.eclipse.dd.dsf.debug.service.IExpressions; +import org.eclipse.dd.dsf.debug.service.IFormattedValues; +import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.IStack; +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMData; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; +import org.eclipse.dd.dsf.debug.service.IStack.IVariableDMContext; +import org.eclipse.dd.dsf.debug.service.IStack.IVariableDMData; +import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; + +@SuppressWarnings("restriction") +public class VariableLocalsLayoutNode extends AbstractDMVMLayoutNode { + + public VariableLocalsLayoutNode(AbstractVMProvider provider, DsfSession session) { + super(provider, session, IExpressions.IExpressionDMContext.class); + } + + /** + * We override this method because we now need to perform an extra level of data fetch to get the + * formatted value of the expression. + * + * @return void + */ + @Override + protected void updateLabelInSessionThread(ILabelUpdate[] updates) { + for (final ILabelUpdate update : updates) { + + final IExpressionDMContext dmc = findDmcInPath(update.getElementPath(), IExpressions.IExpressionDMContext.class); + + ((IDMService)getServicesTracker().getService(null, dmc.getServiceFilter())).getModelData( + dmc, + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + protected void handleCompleted() { + // Check that the request was evaluated and data is still valid. The request could + // fail if the state of the service changed during the request, but the view model + // has not been updated yet. + + if (!getStatus().isOK() || !getData().isValid()) { + assert getStatus().isOK() || + getStatus().getCode() != IDsfService.INTERNAL_ERROR || + getStatus().getCode() != IDsfService.NOT_SUPPORTED; + handleFailedUpdate(update); + return; + } + + // If columns are configured, extract the selected values for each understood column. + // First, we fill all of those columns which can be filled without extra data mining. + // We also note if we do have to do extra data mining. Any columns need to set the + // processing flag so we know we have further work to do. If there are more columns + // which need data extraction they need to be added in both "for" loops. + + String[] localColumns = update.getPresentationContext().getColumns(); + if (localColumns == null) + localColumns = new String[] { null }; + + boolean weAreExtractingFormattedData = false; + + for (int idx = 0; idx < localColumns.length; idx++) { + if (IDebugVMConstants.COLUMN_ID__NAME.equals(localColumns[idx])) { + update.setLabel(getData().getName(), idx); + } else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(localColumns[idx])) { + weAreExtractingFormattedData = true; + } else if (IDebugVMConstants.COLUMN_ID__DESCRIPTION.equals(localColumns[idx])) { + update.setLabel("", idx); //$NON-NLS-1$ + } + } + + if ( ! weAreExtractingFormattedData ) { + update.done(); + } else { + for (int idx = 0; idx < localColumns.length; idx++) { + if (IDebugVMConstants.COLUMN_ID__VALUE.equals(localColumns[idx])) { + updateFormattedExpressionValue(update, idx, dmc); + } + } + } + } + } + ); + } + } + + + /** + * Private data access routine which performs the extra level of data access needed to + * get the formatted data value for a specific register. + */ + private void updateFormattedExpressionValue(final ILabelUpdate update, final int labelIndex, + final IExpressionDMContext dmc) + { + final IExpressions expressionService = getServicesTracker().getService(IExpressions.class); + /* + * PREFPAGE : We are using a default format until the preference page is created + * + * First select the format to be used. This involves checking so see that the preference + * page format is supported by the register service. If the format is not supported then + * we will pick the first available format. + */ + + final String preferencePageFormatId = IFormattedValues.NATURAL_FORMAT; + + expressionService.getAvailableFormattedValues( + dmc, + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + public void handleCompleted() { + if (!getStatus().isOK()) { + handleFailedUpdate(update); + return; + } + + /* + * See if the desired format is supported. + */ + String[] formatIds = getData(); + String finalFormatId = IFormattedValues.NATURAL_FORMAT; + boolean requestedFormatIsSupported = false; + + for ( String fId : formatIds ) { + if ( preferencePageFormatId.equals(fId) ) { + // The desired format is supported. + + finalFormatId = preferencePageFormatId; + requestedFormatIsSupported = true; + break; + } + } + + if ( ! requestedFormatIsSupported ) { + /* + * Desired format is not supported. If there are any formats supported + * then use the first available. + */ + if ( formatIds.length != 0 ) { + finalFormatId = formatIds[0]; + } + else { + // Expression service does not support any format. + + handleFailedUpdate(update); + return; + } + } + + /* + * Format has been validated. Get the formatted value. + */ + FormattedValueDMContext valueDmc = expressionService.getFormattedValue(dmc, finalFormatId); + + expressionService.getModelData( + valueDmc, + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + public void handleCompleted() { + if (!getStatus().isOK()) { + handleFailedUpdate(update); + return; + } + + /* + * Fill the label/column with the properly formatted data value. + */ + update.setLabel(getData().getFormattedValue(), labelIndex); + update.done(); + } + } + ); + } + } + ); + } + + + @Override + protected void updateElementsInSessionThread(final IChildrenUpdate update) { + + // ISSUE: Do we need to explicitly get the IExecutionDMContext and ISymbolDMContext since they + // should be in the parent chain of the IFrameDMContext object? + + final IExecutionDMContext execDmc = + findDmcInPath(update.getElementPath(), IExecutionDMContext.class); + final IFrameDMContext frameDmc = + findDmcInPath(update.getElementPath(), IFrameDMContext.class); + //final ISymbolDMContext symbolDmc = + // findDmcInPath(update.getElementPath(), ISymbolDMContext.class); + + // Get the services we need to use. + + final IExpressions expressionService = getServicesTracker().getService(IExpressions.class); + final IStack stackFrameService = getServicesTracker().getService(IStack.class); + + if (execDmc == null || frameDmc == null || expressionService == null || stackFrameService == null) { + handleFailedUpdate(update); + return; + } + + final DsfExecutor dsfExecutor = getSession().getExecutor(); + + // Call IStack.getLocals() to get an array of IVariableDMContext objects representing the local + // variables in the stack frame represented by frameDmc. + + final DataRequestMonitor rm = + new DataRequestMonitor(dsfExecutor, null) { + @Override + public void handleCompleted() { + if (!getStatus().isOK()) { + handleFailedUpdate(update); + return; + } + + // For each IVariableDMContext object returned by IStack.getLocals(), call + // MIStackFrameService.getModelData() to get the IVariableDMData object. This requires + // a MultiRequestMonitor object. + + // First, get the data model context objects for the local variables. + + IVariableDMContext[] localsDMCs = getData(); + + if (localsDMCs == null) { + handleFailedUpdate(update); + return; + } + + // Create a List in which we store the DM data objects for the local variables. This is + // necessary because there is no MultiDataRequestMonitor. :) + + final List localsDMData = new ArrayList(); + + // Create the MultiRequestMonitor to handle completion of the set of getModelData() calls. + + final MultiRequestMonitor> mrm = + new MultiRequestMonitor>(dsfExecutor, null) { + @Override + public void handleCompleted() { + // Now that all the calls to getModelData() are complete, we create an + // IExpressionDMContext object for each local variable name, saving them all + // in an array. + + IExpressionDMContext[] expressionDMCs = new IExpressionDMContext[localsDMData.size()]; + + int i = 0; + + for (IVariableDMData localDMData : localsDMData) { + expressionDMCs[i++] = expressionService.createExpression(frameDmc, localDMData.getName()); + } + + // Lastly, we fill the update from the array of view model context objects + // that reference the ExpressionDMC objects for the local variables. This is + // the last code to run for a given call to updateElementsInSessionThread(). + // We can now leave anonymous-inner-class hell. + + fillUpdateWithVMCs(update, expressionDMCs); + update.done(); + } + }; + + // Perform a set of getModelData() calls, one for each local variable's data model + // context object. In the handleCompleted() method of the DataRequestMonitor, add the + // IVariableDMData object to the localsDMData List for later processing (see above). + + for (IVariableDMContext localDMC : localsDMCs) { + DataRequestMonitor rm = + new DataRequestMonitor(dsfExecutor, null) { + @Override + public void handleCompleted() { + localsDMData.add(getData()); + mrm.requestMonitorDone(this); + } + }; + + mrm.add(rm); + + stackFrameService.getModelData(localDMC, rm); + } + } + }; + + // Make the asynchronous call to IStack.getLocals(). The results are processed in the + // DataRequestMonitor.handleCompleted() above. + + stackFrameService.getLocals(frameDmc, rm); + } + + @Override + protected int getNodeDeltaFlagsForDMEvent(IDMEvent e) { + if (e instanceof IRunControl.ISuspendedDMEvent) { + return IModelDelta.CONTENT; + // } else if (e instanceof IRegisters.IRegisterChangedDMEvent) { + // return IModelDelta.STATE; + } + return IModelDelta.NO_CHANGE; + } + + @Override + protected void buildDeltaForDMEvent(IDMEvent e, VMDelta parent, + int nodeOffset, RequestMonitor requestMonitor) { + 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 + // DMVMContext(((IRegisters.IRegisterChangedDMEvent)e).getDMContext()), + // IModelDelta.STATE); + // } + super.buildDeltaForDMEvent(e, parent, nodeOffset, requestMonitor); + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableSubExpressionsLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableSubExpressionsLayoutNode.java new file mode 100644 index 00000000000..b5cdf05667b --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableSubExpressionsLayoutNode.java @@ -0,0 +1,297 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel.variable; + +import java.util.Iterator; +import java.util.List; + +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.IDMEvent; +import org.eclipse.dd.dsf.datamodel.IDMService; +import org.eclipse.dd.dsf.debug.service.IExpressions; +import org.eclipse.dd.dsf.debug.service.IFormattedValues; +import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMData; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; +import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; + +@SuppressWarnings("restriction") +public class VariableSubExpressionsLayoutNode extends AbstractDMVMLayoutNode { + + public VariableSubExpressionsLayoutNode(AbstractVMProvider provider, DsfSession session) { + super(provider, session, IExpressions.IExpressionDMContext.class); + } + + /** + * List of child nodes containing only a reference to this. This is what enables the view model + * provider to know about the recursive nature of subexpression nodes. + */ + private final IVMLayoutNode[] fChildLayoutNodes = { this }; + + @Override + public IVMLayoutNode[] getChildLayoutNodes() { + return fChildLayoutNodes; + } + + + /** + * We override this method because we now need to perform an extra level of data fetch to get the + * formatted value of the expression. + * + * @return void + */ + @Override + protected void updateLabelInSessionThread(ILabelUpdate[] updates) { + for (final ILabelUpdate update : updates) { + + final IExpressionDMContext dmc = findDmcInPath(update.getElementPath(), IExpressions.IExpressionDMContext.class); + + ((IDMService)getServicesTracker().getService(null, dmc.getServiceFilter())).getModelData( + dmc, + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + protected void handleCompleted() { + // Check that the request was evaluated and data is still valid. The request could + // fail if the state of the service changed during the request, but the view model + // has not been updated yet. + + if (!getStatus().isOK() || !getData().isValid()) { + assert getStatus().isOK() || + getStatus().getCode() != IDsfService.INTERNAL_ERROR || + getStatus().getCode() != IDsfService.NOT_SUPPORTED; + handleFailedUpdate(update); + return; + } + + // If columns are configured, extract the selected values for each understood column. + // First, we fill all of those columns which can be filled without extra data mining. + // We also note if we do have to do extra data mining. Any columns need to set the + // processing flag so we know we have further work to do. If there are more columns + // which need data extraction they need to be added in both "for" loops. + + String[] localColumns = update.getPresentationContext().getColumns(); + if (localColumns == null) + localColumns = new String[] { null }; + + boolean weAreExtractingFormattedData = false; + + for (int idx = 0; idx < localColumns.length; idx++) { + if (IDebugVMConstants.COLUMN_ID__NAME.equals(localColumns[idx])) { + update.setLabel(getData().getName(), idx); + } else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(localColumns[idx])) { + weAreExtractingFormattedData = true; + } else if (IDebugVMConstants.COLUMN_ID__DESCRIPTION.equals(localColumns[idx])) { + update.setLabel("", idx); //$NON-NLS-1$ + } + } + + if ( ! weAreExtractingFormattedData ) { + update.done(); + } else { + for (int idx = 0; idx < localColumns.length; idx++) { + if (IDebugVMConstants.COLUMN_ID__VALUE.equals(localColumns[idx])) { + updateFormattedExpressionValue(update, idx, dmc); + } + } + } + } + } + ); + } + } + + + /** + * Private data access routine which performs the extra level of data access needed to + * get the formatted data value for a specific register. + */ + private void updateFormattedExpressionValue(final ILabelUpdate update, final int labelIndex, + final IExpressionDMContext dmc) + { + final IExpressions expressionService = getServicesTracker().getService(IExpressions.class); + /* + * PREFPAGE : We are using a default format until the preference page is created + * + * First select the format to be used. This involves checking so see that the preference + * page format is supported by the register service. If the format is not supported then + * we will pick the first available format. + */ + + final String preferencePageFormatId = IFormattedValues.NATURAL_FORMAT; + + expressionService.getAvailableFormattedValues( + dmc, + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + public void handleCompleted() { + if (!getStatus().isOK()) { + handleFailedUpdate(update); + return; + } + + /* + * See if the desired format is supported. + */ + String[] formatIds = getData(); + String finalFormatId = IFormattedValues.NATURAL_FORMAT; + boolean requestedFormatIsSupported = false; + + for ( String fId : formatIds ) { + if ( preferencePageFormatId.equals(fId) ) { + // The desired format is supported. + + finalFormatId = preferencePageFormatId; + requestedFormatIsSupported = true; + break; + } + } + + if ( ! requestedFormatIsSupported ) { + /* + * Desired format is not supported. If there are any formats supported + * then use the first available. + */ + if ( formatIds.length != 0 ) { + finalFormatId = formatIds[0]; + } + else { + // Expression service does not support any format. + + handleFailedUpdate(update); + return; + } + } + + /* + * Format has been validated. Get the formatted value. + */ + FormattedValueDMContext valueDmc = expressionService.getFormattedValue(dmc, finalFormatId); + + expressionService.getModelData( + valueDmc, + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + public void handleCompleted() { + if (!getStatus().isOK()) { + handleFailedUpdate(update); + return; + } + + /* + * Fill the label/column with the properly formatted data value. + */ + update.setLabel(getData().getFormattedValue(), labelIndex); + update.done(); + } + } + ); + } + } + ); + } + + + @Override + protected void updateElementsInSessionThread(final IChildrenUpdate update) { + // Get the data model context object for the current node in the hierarchy. + + final IExpressionDMContext expressionDMC = findDmcInPath(update.getElementPath(), IExpressionDMContext.class); + + // ISSUE: Do we need to explicitly get the IExecutionDMContext and ISymbolDMContext since they + // should be in the parent chain of the IFrameDMContext object? + + final IExecutionDMContext execDmc = findDmcInPath(update.getElementPath(), IExecutionDMContext.class); + final IFrameDMContext frameDmc = findDmcInPath(update.getElementPath(), IFrameDMContext.class); + //final ISymbolDMContext symbolDmc = findDmcInPath(update.getElementPath(), ISymbolDMContext.class); + + // Get the services we need to use. + + final IExpressions expressionService = getServicesTracker().getService(IExpressions.class); + + if (execDmc == null || frameDmc == null || expressionService == null) { + handleFailedUpdate(update); + return; + } + + final DsfExecutor dsfExecutor = getSession().getExecutor(); + + // Call IExpressions.getSubExpressions() to get an Iterable of IExpressionDMContext objects representing + // the sub-expressions of the expression represented by the current expression node. + + final DataRequestMonitor> rm = + new DataRequestMonitor>(dsfExecutor, null) { + @Override + public void handleCompleted() { + if (!getStatus().isOK()) { + handleFailedUpdate(update); + return; + } + + // Fill the update with the the IExpressionDMContext objects returned by + // IExpressions.getSubExpressions(). + + List subExpressionDMCList = (List)getData(); + IExpressionDMContext[] subExpressionDMCArray = new IExpressionDMContext[subExpressionDMCList.size()]; + Iterator iter = subExpressionDMCList.iterator(); + + int i = 0; + while (iter.hasNext()) { + subExpressionDMCArray[i++] = iter.next(); + } + + fillUpdateWithVMCs(update, subExpressionDMCArray); + update.done(); + } + }; + + // Make the asynchronous call to IExpressions.getSubExpressions(). The results are processed in the + // DataRequestMonitor.handleCompleted() above. + + expressionService.getSubExpressions(expressionDMC, rm); + } + + @Override + protected int getNodeDeltaFlagsForDMEvent(IDMEvent e) { + if (e instanceof IRunControl.ISuspendedDMEvent) { + return IModelDelta.CONTENT; +// } else if (e instanceof IRegisters.IExpressionsChangedDMEvent) { +// return IModelDelta.STATE; + } + return IModelDelta.NO_CHANGE; + } + + @Override + protected void buildDeltaForDMEvent(IDMEvent e, VMDelta parent, int nodeOffset, RequestMonitor requestMonitor) { + 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 DMVMContext(((IRegisters.IRegisterChangedDMEvent)e).getDMContext()), IModelDelta.STATE ); +// } + super.buildDeltaForDMEvent(e, parent, nodeOffset, requestMonitor); + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java index 559ee8ba034..9b0ed88eeb4 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java @@ -1,13 +1,11 @@ -/******************************************************************************* - * 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 +/** + * 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 - *******************************************************************************/ + * Contributors: Wind River Systems - initial API and implementation + */ package org.eclipse.dd.dsf.debug.ui.viewmodel.variable; import org.eclipse.dd.dsf.debug.ui.viewmodel.DebugViewSelectionRootLayoutNode; @@ -17,19 +15,37 @@ import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; -/** - * - */ @SuppressWarnings("restriction") -public class VariableVMProvider extends AbstractDMVMProvider { - public VariableVMProvider(AbstractVMAdapter adapter, IPresentationContext context, DsfSession session) { +public class VariableVMProvider extends AbstractDMVMProvider implements + IColumnPresentationFactory { + + public VariableVMProvider(AbstractVMAdapter adapter, IPresentationContext context, DsfSession session) { super(adapter, context, session); - IVMRootLayoutNode debugViewSelectionNode = new DebugViewSelectionRootLayoutNode(this); - IVMLayoutNode localsNode = new LocalsLayoutNode(this, getSession()); - debugViewSelectionNode.setChildNodes(new IVMLayoutNode[] { localsNode }); - setRootLayoutNode(debugViewSelectionNode); + + /* + * Create the top level node to deal with the root selection. + */ + IVMRootLayoutNode debugViewSelection = new DebugViewSelectionRootLayoutNode(this); + + /* + * Create the local variables nodes next. They represent the first level shown in the view. + */ + IVMLayoutNode localsNode = new VariableLocalsLayoutNode(this, getSession()); + debugViewSelection.setChildNodes(new IVMLayoutNode[] { localsNode }); + + /* + * Create the next level which represents members of structs/unions/enums and elements of arrays. + */ + IVMLayoutNode subExpressioNode = new VariableSubExpressionsLayoutNode(this, getSession()); + localsNode.setChildNodes(new IVMLayoutNode[] { subExpressioNode }); + + /* + * Now set this schema set as the layout set. + */ + setRootLayoutNode(debugViewSelection); } @Override From eb61b458b146499d93fd78cc18a2f6001da1ae80 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 11 May 2007 19:07:18 +0000 Subject: [PATCH 084/834] Cleanup ahead of M7: (bugs 185874, 185876, 186267). --- .../META-INF/MANIFEST.MF | 3 +- .../register/RegisterGroupLayoutNode.java | 2 +- .../variable/VariableLocalsLayoutNode.java | 6 +- .../VariableSubExpressionsLayoutNode.java | 2 + .../dd/dsf/debug/service/IAddress.java | 20 ------ .../dd/dsf/debug/service/IBreakpoints.java | 9 ++- .../dd/dsf/debug/service/IExpressions.java | 62 ++++--------------- .../eclipse/dd/dsf/debug/service/IMemory.java | 23 ++----- .../dd/dsf/debug/service/IModules.java | 8 +-- .../dsf/debug/service/INativeProcesses.java | 16 ++--- .../org/eclipse/dd/dsf/debug/service/IOS.java | 7 +-- .../dd/dsf/debug/service/IRegisters.java | 30 ++++----- .../dd/dsf/debug/service/IRunControl.java | 20 +++--- .../dd/dsf/debug/service/ISourceLookup.java | 15 ++--- .../eclipse/dd/dsf/debug/service/IStack.java | 12 ++-- .../dsf/debug/service/IStepQueueManager.java | 13 ++-- 16 files changed, 83 insertions(+), 165 deletions(-) delete mode 100644 plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IAddress.java diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF index 015e3211a95..682b83b2ecd 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF @@ -14,7 +14,8 @@ Require-Bundle: org.eclipse.ui, org.eclipse.ui.ide, org.eclipse.dd.dsf, org.eclipse.dd.dsf.ui, - org.eclipse.dd.dsf.debug + org.eclipse.dd.dsf.debug, + org.eclipse.cdt.core Eclipse-LazyStart: true Export-Package: org.eclipse.dd.dsf.debug.ui, diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java index 5ae69def30d..c74619750e2 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java @@ -158,7 +158,7 @@ public class RegisterGroupLayoutNode extends AbstractExpressionLayoutNode(getSession().getExecutor(), null) { @Override public void handleCompleted() { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLocalsLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLocalsLayoutNode.java index 8e26c2754f8..6fc3aa05055 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLocalsLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLocalsLayoutNode.java @@ -40,7 +40,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; -@SuppressWarnings("restriction") +@SuppressWarnings({"restriction", "nls"}) public class VariableLocalsLayoutNode extends AbstractDMVMLayoutNode { public VariableLocalsLayoutNode(AbstractVMProvider provider, DsfSession session) { @@ -91,10 +91,12 @@ public class VariableLocalsLayoutNode extends AbstractDMVMLayoutNode rm); - public void getBreakpoints(IExecutionDMContext execDmc, IBreakpoint platformBp, DataRequestMonitor rm); + public void getAllBreakpoints(IDMContext execDmc, DataRequestMonitor rm); + public void getBreakpoints(IDMContext execDmc, IBreakpoint platformBp, DataRequestMonitor rm); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java index ec01bf9e7d1..6b76e046870 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java @@ -14,6 +14,7 @@ import java.util.Map; import org.eclipse.cdt.core.IAddress; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +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; @@ -23,6 +24,7 @@ import org.eclipse.dd.dsf.datamodel.IDMService; * dependencies on the Modules service, RunControl service, and Stack service, as all may be used to * provide context for an expression to be evaluated. */ +@SuppressWarnings("nls") public interface IExpressions extends IDMService, IFormattedValues { /** @@ -40,12 +42,12 @@ public interface IExpressions extends IDMService, IFormattedValues { // These static fields define the possible return values of method getTypeId(). QUESTION: Why can't // these have type int? - final static String TYPEID_UNKNOWN = "TYPEID_UNKNOWN"; //$NON-NLS-1$ - final static String TYPEID_INTEGER = "TYPEID_INTEGER"; //$NON-NLS-1$ - final static String TYPEID_CHAR = "TYPEID_CHAR"; //$NON-NLS-1$ - final static String TYPEID_FLOAT = "TYPEID_FLOAT"; //$NON-NLS-1$ - final static String TYPEID_DOUBLE = "TYPEID_DOUBLE"; //$NON-NLS-1$ - final static String TYPEID_OPAQUE = "TYPEID_OPAQUE"; //$NON-NLS-1$ + final static String TYPEID_UNKNOWN = "TYPEID_UNKNOWN"; + final static String TYPEID_INTEGER = "TYPEID_INTEGER"; + final static String TYPEID_CHAR = "TYPEID_CHAR"; + final static String TYPEID_FLOAT = "TYPEID_FLOAT"; + final static String TYPEID_DOUBLE = "TYPEID_DOUBLE"; + final static String TYPEID_OPAQUE = "TYPEID_OPAQUE"; /** * This enumerates the possible basic types that an expression can have. @@ -98,14 +100,6 @@ public interface IExpressions extends IDMService, IFormattedValues { */ int getBitCount(); - /** - * @return A string containing the value of the expression in a format that is natural for its type. - * For example, type "char" is shown as a single-quoted character, type "int" (and its cousins) - * is shown in decimal, type "unsigned int" (and its cousins) and pointers are shown in hex, - * floating point values are shown in non-scientific notation. - */ - String getNaturalValue(); - /** * @return A string containing the value of the expression as returned by the debugger backend. */ @@ -140,48 +134,18 @@ public interface IExpressions extends IDMService, IFormattedValues { interface IExpressionChangedDMEvent extends IDMEvent {} /** - * Returns the data model context object for the specified expression in the context of the symbols - * specified by symbolsDmc. + * Returns the data model context object for the specified expression in the context of + * specified by ctx. * - * @param symbolsDmc: Symbol context in which to evaluate the expression. This parameter can be null if - * there is no symbol context available. + * @param symbolsDmc: Context in which to evaluate the expression. This context could include the + * PC location, stack frame, thread, or just a symbol context. * * @param expression: The expression to evaluate. * * @return An expression data model context object that must be passed to getModelData() to obtain the * value of the expression. */ - IExpressionDMContext createExpression(IModules.ISymbolDMContext symbolsDmc, String expression); - - /** - * Returns the data model context object for the specified expression in the context of the thread - * specified by execDmc. - * - * @param execDmc: Optional execution context for the evaluation. This parameter cannot be null. If - * there is no execution context available, the client should instead call - * createExpression(ISymbolDMContext, String). - * - * @param expression: The expression to evaluate. - * - * @return An expression data model context object that must be passed to getModelData() to obtain the - * value of the expression. - */ - IExpressionDMContext createExpression(IRunControl.IExecutionDMContext execDmc, String expression); - - /** - * Returns the data model context object for the specified expression in the context of the stack frame - * specified by frameDmc. - * - * @param frameDmc: Optional stack frame context for the evaluation. This parameter cannot be null. If - * there is no stack frame context available, the client should instead call - * createExpression(ISymbolDMContext, String) or createExpression(IExecutionDMContext, String). - * - * @param expression: The expression to evaluate. - * - * @return An expression data model context object that must be passed to getModelData() to obtain the - * value of the expression. - */ - IExpressionDMContext createExpression(IStack.IFrameDMContext frameDmc, String expression); + IExpressionDMContext createExpression(IDMContext ctx, String expression); /** * Retrieves the sub-expressions of the given expression. Sub-expressions are fields of a struct, union, diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java index 936df52ee78..df3ccbcbb4b 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java @@ -10,7 +10,9 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.service; +import org.eclipse.cdt.core.IAddress; import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.service.IDsfService; /** @@ -20,27 +22,12 @@ import org.eclipse.dd.dsf.service.IDsfService; */ public interface IMemory extends IDsfService { - /** - * A context for memory is still needed, for debuggers that can debug - * multiple processes/targets at the same time. - */ - public interface IMemoryContext {} - - /** - * I was told that BigInteger is also too restrictive to represent an - * address, but I'm not really sure what is appropriate for this interface. - */ - public interface IAddress { - /** Returns the memory context that this address belongs to. */ - public IMemoryContext getContext(); - } - /** Writes the given value to the given memory location. */ - public void setMemory(IMemoryContext memCtx, IAddress addr, + public void setMemory(IDMContext ctx, IAddress addr, int word_size, byte[] buf, int offs, int size, int mode, RequestMonitor requestMonitor); /** Reads memory at the given location */ - public void getMemory(IMemoryContext memCtx, IAddress addr, + public void getMemory(IDMContext ctx, IAddress addr, int word_size, byte[] buf, int offs, int size, int mode, RequestMonitor requestMonitor); /** @@ -49,7 +36,7 @@ public interface IMemory extends IDsfService { * Parameter 0 of sequent 'done' is assigned with Throwable if * there was an error. */ - public void fillMemory(IMemoryContext memCtx, IAddress addr, + public void fillMemory(IDMContext ctx, IAddress addr, int word_size, byte[] value, int size, int mode, RequestMonitor requestMonitor); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java index 1885eafcfac..6625ffcf9d2 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java @@ -12,12 +12,12 @@ package org.eclipse.dd.dsf.debug.service; import java.math.BigInteger; +import org.eclipse.cdt.core.IAddress; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; 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. @@ -134,16 +134,16 @@ public interface IModules extends IDMService { /** * Retreives the list of modules loaded in given symbol context. */ - void getModules(ISymbolDMContext symCtx, DataRequestMonitor rm); + void getModules(IDMContext symCtx, DataRequestMonitor rm); /** * Calculates the line numbers corresponding to the given address. */ - void calcLineInfo(ISymbolDMContext symCtx, IAddress address, DataRequestMonitor rm); + void calcLineInfo(IDMContext symCtx, IAddress address, DataRequestMonitor rm); /** * Calculates the addresses corresponding to the given source file location. */ - void calcAddressInfo(ISymbolDMContext symCtx, String file, int line, int col, DataRequestMonitor rm); + void calcAddressInfo(IDMContext symCtx, String file, int line, int col, DataRequestMonitor rm); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/INativeProcesses.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/INativeProcesses.java index 8dcb2349e21..7f7c5a52ee4 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/INativeProcesses.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/INativeProcesses.java @@ -10,12 +10,13 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.service; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMData; import org.eclipse.dd.dsf.datamodel.IDMEvent; import org.eclipse.dd.dsf.datamodel.IDMService; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; /** * This interface provides access to the native OS's process @@ -38,9 +39,7 @@ public interface INativeProcesses extends IDMService { String getName(); String getId(); boolean isDebuggerAttached(); - IRunControl.IExecutionDMContext getExecutionContext(); - IMemory.IMemoryContext getMemoryContext(); - IModules.ISymbolDMContext getSymbolContext(); + IDMContext getDebuggingContext(); } /** @@ -48,6 +47,8 @@ public interface INativeProcesses extends IDMService { */ public interface ProcessChangedDMEvent extends IDMEvent {} + public IThreadDMContext getThreadForExecutionContext(IExecutionDMContext execCtx); + /** * Retrieves the current list of processes running on target. * @param rm Request completion monitor, to be filled in with array of process contexts. @@ -80,13 +81,6 @@ public interface INativeProcesses extends IDMService { */ void getProcessesBeingDebugged(DataRequestMonitor rm); - /** - * Returns a thread context for given run control execution context. - * @param execCtx Execution context to return thread for. - * @return Corresponding thread context. - */ - IThreadDMContext getThreadForExecutionContext(IRunControl.IExecutionDMContext execCtx); - /** * Checks whether the given process or thread can be terminated. * @param thread Thread or process to terminate. diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IOS.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IOS.java index 9c3150597bb..165719a2ebd 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IOS.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IOS.java @@ -54,9 +54,6 @@ public interface IOS extends IDMService { String getDescription(); String getSingularName(); String getPluralName(); - boolean hasExecutionContext(); - boolean hasModulesContext(); - boolean hasMemoryContext(); } /** @@ -72,9 +69,7 @@ public interface IOS extends IDMService { String getID(); boolean canAttachDebugger(); boolean isDebuggerAttached(); - IRunControl.IExecutionDMContext getExecutionDMC(); - IModules.ISymbolDMContext getSymbolDMC(); - IMemory.IMemoryContext getMemoryContext(); + IDMContext getDebuggingContext(); } /** diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java index 7725b253332..5993ac7842e 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java @@ -12,6 +12,7 @@ package org.eclipse.dd.dsf.debug.service; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMData; import org.eclipse.dd.dsf.datamodel.IDMEvent; @@ -96,56 +97,55 @@ public interface IRegisters extends IFormattedValues { /** * Retrieves the list of register groups. - * @param execCtx Execution DMC, this is required. - * @param frameCtx Stack frame DMC, this is optional and may be null. + * @param ctx Context for the returned data. * @param rm Request completion monitor. */ - void getRegisterGroups(IRunControl.IExecutionDMContext execCtx, IStack.IFrameDMContext frameCtx, DataRequestMonitor rm); + void getRegisterGroups(IDMContext ctx, DataRequestMonitor rm); /** * Retrieves list of sub-groups of given register group. - * @param groupCtx Group DMC, this is required. + * @param ctx Context for the returned data. * @param rm Request completion monitor. */ - void getRegisterSubGroups(IRegisterGroupDMContext groupCtx, DataRequestMonitor rm); + void getRegisterSubGroups(IDMContext ctx, DataRequestMonitor rm); /** * Retrieves registers in given register group. - * @param groupCtx Group DMC, this is required. + * @param ctx Context for the returned data. * @param rm Request completion monitor. */ - void getRegisters(IRegisterGroupDMContext groupCtx, DataRequestMonitor rm); + void getRegisters(IDMContext ctx, DataRequestMonitor rm); /** * Retrieves bit fields for given register - * @param regCtx Register DMC, this is required. + * @param ctx Context for the returned data. * @param rm Request completion monitor. */ - void getBitFields(IRegisterDMContext regCtx, DataRequestMonitor rm); + void getBitFields(IDMContext ctx, DataRequestMonitor rm); /** * Writes a register value for a given register to the target - * @param regCtx Register DMC, this is required. + * @param regCtx Context containing the register. * @param regValue Value of the register to be written. * @param formatId Format of the value to be written. * @param rm Request completion monitor. */ - void writeRegister(IRegisterDMContext regCtx, String regValue, String formatId, RequestMonitor rm); + void writeRegister(IDMContext regCtx, String regValue, String formatId, RequestMonitor rm); /** * Writes a bit field value for a given bit field to the target - * @param bitFieldCtx Bit field DMC, this is required. + * @param bitFieldCtx Context containing the bit field. * @param bitFieldValue Value of the bit field to be written. * @param formatId Format of the value to be written. * @param rm Request completion monitor. */ - void writeBitField(IBitFieldDMContext bitFieldCtx, String bitFieldValue, String formatId, RequestMonitor rm); + void writeBitField(IDMContext bitFieldCtx, String bitFieldValue, String formatId, RequestMonitor rm); /** * Writes a bit field value for a given bit field to the target - * @param bitFieldCtx Bit field DMC, this is required. + * @param bitFieldCtx Context containing the bit field. * @param mnemonic Mnemonic which represents the value to be written. * @param rm Request completion monitor. */ - void writeBitField(IBitFieldDMContext bitFieldCtx, IMnemonic mnemonic, RequestMonitor rm); + void writeBitField(IDMContext bitFieldCtx, IMnemonic mnemonic, RequestMonitor rm); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java index 0d89a134f10..4d23e119a8c 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java @@ -92,15 +92,15 @@ public interface IRunControl extends IDMService * Run control commands. They all require the IExecutionContext object on * which they perform the operations. */ - boolean canResume(IExecutionDMContext context); - boolean canSuspend(IExecutionDMContext context); - boolean isSuspended(IExecutionDMContext context); - void resume(IExecutionDMContext context, RequestMonitor requestMonitor); - void suspend(IExecutionDMContext context, RequestMonitor requestMonitor); + boolean canResume(IDMContext context); + boolean canSuspend(IDMContext context); + boolean isSuspended(IDMContext context); + void resume(IDMContext context, RequestMonitor requestMonitor); + void suspend(IDMContext context, RequestMonitor requestMonitor); public enum StepType { STEP_OVER, STEP_INTO, STEP_RETURN }; - boolean isStepping(IExecutionDMContext context); - boolean canStep(IExecutionDMContext context); - void step(IExecutionDMContext context, StepType stepType, RequestMonitor requestMonitor); - boolean canInstructionStep(IExecutionDMContext context); - void instructionStep(IExecutionDMContext context, StepType stepType, RequestMonitor requestMonitor); + boolean isStepping(IDMContext context); + boolean canStep(IDMContext context); + void step(IDMContext context, StepType stepType, RequestMonitor requestMonitor); + boolean canInstructionStep(IDMContext context); + void instructionStep(IDMContext context, StepType stepType, RequestMonitor requestMonitor); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISourceLookup.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISourceLookup.java index de58864f456..9f48bd058c3 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISourceLookup.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISourceLookup.java @@ -11,6 +11,7 @@ package org.eclipse.dd.dsf.debug.service; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.debug.core.sourcelookup.ISourceContainer; @@ -22,11 +23,6 @@ import org.eclipse.debug.core.sourcelookup.ISourceContainer; */ public interface ISourceLookup extends IDsfService { - /** - * Context needed for debuggers that debug multiple processes. - */ - public interface ISourceLookupContext {} - public interface ISourceLookupResult { Object getSourceObject(); ISourceContainer getMatchingContainer(); @@ -37,22 +33,19 @@ public interface ISourceLookup extends IDsfService { ISourceContainer getMatchingContainer(); } - /** Returns the source lookup context for the given modules context. */ - ISourceLookupContext getContextForSymbolContext(IModules.ISymbolDMContext symCtx); - /** * Initializes the given context with the given list of source lookup * containers. */ - void initializeSourceContainers(ISourceLookupContext ctx, ISourceContainer[] containers); + void initializeSourceContainers(IDMContext ctx, ISourceContainer[] containers); /** * Retrieves the host source object for given debugger path string. */ - void getSource(ISourceLookupContext srcCtx, String debuggerPath, boolean searchDuplicates, DataRequestMonitor rm); + void getSource(IDMContext ctx, String debuggerPath, boolean searchDuplicates, DataRequestMonitor rm); /** * Retrieves the debugger path string(s) for given host source object. */ - void getDebuggerPath(ISourceLookupContext srcCtx, Object source, boolean searchDuplicates, DataRequestMonitor rm); + void getDebuggerPath(IDMContext ctx, Object source, boolean searchDuplicates, DataRequestMonitor rm); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java index e938f165046..a0c2364f036 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java @@ -10,11 +10,11 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.service; +import org.eclipse.cdt.core.IAddress; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; 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 @@ -59,13 +59,13 @@ public interface IStack extends IDMService { /** * Returns whether the stack frames can be retrieved for given thread. */ - boolean isStackAvailable(IRunControl.IExecutionDMContext execContext); + boolean isStackAvailable(IDMContext 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.IExecutionDMContext execContext, DataRequestMonitor rm); + void getFrames(IDMContext execContext, DataRequestMonitor rm); /** * Retrieves the top stack frame for the given execution context. @@ -76,15 +76,15 @@ public interface IStack extends IDMService { * @param execContext * @param rm */ - void getTopFrame(IRunControl.IExecutionDMContext execContext, DataRequestMonitor rm); + void getTopFrame(IDMContext execContext, DataRequestMonitor rm); /** * Retrieves variables which were arguments to the stack frame's function. */ - void getArguments(IFrameDMContext frameCtx, DataRequestMonitor rm); + void getArguments(IDMContext frameCtx, DataRequestMonitor rm); /** * Retrieves variables local to the stack frame. */ - void getLocals(IFrameDMContext frameCtx, DataRequestMonitor rm); + void getLocals(IDMContext frameCtx, DataRequestMonitor rm); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStepQueueManager.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStepQueueManager.java index 45d3cb45d08..a37a143b328 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStepQueueManager.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStepQueueManager.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.service; +import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMEvent; import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; import org.eclipse.dd.dsf.service.IDsfService; @@ -45,21 +46,21 @@ public interface IStepQueueManager extends IDsfService { * Returns the number of step commands that are queued for given execution * context. */ - int getPendingStepCount(IRunControl.IExecutionDMContext execCtx); + int getPendingStepCount(IDMContext ctx); /** * Checks whether a step command can be queued up for given context. */ - boolean canEnqueueStep(IRunControl.IExecutionDMContext execCtx); + boolean canEnqueueStep(IDMContext execCtx); - boolean canEnqueueInstructionStep(IRunControl.IExecutionDMContext execCtx); + boolean canEnqueueInstructionStep(IDMContext ctx); /** * 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.IExecutionDMContext execCtx, IRunControl.StepType stepType); + void enqueueStep(IDMContext ctx, IRunControl.StepType stepType); /** * Adds an instruction step command to the execution queue for given @@ -67,7 +68,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.IExecutionDMContext execCtx, IRunControl.StepType stepType); + void enqueueInstructionStep(IDMContext ctx, IRunControl.StepType stepType); - boolean isSteppingTimedOut(IExecutionDMContext context); + boolean isSteppingTimedOut(IDMContext context); } From 90fc9e59f0dde1b1151d4adb667c47ea0475bda0 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 11 May 2007 21:01:06 +0000 Subject: [PATCH 085/834] Split the MI plugins to create dedicated GDB plugins (bug 185876). --- .../org.eclipse.dd.dsf.gdb-feature/feature.xml | 6 +++--- .../org.eclipse.dd.dsf.sdk-feature/feature.xml | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/features/org.eclipse.dd.dsf.gdb-feature/feature.xml b/features/org.eclipse.dd.dsf.gdb-feature/feature.xml index 11eaf9477c5..08cd1918017 100644 --- a/features/org.eclipse.dd.dsf.gdb-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.gdb-feature/feature.xml @@ -1,6 +1,6 @@ @@ -125,14 +125,14 @@ Java and all Java-based trademarks are trademarks of Sun Microsystem + + + + From 1b5793e2e0c8eb59a303a35ae0d65f28b164d350 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 18 May 2007 16:03:51 +0000 Subject: [PATCH 086/834] Added a check for failed getModelData() retrieval. --- .../ui/viewmodel/variable/VariableLocalsLayoutNode.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLocalsLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLocalsLayoutNode.java index 6fc3aa05055..815b71281d9 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLocalsLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLocalsLayoutNode.java @@ -270,7 +270,12 @@ public class VariableLocalsLayoutNode extends AbstractDMVMLayoutNode Date: Fri, 18 May 2007 17:53:09 +0000 Subject: [PATCH 087/834] Set default warning level for all DSF projects (bug 187687). --- .../.settings/org.eclipse.jdt.core.prefs | 55 ++++++++++++++++++- .../.settings/org.eclipse.jdt.core.prefs | 55 ++++++++++++++++++- .../.settings/org.eclipse.jdt.core.prefs | 55 ++++++++++++++++++- .../org.eclipse.dd.dsf.ui/build.properties | 3 +- .../.settings/org.eclipse.jdt.core.prefs | 55 ++++++++++++++++++- 5 files changed, 218 insertions(+), 5 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.dd.dsf.debug.ui/.settings/org.eclipse.jdt.core.prefs index 9091eab0ee6..e5a50196ba4 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.eclipse.dd.dsf.debug.ui/.settings/org.eclipse.jdt.core.prefs @@ -1,4 +1,4 @@ -#Wed Nov 01 13:23:23 PST 2006 +#Fri May 18 08:59:36 PDT 2007 eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 @@ -7,6 +7,59 @@ 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.annotationSuperInterface=warning org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=warning +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning +org.eclipse.jdt.core.compiler.problem.nullReference=ignore +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning +org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=error +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=warning +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning org.eclipse.jdt.core.compiler.source=1.5 diff --git a/plugins/org.eclipse.dd.dsf.debug/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.dd.dsf.debug/.settings/org.eclipse.jdt.core.prefs index 93a2ad59b5e..6468150f58d 100644 --- a/plugins/org.eclipse.dd.dsf.debug/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.eclipse.dd.dsf.debug/.settings/org.eclipse.jdt.core.prefs @@ -1,4 +1,4 @@ -#Thu Jul 27 15:22:22 PDT 2006 +#Fri May 18 08:59:30 PDT 2007 eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 @@ -7,6 +7,59 @@ 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.annotationSuperInterface=warning org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=warning +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning +org.eclipse.jdt.core.compiler.problem.nullReference=ignore +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning +org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=error +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=warning +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning org.eclipse.jdt.core.compiler.source=1.5 diff --git a/plugins/org.eclipse.dd.dsf.ui/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.dd.dsf.ui/.settings/org.eclipse.jdt.core.prefs index 5e43d7eeaec..f52190daad7 100644 --- a/plugins/org.eclipse.dd.dsf.ui/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.eclipse.dd.dsf.ui/.settings/org.eclipse.jdt.core.prefs @@ -1,4 +1,4 @@ -#Thu Jul 27 15:22:36 PDT 2006 +#Fri May 18 09:01:11 PDT 2007 eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 @@ -7,6 +7,59 @@ 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.annotationSuperInterface=warning org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=warning +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning +org.eclipse.jdt.core.compiler.problem.nullReference=ignore +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning +org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=error +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=warning +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning org.eclipse.jdt.core.compiler.source=1.5 diff --git a/plugins/org.eclipse.dd.dsf.ui/build.properties b/plugins/org.eclipse.dd.dsf.ui/build.properties index 34d2e4d2dad..e9863e281ea 100644 --- a/plugins/org.eclipse.dd.dsf.ui/build.properties +++ b/plugins/org.eclipse.dd.dsf.ui/build.properties @@ -1,4 +1,5 @@ source.. = src/ output.. = bin/ bin.includes = META-INF/,\ - . + .,\ + plugin.xml diff --git a/plugins/org.eclipse.dd.dsf/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.dd.dsf/.settings/org.eclipse.jdt.core.prefs index 93a2ad59b5e..217edbcea2a 100644 --- a/plugins/org.eclipse.dd.dsf/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.eclipse.dd.dsf/.settings/org.eclipse.jdt.core.prefs @@ -1,4 +1,4 @@ -#Thu Jul 27 15:22:22 PDT 2006 +#Fri May 18 08:59:24 PDT 2007 eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 @@ -7,6 +7,59 @@ 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.annotationSuperInterface=warning org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=warning +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning +org.eclipse.jdt.core.compiler.problem.nullReference=ignore +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning +org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=error +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=warning +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning org.eclipse.jdt.core.compiler.source=1.5 From 782c31afe02d08edb8d1951d0166b9aa5f8f0916 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 29 May 2007 17:55:21 +0000 Subject: [PATCH 088/834] Fixed typo in column ID. --- .../ui/viewmodel/expression/ExpressionColumnPresentation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionColumnPresentation.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionColumnPresentation.java index b2945554a57..87ea315c615 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionColumnPresentation.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionColumnPresentation.java @@ -22,7 +22,7 @@ import org.eclipse.jface.resource.ImageDescriptor; @SuppressWarnings("restriction") public class ExpressionColumnPresentation implements IColumnPresentation { - public static final String ID = DsfDebugUIPlugin.PLUGIN_ID + ".REGISTERS_COLUMN_PRESENTATION_ID"; //$NON-NLS-1$ + public static final String ID = DsfDebugUIPlugin.PLUGIN_ID + ".EXPRESSION_COLUMN_PRESENTATION_ID"; //$NON-NLS-1$ public void init(IPresentationContext context) { } From 73f707787140c742195ba741f231f7354e941e1c Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Wed, 30 May 2007 02:06:59 +0000 Subject: [PATCH 089/834] fixes for 189542 --- .project | 11 ++ .../build.properties | 4 +- .../feature.properties | 126 ++++++++++++++++++ .../feature.xml | 60 +-------- .../license.html | 79 +++++++++++ .../build.properties | 4 +- .../feature.properties | 126 ++++++++++++++++++ .../feature.xml | 104 +-------------- .../license.html | 79 +++++++++++ .../build.properties | 4 +- .../feature.properties | 126 ++++++++++++++++++ .../feature.xml | 101 +------------- .../license.html | 79 +++++++++++ .../build.properties | 4 +- .../feature.properties | 126 ++++++++++++++++++ .../feature.xml | 60 +-------- .../license.html | 79 +++++++++++ .../org.eclipse.dd.dsf.debug.ui/about.html | 24 ++++ .../build.properties | 1 + plugins/org.eclipse.dd.dsf.debug/about.html | 24 ++++ .../org.eclipse.dd.dsf.debug/build.properties | 3 +- plugins/org.eclipse.dd.dsf.ui/about.html | 24 ++++ .../org.eclipse.dd.dsf.ui/build.properties | 3 +- plugins/org.eclipse.dd.dsf/about.html | 24 ++++ plugins/org.eclipse.dd.dsf/build.properties | 3 +- 25 files changed, 962 insertions(+), 316 deletions(-) create mode 100644 .project create mode 100644 features/org.eclipse.dd.dsf.examples-feature/feature.properties create mode 100644 features/org.eclipse.dd.dsf.examples-feature/license.html create mode 100644 features/org.eclipse.dd.dsf.gdb-feature/feature.properties create mode 100644 features/org.eclipse.dd.dsf.gdb-feature/license.html create mode 100644 features/org.eclipse.dd.dsf.sdk-feature/feature.properties create mode 100644 features/org.eclipse.dd.dsf.sdk-feature/license.html create mode 100644 features/org.eclipse.dd.dsf.test-feature/feature.properties create mode 100644 features/org.eclipse.dd.dsf.test-feature/license.html create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/about.html create mode 100644 plugins/org.eclipse.dd.dsf.debug/about.html create mode 100644 plugins/org.eclipse.dd.dsf.ui/about.html create mode 100644 plugins/org.eclipse.dd.dsf/about.html diff --git a/.project b/.project new file mode 100644 index 00000000000..dc3ebe04259 --- /dev/null +++ b/.project @@ -0,0 +1,11 @@ + + + org.eclipse.dd.dsf + + + + + + + + diff --git a/features/org.eclipse.dd.dsf.examples-feature/build.properties b/features/org.eclipse.dd.dsf.examples-feature/build.properties index 64f93a9f0b7..66d3261e69c 100644 --- a/features/org.eclipse.dd.dsf.examples-feature/build.properties +++ b/features/org.eclipse.dd.dsf.examples-feature/build.properties @@ -1 +1,3 @@ -bin.includes = feature.xml +bin.includes = feature.xml,\ + feature.properties,\ + license.html diff --git a/features/org.eclipse.dd.dsf.examples-feature/feature.properties b/features/org.eclipse.dd.dsf.examples-feature/feature.properties new file mode 100644 index 00000000000..fc88e04d681 --- /dev/null +++ b/features/org.eclipse.dd.dsf.examples-feature/feature.properties @@ -0,0 +1,126 @@ +############################################################################### +# Copyright (c) 2006, 2007 Wind River Systems and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Ted Williams (Wind River) - initial API and implementation +############################################################################### + +# "copyright" property - text of the "Feature Update Copyright" +copyright=\ +Copyright (c) 2000, 2007 Wind River Systems and others.\n\ +All rights reserved. This program and the accompanying materials\n\ +are made available under the terms of the Eclipse Public License v1.0\n\ +which accompanies this distribution, and is available at\n\ +http://www.eclipse.org/legal/epl-v10.html\n\ +################ end of copyright property #################################### + +# "licenseURL" property - URL of the "Feature License" +# do not translate value - just change to point to a locale-specific HTML page +licenseURL=license.html + +# "license" property - text of the "Feature Update License" +# should be plain text version of license agreement pointed to be "licenseURL" +license=\ +* Eclipse Public License v1.0 (http://www.eclipse.org/legal/epl-v10.html)\n\ +\n\ +ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\ +March 17, 2005\n\ +\n\ +Usage Of Content\n\ +\n\ +THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\ +OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\ +USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\ +AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\ +NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\ +AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\ +AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\ +OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ +TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\ +OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ +BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\ +\n\ +Applicable Licenses\n\ +\n\ +Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ +is provided to you under the terms and conditions of the Eclipse Public\n\ +License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\ +Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\ +For purposes of the EPL, "Program" will mean the Content.\n\ +\n\ +Content includes, but is not limited to, source code, object code,\n\ +documentation and other files maintained in the Eclipse.org CVS\n\ +repository ("Repository") in CVS modules ("Modules") and made available\n\ +as downloadable archives ("Downloads").\n\ +\n\ + - Content may be structured and packaged into modules to facilitate delivering,\n\ + extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\ + plug-in fragments ("Fragments"), and features ("Features").\n\ + - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\ + in a directory named "plugins".\n\ + - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\ + Each Feature may be packaged as a sub-directory in a directory named "features".\n\ + Within a Feature, files named "feature.xml" may contain a list of the names and version\n\ + numbers of the Plug-ins and/or Fragments associated with that Feature.\n\ + - Features may also include other Features ("Included Features"). Within a Feature, files\n\ + named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\ +\n\ +Features may also include other Features ("Included Features"). Files named\n\ +"feature.xml" may contain a list of the names and version numbers of\n\ +Included Features.\n\ +\n\ +The terms and conditions governing Plug-ins and Fragments should be\n\ +contained in files named "about.html" ("Abouts"). The terms and\n\ +conditions governing Features and Included Features should be contained\n\ +in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\ +Licenses may be located in any directory of a Download or Module\n\ +including, but not limited to the following locations:\n\ +\n\ + - The top-level (root) directory\n\ + - Plug-in and Fragment directories\n\ + - Inside Plug-ins and Fragments packaged as JARs\n\ + - Sub-directories of the directory named "src" of certain Plug-ins\n\ + - Feature directories\n\ +\n\ +Note: if a Feature made available by the Eclipse Foundation is installed using the\n\ +Eclipse Update Manager, you must agree to a license ("Feature Update\n\ +License") during the installation process. If the Feature contains\n\ +Included Features, the Feature Update License should either provide you\n\ +with the terms and conditions governing the Included Features or inform\n\ +you where you can locate them. Feature Update Licenses may be found in\n\ +the "license" property of files named "feature.properties". Such Abouts,\n\ +Feature Licenses and Feature Update Licenses contain the terms and\n\ +conditions (or references to such terms and conditions) that govern your\n\ +use of the associated Content in that directory.\n\ +\n\ +THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\ +TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\ +SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ +\n\ + - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\ + - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\ + - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\ + - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\ + - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\ + - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\ +\n\ +IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\ +TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\ +is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\ +govern that particular Content.\n\ +\n\ +Cryptography\n\ +\n\ +Content may contain encryption software. The country in which you are\n\ +currently may have restrictions on the import, possession, and use,\n\ +and/or re-export to another country, of encryption software. BEFORE\n\ +using any encryption software, please check the country's laws,\n\ +regulations and policies concerning the import, possession, or use,\n\ +and re-export of encryption software, to see if this is permitted.\n\ +\n\ +Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n +########### end of license property ########################################## diff --git a/features/org.eclipse.dd.dsf.examples-feature/feature.xml b/features/org.eclipse.dd.dsf.examples-feature/feature.xml index 413bbdd4a22..9909afd75a9 100644 --- a/features/org.eclipse.dd.dsf.examples-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.examples-feature/feature.xml @@ -12,64 +12,12 @@ Debug Services Framework Examples - - Copyright (c) 2006-2007 Wind River Systems and others. -All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html + + %copyright - - ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT -March 17, 2005 - -Usage Of Content - -THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT. - -Applicable Licenses - -Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is provided with this Content and is also available at http://www.eclipse.org/legal/epl-v10.html. For purposes of the EPL, "Program" will mean the Content. - -Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse.org CVS repository ("Repository") in CVS modules ("Modules") and made available as downloadable archives ("Downloads"). - - - Content may be structured and packaged into modules to facilitate delivering, - extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"), - plug-in fragments ("Fragments"), and features ("Features"). - - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive) - in a directory named "plugins". - - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. - Each Feature may be packaged as a sub-directory in a directory named "features". - Within a Feature, files named "feature.xml" may contain a list of the names and version - numbers of the Plug-ins and/or Fragments associated with that Feature. - - Features may also include other Features ("Included Features"). Within a Feature, files - named "feature.xml" may contain a list of the names and version numbers of Included Features. - -Features may also include other Features ("Included Features"). Files named "feature.xml" may contain a list of the names and version numbers of Included Features. - -The terms and conditions governing Plug-ins and Fragments should be contained in files named "about.html" ("Abouts"). The terms and conditions governing Features and Included Features should be contained in files named "license.html" ("Feature Licenses"). Abouts and Feature -Licenses may be located in any directory of a Download or Module including, but not limited to the following locations: - - - The top-level (root) directory - - Plug-in and Fragment directories - - Inside Plug-ins and Fragments packaged as JARs - - Sub-directories of the directory named "src" of certain Plug-ins - - Feature directories - -Note: if a Feature made available by the Eclipse Foundation is installed using the Eclipse Update Manager, you must agree to a license ("Feature Update License") during the installation process. If the Feature contains Included Features, the Feature Update License should either provide you -with the terms and conditions governing the Included Features or inform you where you can locate them. Feature Update Licenses may be found in the "license" property of files named "feature.properties". Such Abouts, Feature Licenses and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your -use of the associated Content in that directory. - -THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO): - - - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html) - -IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License or Feature Update License is provided, please contact the Eclipse Foundation to determine what terms and conditions govern that particular Content. - -Cryptography - -Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to another country, of encryption software. BEFORE using any encryption software, please check the country's laws, -regulations and policies concerning the import, possession, or use, and re-export of encryption software, to see if this is permitted. - -Java and all Java-based trademarks are trademarks of Sun Microsystem + + %license diff --git a/features/org.eclipse.dd.dsf.examples-feature/license.html b/features/org.eclipse.dd.dsf.examples-feature/license.html new file mode 100644 index 00000000000..c6af966b61e --- /dev/null +++ b/features/org.eclipse.dd.dsf.examples-feature/license.html @@ -0,0 +1,79 @@ + + + + +Eclipse.org Software User Agreement + + + +

    Eclipse Foundation Software User Agreement

    +

    March 17, 2005

    + +

    Usage Of Content

    + +

    THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS + (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND + CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE + OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR + NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND + CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.

    + +

    Applicable Licenses

    + +

    Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0 + ("EPL"). A copy of the EPL is provided with this Content and is also available at http://www.eclipse.org/legal/epl-v10.html. + For purposes of the EPL, "Program" will mean the Content.

    + +

    Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse.org CVS repository ("Repository") in CVS + modules ("Modules") and made available as downloadable archives ("Downloads").

    + +
      +
    • Content may be structured and packaged into modules to facilitate delivering, extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and features ("Features").
    • +
    • Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java™ ARchive) in a directory named "plugins".
    • +
    • A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. Each Feature may be packaged as a sub-directory in a directory named "features". Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of the Plug-ins + and/or Fragments associated with that Feature.
    • +
    • Features may also include other Features ("Included Features"). Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of Included Features.
    • +
    + +

    The terms and conditions governing Plug-ins and Fragments should be contained in files named "about.html" ("Abouts"). The terms and conditions governing Features and +Included Features should be contained in files named "license.html" ("Feature Licenses"). Abouts and Feature Licenses may be located in any directory of a Download or Module +including, but not limited to the following locations:

    + +
      +
    • The top-level (root) directory
    • +
    • Plug-in and Fragment directories
    • +
    • Inside Plug-ins and Fragments packaged as JARs
    • +
    • Sub-directories of the directory named "src" of certain Plug-ins
    • +
    • Feature directories
    • +
    + +

    Note: if a Feature made available by the Eclipse Foundation is installed using the Eclipse Update Manager, you must agree to a license ("Feature Update License") during the +installation process. If the Feature contains Included Features, the Feature Update License should either provide you with the terms and conditions governing the Included Features or +inform you where you can locate them. Feature Update Licenses may be found in the "license" property of files named "feature.properties" found within a Feature. +Such Abouts, Feature Licenses, and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your use of the associated Content in +that directory.

    + +

    THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE +OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):

    + + + +

    IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License, or Feature Update License is provided, please +contact the Eclipse Foundation to determine what terms and conditions govern that particular Content.

    + +

    Cryptography

    + +

    Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to + another country, of encryption software. BEFORE using any encryption software, please check the country's laws, regulations and policies concerning the import, + possession, or use, and re-export of encryption software, to see if this is permitted.

    + +Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both. + + diff --git a/features/org.eclipse.dd.dsf.gdb-feature/build.properties b/features/org.eclipse.dd.dsf.gdb-feature/build.properties index 64f93a9f0b7..66d3261e69c 100644 --- a/features/org.eclipse.dd.dsf.gdb-feature/build.properties +++ b/features/org.eclipse.dd.dsf.gdb-feature/build.properties @@ -1 +1,3 @@ -bin.includes = feature.xml +bin.includes = feature.xml,\ + feature.properties,\ + license.html diff --git a/features/org.eclipse.dd.dsf.gdb-feature/feature.properties b/features/org.eclipse.dd.dsf.gdb-feature/feature.properties new file mode 100644 index 00000000000..fc88e04d681 --- /dev/null +++ b/features/org.eclipse.dd.dsf.gdb-feature/feature.properties @@ -0,0 +1,126 @@ +############################################################################### +# Copyright (c) 2006, 2007 Wind River Systems and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Ted Williams (Wind River) - initial API and implementation +############################################################################### + +# "copyright" property - text of the "Feature Update Copyright" +copyright=\ +Copyright (c) 2000, 2007 Wind River Systems and others.\n\ +All rights reserved. This program and the accompanying materials\n\ +are made available under the terms of the Eclipse Public License v1.0\n\ +which accompanies this distribution, and is available at\n\ +http://www.eclipse.org/legal/epl-v10.html\n\ +################ end of copyright property #################################### + +# "licenseURL" property - URL of the "Feature License" +# do not translate value - just change to point to a locale-specific HTML page +licenseURL=license.html + +# "license" property - text of the "Feature Update License" +# should be plain text version of license agreement pointed to be "licenseURL" +license=\ +* Eclipse Public License v1.0 (http://www.eclipse.org/legal/epl-v10.html)\n\ +\n\ +ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\ +March 17, 2005\n\ +\n\ +Usage Of Content\n\ +\n\ +THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\ +OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\ +USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\ +AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\ +NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\ +AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\ +AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\ +OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ +TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\ +OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ +BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\ +\n\ +Applicable Licenses\n\ +\n\ +Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ +is provided to you under the terms and conditions of the Eclipse Public\n\ +License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\ +Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\ +For purposes of the EPL, "Program" will mean the Content.\n\ +\n\ +Content includes, but is not limited to, source code, object code,\n\ +documentation and other files maintained in the Eclipse.org CVS\n\ +repository ("Repository") in CVS modules ("Modules") and made available\n\ +as downloadable archives ("Downloads").\n\ +\n\ + - Content may be structured and packaged into modules to facilitate delivering,\n\ + extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\ + plug-in fragments ("Fragments"), and features ("Features").\n\ + - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\ + in a directory named "plugins".\n\ + - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\ + Each Feature may be packaged as a sub-directory in a directory named "features".\n\ + Within a Feature, files named "feature.xml" may contain a list of the names and version\n\ + numbers of the Plug-ins and/or Fragments associated with that Feature.\n\ + - Features may also include other Features ("Included Features"). Within a Feature, files\n\ + named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\ +\n\ +Features may also include other Features ("Included Features"). Files named\n\ +"feature.xml" may contain a list of the names and version numbers of\n\ +Included Features.\n\ +\n\ +The terms and conditions governing Plug-ins and Fragments should be\n\ +contained in files named "about.html" ("Abouts"). The terms and\n\ +conditions governing Features and Included Features should be contained\n\ +in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\ +Licenses may be located in any directory of a Download or Module\n\ +including, but not limited to the following locations:\n\ +\n\ + - The top-level (root) directory\n\ + - Plug-in and Fragment directories\n\ + - Inside Plug-ins and Fragments packaged as JARs\n\ + - Sub-directories of the directory named "src" of certain Plug-ins\n\ + - Feature directories\n\ +\n\ +Note: if a Feature made available by the Eclipse Foundation is installed using the\n\ +Eclipse Update Manager, you must agree to a license ("Feature Update\n\ +License") during the installation process. If the Feature contains\n\ +Included Features, the Feature Update License should either provide you\n\ +with the terms and conditions governing the Included Features or inform\n\ +you where you can locate them. Feature Update Licenses may be found in\n\ +the "license" property of files named "feature.properties". Such Abouts,\n\ +Feature Licenses and Feature Update Licenses contain the terms and\n\ +conditions (or references to such terms and conditions) that govern your\n\ +use of the associated Content in that directory.\n\ +\n\ +THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\ +TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\ +SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ +\n\ + - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\ + - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\ + - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\ + - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\ + - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\ + - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\ +\n\ +IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\ +TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\ +is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\ +govern that particular Content.\n\ +\n\ +Cryptography\n\ +\n\ +Content may contain encryption software. The country in which you are\n\ +currently may have restrictions on the import, possession, and use,\n\ +and/or re-export to another country, of encryption software. BEFORE\n\ +using any encryption software, please check the country's laws,\n\ +regulations and policies concerning the import, possession, or use,\n\ +and re-export of encryption software, to see if this is permitted.\n\ +\n\ +Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n +########### end of license property ########################################## diff --git a/features/org.eclipse.dd.dsf.gdb-feature/feature.xml b/features/org.eclipse.dd.dsf.gdb-feature/feature.xml index 08cd1918017..91e0c2146fa 100644 --- a/features/org.eclipse.dd.dsf.gdb-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.gdb-feature/feature.xml @@ -12,108 +12,12 @@ Debug Services Framework GDB-MI Implementation - - Copyright (c) 2006-2007 Wind River Systems and others. -All rights reserved. This program and the accompanying materials -are made available under the terms of the Eclipse Public License -v1.0 which accompanies this distribution, and is available at -http://www.eclipse.org/legal/epl-v10.html + + %copyright - - ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT -March 17, 2005 -Usage Of Content -THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, -INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY -"CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS -OF THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE -AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING -THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED -BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE -LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. -IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT -AND THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS -OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE -THE CONTENT. -Applicable Licenses -Unless otherwise indicated, all Content made available by the -Eclipse Foundation is provided to you under the terms and conditions -of the Eclipse Public License Version 1.0 ("EPL"). A copy of -the EPL is provided with this Content and is also available at -http://www.eclipse.org/legal/epl-v10.html. For purposes of the -EPL, "Program" will mean the Content. -Content includes, but is not limited to, source code, object -code, documentation and other files maintained in the Eclipse.org -CVS repository ("Repository") in CVS modules ("Modules") and -made available as downloadable archives ("Downloads"). -- Content may be structured and packaged into modules to facilitate -delivering, -extending, and upgrading the Content. Typical modules may include -plug-ins ("Plug-ins"), -plug-in fragments ("Fragments"), and features ("Features"). -- Each Plug-in or Fragment may be packaged as a sub-directory -or JAR (Java? ARchive) -in a directory named "plugins". -- A Feature is a bundle of one or more Plug-ins and/or Fragments -and associated material. -Each Feature may be packaged as a sub-directory in a directory -named "features". -Within a Feature, files named "feature.xml" may contain a list -of the names and version -numbers of the Plug-ins and/or Fragments associated with that -Feature. -- Features may also include other Features ("Included Features"). -Within a Feature, files -named "feature.xml" may contain a list of the names and version -numbers of Included Features. -Features may also include other Features ("Included Features"). -Files named "feature.xml" may contain a list of the names and -version numbers of Included Features. -The terms and conditions governing Plug-ins and Fragments should -be contained in files named "about.html" ("Abouts"). The terms -and conditions governing Features and Included Features should -be contained in files named "license.html" ("Feature Licenses"). -Abouts and Feature -Licenses may be located in any directory of a Download or Module -including, but not limited to the following locations: -- The top-level (root) directory -- Plug-in and Fragment directories -- Inside Plug-ins and Fragments packaged as JARs -- Sub-directories of the directory named "src" of certain Plug-ins -- Feature directories -Note: if a Feature made available by the Eclipse Foundation is -installed using the Eclipse Update Manager, you must agree to -a license ("Feature Update License") during the installation -process. If the Feature contains Included Features, the Feature -Update License should either provide you -with the terms and conditions governing the Included Features -or inform you where you can locate them. Feature Update Licenses -may be found in the "license" property of files named "feature.properties". -Such Abouts, Feature Licenses and Feature Update Licenses contain -the terms and conditions (or references to such terms and conditions) -that govern your -use of the associated Content in that directory. -THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY -REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS -AND CONDITIONS. SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE -(BUT ARE NOT LIMITED TO): -- Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html) -IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS -PRIOR TO USE OF THE CONTENT. If no About, Feature License or -Feature Update License is provided, please contact the Eclipse -Foundation to determine what terms and conditions govern that -particular Content. -Cryptography -Content may contain encryption software. The country in which -you are currently may have restrictions on the import, possession, -and use, and/or re-export to another country, of encryption software. -BEFORE using any encryption software, please check the country's -laws, -regulations and policies concerning the import, possession, or -use, and re-export of encryption software, to see if this is -permitted. -Java and all Java-based trademarks are trademarks of Sun Microsystem + + %license diff --git a/features/org.eclipse.dd.dsf.gdb-feature/license.html b/features/org.eclipse.dd.dsf.gdb-feature/license.html new file mode 100644 index 00000000000..c6af966b61e --- /dev/null +++ b/features/org.eclipse.dd.dsf.gdb-feature/license.html @@ -0,0 +1,79 @@ + + + + +Eclipse.org Software User Agreement + + + +

    Eclipse Foundation Software User Agreement

    +

    March 17, 2005

    + +

    Usage Of Content

    + +

    THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS + (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND + CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE + OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR + NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND + CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.

    + +

    Applicable Licenses

    + +

    Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0 + ("EPL"). A copy of the EPL is provided with this Content and is also available at http://www.eclipse.org/legal/epl-v10.html. + For purposes of the EPL, "Program" will mean the Content.

    + +

    Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse.org CVS repository ("Repository") in CVS + modules ("Modules") and made available as downloadable archives ("Downloads").

    + +
      +
    • Content may be structured and packaged into modules to facilitate delivering, extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and features ("Features").
    • +
    • Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java™ ARchive) in a directory named "plugins".
    • +
    • A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. Each Feature may be packaged as a sub-directory in a directory named "features". Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of the Plug-ins + and/or Fragments associated with that Feature.
    • +
    • Features may also include other Features ("Included Features"). Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of Included Features.
    • +
    + +

    The terms and conditions governing Plug-ins and Fragments should be contained in files named "about.html" ("Abouts"). The terms and conditions governing Features and +Included Features should be contained in files named "license.html" ("Feature Licenses"). Abouts and Feature Licenses may be located in any directory of a Download or Module +including, but not limited to the following locations:

    + +
      +
    • The top-level (root) directory
    • +
    • Plug-in and Fragment directories
    • +
    • Inside Plug-ins and Fragments packaged as JARs
    • +
    • Sub-directories of the directory named "src" of certain Plug-ins
    • +
    • Feature directories
    • +
    + +

    Note: if a Feature made available by the Eclipse Foundation is installed using the Eclipse Update Manager, you must agree to a license ("Feature Update License") during the +installation process. If the Feature contains Included Features, the Feature Update License should either provide you with the terms and conditions governing the Included Features or +inform you where you can locate them. Feature Update Licenses may be found in the "license" property of files named "feature.properties" found within a Feature. +Such Abouts, Feature Licenses, and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your use of the associated Content in +that directory.

    + +

    THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE +OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):

    + + + +

    IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License, or Feature Update License is provided, please +contact the Eclipse Foundation to determine what terms and conditions govern that particular Content.

    + +

    Cryptography

    + +

    Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to + another country, of encryption software. BEFORE using any encryption software, please check the country's laws, regulations and policies concerning the import, + possession, or use, and re-export of encryption software, to see if this is permitted.

    + +Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both. + + diff --git a/features/org.eclipse.dd.dsf.sdk-feature/build.properties b/features/org.eclipse.dd.dsf.sdk-feature/build.properties index 64f93a9f0b7..66d3261e69c 100644 --- a/features/org.eclipse.dd.dsf.sdk-feature/build.properties +++ b/features/org.eclipse.dd.dsf.sdk-feature/build.properties @@ -1 +1,3 @@ -bin.includes = feature.xml +bin.includes = feature.xml,\ + feature.properties,\ + license.html diff --git a/features/org.eclipse.dd.dsf.sdk-feature/feature.properties b/features/org.eclipse.dd.dsf.sdk-feature/feature.properties new file mode 100644 index 00000000000..fc88e04d681 --- /dev/null +++ b/features/org.eclipse.dd.dsf.sdk-feature/feature.properties @@ -0,0 +1,126 @@ +############################################################################### +# Copyright (c) 2006, 2007 Wind River Systems and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Ted Williams (Wind River) - initial API and implementation +############################################################################### + +# "copyright" property - text of the "Feature Update Copyright" +copyright=\ +Copyright (c) 2000, 2007 Wind River Systems and others.\n\ +All rights reserved. This program and the accompanying materials\n\ +are made available under the terms of the Eclipse Public License v1.0\n\ +which accompanies this distribution, and is available at\n\ +http://www.eclipse.org/legal/epl-v10.html\n\ +################ end of copyright property #################################### + +# "licenseURL" property - URL of the "Feature License" +# do not translate value - just change to point to a locale-specific HTML page +licenseURL=license.html + +# "license" property - text of the "Feature Update License" +# should be plain text version of license agreement pointed to be "licenseURL" +license=\ +* Eclipse Public License v1.0 (http://www.eclipse.org/legal/epl-v10.html)\n\ +\n\ +ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\ +March 17, 2005\n\ +\n\ +Usage Of Content\n\ +\n\ +THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\ +OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\ +USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\ +AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\ +NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\ +AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\ +AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\ +OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ +TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\ +OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ +BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\ +\n\ +Applicable Licenses\n\ +\n\ +Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ +is provided to you under the terms and conditions of the Eclipse Public\n\ +License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\ +Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\ +For purposes of the EPL, "Program" will mean the Content.\n\ +\n\ +Content includes, but is not limited to, source code, object code,\n\ +documentation and other files maintained in the Eclipse.org CVS\n\ +repository ("Repository") in CVS modules ("Modules") and made available\n\ +as downloadable archives ("Downloads").\n\ +\n\ + - Content may be structured and packaged into modules to facilitate delivering,\n\ + extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\ + plug-in fragments ("Fragments"), and features ("Features").\n\ + - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\ + in a directory named "plugins".\n\ + - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\ + Each Feature may be packaged as a sub-directory in a directory named "features".\n\ + Within a Feature, files named "feature.xml" may contain a list of the names and version\n\ + numbers of the Plug-ins and/or Fragments associated with that Feature.\n\ + - Features may also include other Features ("Included Features"). Within a Feature, files\n\ + named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\ +\n\ +Features may also include other Features ("Included Features"). Files named\n\ +"feature.xml" may contain a list of the names and version numbers of\n\ +Included Features.\n\ +\n\ +The terms and conditions governing Plug-ins and Fragments should be\n\ +contained in files named "about.html" ("Abouts"). The terms and\n\ +conditions governing Features and Included Features should be contained\n\ +in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\ +Licenses may be located in any directory of a Download or Module\n\ +including, but not limited to the following locations:\n\ +\n\ + - The top-level (root) directory\n\ + - Plug-in and Fragment directories\n\ + - Inside Plug-ins and Fragments packaged as JARs\n\ + - Sub-directories of the directory named "src" of certain Plug-ins\n\ + - Feature directories\n\ +\n\ +Note: if a Feature made available by the Eclipse Foundation is installed using the\n\ +Eclipse Update Manager, you must agree to a license ("Feature Update\n\ +License") during the installation process. If the Feature contains\n\ +Included Features, the Feature Update License should either provide you\n\ +with the terms and conditions governing the Included Features or inform\n\ +you where you can locate them. Feature Update Licenses may be found in\n\ +the "license" property of files named "feature.properties". Such Abouts,\n\ +Feature Licenses and Feature Update Licenses contain the terms and\n\ +conditions (or references to such terms and conditions) that govern your\n\ +use of the associated Content in that directory.\n\ +\n\ +THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\ +TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\ +SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ +\n\ + - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\ + - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\ + - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\ + - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\ + - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\ + - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\ +\n\ +IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\ +TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\ +is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\ +govern that particular Content.\n\ +\n\ +Cryptography\n\ +\n\ +Content may contain encryption software. The country in which you are\n\ +currently may have restrictions on the import, possession, and use,\n\ +and/or re-export to another country, of encryption software. BEFORE\n\ +using any encryption software, please check the country's laws,\n\ +regulations and policies concerning the import, possession, or use,\n\ +and re-export of encryption software, to see if this is permitted.\n\ +\n\ +Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n +########### end of license property ########################################## diff --git a/features/org.eclipse.dd.dsf.sdk-feature/feature.xml b/features/org.eclipse.dd.dsf.sdk-feature/feature.xml index 74484ba40d8..83c4870e544 100644 --- a/features/org.eclipse.dd.dsf.sdk-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.sdk-feature/feature.xml @@ -12,105 +12,12 @@ Debug Services Framework Core SDK - - Copyright (c) 2006-2007 Wind River Systems and others. -All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at + + %copyright - - ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT -March 17, 2005 -Usage Of Content -THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, -INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY -"CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS -OF THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE -AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING -THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED -BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE -LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. -IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT -AND THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS -OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE -THE CONTENT. -Applicable Licenses -Unless otherwise indicated, all Content made available by the -Eclipse Foundation is provided to you under the terms and conditions -of the Eclipse Public License Version 1.0 ("EPL"). A copy of -the EPL is provided with this Content and is also available at -http://www.eclipse.org/legal/epl-v10.html. For purposes of the -EPL, "Program" will mean the Content. -Content includes, but is not limited to, source code, object -code, documentation and other files maintained in the Eclipse.org -CVS repository ("Repository") in CVS modules ("Modules") and -made available as downloadable archives ("Downloads"). -- Content may be structured and packaged into modules to facilitate -delivering, -extending, and upgrading the Content. Typical modules may include -plug-ins ("Plug-ins"), -plug-in fragments ("Fragments"), and features ("Features"). -- Each Plug-in or Fragment may be packaged as a sub-directory -or JAR (Java? ARchive) -in a directory named "plugins". -- A Feature is a bundle of one or more Plug-ins and/or Fragments -and associated material. -Each Feature may be packaged as a sub-directory in a directory -named "features". -Within a Feature, files named "feature.xml" may contain a list -of the names and version -numbers of the Plug-ins and/or Fragments associated with that -Feature. -- Features may also include other Features ("Included Features"). -Within a Feature, files -named "feature.xml" may contain a list of the names and version -numbers of Included Features. -Features may also include other Features ("Included Features"). -Files named "feature.xml" may contain a list of the names and -version numbers of Included Features. -The terms and conditions governing Plug-ins and Fragments should -be contained in files named "about.html" ("Abouts"). The terms -and conditions governing Features and Included Features should -be contained in files named "license.html" ("Feature Licenses"). -Abouts and Feature -Licenses may be located in any directory of a Download or Module -including, but not limited to the following locations: -- The top-level (root) directory -- Plug-in and Fragment directories -- Inside Plug-ins and Fragments packaged as JARs -- Sub-directories of the directory named "src" of certain Plug-ins -- Feature directories -Note: if a Feature made available by the Eclipse Foundation is -installed using the Eclipse Update Manager, you must agree to -a license ("Feature Update License") during the installation -process. If the Feature contains Included Features, the Feature -Update License should either provide you -with the terms and conditions governing the Included Features -or inform you where you can locate them. Feature Update Licenses -may be found in the "license" property of files named "feature.properties". -Such Abouts, Feature Licenses and Feature Update Licenses contain -the terms and conditions (or references to such terms and conditions) -that govern your -use of the associated Content in that directory. -THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY -REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS -AND CONDITIONS. SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE -(BUT ARE NOT LIMITED TO): -- Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html) -IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS -PRIOR TO USE OF THE CONTENT. If no About, Feature License or -Feature Update License is provided, please contact the Eclipse -Foundation to determine what terms and conditions govern that -particular Content. -Cryptography -Content may contain encryption software. The country in which -you are currently may have restrictions on the import, possession, -and use, and/or re-export to another country, of encryption software. -BEFORE using any encryption software, please check the country's -laws, -regulations and policies concerning the import, possession, or -use, and re-export of encryption software, to see if this is -permitted. -Java and all Java-based trademarks are trademarks of Sun Microsystem + + %license diff --git a/features/org.eclipse.dd.dsf.sdk-feature/license.html b/features/org.eclipse.dd.dsf.sdk-feature/license.html new file mode 100644 index 00000000000..c6af966b61e --- /dev/null +++ b/features/org.eclipse.dd.dsf.sdk-feature/license.html @@ -0,0 +1,79 @@ + + + + +Eclipse.org Software User Agreement + + + +

    Eclipse Foundation Software User Agreement

    +

    March 17, 2005

    + +

    Usage Of Content

    + +

    THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS + (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND + CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE + OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR + NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND + CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.

    + +

    Applicable Licenses

    + +

    Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0 + ("EPL"). A copy of the EPL is provided with this Content and is also available at http://www.eclipse.org/legal/epl-v10.html. + For purposes of the EPL, "Program" will mean the Content.

    + +

    Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse.org CVS repository ("Repository") in CVS + modules ("Modules") and made available as downloadable archives ("Downloads").

    + +
      +
    • Content may be structured and packaged into modules to facilitate delivering, extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and features ("Features").
    • +
    • Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java™ ARchive) in a directory named "plugins".
    • +
    • A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. Each Feature may be packaged as a sub-directory in a directory named "features". Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of the Plug-ins + and/or Fragments associated with that Feature.
    • +
    • Features may also include other Features ("Included Features"). Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of Included Features.
    • +
    + +

    The terms and conditions governing Plug-ins and Fragments should be contained in files named "about.html" ("Abouts"). The terms and conditions governing Features and +Included Features should be contained in files named "license.html" ("Feature Licenses"). Abouts and Feature Licenses may be located in any directory of a Download or Module +including, but not limited to the following locations:

    + +
      +
    • The top-level (root) directory
    • +
    • Plug-in and Fragment directories
    • +
    • Inside Plug-ins and Fragments packaged as JARs
    • +
    • Sub-directories of the directory named "src" of certain Plug-ins
    • +
    • Feature directories
    • +
    + +

    Note: if a Feature made available by the Eclipse Foundation is installed using the Eclipse Update Manager, you must agree to a license ("Feature Update License") during the +installation process. If the Feature contains Included Features, the Feature Update License should either provide you with the terms and conditions governing the Included Features or +inform you where you can locate them. Feature Update Licenses may be found in the "license" property of files named "feature.properties" found within a Feature. +Such Abouts, Feature Licenses, and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your use of the associated Content in +that directory.

    + +

    THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE +OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):

    + + + +

    IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License, or Feature Update License is provided, please +contact the Eclipse Foundation to determine what terms and conditions govern that particular Content.

    + +

    Cryptography

    + +

    Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to + another country, of encryption software. BEFORE using any encryption software, please check the country's laws, regulations and policies concerning the import, + possession, or use, and re-export of encryption software, to see if this is permitted.

    + +Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both. + + diff --git a/features/org.eclipse.dd.dsf.test-feature/build.properties b/features/org.eclipse.dd.dsf.test-feature/build.properties index 64f93a9f0b7..66d3261e69c 100644 --- a/features/org.eclipse.dd.dsf.test-feature/build.properties +++ b/features/org.eclipse.dd.dsf.test-feature/build.properties @@ -1 +1,3 @@ -bin.includes = feature.xml +bin.includes = feature.xml,\ + feature.properties,\ + license.html diff --git a/features/org.eclipse.dd.dsf.test-feature/feature.properties b/features/org.eclipse.dd.dsf.test-feature/feature.properties new file mode 100644 index 00000000000..fc88e04d681 --- /dev/null +++ b/features/org.eclipse.dd.dsf.test-feature/feature.properties @@ -0,0 +1,126 @@ +############################################################################### +# Copyright (c) 2006, 2007 Wind River Systems and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Ted Williams (Wind River) - initial API and implementation +############################################################################### + +# "copyright" property - text of the "Feature Update Copyright" +copyright=\ +Copyright (c) 2000, 2007 Wind River Systems and others.\n\ +All rights reserved. This program and the accompanying materials\n\ +are made available under the terms of the Eclipse Public License v1.0\n\ +which accompanies this distribution, and is available at\n\ +http://www.eclipse.org/legal/epl-v10.html\n\ +################ end of copyright property #################################### + +# "licenseURL" property - URL of the "Feature License" +# do not translate value - just change to point to a locale-specific HTML page +licenseURL=license.html + +# "license" property - text of the "Feature Update License" +# should be plain text version of license agreement pointed to be "licenseURL" +license=\ +* Eclipse Public License v1.0 (http://www.eclipse.org/legal/epl-v10.html)\n\ +\n\ +ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\ +March 17, 2005\n\ +\n\ +Usage Of Content\n\ +\n\ +THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\ +OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\ +USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\ +AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\ +NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\ +AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\ +AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\ +OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ +TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\ +OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ +BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\ +\n\ +Applicable Licenses\n\ +\n\ +Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ +is provided to you under the terms and conditions of the Eclipse Public\n\ +License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\ +Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\ +For purposes of the EPL, "Program" will mean the Content.\n\ +\n\ +Content includes, but is not limited to, source code, object code,\n\ +documentation and other files maintained in the Eclipse.org CVS\n\ +repository ("Repository") in CVS modules ("Modules") and made available\n\ +as downloadable archives ("Downloads").\n\ +\n\ + - Content may be structured and packaged into modules to facilitate delivering,\n\ + extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\ + plug-in fragments ("Fragments"), and features ("Features").\n\ + - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\ + in a directory named "plugins".\n\ + - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\ + Each Feature may be packaged as a sub-directory in a directory named "features".\n\ + Within a Feature, files named "feature.xml" may contain a list of the names and version\n\ + numbers of the Plug-ins and/or Fragments associated with that Feature.\n\ + - Features may also include other Features ("Included Features"). Within a Feature, files\n\ + named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\ +\n\ +Features may also include other Features ("Included Features"). Files named\n\ +"feature.xml" may contain a list of the names and version numbers of\n\ +Included Features.\n\ +\n\ +The terms and conditions governing Plug-ins and Fragments should be\n\ +contained in files named "about.html" ("Abouts"). The terms and\n\ +conditions governing Features and Included Features should be contained\n\ +in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\ +Licenses may be located in any directory of a Download or Module\n\ +including, but not limited to the following locations:\n\ +\n\ + - The top-level (root) directory\n\ + - Plug-in and Fragment directories\n\ + - Inside Plug-ins and Fragments packaged as JARs\n\ + - Sub-directories of the directory named "src" of certain Plug-ins\n\ + - Feature directories\n\ +\n\ +Note: if a Feature made available by the Eclipse Foundation is installed using the\n\ +Eclipse Update Manager, you must agree to a license ("Feature Update\n\ +License") during the installation process. If the Feature contains\n\ +Included Features, the Feature Update License should either provide you\n\ +with the terms and conditions governing the Included Features or inform\n\ +you where you can locate them. Feature Update Licenses may be found in\n\ +the "license" property of files named "feature.properties". Such Abouts,\n\ +Feature Licenses and Feature Update Licenses contain the terms and\n\ +conditions (or references to such terms and conditions) that govern your\n\ +use of the associated Content in that directory.\n\ +\n\ +THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\ +TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\ +SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ +\n\ + - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\ + - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\ + - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\ + - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\ + - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\ + - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\ +\n\ +IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\ +TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\ +is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\ +govern that particular Content.\n\ +\n\ +Cryptography\n\ +\n\ +Content may contain encryption software. The country in which you are\n\ +currently may have restrictions on the import, possession, and use,\n\ +and/or re-export to another country, of encryption software. BEFORE\n\ +using any encryption software, please check the country's laws,\n\ +regulations and policies concerning the import, possession, or use,\n\ +and re-export of encryption software, to see if this is permitted.\n\ +\n\ +Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n +########### end of license property ########################################## diff --git a/features/org.eclipse.dd.dsf.test-feature/feature.xml b/features/org.eclipse.dd.dsf.test-feature/feature.xml index d8a1d0e8111..bb90c52e773 100644 --- a/features/org.eclipse.dd.dsf.test-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.test-feature/feature.xml @@ -12,64 +12,12 @@ Debug Services Framework Tests - - Copyright (c) 2006-2007 Wind River Systems and others. -All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html + + %copyright - - ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT -March 17, 2005 - -Usage Of Content - -THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT. - -Applicable Licenses - -Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is provided with this Content and is also available at http://www.eclipse.org/legal/epl-v10.html. For purposes of the EPL, "Program" will mean the Content. - -Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse.org CVS repository ("Repository") in CVS modules ("Modules") and made available as downloadable archives ("Downloads"). - - - Content may be structured and packaged into modules to facilitate delivering, - extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"), - plug-in fragments ("Fragments"), and features ("Features"). - - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive) - in a directory named "plugins". - - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. - Each Feature may be packaged as a sub-directory in a directory named "features". - Within a Feature, files named "feature.xml" may contain a list of the names and version - numbers of the Plug-ins and/or Fragments associated with that Feature. - - Features may also include other Features ("Included Features"). Within a Feature, files - named "feature.xml" may contain a list of the names and version numbers of Included Features. - -Features may also include other Features ("Included Features"). Files named "feature.xml" may contain a list of the names and version numbers of Included Features. - -The terms and conditions governing Plug-ins and Fragments should be contained in files named "about.html" ("Abouts"). The terms and conditions governing Features and Included Features should be contained in files named "license.html" ("Feature Licenses"). Abouts and Feature -Licenses may be located in any directory of a Download or Module including, but not limited to the following locations: - - - The top-level (root) directory - - Plug-in and Fragment directories - - Inside Plug-ins and Fragments packaged as JARs - - Sub-directories of the directory named "src" of certain Plug-ins - - Feature directories - -Note: if a Feature made available by the Eclipse Foundation is installed using the Eclipse Update Manager, you must agree to a license ("Feature Update License") during the installation process. If the Feature contains Included Features, the Feature Update License should either provide you -with the terms and conditions governing the Included Features or inform you where you can locate them. Feature Update Licenses may be found in the "license" property of files named "feature.properties". Such Abouts, Feature Licenses and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your -use of the associated Content in that directory. - -THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO): - - - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html) - -IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License or Feature Update License is provided, please contact the Eclipse Foundation to determine what terms and conditions govern that particular Content. - -Cryptography - -Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to another country, of encryption software. BEFORE using any encryption software, please check the country's laws, -regulations and policies concerning the import, possession, or use, and re-export of encryption software, to see if this is permitted. - -Java and all Java-based trademarks are trademarks of Sun Microsystem + + %license diff --git a/features/org.eclipse.dd.dsf.test-feature/license.html b/features/org.eclipse.dd.dsf.test-feature/license.html new file mode 100644 index 00000000000..c6af966b61e --- /dev/null +++ b/features/org.eclipse.dd.dsf.test-feature/license.html @@ -0,0 +1,79 @@ + + + + +Eclipse.org Software User Agreement + + + +

    Eclipse Foundation Software User Agreement

    +

    March 17, 2005

    + +

    Usage Of Content

    + +

    THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS + (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND + CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE + OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR + NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND + CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.

    + +

    Applicable Licenses

    + +

    Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0 + ("EPL"). A copy of the EPL is provided with this Content and is also available at http://www.eclipse.org/legal/epl-v10.html. + For purposes of the EPL, "Program" will mean the Content.

    + +

    Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse.org CVS repository ("Repository") in CVS + modules ("Modules") and made available as downloadable archives ("Downloads").

    + +
      +
    • Content may be structured and packaged into modules to facilitate delivering, extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and features ("Features").
    • +
    • Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java™ ARchive) in a directory named "plugins".
    • +
    • A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. Each Feature may be packaged as a sub-directory in a directory named "features". Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of the Plug-ins + and/or Fragments associated with that Feature.
    • +
    • Features may also include other Features ("Included Features"). Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of Included Features.
    • +
    + +

    The terms and conditions governing Plug-ins and Fragments should be contained in files named "about.html" ("Abouts"). The terms and conditions governing Features and +Included Features should be contained in files named "license.html" ("Feature Licenses"). Abouts and Feature Licenses may be located in any directory of a Download or Module +including, but not limited to the following locations:

    + +
      +
    • The top-level (root) directory
    • +
    • Plug-in and Fragment directories
    • +
    • Inside Plug-ins and Fragments packaged as JARs
    • +
    • Sub-directories of the directory named "src" of certain Plug-ins
    • +
    • Feature directories
    • +
    + +

    Note: if a Feature made available by the Eclipse Foundation is installed using the Eclipse Update Manager, you must agree to a license ("Feature Update License") during the +installation process. If the Feature contains Included Features, the Feature Update License should either provide you with the terms and conditions governing the Included Features or +inform you where you can locate them. Feature Update Licenses may be found in the "license" property of files named "feature.properties" found within a Feature. +Such Abouts, Feature Licenses, and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your use of the associated Content in +that directory.

    + +

    THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE +OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):

    + + + +

    IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License, or Feature Update License is provided, please +contact the Eclipse Foundation to determine what terms and conditions govern that particular Content.

    + +

    Cryptography

    + +

    Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to + another country, of encryption software. BEFORE using any encryption software, please check the country's laws, regulations and policies concerning the import, + possession, or use, and re-export of encryption software, to see if this is permitted.

    + +Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both. + + diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/about.html b/plugins/org.eclipse.dd.dsf.debug.ui/about.html new file mode 100644 index 00000000000..cb740ae8bc8 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/about.html @@ -0,0 +1,24 @@ + + + + +About +

    About This Content

    + +

    June 5, 2007

    +

    License

    + +

    The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at http://www.eclipse.org/legal/epl-v10.html. +For purposes of the EPL, "Program" will mean the Content.

    + +

    If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at http://www.eclipse.org.

    + + \ No newline at end of file diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/build.properties b/plugins/org.eclipse.dd.dsf.debug.ui/build.properties index 34d2e4d2dad..6b1faf87df1 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/build.properties +++ b/plugins/org.eclipse.dd.dsf.debug.ui/build.properties @@ -1,4 +1,5 @@ source.. = src/ output.. = bin/ bin.includes = META-INF/,\ + about.html\ . diff --git a/plugins/org.eclipse.dd.dsf.debug/about.html b/plugins/org.eclipse.dd.dsf.debug/about.html new file mode 100644 index 00000000000..cb740ae8bc8 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug/about.html @@ -0,0 +1,24 @@ + + + + +About +

    About This Content

    + +

    June 5, 2007

    +

    License

    + +

    The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at http://www.eclipse.org/legal/epl-v10.html. +For purposes of the EPL, "Program" will mean the Content.

    + +

    If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at http://www.eclipse.org.

    + + \ No newline at end of file diff --git a/plugins/org.eclipse.dd.dsf.debug/build.properties b/plugins/org.eclipse.dd.dsf.debug/build.properties index e9863e281ea..f8adf614f3e 100644 --- a/plugins/org.eclipse.dd.dsf.debug/build.properties +++ b/plugins/org.eclipse.dd.dsf.debug/build.properties @@ -2,4 +2,5 @@ source.. = src/ output.. = bin/ bin.includes = META-INF/,\ .,\ - plugin.xml + plugin.xml\ + about.html diff --git a/plugins/org.eclipse.dd.dsf.ui/about.html b/plugins/org.eclipse.dd.dsf.ui/about.html new file mode 100644 index 00000000000..cb740ae8bc8 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/about.html @@ -0,0 +1,24 @@ + + + + +About +

    About This Content

    + +

    June 5, 2007

    +

    License

    + +

    The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at http://www.eclipse.org/legal/epl-v10.html. +For purposes of the EPL, "Program" will mean the Content.

    + +

    If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at http://www.eclipse.org.

    + + \ No newline at end of file diff --git a/plugins/org.eclipse.dd.dsf.ui/build.properties b/plugins/org.eclipse.dd.dsf.ui/build.properties index e9863e281ea..f8adf614f3e 100644 --- a/plugins/org.eclipse.dd.dsf.ui/build.properties +++ b/plugins/org.eclipse.dd.dsf.ui/build.properties @@ -2,4 +2,5 @@ source.. = src/ output.. = bin/ bin.includes = META-INF/,\ .,\ - plugin.xml + plugin.xml\ + about.html diff --git a/plugins/org.eclipse.dd.dsf/about.html b/plugins/org.eclipse.dd.dsf/about.html new file mode 100644 index 00000000000..cb740ae8bc8 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/about.html @@ -0,0 +1,24 @@ + + + + +About +

    About This Content

    + +

    June 5, 2007

    +

    License

    + +

    The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at http://www.eclipse.org/legal/epl-v10.html. +For purposes of the EPL, "Program" will mean the Content.

    + +

    If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at http://www.eclipse.org.

    + + \ No newline at end of file diff --git a/plugins/org.eclipse.dd.dsf/build.properties b/plugins/org.eclipse.dd.dsf/build.properties index e9863e281ea..f8adf614f3e 100644 --- a/plugins/org.eclipse.dd.dsf/build.properties +++ b/plugins/org.eclipse.dd.dsf/build.properties @@ -2,4 +2,5 @@ source.. = src/ output.. = bin/ bin.includes = META-INF/,\ .,\ - plugin.xml + plugin.xml\ + about.html From a94cbbba9bf8c0fae51ff31a14102cd249e6a88b Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 30 May 2007 20:43:00 +0000 Subject: [PATCH 090/834] Added plugin.xml to jar (bug 189975). --- plugins/org.eclipse.dd.dsf.debug.ui/build.properties | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/build.properties b/plugins/org.eclipse.dd.dsf.debug.ui/build.properties index 6b1faf87df1..b7a6b599dc7 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/build.properties +++ b/plugins/org.eclipse.dd.dsf.debug.ui/build.properties @@ -1,5 +1,6 @@ source.. = src/ output.. = bin/ bin.includes = META-INF/,\ - about.html\ + plugin.xml\ + about.xml\ . From 30dbfc7cedb0172d21b562507fd58da26b049679 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Wed, 30 May 2007 21:36:14 +0000 Subject: [PATCH 091/834] missing commas --- plugins/org.eclipse.dd.dsf.debug.ui/build.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/build.properties b/plugins/org.eclipse.dd.dsf.debug.ui/build.properties index b7a6b599dc7..5a18b73d486 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/build.properties +++ b/plugins/org.eclipse.dd.dsf.debug.ui/build.properties @@ -1,6 +1,6 @@ source.. = src/ output.. = bin/ bin.includes = META-INF/,\ - plugin.xml\ - about.xml\ + plugin.xml,\ + about.xml,\ . From 1f71a2fac3cdb19aa818aa3f46191183337e8fc7 Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Wed, 30 May 2007 23:34:23 +0000 Subject: [PATCH 092/834] Bugzilla defect 190091. --- .../register/RegisterBitFieldLayoutNode.java | 25 ++++++------------- .../register/RegisterGroupLayoutNode.java | 5 ++-- .../register/RegisterLayoutNode.java | 17 ++++--------- .../dd/dsf/debug/service/IRegisters.java | 12 ++++++--- 4 files changed, 23 insertions(+), 36 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java index 77a3fa7aa7d..18ede371ca0 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java @@ -29,9 +29,7 @@ import org.eclipse.dd.dsf.debug.service.IRegisters.IBitFieldDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IBitFieldDMData; import org.eclipse.dd.dsf.debug.service.IRegisters.IMnemonic; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext; -import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMData; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext; -import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMData; import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent; import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; @@ -137,32 +135,23 @@ public class RegisterBitFieldLayoutNode extends AbstractExpressionLayoutNode {} /** Register group context */ - public interface IRegisterGroupDMContext extends IFormattedDataDMContext {} + public interface IRegisterGroupDMContext extends IFormattedDataDMContext { + public String getName(); + } /** Event indicating registers in a group have changed. */ public interface IRegistersChangedDMEvent extends IDMEvent {} @@ -40,7 +42,9 @@ public interface IRegisters extends IFormattedValues { } /** Register context */ - public interface IRegisterDMContext extends IFormattedDataDMContext {} + public interface IRegisterDMContext extends IFormattedDataDMContext { + public String getName(); + } /** Event indicating register value changed. */ public interface IRegisterChangedDMEvent extends IDMEvent {} @@ -59,7 +63,9 @@ public interface IRegisters extends IFormattedValues { } /** Bit field context */ - public interface IBitFieldDMContext extends IFormattedDataDMContext {} + public interface IBitFieldDMContext extends IFormattedDataDMContext { + public String getName(); + } /** Event indicating register value changed. */ public interface IBitFieldChangedDMEvent extends IDMEvent {} From eb5188e48f9c68e7d2464f90931b9892ee211f8e Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Thu, 31 May 2007 18:52:45 +0000 Subject: [PATCH 093/834] This is an udate that contains Fran Literrio's expression/variables view stuff along with my additions to make the expression view interact with the variables layout nodes. I do not have the bugzilla number offhand --- .../expression/ExpressionVMProvider.java | 51 +- .../variable/SyncVariableDataAccess.java | 487 ++++++++++++++++++ .../VariableLayoutValueCellModifier.java | 91 ++++ .../variable/VariableLocalsLayoutNode.java | 199 ++++++- .../VariableSubExpressionsLayoutNode.java | 5 +- .../variable/VariableVMProvider.java | 33 +- .../dd/dsf/debug/service/IExpressions.java | 14 + 7 files changed, 861 insertions(+), 19 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutValueCellModifier.java diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java index 9b82c745d9b..0356fc87ca3 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java @@ -16,6 +16,9 @@ import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePrefer import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterGroupLayoutNode; import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterLayoutNode; import org.eclipse.dd.dsf.debug.ui.viewmodel.register.SyncRegisterDataAccess; +import org.eclipse.dd.dsf.debug.ui.viewmodel.variable.SyncVariableDataAccess; +import org.eclipse.dd.dsf.debug.ui.viewmodel.variable.VariableLocalsLayoutNode; +import org.eclipse.dd.dsf.debug.ui.viewmodel.variable.VariableSubExpressionsLayoutNode; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; @@ -58,16 +61,54 @@ public class ExpressionVMProvider extends AbstractDMVMProvider } protected void configureLayout() { - SyncRegisterDataAccess syncDataAccess = new SyncRegisterDataAccess(); - // Configure the layout nodes + /* + * Allocate the synchronous data providers. + */ + SyncRegisterDataAccess syncRegDataAccess = new SyncRegisterDataAccess(); + SyncVariableDataAccess syncvarDataAccess = new SyncVariableDataAccess() ; + + /* + * Create the top level node which provides the anchor starting point. + */ IVMRootLayoutNode debugViewSelectionNode = new DebugViewSelectionRootLayoutNode(this); + + /* + * Now the Overarching management node. + */ ExpressionManagerLayoutNode expressionManagerNode = new ExpressionManagerLayoutNode(this); debugViewSelectionNode.setChildNodes(new IVMLayoutNode[] {expressionManagerNode}); - IExpressionLayoutNode registerGroupNode = new RegisterGroupLayoutNode(this, getSession(), syncDataAccess); - expressionManagerNode.setExpressionLayoutNodes(new IExpressionLayoutNode[] { registerGroupNode }); - IVMLayoutNode registerNode = new RegisterLayoutNode(this, this, getSession(), syncDataAccess); + + /* + * The expression view wants to support fully all of the components of the register view. + */ + IExpressionLayoutNode registerGroupNode = new RegisterGroupLayoutNode(this, getSession(), syncRegDataAccess); + IVMLayoutNode registerNode = new RegisterLayoutNode(this, this, getSession(), syncRegDataAccess); registerGroupNode.setChildNodes(new IVMLayoutNode[] { registerNode }); + + /* + * Create the local variables nodes next. They represent the first level shown in the view. + */ + IExpressionLayoutNode localsNode = new VariableLocalsLayoutNode(this, this, getSession(), syncvarDataAccess); + IVMLayoutNode subExpressioNode = new VariableSubExpressionsLayoutNode(this, getSession(), syncvarDataAccess); + localsNode.setChildNodes(new IVMLayoutNode[] { subExpressioNode }); + + /* + * Tell the expression node which subnodes it will directly support. It is very important + * that the variables node be the last in this chain. The model assumes that there is some + * form of metalanguage expression syntax which each of the nodes evaluates and decides if + * they are dealing with it or not. The variables node assumes that the expression is fully + * qualified and there is no analysis or subdivision of the expression it will parse. So it + * it currently the case that the location of the nodes within the array being passed in is + * the order of search/evaluation. Thus variables wants to be last. Otherwise it would just + * assume what it was passed was for it and the real node which wants to handle it would be + * left out in the cold. + */ + expressionManagerNode.setExpressionLayoutNodes(new IExpressionLayoutNode[] { registerGroupNode, localsNode }); + + /* + * Let the work know which is the top level node. + */ setRootLayoutNode(debugViewSelectionNode); } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java new file mode 100644 index 00000000000..98cdf977268 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java @@ -0,0 +1,487 @@ +/* + * SyncVariableDataAccess.java + * Created on May 22, 2007 + * + * Copyright 2007 Wind River Systems Inc. All rights reserved. +*/ +package org.eclipse.dd.dsf.debug.ui.viewmodel.variable; + +import java.util.concurrent.ExecutionException; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.Query; +import org.eclipse.dd.dsf.concurrent.ThreadSafeAndProhibitedFromDsfExecutor; +import org.eclipse.dd.dsf.debug.service.IExpressions; +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMData; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.IFormattedDataDMContext; +import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.util.tracker.ServiceTracker; + +@ThreadSafeAndProhibitedFromDsfExecutor("") +public class SyncVariableDataAccess { + + /** + * Need to use the OSGi service tracker here (instead of DsfServiceTracker), + * because we're accessing it in non-dispatch thread. DsfServiceTracker is + * not thread-safe. + */ + private ServiceTracker fServiceTracker; + + private synchronized IExpressions getService(String filter) { + + if (fServiceTracker == null) { + try { + fServiceTracker = new ServiceTracker(DsfDebugUIPlugin + .getBundleContext(), DsfDebugUIPlugin.getBundleContext() + .createFilter(filter), null); + fServiceTracker.open(); + } catch (InvalidSyntaxException e) { + assert false : "Invalid filter in DMC: " + filter; //$NON-NLS-1$ + return null; + } + } else { + /* + * All of the DMCs that this cell modifier is invoked for should + * originate from the same service. This assertion checks this + * assumption by comparing the service reference in the tracker to + * the filter string in the DMC. + */ + try { + assert DsfDebugUIPlugin.getBundleContext().createFilter(filter) + .match(fServiceTracker.getServiceReference()); + } catch (InvalidSyntaxException e) { + } + } + return (IExpressions) fServiceTracker.getService(); + } + + public void dispose() { + if (fServiceTracker != null) { + fServiceTracker.close(); + } + } + + public IExpressionDMContext getVariableDMC(Object element) { + if (element instanceof IAdaptable) { + return (IExpressionDMContext) ((IAdaptable) element).getAdapter(IExpressionDMContext.class); + } + return null; + } + + + public class GetVariableValueQuery extends Query { + + private IExpressionDMContext fDmc; + + public GetVariableValueQuery(DsfExecutor executor, IExpressionDMContext dmc) { + super(executor); + fDmc = dmc; + } + + @Override + protected void execute(final DataRequestMonitor rm) { + /* + * Guard agains the session being disposed. If session is disposed + * it could mean that the executor is shut-down, which in turn could + * mean that we can't complete the RequestMonitor argument. in that + * case, cancel to notify waiting thread. + */ + final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); + if (session == null) { + cancel(false); + return; + } + + IExpressions service = getService(fDmc.getServiceFilter()); + if (service == null) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service not available", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + service.getModelData(fDmc, new DataRequestMonitor(session.getExecutor(), rm) { + @Override + protected void handleCompleted() { + /* + * We're in another dispatch, so we must guard against + * executor shutdown again. + */ + if (!DsfSession.isSessionActive(session.getId())) { + GetVariableValueQuery.this.cancel(false); + return; + } + super.handleCompleted(); + } + + @Override + protected void handleOK() { + /* + * All good set return value. + */ + rm.setData(getData()); + rm.done(); + } + }); + } + } + + public IExpressionDMContext getExpressionDMC(Object element) { + if (element instanceof IAdaptable) { + return (IExpressionDMContext) ((IAdaptable) element).getAdapter(IExpressionDMContext.class); + } + return null; + } + + public IExpressionDMData readVariable(Object element) { + /* + * Get the DMC and the session. If element is not an register DMC, or + * session is stale, then bail out. + */ + IExpressionDMContext dmc = getExpressionDMC(element); + if (dmc == null) return null; + DsfSession session = DsfSession.getSession(dmc.getSessionId()); + if (session == null) return null; + + /* + * Create the query to request the value from service. Note: no need to + * guard agains RejectedExecutionException, because + * DsfSession.getSession() above would only return an active session. + */ + GetVariableValueQuery query = new GetVariableValueQuery(session.getExecutor(), dmc); + session.getExecutor().execute(query); + + /* + * Now we have the data, go and get it. Since the call is completed now + * the ".get()" will not suspend it will immediately return with the + * data. + */ + try { + return query.get(); + } catch (InterruptedException e) { + assert false; + return null; + } catch (ExecutionException e) { + return null; + } + } + + public class SetVariableValueQuery extends Query { + + private IExpressionDMContext fDmc; + private String fValue; + private String fFormatId; + + public SetVariableValueQuery(DsfExecutor executor, IExpressionDMContext dmc, String value, String formatId) { + super(executor); + fDmc = dmc; + fValue = value; + fFormatId = formatId; + } + + @Override + protected void execute(final DataRequestMonitor rm) { + /* + * We're in another dispatch, so we must guard against executor + * shutdown again. + */ + final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); + if (session == null) { + cancel(false); + return; + } + + /* + * Guard against a disposed service + */ + IExpressions service = getService(fDmc.getServiceFilter()); + if (service == null) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + /* + * Write the bit field using a string/format style. + */ + service.writeExpression( + fDmc, + fValue, + fFormatId, + new DataRequestMonitor(session.getExecutor(), rm) { + @Override + protected void handleCompleted() { + /* + * We're in another dispatch, so we must guard + * against executor shutdown again. + */ + if (!DsfSession.isSessionActive(session.getId())) { + SetVariableValueQuery.this.cancel(false); + return; + } + super.handleCompleted(); + } + + @Override + protected void handleOK() { + /* + * All good set return value. + */ + rm.setData(new Object()); + rm.done(); + } + } + ); + } + } + + public void writeVariable(Object element, String value, String formatId) { + + /* + * Get the DMC and the session. If element is not an register DMC, or + * session is stale, then bail out. + */ + IExpressionDMContext dmc = getExpressionDMC(element); + if (dmc == null) return; + DsfSession session = DsfSession.getSession(dmc.getSessionId()); + if (session == null) return; + + /* + * Create the query to write the value to the service. Note: no need to + * guard agains RejectedExecutionException, because + * DsfSession.getSession() above would only return an active session. + */ + SetVariableValueQuery query = new SetVariableValueQuery(session.getExecutor(), dmc, value, formatId); + session.getExecutor().execute(query); + + /* + * Now we have the data, go and get it. Since the call is completed now + * the ".get()" will not suspend it will immediately return with the + * data. + */ + try { + /* + * Return value is irrelevant, any error would come through with an + * exception. + */ + query.get(); + } catch (InterruptedException e) { + assert false; + } catch (ExecutionException e) { + /* + * View must be shutting down, no need to show error dialog. + */ + } + } + + public IFormattedDataDMContext getFormattedDMC(Object element) { + if (element instanceof IAdaptable) { + return (IFormattedDataDMContext) ((IAdaptable) element).getAdapter(IFormattedDataDMContext.class); + } + return null; + } + + public class GetSupportFormatsValueQuery extends Query { + + IFormattedDataDMContext fDmc; + + public GetSupportFormatsValueQuery(DsfExecutor executor, IFormattedDataDMContext dmc) { + super(executor); + fDmc = dmc; + } + + @Override + protected void execute(final DataRequestMonitor rm) { + /* + * We're in another dispatch, so we must guard against executor + * shutdown again. + */ + final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); + if (session == null) { + cancel(false); + return; + } + + /* + * Guard against a disposed service + */ + IExpressions service = getService(fDmc.getServiceFilter()); + if (service == null) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + /* + * Write the bit field using a string/format style. + */ + service.getAvailableFormattedValues( + fDmc, + new DataRequestMonitor(session.getExecutor(), rm) { + @Override + protected void handleCompleted() { + /* + * We're in another dispatch, so we must + * guard against executor shutdown again. + */ + if (!DsfSession.isSessionActive(session.getId())) { + GetSupportFormatsValueQuery.this.cancel(false); + return; + } + super.handleCompleted(); + } + + @Override + protected void handleOK() { + /* + * All good set return value. + */ + rm.setData(new Object()); + rm.done(); + } + } + ); + } + } + + public String[] getSupportedFormats(Object element) { + + /* + * Get the DMC and the session. If element is not an register DMC, or + * session is stale, then bail out. + */ + IFormattedDataDMContext dmc = getFormattedDMC(element); + if (dmc == null) return null; + DsfSession session = DsfSession.getSession(dmc.getSessionId()); + if (session == null) return null; + + /* + * Create the query to write the value to the service. Note: no need to + * guard agains RejectedExecutionException, because + * DsfSession.getSession() above would only return an active session. + */ + GetSupportFormatsValueQuery query = new GetSupportFormatsValueQuery(session.getExecutor(), dmc); + session.getExecutor().execute(query); + + /* + * Now we have the data, go and get it. Since the call is completed now + * the ".get()" will not suspend it will immediately return with the + * data. + */ + try { + return (String[]) query.get(); + } catch (InterruptedException e) { + assert false; + return null; + } catch (ExecutionException e) { + return null; + } + } + + public class GetFormattedValueValueQuery extends Query { + + private IFormattedDataDMContext fDmc; + private String fFormatId; + + public GetFormattedValueValueQuery(DsfExecutor executor, IFormattedDataDMContext dmc, String formatId) { + super(executor); + fDmc = dmc; + fFormatId = formatId; + } + + @Override + protected void execute(final DataRequestMonitor rm) { + /* + * We're in another dispatch, so we must guard against executor + * shutdown again. + */ + final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); + if (session == null) { + cancel(false); + return; + } + + /* + * Guard against a disposed service + */ + IExpressions service = getService(fDmc.getServiceFilter()); + if (service == null) { + rm .setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + /* + * Convert to the proper formatting DMC then go get the formatted value. + */ + + FormattedValueDMContext formDmc = service.getFormattedValue(fDmc, fFormatId); + + service.getModelData(formDmc, new DataRequestMonitor(session.getExecutor(), rm) { + @Override + protected void handleCompleted() { + /* + * We're in another dispatch, so we must guard against executor shutdown again. + */ + if (!DsfSession.isSessionActive(session.getId())) { + GetFormattedValueValueQuery.this.cancel(false); + return; + } + super.handleCompleted(); + } + + @Override + protected void handleOK() { + /* + * All good set return value. + */ + rm.setData(getData().getFormattedValue()); + rm.done(); + } + }); + } + } + + public String getFormattedValue(Object element, String formatId) { + + /* + * Get the DMC and the session. If element is not an register DMC, or + * session is stale, then bail out. + */ + IFormattedDataDMContext dmc = getFormattedDMC(element); + if (dmc == null) return null; + DsfSession session = DsfSession.getSession(dmc.getSessionId()); + if (session == null) return null; + + /* + * Create the query to write the value to the service. Note: no need to + * guard agains RejectedExecutionException, because + * DsfSession.getSession() above would only return an active session. + */ + GetFormattedValueValueQuery query = new GetFormattedValueValueQuery(session.getExecutor(), dmc, formatId); + session.getExecutor().execute(query); + + /* + * Now we have the data, go and get it. Since the call is completed now + * the ".get()" will not suspend it will immediately return with the + * data. + */ + try { + return (String) query.get(); + } catch (InterruptedException e) { + assert false; + return null; + } catch (ExecutionException e) { + return null; + } + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutValueCellModifier.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutValueCellModifier.java new file mode 100644 index 00000000000..ab3a27ac600 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutValueCellModifier.java @@ -0,0 +1,91 @@ +/* + * VariableLayoutValueCellModifier.java + * Created on May 22, 2007 + * + * Copyright 2007 Wind River Systems Inc. All rights reserved. +*/ +package org.eclipse.dd.dsf.debug.ui.viewmodel.variable; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; +import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionCellModifier; +import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePreferenceStore; + +public class VariableLayoutValueCellModifier extends WatchExpressionCellModifier { + + private SyncVariableDataAccess fDataAccess = null; + private IFormattedValuePreferenceStore fFormattedValuePreferenceStore; + + public VariableLayoutValueCellModifier(IFormattedValuePreferenceStore formattedValuePreferenceStore, SyncVariableDataAccess access) { + fDataAccess = access; + fFormattedValuePreferenceStore = formattedValuePreferenceStore; + } + + /* + * Used to make sure we are dealing with a valid variable. + */ + private IExpressionDMContext getVariableDMC(Object element) { + if (element instanceof IAdaptable) { + return (IExpressionDMContext)((IAdaptable)element).getAdapter(IExpressionDMContext.class); + } + return null; + } + + @Override + public boolean canModify(Object element, String property) { + // If we're in the column value, modify the register data. Otherwise, call the super-class to edit + // the watch expression. + + if (IDebugVMConstants.COLUMN_ID__VALUE.equals(property)) { + // Make sure we are are dealing with a valid set of information. + + if (getVariableDMC(element) == null) + return false; + + return true ; + } + + return super.canModify(element, property); + } + + @Override + public Object getValue(Object element, String property) { + // If we're in the column value, modify the variable value. Otherwise, call the super-class to edit + // the watch expression. + + if (IDebugVMConstants.COLUMN_ID__VALUE.equals(property)) { + // Make sure we are working on the editable areas. + + // Write the value in the currently requested format. Since they could + // have freeformed typed in any format this is just a guess and may not + // really accomplish anything. + + String value = fDataAccess.getFormattedValue(element, fFormattedValuePreferenceStore.getDefaultFormatId()); + + if (value == null) + return "..."; //$NON-NLS-1$ + + return value; + } + + return super.getValue(element, property); + } + + @Override + public void modify(Object element, String property, Object value) { + // If we're in the column value, modify the register data. Otherwise, call the super-class to edit + // the watch expression. + + if (IDebugVMConstants.COLUMN_ID__VALUE.equals(property)) { + if (value instanceof String) { + // PREFPAGE : We are using a default format until the preference page is created. + fDataAccess.writeVariable(element, (String) value, fFormattedValuePreferenceStore.getDefaultFormatId()); + } + } + else { + super.modify(element, property, value); + } + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLocalsLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLocalsLayoutNode.java index 815b71281d9..03edcdbd631 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLocalsLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLocalsLayoutNode.java @@ -12,10 +12,12 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.variable; import java.util.ArrayList; import java.util.List; +import org.eclipse.core.runtime.CoreException; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfExecutor; import org.eclipse.dd.dsf.concurrent.MultiRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMEvent; import org.eclipse.dd.dsf.datamodel.IDMService; import org.eclipse.dd.dsf.debug.service.IExpressions; @@ -30,23 +32,130 @@ import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; import org.eclipse.dd.dsf.debug.service.IStack.IVariableDMContext; import org.eclipse.dd.dsf.debug.service.IStack.IVariableDMData; +import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; +import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.AbstractExpressionLayoutNode; +import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePreferenceStore; +import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValueVMContext; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.model.IDebugTarget; +import org.eclipse.debug.core.model.IExpression; +import org.eclipse.debug.core.model.IValue; +import org.eclipse.debug.core.model.IVariable; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementEditor; import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapterExtension; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ICellModifier; +import org.eclipse.jface.viewers.TextCellEditor; +import org.eclipse.swt.widgets.Composite; @SuppressWarnings({"restriction", "nls"}) -public class VariableLocalsLayoutNode extends AbstractDMVMLayoutNode { +public class VariableLocalsLayoutNode extends AbstractExpressionLayoutNode implements IElementEditor { + private final IFormattedValuePreferenceStore fFormattedPrefStore; + + private final SyncVariableDataAccess fSyncVariableDataAccess; + + protected class VariableLocalsVMC extends DMVMContext implements IFormattedValueVMContext, IVariable { + + private IExpression fExpression; + + public VariableLocalsVMC(IDMContext dmc) { + super(dmc); + } - public VariableLocalsLayoutNode(AbstractVMProvider provider, DsfSession session) { - super(provider, session, IExpressions.IExpressionDMContext.class); + public IFormattedValuePreferenceStore getPreferenceStore() { + return fFormattedPrefStore; + } + + public void setExpression(IExpression expression) { + fExpression = expression; + } + + @Override + @SuppressWarnings("unchecked") + public Object getAdapter(Class adapter) { + if (fExpression != null && adapter.isAssignableFrom(fExpression.getClass())) { + return fExpression; + } else if (adapter.isAssignableFrom(IWatchExpressionFactoryAdapterExtension.class)) { + return fVariableLocalsExpressionFactory; + } else { + return super.getAdapter(adapter); + } + } + + @Override + public boolean equals(Object other) { + if (other instanceof VariableLocalsVMC && super.equals(other)) { + VariableLocalsVMC otherGroup = (VariableLocalsVMC)other; + return (otherGroup.fExpression == null && fExpression == null) || + (otherGroup.fExpression != null && otherGroup.fExpression.equals(fExpression)); + } + return false; + } + + @Override + public int hashCode() { + return super.hashCode() + (fExpression != null ? fExpression.hashCode() : 0); + } + + public String getName() throws DebugException { return toString(); } + public String getReferenceTypeName() throws DebugException { return ""; } //$NON-NLS-1$ + public IValue getValue() throws DebugException { return null; } + public boolean hasValueChanged() throws DebugException { return false; } + public void setValue(IValue value) throws DebugException {} + public void setValue(String expression) throws DebugException {} + public boolean supportsValueModification() { return false; } + public boolean verifyValue(IValue value) throws DebugException { return false; } + public boolean verifyValue(String expression) throws DebugException { return false; } + public IDebugTarget getDebugTarget() { return null;} + public ILaunch getLaunch() { return null; } + public String getModelIdentifier() { return DsfDebugUIPlugin.PLUGIN_ID; } + } + + protected class VariableLocalsExpressionFactory implements IWatchExpressionFactoryAdapterExtension { + + public boolean canCreateWatchExpression(IVariable variable) { + return variable instanceof VariableLocalsVMC; + } + + public String createWatchExpression(IVariable variable) throws CoreException { + + //VariableLocalsVMC registerVmc = ((VariableLocalsVMC)variable); + + /* + * This needs to be completed by filling in the fully qualified expression. + * Currently the ExpressionDMC does not support that. This will be changed + * shortly. For now I am creating a bugzilla about this not being complete + * and checking this in. + */ + return null; + } } + final protected VariableLocalsExpressionFactory fVariableLocalsExpressionFactory = new VariableLocalsExpressionFactory(); + + public VariableLocalsLayoutNode(IFormattedValuePreferenceStore prefStore, AbstractVMProvider provider, + DsfSession session, SyncVariableDataAccess syncVariableDataAccess) { + super(provider, session, IExpressions.IExpressionDMContext.class); + fFormattedPrefStore = prefStore; + fSyncVariableDataAccess = syncVariableDataAccess; + } + + @Override + protected IVMContext createVMContext(IDMContext dmc) { + return new VariableLocalsVMC(dmc); + } + /** * We override this method because we now need to perform an extra level of data fetch to get the * formatted value of the expression. @@ -97,6 +206,8 @@ public class VariableLocalsLayoutNode extends AbstractDMVMLayoutNode rm) { + /* + * Since we are overriding "getElementForExpression" we do not need to do anything here. But + * we are forced to supply this routine because it is abstract in the extending class. + */ + } + + public int getExpressionLength(String expression) { + /* + * Since we are overriding "getElementForExpression" we do not need to do anything here. + * We just assume the entire expression is for us. + */ + return expression.length() ; + } } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableSubExpressionsLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableSubExpressionsLayoutNode.java index e31de76dfcc..9b9a8984a70 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableSubExpressionsLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableSubExpressionsLayoutNode.java @@ -40,9 +40,12 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; @SuppressWarnings("restriction") public class VariableSubExpressionsLayoutNode extends AbstractDMVMLayoutNode { + + private SyncVariableDataAccess fSyncVariableDataAccess; - public VariableSubExpressionsLayoutNode(AbstractVMProvider provider, DsfSession session) { + public VariableSubExpressionsLayoutNode(AbstractVMProvider provider, DsfSession session, SyncVariableDataAccess syncVariableDataAccess) { super(provider, session, IExpressions.IExpressionDMContext.class); + fSyncVariableDataAccess = syncVariableDataAccess; } /** diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java index 9b0ed88eeb4..e8c0001aa37 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java @@ -8,7 +8,9 @@ */ package org.eclipse.dd.dsf.debug.ui.viewmodel.variable; +import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.dd.dsf.debug.ui.viewmodel.DebugViewSelectionRootLayoutNode; +import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePreferenceStore; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; @@ -20,11 +22,18 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationCont @SuppressWarnings("restriction") public class VariableVMProvider extends AbstractDMVMProvider implements - IColumnPresentationFactory { + IColumnPresentationFactory, IFormattedValuePreferenceStore { + + private String defaultFormatId = IFormattedValues.NATURAL_FORMAT; public VariableVMProvider(AbstractVMAdapter adapter, IPresentationContext context, DsfSession session) { super(adapter, context, session); - + + /* + * Create the variable data access routines. + */ + SyncVariableDataAccess varAccess = new SyncVariableDataAccess() ; + /* * Create the top level node to deal with the root selection. */ @@ -33,13 +42,13 @@ public class VariableVMProvider extends AbstractDMVMProvider implements /* * Create the local variables nodes next. They represent the first level shown in the view. */ - IVMLayoutNode localsNode = new VariableLocalsLayoutNode(this, getSession()); + IVMLayoutNode localsNode = new VariableLocalsLayoutNode(this, this, getSession(), varAccess); debugViewSelection.setChildNodes(new IVMLayoutNode[] { localsNode }); /* * Create the next level which represents members of structs/unions/enums and elements of arrays. */ - IVMLayoutNode subExpressioNode = new VariableSubExpressionsLayoutNode(this, getSession()); + IVMLayoutNode subExpressioNode = new VariableSubExpressionsLayoutNode(this, getSession(), varAccess); localsNode.setChildNodes(new IVMLayoutNode[] { subExpressioNode }); /* @@ -57,4 +66,20 @@ public class VariableVMProvider extends AbstractDMVMProvider implements public String getColumnPresentationId(IPresentationContext context, Object element) { return VariableColumnPresentation.ID; } + + /* + * (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePreferenceStore#getDefaultFormatId() + */ + public String getDefaultFormatId() { + return defaultFormatId; + } + + /* + * (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePreferenceStore#setDefaultFormatId(java.lang.String) + */ + public void setDefaultFormatId(String id) { + defaultFormatId = id; + } } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java index 6b76e046870..c4f2121246f 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java @@ -14,6 +14,7 @@ import java.util.Map; import org.eclipse.cdt.core.IAddress; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMData; import org.eclipse.dd.dsf.datamodel.IDMEvent; @@ -167,4 +168,17 @@ public interface IExpressions extends IDMService, IFormattedValues { * @param rm: Request completion monitor. */ void getBaseExpressions(IExpressionDMContext exprContext, DataRequestMonitor rm); + + /** + * This method supports the writing/modifying the value of the expression. + * + * @param expressionContext: The data model context representing an expression. + * + * @param expressionValue: The new value of the expression as a String. + * + * @param formatId: The format ID specifying the format of parameter expressionValue. + * + * @param rm: Request completion monitor. + */ + void writeExpression(IDMContext expressionContext, String exressionValue, String formatId, RequestMonitor rm); } From a3112d1cd29a9759e861e7b888ce2e259a493777 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Thu, 31 May 2007 21:53:38 +0000 Subject: [PATCH 094/834] missing commas --- plugins/org.eclipse.dd.dsf.debug/build.properties | 2 +- plugins/org.eclipse.dd.dsf.ui/build.properties | 2 +- plugins/org.eclipse.dd.dsf/build.properties | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/build.properties b/plugins/org.eclipse.dd.dsf.debug/build.properties index f8adf614f3e..786b1df9364 100644 --- a/plugins/org.eclipse.dd.dsf.debug/build.properties +++ b/plugins/org.eclipse.dd.dsf.debug/build.properties @@ -2,5 +2,5 @@ source.. = src/ output.. = bin/ bin.includes = META-INF/,\ .,\ - plugin.xml\ + plugin.xml,\ about.html diff --git a/plugins/org.eclipse.dd.dsf.ui/build.properties b/plugins/org.eclipse.dd.dsf.ui/build.properties index f8adf614f3e..786b1df9364 100644 --- a/plugins/org.eclipse.dd.dsf.ui/build.properties +++ b/plugins/org.eclipse.dd.dsf.ui/build.properties @@ -2,5 +2,5 @@ source.. = src/ output.. = bin/ bin.includes = META-INF/,\ .,\ - plugin.xml\ + plugin.xml,\ about.html diff --git a/plugins/org.eclipse.dd.dsf/build.properties b/plugins/org.eclipse.dd.dsf/build.properties index f8adf614f3e..786b1df9364 100644 --- a/plugins/org.eclipse.dd.dsf/build.properties +++ b/plugins/org.eclipse.dd.dsf/build.properties @@ -2,5 +2,5 @@ source.. = src/ output.. = bin/ bin.includes = META-INF/,\ .,\ - plugin.xml\ + plugin.xml,\ about.html From 68057fa52d8280a1b75a372077446cfa5bd35906 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Thu, 31 May 2007 22:01:16 +0000 Subject: [PATCH 095/834] typo --- plugins/org.eclipse.dd.dsf.debug.ui/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/build.properties b/plugins/org.eclipse.dd.dsf.debug.ui/build.properties index 5a18b73d486..4a2586141ff 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/build.properties +++ b/plugins/org.eclipse.dd.dsf.debug.ui/build.properties @@ -2,5 +2,5 @@ source.. = src/ output.. = bin/ bin.includes = META-INF/,\ plugin.xml,\ - about.xml,\ + about.html,\ . From aaa58b4fdb2256912f42790c8f6a5698b323c359 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 31 May 2007 22:31:30 +0000 Subject: [PATCH 096/834] Fixed update bug in registers view (bug 190366). --- .../dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java index f5698376115..3c654654c55 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java @@ -379,7 +379,7 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode Date: Fri, 1 Jun 2007 00:12:00 +0000 Subject: [PATCH 097/834] Added javadocs to ExpressionManagerLayoutNode.java (bug 187886). --- .../ExpressionManagerLayoutNode.java | 101 +++++++++++++----- 1 file changed, 75 insertions(+), 26 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerLayoutNode.java index f8adf60a30b..d658cf26866 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerLayoutNode.java @@ -10,9 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; -import java.util.HashMap; import java.util.List; -import java.util.Map; import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; @@ -42,11 +40,31 @@ import org.eclipse.jface.viewers.ICellModifier; import org.eclipse.jface.viewers.TextCellEditor; import org.eclipse.swt.widgets.Composite; +/** + * This is the top-level layout node in the expressions view. Its job is to: + *
  • + *
      retrieve the {@link IExpression} objects from the global {@link IExpressionManager},
    + *
      retrieve the expression string from the IExpression object,
    + *
      then to call the configured expression nodes to parse the expression string.
    + *
  • + *

    + * This node is not intended to have any standard child layout nodes, therefore + * the implementation of {@link #setChildNodes(IVMLayoutNode[])} throws an exception. + * Instead users should call {@link #setExpressionLayoutNodes(IExpressionLayoutNode[])} + * to configure layout nodes that this node will delegate to when processing expressions. + *

    + */ @SuppressWarnings("restriction") public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode implements IElementLabelProvider, IElementEditor { + /** + * VMC of an expression object that failed to get parsed by any of the + * configured expression layout nodes. It is only used to display an + * error message in the view, and to allow the user to edit the + * expression. + */ private class InvalidExpressionVMC extends AbstractVMContext { final IExpression fExpression; @@ -76,8 +94,13 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode } } + /** Array of expression nodes which parse the user expressions and handle model events */ private IExpressionLayoutNode[] fExpressionNodes = new IExpressionLayoutNode[0]; + + /** Local reference to the global expression manager */ private IExpressionManager fManager = DebugPlugin.getDefault().getExpressionManager(); + + /** Cached reference to a cell modifier for editing expression strings of invalid expressions */ private WatchExpressionCellModifier fWatchExpressionCellModifier = new WatchExpressionCellModifier(); public ExpressionManagerLayoutNode(AbstractVMProvider provider) { @@ -85,6 +108,10 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode } public void updateHasElements(IHasChildrenUpdate[] updates) { + // Test availability of children based on whether there are any expressions + // in the manager. We assume that the getExpressions() will just read + // local state data, so we don't bother using a job to perform this + // operation. for (int i = 0; i < updates.length; i++) { updates[i].setHasChilren(fManager.getExpressions().length != 0); updates[i].done(); @@ -99,6 +126,11 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode public void updateElements(final IChildrenUpdate update) { final IExpression[] expressions = fManager.getExpressions(); + // For each (expression) element in update, find the layout node that can + // parse it. And for each expression that has a corresponding layout node, + // call IExpressionLayoutNode#getElementForExpression to generate a VMC. + // Since the last is an async call, we need to create a multi-RM to wait + // for all the calls to complete. final CountingRequestMonitor multiRm = new CountingRequestMonitor(getExecutor(), null) { @Override protected void handleCompleted() { @@ -107,10 +139,9 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode }; int expressionRmCount = 0; - for (int i = update.getOffset(); i < update.getOffset() + update.getLength() && i < expressions.length; i++) { - // Check the array boundries as the expression manager could change asynchronously. + // Check the array boundaries as the expression manager could change asynchronously. // The expression manager change should lead to a refresh in the view. if (i > expressions.length) { continue; @@ -124,6 +155,10 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode update.setChild(new InvalidExpressionVMC(expression), i); } else { expressionRmCount++; + // getElementForExpression() accepts a IElementsUpdate as an argument. + // Construct an instance of VMElementsUpdate which will call a + // the request monitor when it is finished. The request monitor + // will in turn set the element in the update argument in this method. VMElementsUpdate expressionElementUpdate = new VMElementsUpdate( update, 0, 1, new DataRequestMonitor>(getExecutor(), multiRm) { @@ -143,6 +178,7 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode } } + // If no expressions were parsed, we're finished. if (expressionRmCount > 0) { multiRm.setCount(expressionRmCount); } else { @@ -151,6 +187,9 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode } public void update(ILabelUpdate[] updates) { + // The label update handler only handles labels for the invalid expression VMCs. + // The expression layout nodes are responsible for supplying label providers + // for their VMCs. for (ILabelUpdate update : updates) { if (update.getElement() instanceof InvalidExpressionVMC) { updateInvalidExpressionVMCLabel(update, (InvalidExpressionVMC) update.getElement()); @@ -159,7 +198,10 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode } } } - + + /** + * Updates the label for the InvalidExpressionVMC. + */ private void updateInvalidExpressionVMCLabel(ILabelUpdate update, InvalidExpressionVMC vmc) { String[] columnIds = update.getColumnIds() != null ? update.getColumnIds() : new String[] { IDebugVMConstants.COLUMN_ID__NAME }; @@ -182,6 +224,10 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode update.done(); } + /** + * Convenience call that iterates through all the configured expression + * layout nodes and finds the first one that can parse the given expression. + */ private IExpressionLayoutNode findNodeForExpression(String expressionText) { for (IExpressionLayoutNode node : fExpressionNodes) { if (node.getExpressionLength(expressionText) > 0) { @@ -191,11 +237,26 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode return null; } + /** + * ExpressionManagerLayoutNode does not support child layout nodes. + * @see #setExpressionLayoutNodes(IExpressionLayoutNode[]) + */ @Override public void setChildNodes(IVMLayoutNode[] childNodes) { throw new UnsupportedOperationException("This node does not support children."); //$NON-NLS-1$ } + /** + * Configures the set of expression layout nodes that the expression manager layout + * node will use to parse the expressions. + *

    + * Note: The nodes specified in the array will be called to parse expressions, + * in the order as they are in the array. Therefore if one node is a "greedy" + * parser, and will accept any expression string, it should appear last in the list + * of the nodes. + *

    + * @param nodes Array of expression layout nodes to configure with the manager. + */ public void setExpressionLayoutNodes(IExpressionLayoutNode[] nodes) { fExpressionNodes = nodes; } @@ -209,19 +270,20 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode super.dispose(); } - /** - * If any of the children nodes have delta flags, that means that this - * node has to generate a delta as well. - */ @Override public int getDeltaFlags(Object event) { int retVal = 0; - // Add a flag if the list of expressions has changed. + // Add a flag if the list of expressions in the global expression manager has changed. if (event instanceof ExpressionsChangedEvent) { retVal |= IModelDelta.CONTENT; } + // If any of the expressions nodes have delta flags, that means that this + // node probably needs to generate a delta as well. Ideally, we would call + // IExpressionLayoutNode.getDeltaFlagsForExpression() here, but getDeltaFlags() + // is an optimization call anyway, and it's OK if it generates some false + // positives. We will call getDeltaFlagsForExpression in buildDelta() instead.. for (IExpressionLayoutNode node : fExpressionNodes) { retVal |= node.getDeltaFlags(event); } @@ -236,6 +298,9 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode parentDelta.addFlags(IModelDelta.CONTENT); } + // Once again, for each expression, find its corresponding layout node and ask that + // layout node for its delta flags for given event. If there are delta flags to be + // generated, call the asynchronous method to do so. CountingRequestMonitor multiRm = new CountingRequestMonitor(getExecutor(), requestMonitor); int buildDeltaForExpressionCallCount = 0; @@ -263,22 +328,6 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode } } - /** - * Convenience method that returns the child layout nodes which return - * true to the hasDeltaFlags() test for the given - * event. - */ - protected Map getExpressionsWithDeltaFlags(String expressionText, Object e) { - Map nodes = new HashMap(); - for (final IExpressionLayoutNode node : fExpressionNodes) { - int delta = node.getDeltaFlagsForExpression(expressionText, e); - if (delta != IModelDelta.NO_CHANGE) { - nodes.put(node, delta); - } - } - return nodes; - } - public CellEditor getCellEditor(IPresentationContext context, String columnId, Object element, Composite parent) { if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(columnId)) { From 3bef5d71e52147cfccb87777e70159937485d7bb Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 1 Jun 2007 04:50:03 +0000 Subject: [PATCH 098/834] Added some javadocs to IExpressionLayoutNode.java (bug 187886). --- .../expression/IExpressionLayoutNode.java | 32 ++++++++++++++++--- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionLayoutNode.java index ea30c602a42..782ba7784a0 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionLayoutNode.java @@ -18,14 +18,38 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.jface.viewers.TreePath; /** - * + * Interface for layout nodes that can be used within the expression view. + * The methods of this interface allow the {@link ExpressionManagerLayoutNode} + * to use this layout node to delegate expression parsing to this node, and to + * generate deltas for expressions that are owned by this node. */ @SuppressWarnings("restriction") public interface IExpressionLayoutNode extends IVMLayoutNode { - int getExpressionLength(String expression); - void getElementForExpression(IChildrenUpdate update, String expressionText, IExpression expression); - int getDeltaFlagsForExpression(String expressionText, Object event); + /** + * Returns the length of the portion of the expression that can be parsed + * by this node. + * @param expression String to parse + * @return length of the expression recognized by this node. Length of less than 1 + * indicates that this node cannot parse this expression. + */ + int getExpressionLength(String expression); + + /** + * Retrieves the element for the given expression. The node implementing + * this method should parse the expression and set a valid view model + * context (VMC) element in the update provided as an argument. + * @param update to fill in with the element. The tree path in this update + * object may contain elements which are not actually displayed in the viewer. + * These element may have been added to the original path by other expression + * layout nodes that have parsed preceding parts of the expression. + * @param expressionText expression string to parse + * @param expression expression object that the returned element should contain + */ + void getElementForExpression(IChildrenUpdate update, String expressionText, IExpression expression); + + int getDeltaFlagsForExpression(String expressionText, Object event); + void buildDeltaForExpression(IExpression expression, int elementIdx, String expressionText, Object event, VMDelta parentDelta, TreePath path, RequestMonitor rm); } From 4cade0e00c53e4bf11a2724a4d92d754d31c9911 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Thu, 7 Jun 2007 18:35:58 +0000 Subject: [PATCH 099/834] bumped versions to 1.0.0 on HEAD for all DSF plugins and features --- features/org.eclipse.dd.dsf.examples-feature/feature.xml | 2 +- features/org.eclipse.dd.dsf.gdb-feature/feature.xml | 2 +- features/org.eclipse.dd.dsf.sdk-feature/feature.xml | 2 +- features/org.eclipse.dd.dsf.test-feature/feature.xml | 2 +- plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF | 2 +- plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF | 2 +- plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF | 2 +- plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/features/org.eclipse.dd.dsf.examples-feature/feature.xml b/features/org.eclipse.dd.dsf.examples-feature/feature.xml index 9909afd75a9..60bd795e6e9 100644 --- a/features/org.eclipse.dd.dsf.examples-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.examples-feature/feature.xml @@ -2,7 +2,7 @@ diff --git a/features/org.eclipse.dd.dsf.gdb-feature/feature.xml b/features/org.eclipse.dd.dsf.gdb-feature/feature.xml index 91e0c2146fa..512cf8270ce 100644 --- a/features/org.eclipse.dd.dsf.gdb-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.gdb-feature/feature.xml @@ -2,7 +2,7 @@ diff --git a/features/org.eclipse.dd.dsf.sdk-feature/feature.xml b/features/org.eclipse.dd.dsf.sdk-feature/feature.xml index 83c4870e544..dcf8eb7c355 100644 --- a/features/org.eclipse.dd.dsf.sdk-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.sdk-feature/feature.xml @@ -2,7 +2,7 @@ diff --git a/features/org.eclipse.dd.dsf.test-feature/feature.xml b/features/org.eclipse.dd.dsf.test-feature/feature.xml index bb90c52e773..8506c43062a 100644 --- a/features/org.eclipse.dd.dsf.test-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.test-feature/feature.xml @@ -2,7 +2,7 @@ diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF index 682b83b2ecd..c768637b570 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: Debug Services Framework Debug UI Bundle-Vendor: Eclipse.org Bundle-SymbolicName: org.eclipse.dd.dsf.debug.ui; singleton:=true -Bundle-Version: 0.9.0.qualifier +Bundle-Version: 1.0.0.qualifier Bundle-Activator: org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin Bundle-Localization: plugin Require-Bundle: org.eclipse.ui, diff --git a/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF index d15f4f53dbd..e803dac64a4 100644 --- a/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: Debug Services Framework Debug Bundle-Vendor: Eclipse.org Bundle-SymbolicName: org.eclipse.dd.dsf.debug -Bundle-Version: 0.9.0.qualifier +Bundle-Version: 1.0.0.qualifier Bundle-Activator: org.eclipse.dd.dsf.debug.DsfDebugPlugin Bundle-Localization: plugin Require-Bundle: org.eclipse.core.runtime, diff --git a/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF index b1e95a31747..f2946e4c0df 100644 --- a/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: Debug Services Framework UI Bundle-Vendor: Eclipse.org Bundle-SymbolicName: org.eclipse.dd.dsf.ui -Bundle-Version: 0.9.0.qualifier +Bundle-Version: 1.0.0.qualifier Bundle-Activator: org.eclipse.dd.dsf.ui.DsfUIPlugin Bundle-Localization: plugin Require-Bundle: org.eclipse.ui, diff --git a/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF index e02419404ab..7464f6a24e4 100644 --- a/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: Debug Services Framework Core Bundle-Vendor: Eclipse.org Bundle-SymbolicName: org.eclipse.dd.dsf -Bundle-Version: 0.9.0.qualifier +Bundle-Version: 1.0.0.qualifier Bundle-Activator: org.eclipse.dd.dsf.DsfPlugin Bundle-Localization: plugin Require-Bundle: org.eclipse.core.runtime From d791a663238082b87eb4151b89a8ec458c900e55 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 7 Jun 2007 21:18:56 +0000 Subject: [PATCH 100/834] Got rid of compiler warning for un-used parameters. --- .../.settings/org.eclipse.jdt.core.prefs | 4 ++-- .../.settings/org.eclipse.jdt.core.prefs | 4 ++-- .../org.eclipse.dd.dsf/.settings/org.eclipse.jdt.core.prefs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.dd.dsf.debug/.settings/org.eclipse.jdt.core.prefs index 6468150f58d..576c2ef7ad5 100644 --- a/plugins/org.eclipse.dd.dsf.debug/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.eclipse.dd.dsf.debug/.settings/org.eclipse.jdt.core.prefs @@ -1,4 +1,4 @@ -#Fri May 18 08:59:30 PDT 2007 +#Thu Jun 07 11:07:03 PDT 2007 eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 @@ -57,7 +57,7 @@ org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverridin org.eclipse.jdt.core.compiler.problem.unusedImport=error org.eclipse.jdt.core.compiler.problem.unusedLabel=warning org.eclipse.jdt.core.compiler.problem.unusedLocal=warning -org.eclipse.jdt.core.compiler.problem.unusedParameter=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning diff --git a/plugins/org.eclipse.dd.dsf.ui/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.dd.dsf.ui/.settings/org.eclipse.jdt.core.prefs index f52190daad7..90518f96b4e 100644 --- a/plugins/org.eclipse.dd.dsf.ui/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.eclipse.dd.dsf.ui/.settings/org.eclipse.jdt.core.prefs @@ -1,4 +1,4 @@ -#Fri May 18 09:01:11 PDT 2007 +#Thu Jun 07 11:08:31 PDT 2007 eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 @@ -57,7 +57,7 @@ org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverridin org.eclipse.jdt.core.compiler.problem.unusedImport=error org.eclipse.jdt.core.compiler.problem.unusedLabel=warning org.eclipse.jdt.core.compiler.problem.unusedLocal=warning -org.eclipse.jdt.core.compiler.problem.unusedParameter=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning diff --git a/plugins/org.eclipse.dd.dsf/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.dd.dsf/.settings/org.eclipse.jdt.core.prefs index 217edbcea2a..38c2cca3757 100644 --- a/plugins/org.eclipse.dd.dsf/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.eclipse.dd.dsf/.settings/org.eclipse.jdt.core.prefs @@ -1,4 +1,4 @@ -#Fri May 18 08:59:24 PDT 2007 +#Thu Jun 07 11:06:42 PDT 2007 eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 @@ -57,7 +57,7 @@ org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverridin org.eclipse.jdt.core.compiler.problem.unusedImport=error org.eclipse.jdt.core.compiler.problem.unusedLabel=warning org.eclipse.jdt.core.compiler.problem.unusedLocal=warning -org.eclipse.jdt.core.compiler.problem.unusedParameter=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning From bc990e09bac1353be789002d65aa2a5555817a4c Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 7 Jun 2007 21:20:22 +0000 Subject: [PATCH 101/834] Applied implementation of service from DSF Coding Camp (bug 159696). --- .../dd/dsf/debug/service/IExpressions.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java index c4f2121246f..a23ac975104 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java @@ -30,9 +30,22 @@ public interface IExpressions extends IDMService, IFormattedValues { /** * Expression context. Since some expressions have children, expression contexts can be have an - * arbitrary number of parents of type ExpressionContext. + * arbitrary number of parents of type IExpressionDMContext. */ public interface IExpressionDMContext extends IFormattedDataDMContext { + /** + * Returns a fully qualified expression string represented by this context. This + * expression string is the same as the string that is sent to the debug engine to be + * evaluated in context of a stack frame, thread, or a symbol context. + * @return + */ + String getQualifiedExpression(); + + /** + * If this expression is a sub-expression of another expression, this method returns + * the expression relative to the parent of this expression. Otherwise this method + * will return the same string as {@link #getQualifiedExpression()}. + */ String getExpression(); } From 6e3bf13abdd344823a78a6d8bc9aca9376aebda4 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 7 Jun 2007 21:59:06 +0000 Subject: [PATCH 102/834] Got rid of compiler warning for un-used parameters. --- .../.settings/org.eclipse.jdt.core.prefs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.dd.dsf.debug.ui/.settings/org.eclipse.jdt.core.prefs index e5a50196ba4..1d69933f2bd 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.eclipse.dd.dsf.debug.ui/.settings/org.eclipse.jdt.core.prefs @@ -1,4 +1,4 @@ -#Fri May 18 08:59:36 PDT 2007 +#Thu Jun 07 11:07:18 PDT 2007 eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 @@ -57,7 +57,7 @@ org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverridin org.eclipse.jdt.core.compiler.problem.unusedImport=error org.eclipse.jdt.core.compiler.problem.unusedLabel=warning org.eclipse.jdt.core.compiler.problem.unusedLocal=warning -org.eclipse.jdt.core.compiler.problem.unusedParameter=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning From 434c29ab17cc6c017a6965352a946e1952ed1d2f Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 7 Jun 2007 23:17:06 +0000 Subject: [PATCH 103/834] Applied patch implementing tracking of selected stack frame (bug 159696). --- .../eclipse/dd/dsf/debug/service/command/ICommand.java | 9 +++++++++ .../src/org/eclipse/dd/dsf/datamodel/DMContexts.java | 3 +++ 2 files changed, 12 insertions(+) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommand.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommand.java index 1e6a2520705..8c8a53c4b48 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommand.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommand.java @@ -7,10 +7,13 @@ * * Contributors: * Wind River Systems - initial API and implementation + * Ericsson - Modified for additional features in DSF Reference implementation *******************************************************************************/ package org.eclipse.dd.dsf.debug.service.command; +import org.eclipse.dd.dsf.datamodel.IDMContext; + /** * Command interface for creating and manipulating GDB/MI commands @@ -31,6 +34,12 @@ public interface ICommand { * @return newly created command, or null if command cannot be coalesced */ public ICommand coalesceWith( ICommand command ); + + /** + * Returns the context that this command is to be evaluated in. May be null + * if the command does not need to be evaluated in a specific context. + */ + public IDMContext getContext(); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/DMContexts.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/DMContexts.java index 6b7e0bd0e71..d0877827bf3 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/DMContexts.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/DMContexts.java @@ -7,6 +7,7 @@ * * Contributors: * Wind River Systems - initial API and implementation + * Ericsson - Modified for additional features in DSF Reference implementation *******************************************************************************/ package org.eclipse.dd.dsf.datamodel; @@ -31,6 +32,8 @@ public class DMContexts { @ThreadSafe @SuppressWarnings("unchecked") public static V getAncestorOfType(IDMContext ctx, Class ancestorType) { + if(ctx == null) + return null; if (ancestorType.isAssignableFrom(ctx.getClass())) { return (V)ctx; } From 51452d7e2c7473e9ee0c74883a3c34b9e092c4cd Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 8 Jun 2007 20:37:43 +0000 Subject: [PATCH 104/834] Moved generic packages out of the org.eclipse.dd.dsf.mi.* plugins and into the org.eclipse.dd.dsf.debug.* plugins as appropriate, in preparation for the memory view work (bug 160047). --- .../META-INF/MANIFEST.MF | 6 +- .../org.eclipse.dd.dsf.debug.ui/plugin.xml | 46 ++ .../debug/ui/actions/DsfCommandRunnable.java | 84 +++ .../debug/ui/actions/DsfResumeCommand.java | 66 +++ .../debug/ui/actions/DsfStepIntoCommand.java | 65 +++ .../debug/ui/actions/DsfStepOverCommand.java | 65 +++ .../ui/actions/DsfStepReturnCommand.java | 65 +++ .../debug/ui/actions/DsfSuspendCommand.java | 65 +++ .../debug/ui/actions/DsfTerminateCommand.java | 102 ++++ .../InstructionPointerImageProvider.java | 45 ++ .../InstructionPointerManager.java | 231 ++++++++ .../sourcelookup/MISourceDisplayAdapter.java | 552 ++++++++++++++++++ .../ui/sourcelookup/SourceLookupResult.java | 129 ++++ .../META-INF/MANIFEST.MF | 6 +- .../debug/model/DsfMemoryBlockRetrieval.java | 49 ++ .../DsfMISourceLookupParticipant.java | 228 ++++++++ 16 files changed, 1801 insertions(+), 3 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfResumeCommand.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepIntoCommand.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepOverCommand.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepReturnCommand.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfSuspendCommand.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfTerminateCommand.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/InstructionPointerImageProvider.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/InstructionPointerManager.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/SourceLookupResult.java create mode 100644 plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java create mode 100644 plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF index c768637b570..1a96a0189b8 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF @@ -12,6 +12,8 @@ Require-Bundle: org.eclipse.ui, org.eclipse.debug.core, org.eclipse.debug.ui, org.eclipse.ui.ide, + org.eclipse.jface.text, + org.eclipse.ui.workbench.texteditor, org.eclipse.dd.dsf, org.eclipse.dd.dsf.ui, org.eclipse.dd.dsf.debug, @@ -24,5 +26,7 @@ Export-Package: org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport, org.eclipse.dd.dsf.debug.ui.viewmodel.launch, org.eclipse.dd.dsf.debug.ui.viewmodel.register, - org.eclipse.dd.dsf.debug.ui.viewmodel.variable + org.eclipse.dd.dsf.debug.ui.viewmodel.variable, + org.eclipse.dd.dsf.debug.ui.sourcelookup, + org.eclipse.dd.dsf.debug.ui.actions Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml index 614503dc5b9..ec8c6e8158e 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml +++ b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml @@ -7,4 +7,50 @@ delegateClass="org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionDelegate"/> + + + + + + + + + + + + + + + + diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java new file mode 100644 index 00000000000..d77cfa1a26d --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * 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.actions; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.debug.service.INativeProcesses; +import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.IStepQueueManager; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode.DMVMContext; +import org.eclipse.debug.core.commands.IDebugCommandRequest; + +@SuppressWarnings("restriction") +@Immutable +public abstract class DsfCommandRunnable extends DsfRunnable { + private final IExecutionDMContext fContext; + private final DsfServicesTracker fTracker; + private final IDebugCommandRequest fRequest; + + public IExecutionDMContext getContext() { return fContext; } + public IRunControl getRunControl() { + return fTracker.getService(IRunControl.class); + } + public IStepQueueManager getStepQueueMgr() { + return fTracker.getService(IStepQueueManager.class); + } + + public INativeProcesses getProcesses() { + return fTracker.getService(INativeProcesses.class); + } + + public DsfCommandRunnable(DsfServicesTracker servicesTracker, Object element, IDebugCommandRequest request) { + fTracker = servicesTracker; + if (element instanceof DMVMContext) { + // Javac doesn't like the cast to "(AbstractDMVMLayoutNode.DMVMContext)" need to use the + // construct below and suppress warnings. + @SuppressWarnings("unchecked") + AbstractDMVMLayoutNode.DMVMContext vmc = (AbstractDMVMLayoutNode.DMVMContext)element; + fContext = DMContexts.getAncestorOfType(vmc.getDMC(), IExecutionDMContext.class); + } else { + fContext = null; + } + + fRequest = request; + } + + public final void run() { + if (fRequest.isCanceled()) return; + if (getContext() == null) { + fRequest.setStatus(makeError("Selected object does not support run control.", null)); //$NON-NLS-1$ + } else if (getRunControl() == null) { + fRequest.setStatus(makeError("Run Control not available", null)); //$NON-NLS-1$ + } else { + doExecute(); + } + fRequest.done(); + } + + /** + * Method to perform the actual work. It should not call monitor.done(), because + * it will be called in the super-class. + */ + protected abstract void doExecute(); + + protected IStatus makeError(String message, Throwable e) { + return new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, -1, message, e); + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfResumeCommand.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfResumeCommand.java new file mode 100644 index 00000000000..23adc2644d4 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfResumeCommand.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.actions; + +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.debug.core.commands.IDebugCommandRequest; +import org.eclipse.debug.core.commands.IEnabledStateRequest; +import org.eclipse.debug.core.commands.IResumeHandler; + +@Immutable +public class DsfResumeCommand implements IResumeHandler { + + private final DsfExecutor fExecutor; + private final DsfServicesTracker fTracker; + + public DsfResumeCommand(DsfSession session) { + fExecutor = session.getExecutor(); + fTracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), session.getId()); + } + + public void dispose() { + fTracker.dispose(); + } + + public void canExecute(final IEnabledStateRequest request) { + if (request.getElements().length != 1) { + request.setEnabled(false); + request.done(); + return; + } + + fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) { + @Override public void doExecute() { + request.setEnabled(getRunControl().canResume(getContext())); + } + }); + } + + public boolean execute(final IDebugCommandRequest request) { + if (request.getElements().length != 1) { + request.done(); + return false; + } + + fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) { + @Override public void doExecute() { + getRunControl().resume(getContext(), new RequestMonitor(fExecutor, null)); + } + }); + return false; + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepIntoCommand.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepIntoCommand.java new file mode 100644 index 00000000000..16c1b183d48 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepIntoCommand.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * 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.actions; + +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.debug.service.IRunControl.StepType; +import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.debug.core.commands.IDebugCommandRequest; +import org.eclipse.debug.core.commands.IEnabledStateRequest; +import org.eclipse.debug.core.commands.IStepIntoHandler; + +@Immutable +public class DsfStepIntoCommand implements IStepIntoHandler { + + private final DsfExecutor fExecutor; + private final DsfServicesTracker fTracker; + + public DsfStepIntoCommand(DsfSession session) { + fExecutor = session.getExecutor(); + fTracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), session.getId()); + } + + public void dispose() { + fTracker.dispose(); + } + + public void canExecute(final IEnabledStateRequest request) { + if (request.getElements().length != 1) { + request.setEnabled(false); + request.done(); + return; + } + + fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) { + @Override public void doExecute() { + request.setEnabled(getStepQueueMgr().canEnqueueStep(getContext())); + } + }); + } + + public boolean execute(final IDebugCommandRequest request) { + if (request.getElements().length != 1) { + request.done(); + return false; + } + + fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) { + @Override public void doExecute() { + getStepQueueMgr().enqueueStep(getContext(), StepType.STEP_INTO); + } + }); + return true; + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepOverCommand.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepOverCommand.java new file mode 100644 index 00000000000..6881453e80d --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepOverCommand.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * 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.actions; + +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.debug.service.IRunControl.StepType; +import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.debug.core.commands.IDebugCommandRequest; +import org.eclipse.debug.core.commands.IEnabledStateRequest; +import org.eclipse.debug.core.commands.IStepIntoHandler; + +@Immutable +public class DsfStepOverCommand implements IStepIntoHandler { + + private final DsfExecutor fExecutor; + private final DsfServicesTracker fTracker; + + public DsfStepOverCommand(DsfSession session) { + fExecutor = session.getExecutor(); + fTracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), session.getId()); + } + + public void dispose() { + fTracker.dispose(); + } + + public void canExecute(final IEnabledStateRequest request) { + if (request.getElements().length != 1) { + request.setEnabled(false); + request.done(); + return; + } + + fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) { + @Override public void doExecute() { + request.setEnabled(getStepQueueMgr().canEnqueueStep(getContext())); + } + }); + } + + public boolean execute(final IDebugCommandRequest request) { + if (request.getElements().length != 1) { + request.done(); + return false; + } + + fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) { + @Override public void doExecute() { + getStepQueueMgr().enqueueStep(getContext(), StepType.STEP_OVER); + } + }); + return true; + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepReturnCommand.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepReturnCommand.java new file mode 100644 index 00000000000..0e179cebc19 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepReturnCommand.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * 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.actions; + +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.debug.service.IRunControl.StepType; +import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.debug.core.commands.IDebugCommandRequest; +import org.eclipse.debug.core.commands.IEnabledStateRequest; +import org.eclipse.debug.core.commands.IStepIntoHandler; + +@Immutable +public class DsfStepReturnCommand implements IStepIntoHandler { + + private final DsfExecutor fExecutor; + private final DsfServicesTracker fTracker; + + public DsfStepReturnCommand(DsfSession session) { + fExecutor = session.getExecutor(); + fTracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), session.getId()); + } + + public void dispose() { + fTracker.dispose(); + } + + public void canExecute(final IEnabledStateRequest request) { + if (request.getElements().length != 1) { + request.setEnabled(false); + request.done(); + return; + } + + fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) { + @Override public void doExecute() { + request.setEnabled(getStepQueueMgr().canEnqueueStep(getContext())); + } + }); + } + + public boolean execute(final IDebugCommandRequest request) { + if (request.getElements().length != 1) { + request.done(); + return false; + } + + fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) { + @Override public void doExecute() { + getStepQueueMgr().enqueueStep(getContext(), StepType.STEP_RETURN); + } + }); + return true; + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfSuspendCommand.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfSuspendCommand.java new file mode 100644 index 00000000000..882d165fe09 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfSuspendCommand.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * 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.actions; + +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.debug.core.commands.IDebugCommandRequest; +import org.eclipse.debug.core.commands.IEnabledStateRequest; +import org.eclipse.debug.core.commands.ISuspendHandler; + +@Immutable +public class DsfSuspendCommand implements ISuspendHandler { + private final DsfExecutor fExecutor; + private final DsfServicesTracker fTracker; + + public DsfSuspendCommand(DsfSession session) { + fExecutor = session.getExecutor(); + fTracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), session.getId()); + } + + public void dispose() { + fTracker.dispose(); + } + + public void canExecute(final IEnabledStateRequest request) { + if (request.getElements().length != 1) { + request.setEnabled(false); + request.done(); + return; + } + + fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) { + @Override public void doExecute() { + request.setEnabled(getRunControl().canSuspend(getContext())); + } + }); + } + + public boolean execute(final IDebugCommandRequest request) { + if (request.getElements().length != 1) { + request.done(); + return false; + } + + fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) { + @Override public void doExecute() { + getRunControl().suspend(getContext(), new RequestMonitor(fExecutor, null)); + } + }); + return false; + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfTerminateCommand.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfTerminateCommand.java new file mode 100644 index 00000000000..5f1af3cd6a9 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfTerminateCommand.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * 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.actions; + +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.debug.service.INativeProcesses; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode.DMVMContext; +import org.eclipse.debug.core.commands.IDebugCommandRequest; +import org.eclipse.debug.core.commands.IEnabledStateRequest; +import org.eclipse.debug.core.commands.ITerminateHandler; + +public class DsfTerminateCommand implements ITerminateHandler { + private final DsfExecutor fExecutor; + private final DsfServicesTracker fTracker; + + public DsfTerminateCommand(DsfSession session) { + fExecutor = session.getExecutor(); + fTracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), session.getId()); + } + + public void dispose() { + fTracker.dispose(); + } + + // Run control may not be avilable after a connection is terminated and shut down. + public void canExecute(final IEnabledStateRequest request) { + if (request.getElements().length != 1 || + !(request.getElements()[0] instanceof DMVMContext) ) + { + request.setEnabled(false); + request.done(); + return; + } + + // Javac doesn't like the cast to "(AbstractDMVMLayoutNode.DMVMContext)" need to use the + // construct below and suppress warnings. + @SuppressWarnings("unchecked") + AbstractDMVMLayoutNode.DMVMContext vmc = (AbstractDMVMLayoutNode.DMVMContext)request.getElements()[0]; + final IExecutionDMContext dmc = DMContexts.getAncestorOfType(vmc.getDMC(), IExecutionDMContext.class); + if (dmc == null) { + request.setEnabled(false); + request.done(); + return; + } + + fExecutor.execute( + new DsfRunnable() { + public void run() { + // Get the processes service and the exec context. + INativeProcesses processes = fTracker.getService(INativeProcesses.class); + if (processes == null || dmc == null) { + // Context or service already invalid. + request.done(); + } else { + // Check the teriminate. + processes.canTerminate( + processes.getThreadForExecutionContext(dmc), + new DataRequestMonitor(fExecutor, null) { + @Override + public void handleCompleted() { + request.setEnabled(getData()); + request.done(); + } + }); + } + } + }); + } + + public boolean execute(final IDebugCommandRequest request) { + if (request.getElements().length != 1) { + request.done(); + return false; + } + + fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) { + @Override public void doExecute() { + getProcesses().terminate( + getProcesses().getThreadForExecutionContext(getContext()), new RequestMonitor(fExecutor, null)); + } + }); + return false; + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/InstructionPointerImageProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/InstructionPointerImageProvider.java new file mode 100644 index 00000000000..4c3d3bc6c99 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/InstructionPointerImageProvider.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.dsf.debug.ui.sourcelookup; + +import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.dd.dsf.debug.ui.sourcelookup.InstructionPointerManager.IPAnnotation; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.text.source.Annotation; +import org.eclipse.swt.graphics.Image; +import org.eclipse.ui.texteditor.IAnnotationImageProvider; + +@ThreadSafe +public class InstructionPointerImageProvider implements IAnnotationImageProvider { + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IAnnotationImageProvider#getManagedImage(org.eclipse.jface.text.source.Annotation) + */ + public Image getManagedImage(Annotation annotation) { + return ((IPAnnotation)annotation).getImage(); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IAnnotationImageProvider#getImageDescriptorId(org.eclipse.jface.text.source.Annotation) + */ + public String getImageDescriptorId(Annotation annotation) { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IAnnotationImageProvider#getImageDescriptor(java.lang.String) + */ + public ImageDescriptor getImageDescriptor(String imageDescritporId) { + return null; + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/InstructionPointerManager.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/InstructionPointerManager.java new file mode 100644 index 00000000000..d24ddce5c3a --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/InstructionPointerManager.java @@ -0,0 +1,231 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Wind River Systems - Adapter to use with DSF + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.sourcelookup; + + +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.IStack; +import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.debug.ui.IDebugUIConstants; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.source.Annotation; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.swt.graphics.Image; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.texteditor.IDocumentProvider; +import org.eclipse.ui.texteditor.ITextEditor; + +/** + * This class tracks instruction pointer contexts for a single DSF session. + */ +@ThreadSafe +class InstructionPointerManager { + + /** + * Editor annotation object for instruction pointers. + */ + static class IPAnnotation extends Annotation { + + /** The image for this annotation. */ + private Image fImage; + + /** Frame DMC that this IP is for **/ + private IStack.IFrameDMContext fFrame; + + /** + * Constructs an instruction pointer image. + * + * @param frame stack frame the instruction pointer is associated with + * @param annotationType the type of annotation to display (annotation identifier) + * @param text the message to display with the annotation as hover help + * @param image the image used to display the annotation + */ + IPAnnotation(IStack.IFrameDMContext frame, String annotationType, String text, Image image) { + super(annotationType, false, text); + fFrame = frame; + fImage = image; + } + + /** + * Returns this annotation's image. + * + * @return image + */ + protected Image getImage() { + return fImage; + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object other) { + if (other instanceof IPAnnotation) { + return fFrame.equals(((IPAnnotation)other).fFrame); + } + return false; + } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return fFrame.hashCode(); + } + + } + + /** + * Represents the context for a single instruction pointer. This is a convenience class + * used to store the three objects that comprise an instruction pointer 'context' so it + * can be stored in collections. + */ + static class AnnotationWrapper { + + /** The text editor for this context. */ + private ITextEditor fTextEditor; + + /** Stack frame that this annotation is for */ + private IStack.IFrameDMContext fFrameDmc; + + /** The vertical ruler annotation for this context. */ + private Annotation fAnnotation; + + AnnotationWrapper(ITextEditor textEditor, Annotation annotation, IStack.IFrameDMContext frameDmc) { + fTextEditor = textEditor; + fAnnotation = annotation; + fFrameDmc = frameDmc; + } + + /** + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object other) { + if (other instanceof AnnotationWrapper) { + AnnotationWrapper otherContext = (AnnotationWrapper) other; + return getAnnotation().equals(otherContext.getAnnotation()); + } + return false; + } + + /** + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return getAnnotation().hashCode(); + } + + ITextEditor getTextEditor() { return fTextEditor; } + Annotation getAnnotation() { return fAnnotation; } + IStack.IFrameDMContext getFrameDMC() { return fFrameDmc; } + } + + /** + * Mapping of IDebugTarget objects to (mappings of IThread objects to lists of instruction + * pointer contexts). + */ + private List fAnnotationWrappers; + + /** + * Clients must not instantiate this class. + */ + public InstructionPointerManager() { + fAnnotationWrappers = Collections.synchronizedList(new LinkedList()); + } + + /** + * Add an instruction pointer annotation in the specified editor for the + * specified stack frame. + */ + public void addAnnotation(ITextEditor textEditor, IStack.IFrameDMContext frame, Position position, boolean isTopFrame) { + + IDocumentProvider docProvider = textEditor.getDocumentProvider(); + IEditorInput editorInput = textEditor.getEditorInput(); + // If there is no annotation model, there's nothing more to do + IAnnotationModel annModel = docProvider.getAnnotationModel(editorInput); + if (annModel == null) { + return; + } + + String id; + String text; + Image image; + if (isTopFrame) { + id = "org.eclipse.dd.debug.currentIP"; //$NON-NLS-1$ + text = "Debug Current Instruction Pointer"; //$NON-NLS-1$ + image = DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_INSTRUCTION_POINTER_TOP); + } else { + id = "org.eclipse.dd.debug.secondaryIP"; //$NON-NLS-1$ + text = "Debug Call Stack"; //$NON-NLS-1$ + image = DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_INSTRUCTION_POINTER); + } + + Annotation annotation = new IPAnnotation(frame, id, text, image); + + // Add the annotation at the position to the editor's annotation model. + annModel.removeAnnotation(annotation); + annModel.addAnnotation(annotation, position); + + // Add to list of existing wrappers + fAnnotationWrappers.add(new AnnotationWrapper(textEditor, annotation, frame)); + } + + /** + * Remove all annotations associated with the specified debug target that this class + * is tracking. + */ + public void removeAnnotations(IRunControl.IExecutionDMContext execDmc) { + // Retrieve the mapping of threads to context lists + synchronized(fAnnotationWrappers) { + for (Iterator wrapperItr = fAnnotationWrappers.iterator(); wrapperItr.hasNext();) { + AnnotationWrapper wrapper = wrapperItr.next(); + if (DMContexts.isAncestorOf(wrapper.getFrameDMC(), execDmc)) { + removeAnnotation(wrapper.getTextEditor(), wrapper.getAnnotation()); + wrapperItr.remove(); + } + } + } + } + + /** Removes all annotations tracked by this manager */ + public void removeAllAnnotations() { + synchronized(fAnnotationWrappers) { + for (AnnotationWrapper wrapper : fAnnotationWrappers) { + removeAnnotation(wrapper.getTextEditor(), wrapper.getAnnotation()); + } + fAnnotationWrappers.clear(); + } + } + + /** + * Remove the specified annotation from the specified text editor. + */ + private void removeAnnotation(ITextEditor textEditor, Annotation annotation) { + IDocumentProvider docProvider = textEditor.getDocumentProvider(); + if (docProvider != null) { + IAnnotationModel annotationModel = docProvider.getAnnotationModel(textEditor.getEditorInput()); + if (annotationModel != null) { + annotationModel.removeAnnotation(annotation); + } + } + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java new file mode 100644 index 00000000000..38cab0bd740 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java @@ -0,0 +1,552 @@ +/******************************************************************************* + * 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: + * IBM Corporation - initial API and implementation + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.sourcelookup; + +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.Query; +import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.datamodel.IDMContext; +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.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.sourcelookup.DsfMISourceLookupParticipant; +import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode.DMVMContext; +import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector; +import org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant; +import org.eclipse.debug.ui.IDebugUIConstants; +import org.eclipse.debug.ui.sourcelookup.CommonSourceNotFoundEditorInput; +import org.eclipse.debug.ui.sourcelookup.ISourceDisplay; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.Position; +import org.eclipse.swt.custom.BusyIndicator; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IEditorDescriptor; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IEditorRegistry; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.part.FileEditorInput; +import org.eclipse.ui.progress.UIJob; +import org.eclipse.ui.texteditor.IDocumentProvider; +import org.eclipse.ui.texteditor.ITextEditor; + +/** + * Source display adapter that performs the source lookup, opens the editor, + * and paints the IP for the given object. + *

    + * The implementation relies on three types of jobs to perform the operations.
    + * - The first kind, "lookup job" performs the source lookup operation.
    + * - The second "display job" positions and annotates the editor.
    + * - The third clears the old IP annotations when a thread or process has resumed + * or exited. + *

    + * The the lookup jobs can run in parallel with the display or the clearing job, + * but the clearing job and the display job must not run at the same time. + * Hence there is some involved logic which ensures that the jobs are run in + * proper order. To avoid race conditions, this logic uses the session's + * dispatch thread to synchronize access to the state data of the running jobs. + */ +@ThreadSafe +@SuppressWarnings("restriction") +public class MISourceDisplayAdapter implements ISourceDisplay +{ + /** + * A job to perform source lookup on the given DMC. + */ + class LookupJob extends Job { + + private IDMContext fDmc; + private IWorkbenchPage fPage; + + /** + * Constructs a new source lookup job. + */ + public LookupJob(IDMContext dmc, IWorkbenchPage page) { + super("DSF Source Lookup"); //$NON-NLS-1$ + setPriority(Job.INTERACTIVE); + setSystem(true); + fDmc = dmc; + fPage = page; + } + + IDMContext getDmc() { return fDmc; } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + protected IStatus run(final IProgressMonitor monitor) { + if (monitor.isCanceled()) { + return Status.CANCEL_STATUS; + } + + final SourceLookupResult result = performLookup(); + executeFromJob(new DsfRunnable() { public void run() { + if (!monitor.isCanceled()) { + fPrevResult = result; + fPrevModelContext = fDmc; + fRunningLookupJob = null; + startDisplayJob(fPrevResult, fPage); + } + }}); + return Status.OK_STATUS; + } + + private SourceLookupResult performLookup() { + SourceLookupResult result = new SourceLookupResult(fDmc, null, null, null); + String editorId = null; + IEditorInput editorInput = null; + Object sourceElement = fSourceLookup.getSourceElement(fDmc); + + if (sourceElement == null) { + editorInput = new CommonSourceNotFoundEditorInput(fDmc); + editorId = IDebugUIConstants.ID_COMMON_SOURCE_NOT_FOUND_EDITOR; + } else if (sourceElement instanceof IFile) { + editorId = getEditorIdForFilename(((IFile)sourceElement).getName()); + editorInput = new FileEditorInput((IFile)sourceElement); + } + result.setEditorInput(editorInput); + result.setEditorId(editorId); + result.setSourceElement(sourceElement); + + return result; + } + + private String getEditorIdForFilename(String filename) { + IEditorRegistry registry = PlatformUI.getWorkbench().getEditorRegistry(); + IEditorDescriptor descriptor = registry.getDefaultEditor(filename); + if (descriptor == null) { + return "org.eclipse.ui.DefaultTextEditor"; //$NON-NLS-1$ + } + + return descriptor.getId(); + } + } + + /** + * Job that positions the editor and paints the IP Annotation for given DMC. + */ + class DisplayJob extends UIJob { + private SourceLookupResult fResult; + private IWorkbenchPage fPage; + + IDMContext getDmc() { return fResult.getDmc(); } + + /** + * Constructs a new source display job + */ + public DisplayJob(SourceLookupResult result, IWorkbenchPage page) { + super("Debug Source Display"); //$NON-NLS-1$ + setSystem(true); + setPriority(Job.INTERACTIVE); + fResult = result; + fPage = page; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public IStatus runInUIThread(final IProgressMonitor monitor) { + DsfRunnable displayJobFinishedRunnable = new DsfRunnable() { + public void run() { + // If the current display job does not match up with "this", it means that this job got cancelled + // after it already completed and after this runnable was queued into the dispatch thread. + if (fRunningDisplayJob == DisplayJob.this) { + fRunningDisplayJob = null; + serviceDisplayAndClearingJobs(); + } + } + }; + + if (monitor.isCanceled()) { + executeFromJob(displayJobFinishedRunnable); + return Status.CANCEL_STATUS; + } + + IEditorPart editor = openEditor(fResult, fPage); + if (editor == null) { + executeFromJob(displayJobFinishedRunnable); + return Status.OK_STATUS; + } + + ITextEditor textEditor = null; + if (editor instanceof ITextEditor) { + textEditor = (ITextEditor)editor; + } else { + textEditor = (ITextEditor) editor.getAdapter(ITextEditor.class); + } + if (textEditor != null) { + positionEditor(textEditor, fResult.getDmc()); + } + + executeFromJob(displayJobFinishedRunnable); + + return Status.OK_STATUS; + } + + /** + * Opens the editor used to display the source for an element selected in + * this view and returns the editor that was opened or null if + * no editor could be opened. + */ + private IEditorPart openEditor(SourceLookupResult result, IWorkbenchPage page) { + IEditorInput input= result.getEditorInput(); + String id= result.getEditorId(); + if (input == null || id == null) { + return null; + } + + return openEditor(page, input, id); + } + + /** + * Opens an editor in the workbench and returns the editor that was opened + * or null if an error occurred while attempting to open the + * editor. + */ + private IEditorPart openEditor(final IWorkbenchPage page, final IEditorInput input, final String id) { + final IEditorPart[] editor = new IEditorPart[] {null}; + Runnable r = new Runnable() { + public void run() { + if (!page.getWorkbenchWindow().getWorkbench().isClosing()) { + try { + editor[0] = page.openEditor(input, id, false); + } catch (PartInitException e) {} + } + } + }; + BusyIndicator.showWhile(Display.getDefault(), r); + return editor[0]; + } + + /** + * Positions the text editor for the given stack frame + */ + private void positionEditor(ITextEditor editor, final IDMContext dmc) { + if (!(dmc instanceof IFrameDMContext)) return; + final IFrameDMContext frameDmc = (IFrameDMContext)dmc; + + // We need to retrieve the frame level and line number from the service. + // Normally we could just get the needed information from IFrameDMData, but + // IFrameDMData, which derives from IModelData can only be accessed on the + // dispatch thread, so we need to copy over relevant information from + // IFrameDMData into this structure so we can read it in the job thread. + class FramePositioningData { + int fLine; + int fLevel; + } + + // Query the service for frame data. We are calling from a job thread, + // so we use the Query.get() method, which will block until the + // query is completed. + Query query = new Query(fExecutor) { + @Override + protected void execute(final DataRequestMonitor rm) { + IStack stackService = fServicesTracker.getService(IStack.class); + if (stackService == null) { + doneException(new CoreException(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, -1, "Stack data not available", null))); //$NON-NLS-1$ + return; + } + stackService.getModelData( + frameDmc, + new DataRequestMonitor(fExecutor, rm) { + @Override + public void handleOK() { + FramePositioningData clientData = new FramePositioningData(); + clientData.fLevel = getData().getLevel(); + // Document line numbers are 0-based. While debugger line numbers are 1-based. + clientData.fLine = getData().getLine() - 1; + rm.setData(clientData); + rm.done(); + } + }); + } + }; + try { + fExecutor.execute(query); + FramePositioningData framePositioningData = query.get(); + // If the frame data is not available, or the line number is not + // known, give up. + if (framePositioningData == null || framePositioningData.fLevel < 0) { + return; + } + + // Position and annotate the editor. + IRegion region= getLineInformation(editor, framePositioningData.fLine); + if (region != null) { + editor.selectAndReveal(region.getOffset(), 0); + fIPManager.addAnnotation( + editor, frameDmc, new Position(region.getOffset(), region.getLength()), + framePositioningData.fLevel == 0); + } + } catch (InterruptedException e) { assert false : "Interrupted exception in DSF thread"; //$NON-NLS-1$ + } catch (ExecutionException e) { // Ignore + } + + + } + + /** + * Returns the line information for the given line in the given editor + */ + private IRegion getLineInformation(ITextEditor editor, int lineNumber) { + IDocumentProvider provider= editor.getDocumentProvider(); + IEditorInput input= editor.getEditorInput(); + try { + provider.connect(input); + } catch (CoreException e) { + return null; + } + try { + IDocument document= provider.getDocument(input); + if (document != null) + return document.getLineInformation(lineNumber); + } catch (BadLocationException e) { + } finally { + provider.disconnect(input); + } + return null; + } + + } + + /** + * Job that removes the old IP Annotations associated with given execution + * context. + */ + class ClearingJob extends UIJob { + List fDmcsToClear; + + public ClearingJob(List dmcs) { + super("Debug Source Display"); //$NON-NLS-1$ + setSystem(true); + setPriority(Job.INTERACTIVE); + fDmcsToClear = dmcs; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public IStatus runInUIThread(IProgressMonitor monitor) { + DsfRunnable clearingJobFinishedRunnable = new DsfRunnable() { public void run() { + assert fRunningClearingJob == ClearingJob.this; + fRunningClearingJob = null; + serviceDisplayAndClearingJobs(); + }}; + + if (monitor.isCanceled()) { + executeFromJob(clearingJobFinishedRunnable); + return Status.CANCEL_STATUS; + } + + for (IRunControl.IExecutionDMContext dmc : fDmcsToClear) { + fIPManager.removeAnnotations(dmc); + } + + executeFromJob(clearingJobFinishedRunnable); + return Status.OK_STATUS; + } + } + + private DsfSession fSession; + private DsfExecutor fExecutor; + private DsfServicesTracker fServicesTracker; + private IDMContext fPrevModelContext; + private SourceLookupResult fPrevResult; + private ISourceLookupDirector fSourceLookup; + private DsfMISourceLookupParticipant fSourceLookupParticipant; + private InstructionPointerManager fIPManager; + + private LookupJob fRunningLookupJob; + private DisplayJob fRunningDisplayJob; + private DisplayJob fPendingDisplayJob; + private ClearingJob fRunningClearingJob; + private List fPendingExecDmcsToClear = new LinkedList(); + + public MISourceDisplayAdapter(DsfSession session, ISourceLookupDirector sourceLocator) { + fSession = session; + fExecutor = session.getExecutor(); + fServicesTracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), session.getId()); + fSourceLookup = sourceLocator; + fSourceLookupParticipant = new DsfMISourceLookupParticipant(session); + fSourceLookup.addParticipants(new ISourceLookupParticipant[] {fSourceLookupParticipant} ); + + fIPManager = new InstructionPointerManager(); + + fSession.addServiceEventListener(this, null); + } + + public void dispose() { + fSession.removeServiceEventListener(this); + fServicesTracker.dispose(); + fSourceLookup.removeParticipants(new ISourceLookupParticipant[] {fSourceLookupParticipant}); + + // fSourceLookupParticipant is disposed by teh source lookup director + + // Need to remove annotations in UI thread. + //fIPManager.removeAllAnnotations(); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.contexts.ISourceDisplayAdapter#displaySource(java.lang.Object, org.eclipse.ui.IWorkbenchPage, boolean) + */ + public void displaySource(Object context, final IWorkbenchPage page, final boolean force) { + if (!(context instanceof DMVMContext)) return; + // Correct cast: (AbstractDMVMLayoutNode.DMVMContext) breaks the javac compiler + @SuppressWarnings("unchecked") + final IDMContext dmc = ((DMVMContext)context).getDMC(); + + // Quick test. DMC is checked again in source lookup participant, but + // it's much quicker to test here. + if (!(dmc instanceof IFrameDMContext)) return; + + // Re-dispatch to executor thread before accessing job lists. + fExecutor.execute(new DsfRunnable() { public void run() { + if (!force && dmc.equals(fPrevModelContext)) { + fPrevResult.updateArtifact(dmc); + startDisplayJob(fPrevResult, page); + } else { + startLookupJob(dmc, page); + } + }}); + } + + private void executeFromJob(Runnable runnable) { + try { + fExecutor.execute(runnable); + } catch (RejectedExecutionException e) { + // Session disposed, ignore + } + } + + private void startLookupJob(final IDMContext dmc, final IWorkbenchPage page) { + // If there is a previous lookup job running, cancel it. + if (fRunningLookupJob != null) { + fRunningLookupJob.cancel(); + } + + fRunningLookupJob = new LookupJob(dmc, page); + fRunningLookupJob.schedule(); + } + + // To be called only on dispatch thread. + private void startDisplayJob(SourceLookupResult lookupResult, IWorkbenchPage page) { + DisplayJob nextDisplayJob = new DisplayJob(lookupResult, page); + if (fRunningDisplayJob != null) { + // There is a display job currently running. Cancel it, and set + // the next display job to be run. + if (false && fRunningDisplayJob.cancel()) { + fPendingDisplayJob = nextDisplayJob; + fRunningDisplayJob = null; + serviceDisplayAndClearingJobs(); + } else { + // The job already started, so we need to wait until + // serviceDisplayAndClearingJobs() is called by the job itself. + fPendingDisplayJob = nextDisplayJob; + } + } else if (fRunningClearingJob != null) { + // Wait for the clearing job to finish, instead, set the + // display job as pending. + fPendingDisplayJob = nextDisplayJob; + } else { + fRunningDisplayJob = nextDisplayJob; + fRunningDisplayJob.schedule(); + } + } + + + private void serviceDisplayAndClearingJobs() { + if (!fPendingExecDmcsToClear.isEmpty()) { + // There are annotations to be cleared, run the job first + fRunningClearingJob = new ClearingJob(fPendingExecDmcsToClear); + fRunningClearingJob.schedule(); + fPendingExecDmcsToClear = new LinkedList(); + } else if (fPendingDisplayJob != null) { + fRunningDisplayJob = fPendingDisplayJob; + fRunningDisplayJob.schedule(); + fPendingDisplayJob = null; + } + } + + private void startAnnotationClearingJob(IRunControl.IExecutionDMContext execDmc) { + // Make sure to add the dmc to the list. + fPendingExecDmcsToClear.add(execDmc); + + // If lookup job is running, check it agains the exec context, + // and cancel it if matches. + if (fRunningLookupJob != null) { + if (DMContexts.isAncestorOf(fRunningLookupJob.getDmc(), execDmc)) { + fRunningLookupJob.cancel(); + fRunningLookupJob = null; + } + } + // If there is a pending displahy job, make sure it doesn't get + // pre-empted by this event. If so, just cancel the pending + // display job. + if (fPendingDisplayJob != null) { + if (DMContexts.isAncestorOf(fPendingDisplayJob.getDmc(), execDmc)) { + fPendingDisplayJob = null; + } + } + + // If no display or clearing jobs are running, schedule the clearing job. + if (fRunningClearingJob == null && fRunningDisplayJob == null) { + fRunningClearingJob = new ClearingJob(fPendingExecDmcsToClear); + fRunningClearingJob.schedule(); + fPendingExecDmcsToClear = new LinkedList(); + } + } + + @DsfServiceEventHandler + public void eventDispatched(IRunControl.IResumedDMEvent e) { + if (e.getReason() != StateChangeReason.STEP) { + startAnnotationClearingJob(e.getDMContext()); + } + } + + @DsfServiceEventHandler + public void eventDispatched(IRunControl.IExitedDMEvent e) { + startAnnotationClearingJob(e.getExecutionContext()); + } + + @DsfServiceEventHandler + public void eventDispatched(IStepQueueManager.ISteppingTimedOutEvent e) { + startAnnotationClearingJob(e.getDMContext()); + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/SourceLookupResult.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/SourceLookupResult.java new file mode 100644 index 00000000000..fdf90a4eeab --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/SourceLookupResult.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * 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.sourcelookup; + +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.ui.IEditorInput; + +/** + * The result of a source lookup contains the source element, editor id, and + * editor input resolved for a debug artifact. + * + * @since 3.1 + */ +class SourceLookupResult { + + /** + * Element that source was resolved for. + */ + private IDMContext fDmc; + /** + * Corresponding source element, or null + * if unknown. + */ + private Object fSourceElement; + /** + * Associated editor id, used to display the source element, + * or null if unknown. + */ + private String fEditorId; + /** + * Associatd editor input, used to display the source element, + * or null if unknown. + */ + private IEditorInput fEditorInput; + + /** + * Creates a source lookup result on the given artifact, source element, + * editor id, and editor input. + */ + public SourceLookupResult(IDMContext dmc, Object sourceElement, String editorId, IEditorInput editorInput) { + fDmc = dmc; + setSourceElement(sourceElement); + setEditorId(editorId); + setEditorInput(editorInput); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.sourcelookup.ISourceLookupResult#getArtifact() + */ + public IDMContext getDmc() { + return fDmc; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.sourcelookup.ISourceLookupResult#getSourceElement() + */ + public Object getSourceElement() { + return fSourceElement; + } + + /** + * Sets the source element resolved for the artifact that source + * lookup was performed for, or null if a source element + * was not resolved. + * + * @param element resolved source element or null if unknown + */ + protected void setSourceElement(Object element) { + fSourceElement = element; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.sourcelookup.ISourceLookupResult#getEditorId() + */ + public String getEditorId() { + return fEditorId; + } + + /** + * Sets the identifier of the editor used to display this source + * lookup result's source element, or null if unknown. + * + * @param id the identifier of the editor used to display this source + * lookup result's source element, or null if unknown + */ + protected void setEditorId(String id) { + fEditorId = id; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.sourcelookup.ISourceLookupResult#getEditorInput() + */ + public IEditorInput getEditorInput() { + return fEditorInput; + } + + /** + * Sets the editor input used to display this source lookup + * result's source element, or null if unknown. + * + * @param input the editor input used to display this source lookup + * result's source element, or null if unknown + */ + protected void setEditorInput(IEditorInput input) { + fEditorInput = input; + } + + /** + * Updates the artifact to refer to the given artifact + * if equal. For example, when a source lookup result is resued + * for the same stack frame, we still need to update in case + * the stack frame is not identical. + * + * @param artifact new artifact state + */ + public void updateArtifact(IDMContext dmc) { + if (fDmc.equals(dmc)) { + fDmc = dmc; + } + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF index e803dac64a4..42715ebf451 100644 --- a/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF @@ -11,6 +11,8 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.dd.dsf, org.eclipse.cdt.core Eclipse-LazyStart: true -Export-Package: org.eclipse.dd.dsf.debug.service, - org.eclipse.dd.dsf.debug.service.command +Export-Package: org.eclipse.dd.dsf.debug.model, + org.eclipse.dd.dsf.debug.service, + org.eclipse.dd.dsf.debug.service.command, + org.eclipse.dd.dsf.debug.sourcelookup Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java new file mode 100644 index 00000000000..ffd9d525696 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.model; + +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.DsfDebugPlugin; +import org.eclipse.dd.dsf.debug.service.IMemory; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.model.IMemoryBlock; +import org.eclipse.debug.core.model.IMemoryBlockRetrieval; +import org.osgi.util.tracker.ServiceTracker; + +/** + * + */ +public class DsfMemoryBlockRetrieval implements IMemoryBlockRetrieval { + + private final IDMContext fContext; + private final ServiceTracker fServiceTracker; + + public DsfMemoryBlockRetrieval(IDMContext dmc) { + fContext = dmc; + String memoryServiceFilter = + "(&" + + "(OBJECTCLASS=" + IMemory.class.getName() + ")" + + "(" + IDsfService.PROP_SESSION_ID + "=" + dmc.getSessionId() + ")" + + ")"; + fServiceTracker = new ServiceTracker(DsfDebugPlugin.getBundleContext(), memoryServiceFilter, null); + fServiceTracker.open(); + } + + public IMemoryBlock getMemoryBlock(long startAddress, long length) throws DebugException { + return null; + } + + public boolean supportsStorageRetrieval() { + return false; + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java new file mode 100644 index 00000000000..e890d519889 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java @@ -0,0 +1,228 @@ +/******************************************************************************* + * 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.sourcelookup; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutionException; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.Query; +import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.DsfDebugPlugin; +import org.eclipse.dd.dsf.debug.service.IStack; +import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; +import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMData; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.sourcelookup.ISourceContainer; +import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector; +import org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant; + +/** + */ +@ThreadSafe +public class DsfMISourceLookupParticipant implements ISourceLookupParticipant { + protected static final Object[] EMPTY = new Object[0]; + + private DsfExecutor fExecutor; + private String fSessionId; + private DsfServicesTracker fServicesTracker; + private ISourceLookupDirector fDirector; + private Map> fLookupCache = Collections.synchronizedMap(new HashMap>()); + + public DsfMISourceLookupParticipant(DsfSession session) { + fSessionId = session.getId(); + fExecutor = DsfSession.getSession(fSessionId).getExecutor(); + fServicesTracker = new DsfServicesTracker(DsfDebugPlugin.getBundleContext(), fSessionId); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant#init(org.eclipse.debug.core.sourcelookup.ISourceLookupDirector) + */ + public void init(ISourceLookupDirector director) { + fDirector = director; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant#dispose() + */ + public void dispose() { + fServicesTracker.dispose(); + fDirector = null; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant#findSourceElements(java.lang.Object) + */ + public Object[] findSourceElements(Object object) throws CoreException { + CoreException single = null; + MultiStatus multiStatus = null; + List results = null; + + String name = getSourceName(object); + if (name != null) { + results = fLookupCache.get(name); + if (results != null) { + return results.toArray(); + } else { + results = new ArrayList(); + } + ISourceContainer[] containers = getSourceContainers(); + for (int i = 0; i < containers.length; i++) { + try { + ISourceContainer container = containers[i]; + if (container != null) { + Object[] objects = container.findSourceElements(name); + if (objects.length > 0) { + if (isFindDuplicates()) { + results.addAll(Arrays.asList(objects)); + } else { + results.add(objects[0]); + break; + } + } + } + } catch (CoreException e) { + if (single == null) { + single = e; + } else if (multiStatus == null) { + multiStatus = new MultiStatus(DebugPlugin.getUniqueIdentifier(), DebugPlugin.INTERNAL_ERROR, new IStatus[]{single.getStatus()}, "Source Lookup error", null); //$NON-NLS-1$ + multiStatus.add(e.getStatus()); + } else { + multiStatus.add(e.getStatus()); + } + } + } + + if (!results.isEmpty()) { + synchronized(fLookupCache) { + if (!fLookupCache.containsKey(name)) { + fLookupCache.put(name, results); + } + } + } + } + if (results == null || results.isEmpty()) { + if (multiStatus != null) { + throw new CoreException(multiStatus); + } else if (single != null) { + throw single; + } + return EMPTY; + } + return results.toArray(); + } + + /** + * Returns whether this participant's source lookup director is configured + * to search for duplicate source elements. + * + * @return whether this participant's source lookup director is configured + * to search for duplicate source elements + */ + protected boolean isFindDuplicates() { + ISourceLookupDirector director = fDirector; + if (director != null) { + return director.isFindDuplicates(); + } + return false; + } + + /** + * Returns the source containers currently registered with this participant's + * source lookup director. + * + * @return the source containers currently registered with this participant's + * source lookup director + */ + protected ISourceContainer[] getSourceContainers() { + ISourceLookupDirector director = fDirector; + if (director != null) { + return director.getSourceContainers(); + } + return new ISourceContainer[0]; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant#sourceContainersChanged(org.eclipse.debug.core.sourcelookup.ISourceLookupDirector) + */ + public void sourceContainersChanged(ISourceLookupDirector director) { + fLookupCache.clear(); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.core.sourcelookup.ISourceLookupParticipant#getSourceName(java.lang.Object) + */ + public String getSourceName(Object object) throws CoreException { + if ( !(object instanceof IDMContext) || + !((IDMContext)object).getSessionId().equals(fSessionId) ) + { + throw new CoreException(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, -1, "Invalid object", null)); //$NON-NLS-1$ + } + + final IDMContext dmc = (IDMContext)object; + Query query = new Query(fExecutor) { + @Override + protected void execute(final DataRequestMonitor rm) { + getSourceNameOnDispatchThread(dmc, rm); + }}; + fExecutor.execute(query); + try { + return query.get(); + } catch (InterruptedException e) { assert false : "Interrupted exception in DSF executor"; //$NON-NLS-1$ + } catch (ExecutionException e) { + if (e.getCause() instanceof CoreException) { + throw (CoreException)e.getCause(); + } + assert false : "Unexptected exception"; //$NON-NLS-1$ + } + return null; // Should never get here. + } + + @ConfinedToDsfExecutor("fExecutor") + private void getSourceNameOnDispatchThread(IDMContext dmc, final DataRequestMonitor rm) { + if (!(dmc instanceof IStack.IFrameDMContext)) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "No source for this object", null)); //$NON-NLS-1$ + rm.done(); + return; + } + IFrameDMContext frameDmc = (IFrameDMContext)dmc; + + IStack stackService = fServicesTracker.getService(IStack.class); + if (stackService == null) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Stack data not available", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + stackService.getModelData( + frameDmc, + new DataRequestMonitor(fExecutor, rm) { @Override + public void handleOK() { + rm.setData(getData().getFile()); + rm.done(); + }}); + } +} From fd8daca687970752c3829952eb40342bd1e62175 Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Fri, 8 Jun 2007 21:34:39 +0000 Subject: [PATCH 105/834] Bugzilla 191784 --- .../register/RegisterBitFieldLayoutNode.java | 24 +++++++-------- .../register/RegisterGroupLayoutNode.java | 29 +++++++------------ .../register/RegisterLayoutNode.java | 27 ++++++++--------- .../RegisterLayoutValueCellModifier.java | 3 ++ 4 files changed, 35 insertions(+), 48 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java index 18ede371ca0..717e29863e2 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java @@ -168,6 +168,9 @@ public class RegisterBitFieldLayoutNode extends AbstractExpressionLayoutNode(getSession().getExecutor(), rm) { - @Override - protected void handleOK() { - String bitFieldName = expression.substring(1); - if (bitFieldName.equals(getData().getName())) { - rm.setData(Boolean.TRUE); - } else { - rm.setData(Boolean.FALSE); - } - rm.done(); - } - }); + String bitFieldName = expression.substring(1); + if (bitFieldName.equals(dmc.getName())) { + rm.setData(Boolean.TRUE); + } else { + rm.setData(Boolean.FALSE); + } + rm.done(); } public int getExpressionLength(String expression) { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java index e2f7439b7c9..ddc7b9799f7 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java @@ -18,7 +18,6 @@ import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMEvent; -import org.eclipse.dd.dsf.datamodel.IDMService; import org.eclipse.dd.dsf.debug.service.IRegisters; import org.eclipse.dd.dsf.debug.service.IRunControl; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext; @@ -144,10 +143,9 @@ public class RegisterGroupLayoutNode extends AbstractExpressionLayoutNode(getSession().getExecutor(), rm) { - @Override - protected void handleOK() { - int startIdx = "$$\"".length(); //$NON-NLS-1$ - int endIdx = expression.indexOf('"', startIdx); - String groupName = expression.substring(startIdx, endIdx); - if (groupName.equals(getData().getName())) { - rm.setData(Boolean.TRUE); - } else { - rm.setData(Boolean.FALSE); - } - rm.done(); - } - }); + int startIdx = "$$\"".length(); //$NON-NLS-1$ + int endIdx = expression.indexOf('"', startIdx); + String groupName = expression.substring(startIdx, endIdx); + if (groupName.equals(dmc.getName())) { + rm.setData(Boolean.TRUE); + } else { + rm.setData(Boolean.FALSE); + } + rm.done(); } @Override diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java index 3c654654c55..09b79c84079 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java @@ -165,6 +165,10 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode(getSession().getExecutor(), rm) { - @Override - protected void handleOK() { - String regName = expression.substring(1); - if (regName.equals(getData().getName())) { - rm.setData(Boolean.TRUE); - } else { - rm.setData(Boolean.FALSE); - } - rm.done(); - } - }); + String regName = expression.substring(1); + if (regName.equals(dmc.getName())) { + rm.setData(Boolean.TRUE); + } else { + rm.setData(Boolean.FALSE); + } + rm.done(); } @Override @@ -447,7 +444,7 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode Date: Fri, 8 Jun 2007 23:52:55 +0000 Subject: [PATCH 106/834] Streamlined use of Query object, in preparation for the memory view work (bug 160047). --- .../sourcelookup/MISourceDisplayAdapter.java | 2 +- .../register/SyncRegisterDataAccess.java | 49 ++++++++------- .../variable/SyncVariableDataAccess.java | 25 ++++---- .../DsfMISourceLookupParticipant.java | 2 +- .../concurrent/CountingRequestMonitor.java | 4 +- .../dd/dsf/concurrent/DataRequestMonitor.java | 4 +- .../dd/dsf/concurrent/DefaultDsfExecutor.java | 2 +- .../dd/dsf/concurrent/DsfExecutable.java | 2 +- .../dsf/concurrent/MultiRequestMonitor.java | 3 +- .../org/eclipse/dd/dsf/concurrent/Query.java | 59 +++++++++++++++++-- .../dd/dsf/concurrent/RequestMonitor.java | 47 +++++++++++---- 11 files changed, 136 insertions(+), 63 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java index 38cab0bd740..97db364a8ff 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java @@ -274,7 +274,7 @@ public class MISourceDisplayAdapter implements ISourceDisplay // Query the service for frame data. We are calling from a job thread, // so we use the Query.get() method, which will block until the // query is completed. - Query query = new Query(fExecutor) { + Query query = new Query() { @Override protected void execute(final DataRequestMonitor rm) { IStack stackService = fServicesTracker.getService(IStack.class); diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java index 63c901c1787..185b0f9e8fa 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java @@ -17,7 +17,6 @@ import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.DsfExecutor; import org.eclipse.dd.dsf.concurrent.Query; import org.eclipse.dd.dsf.concurrent.ThreadSafeAndProhibitedFromDsfExecutor; import org.eclipse.dd.dsf.debug.service.IRegisters; @@ -85,8 +84,8 @@ public class SyncRegisterDataAccess { private IBitFieldDMContext fDmc; - public GetBitFieldValueQuery(DsfExecutor executor, IBitFieldDMContext dmc) { - super(executor); + public GetBitFieldValueQuery(IBitFieldDMContext dmc) { + super(); fDmc = dmc; } @@ -159,7 +158,7 @@ public class SyncRegisterDataAccess { * guard agains RejectedExecutionException, because * DsfSession.getSession() above would only return an active session. */ - GetBitFieldValueQuery query = new GetBitFieldValueQuery(session.getExecutor(), dmc); + GetBitFieldValueQuery query = new GetBitFieldValueQuery(dmc); session.getExecutor().execute(query); /* @@ -183,8 +182,8 @@ public class SyncRegisterDataAccess { private String fValue; private String fFormatId; - public SetBitFieldValueQuery(DsfExecutor executor, IBitFieldDMContext dmc, String value, String formatId) { - super(executor); + public SetBitFieldValueQuery(IBitFieldDMContext dmc, String value, String formatId) { + super(); fDmc = dmc; fValue = value; fFormatId = formatId; @@ -262,7 +261,7 @@ public class SyncRegisterDataAccess { * guard agains RejectedExecutionException, because * DsfSession.getSession() above would only return an active session. */ - SetBitFieldValueQuery query = new SetBitFieldValueQuery(session.getExecutor(), dmc, value, formatId); + SetBitFieldValueQuery query = new SetBitFieldValueQuery(dmc, value, formatId); session.getExecutor().execute(query); /* @@ -292,8 +291,8 @@ public class SyncRegisterDataAccess { IMnemonic fMnemonic; - public SetBitFieldValueMnemonicQuery(DsfExecutor executor, IBitFieldDMContext dmc, IMnemonic mnemonic) { - super(executor); + public SetBitFieldValueMnemonicQuery(IBitFieldDMContext dmc, IMnemonic mnemonic) { + super(); fDmc = dmc; fMnemonic = mnemonic; } @@ -369,7 +368,7 @@ public class SyncRegisterDataAccess { * guard agains RejectedExecutionException, because * DsfSession.getSession() above would only return an active session. */ - SetBitFieldValueMnemonicQuery query = new SetBitFieldValueMnemonicQuery( session.getExecutor(), dmc, mnemonic); + SetBitFieldValueMnemonicQuery query = new SetBitFieldValueMnemonicQuery(dmc, mnemonic); session.getExecutor().execute(query); /* @@ -417,8 +416,8 @@ public class SyncRegisterDataAccess { IRegisterGroupDMContext fDmc; - public GetRegisterGroupValueQuery(DsfExecutor executor, IRegisterGroupDMContext dmc) { - super(executor); + public GetRegisterGroupValueQuery(IRegisterGroupDMContext dmc) { + super(); fDmc = dmc; } @@ -484,7 +483,7 @@ public class SyncRegisterDataAccess { * guard agains RejectedExecutionException, because * DsfSession.getSession() above would only return an active session. */ - GetRegisterGroupValueQuery query = new GetRegisterGroupValueQuery(session.getExecutor(), dmc); + GetRegisterGroupValueQuery query = new GetRegisterGroupValueQuery(dmc); session.getExecutor().execute(query); /* @@ -506,8 +505,8 @@ public class SyncRegisterDataAccess { IRegisterDMContext fDmc; - public GetRegisterValueQuery(DsfExecutor executor, IRegisterDMContext dmc) { - super(executor); + public GetRegisterValueQuery(IRegisterDMContext dmc) { + super(); fDmc = dmc; } @@ -573,7 +572,7 @@ public class SyncRegisterDataAccess { * guard agains RejectedExecutionException, because * DsfSession.getSession() above would only return an active session. */ - GetRegisterValueQuery query = new GetRegisterValueQuery(session.getExecutor(), dmc); + GetRegisterValueQuery query = new GetRegisterValueQuery(dmc); session.getExecutor().execute(query); /* @@ -597,8 +596,8 @@ public class SyncRegisterDataAccess { private String fValue; private String fFormatId; - public SetRegisterValueQuery(DsfExecutor executor, IRegisterDMContext dmc, String value, String formatId) { - super(executor); + public SetRegisterValueQuery(IRegisterDMContext dmc, String value, String formatId) { + super(); fDmc = dmc; fValue = value; fFormatId = formatId; @@ -681,7 +680,7 @@ public class SyncRegisterDataAccess { * guard agains RejectedExecutionException, because * DsfSession.getSession() above would only return an active session. */ - SetRegisterValueQuery query = new SetRegisterValueQuery(session.getExecutor(), dmc, value, formatId); + SetRegisterValueQuery query = new SetRegisterValueQuery(dmc, value, formatId); session.getExecutor().execute(query); /* @@ -708,8 +707,8 @@ public class SyncRegisterDataAccess { IFormattedDataDMContext fDmc; - public GetSupportFormatsValueQuery(DsfExecutor executor, IFormattedDataDMContext dmc) { - super(executor); + public GetSupportFormatsValueQuery(IFormattedDataDMContext dmc) { + super(); fDmc = dmc; } @@ -783,7 +782,7 @@ public class SyncRegisterDataAccess { * guard agains RejectedExecutionException, because * DsfSession.getSession() above would only return an active session. */ - GetSupportFormatsValueQuery query = new GetSupportFormatsValueQuery( session.getExecutor(), dmc); + GetSupportFormatsValueQuery query = new GetSupportFormatsValueQuery(dmc); session.getExecutor().execute(query); /* @@ -806,8 +805,8 @@ public class SyncRegisterDataAccess { private IFormattedDataDMContext fDmc; private String fFormatId; - public GetFormattedValueValueQuery(DsfExecutor executor, IFormattedDataDMContext dmc, String formatId) { - super(executor); + public GetFormattedValueValueQuery(IFormattedDataDMContext dmc, String formatId) { + super(); fDmc = dmc; fFormatId = formatId; } @@ -881,7 +880,7 @@ public class SyncRegisterDataAccess { * guard agains RejectedExecutionException, because * DsfSession.getSession() above would only return an active session. */ - GetFormattedValueValueQuery query = new GetFormattedValueValueQuery(session.getExecutor(), dmc, formatId); + GetFormattedValueValueQuery query = new GetFormattedValueValueQuery(dmc, formatId); session.getExecutor().execute(query); /* diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java index 98cdf977268..d309c83ef0e 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java @@ -12,7 +12,6 @@ import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.DsfExecutor; import org.eclipse.dd.dsf.concurrent.Query; import org.eclipse.dd.dsf.concurrent.ThreadSafeAndProhibitedFromDsfExecutor; import org.eclipse.dd.dsf.debug.service.IExpressions; @@ -83,8 +82,8 @@ public class SyncVariableDataAccess { private IExpressionDMContext fDmc; - public GetVariableValueQuery(DsfExecutor executor, IExpressionDMContext dmc) { - super(executor); + public GetVariableValueQuery(IExpressionDMContext dmc) { + super(); fDmc = dmc; } @@ -157,7 +156,7 @@ public class SyncVariableDataAccess { * guard agains RejectedExecutionException, because * DsfSession.getSession() above would only return an active session. */ - GetVariableValueQuery query = new GetVariableValueQuery(session.getExecutor(), dmc); + GetVariableValueQuery query = new GetVariableValueQuery(dmc); session.getExecutor().execute(query); /* @@ -181,8 +180,8 @@ public class SyncVariableDataAccess { private String fValue; private String fFormatId; - public SetVariableValueQuery(DsfExecutor executor, IExpressionDMContext dmc, String value, String formatId) { - super(executor); + public SetVariableValueQuery(IExpressionDMContext dmc, String value, String formatId) { + super(); fDmc = dmc; fValue = value; fFormatId = formatId; @@ -260,7 +259,7 @@ public class SyncVariableDataAccess { * guard agains RejectedExecutionException, because * DsfSession.getSession() above would only return an active session. */ - SetVariableValueQuery query = new SetVariableValueQuery(session.getExecutor(), dmc, value, formatId); + SetVariableValueQuery query = new SetVariableValueQuery(dmc, value, formatId); session.getExecutor().execute(query); /* @@ -294,8 +293,8 @@ public class SyncVariableDataAccess { IFormattedDataDMContext fDmc; - public GetSupportFormatsValueQuery(DsfExecutor executor, IFormattedDataDMContext dmc) { - super(executor); + public GetSupportFormatsValueQuery(IFormattedDataDMContext dmc) { + super(); fDmc = dmc; } @@ -369,7 +368,7 @@ public class SyncVariableDataAccess { * guard agains RejectedExecutionException, because * DsfSession.getSession() above would only return an active session. */ - GetSupportFormatsValueQuery query = new GetSupportFormatsValueQuery(session.getExecutor(), dmc); + GetSupportFormatsValueQuery query = new GetSupportFormatsValueQuery(dmc); session.getExecutor().execute(query); /* @@ -392,8 +391,8 @@ public class SyncVariableDataAccess { private IFormattedDataDMContext fDmc; private String fFormatId; - public GetFormattedValueValueQuery(DsfExecutor executor, IFormattedDataDMContext dmc, String formatId) { - super(executor); + public GetFormattedValueValueQuery(IFormattedDataDMContext dmc, String formatId) { + super(); fDmc = dmc; fFormatId = formatId; } @@ -467,7 +466,7 @@ public class SyncVariableDataAccess { * guard agains RejectedExecutionException, because * DsfSession.getSession() above would only return an active session. */ - GetFormattedValueValueQuery query = new GetFormattedValueValueQuery(session.getExecutor(), dmc, formatId); + GetFormattedValueValueQuery query = new GetFormattedValueValueQuery(dmc, formatId); session.getExecutor().execute(query); /* diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java index e890d519889..ed5a6438270 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java @@ -183,7 +183,7 @@ public class DsfMISourceLookupParticipant implements ISourceLookupParticipant { } final IDMContext dmc = (IDMContext)object; - Query query = new Query(fExecutor) { + Query query = new Query() { @Override protected void execute(final DataRequestMonitor rm) { getSourceNameOnDispatchThread(dmc, rm); diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/CountingRequestMonitor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/CountingRequestMonitor.java index 6e6220f4a25..6b1bb09585b 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/CountingRequestMonitor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/CountingRequestMonitor.java @@ -10,6 +10,8 @@ *******************************************************************************/ package org.eclipse.dd.dsf.concurrent; +import java.util.concurrent.Executor; + import org.eclipse.core.runtime.MultiStatus; import org.eclipse.dd.dsf.DsfPlugin; @@ -37,7 +39,7 @@ import org.eclipse.dd.dsf.DsfPlugin; public class CountingRequestMonitor extends RequestMonitor { private int fDoneCounter; - public CountingRequestMonitor(DsfExecutor executor, RequestMonitor parentRequestMonitor) { + public CountingRequestMonitor(Executor executor, RequestMonitor parentRequestMonitor) { super(executor, parentRequestMonitor); setStatus(new MultiStatus(DsfPlugin.PLUGIN_ID, 0, "Collective status for set of sub-operations.", null)); //$NON-NLS-1$ } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DataRequestMonitor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DataRequestMonitor.java index 9cfe5a24e2f..caf54f5513e 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DataRequestMonitor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DataRequestMonitor.java @@ -10,6 +10,8 @@ *******************************************************************************/ package org.eclipse.dd.dsf.concurrent; +import java.util.concurrent.Executor; + /** * Request monitor that allows data to be returned to the request initiator. @@ -21,7 +23,7 @@ public class DataRequestMonitor extends RequestMonitor { /** Data object reference */ private V fData; - public DataRequestMonitor(DsfExecutor executor, RequestMonitor parentRequestMonitor) { + public DataRequestMonitor(Executor executor, RequestMonitor parentRequestMonitor) { super(executor, parentRequestMonitor); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java index b5f5a240a53..c809f8bb522 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java @@ -88,7 +88,7 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor static { DEBUG_EXECUTOR = DsfPlugin.DEBUG && "true".equals( //$NON-NLS-1$ Platform.getDebugOption("org.eclipse.dd.dsf/debug/executor")); //$NON-NLS-1$ - assert ASSERTIONS_ENABLED = true; + assert (ASSERTIONS_ENABLED = true) == true; } /** diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java index 24f20df4522..4391606ddd5 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java @@ -40,7 +40,7 @@ public class DsfExecutable { static boolean ASSERTIONS_ENABLED = false; static { - assert ASSERTIONS_ENABLED = true; + assert (ASSERTIONS_ENABLED = true) == true; DEBUG_EXECUTOR = DsfPlugin.DEBUG && "true".equals( //$NON-NLS-1$ Platform.getDebugOption("org.eclipse.dd.dsf/debug/executor")); //$NON-NLS-1$ } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/MultiRequestMonitor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/MultiRequestMonitor.java index e084cdd3a5a..ef8a98acfab 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/MultiRequestMonitor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/MultiRequestMonitor.java @@ -14,6 +14,7 @@ import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.concurrent.Executor; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.dd.dsf.DsfPlugin; @@ -44,7 +45,7 @@ public class MultiRequestMonitor extends RequestMonito private Map fStatusMap = new HashMap(); private int fDoneCounter; - public MultiRequestMonitor(DsfExecutor executor, RequestMonitor parentRequestMonitor) { + public MultiRequestMonitor(Executor executor, RequestMonitor parentRequestMonitor) { super(executor, parentRequestMonitor); setStatus(new MultiStatus(DsfPlugin.PLUGIN_ID, 0, "Collective status for set of sub-operations.", null)); //$NON-NLS-1$ } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Query.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Query.java index c85c99fb010..ee1bec45ded 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Query.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Query.java @@ -12,6 +12,7 @@ package org.eclipse.dd.dsf.concurrent; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -26,7 +27,26 @@ import org.eclipse.core.runtime.CoreException; * a Callable in that it allows the implementation code to calculate * the result in several dispatches, rather than requiring it to return the * data at end of Callable#call method. - * + *

    + * Usage:
    + *

    + *     class DataQuery extends Query {
    + *         protected void execute(DataRequestMonitor rm) {
    + *             rm.setData(fSlowService.getData());
    + *             rm.done();
    + *         }
    + *     }
    + *     
    + *     DsfExecutor executor = getExecutor();
    + *     DataQuery query = new DataQuery();
    + *     executor.submit(query);
    + *     
    + *     try {
    + *         Data data = query.get();
    + *     }
    + *     
    + * 
    + *

    * @see java.util.concurrent.Callable */ @ThreadSafe @@ -36,13 +56,22 @@ abstract public class Query extends DsfRunnable /** The synchronization object for this query */ private final Sync fSync = new Sync(); - /** The executor that is used to complete the asynchronous operation of this query */ - private final DsfExecutor fExecutor; - + /** + * The Query constructor no longer requires an executor to be specified. + * This executor was used to contruct the DataRequestMonitor argument to the + * {@link #execute(DataRequestMonitor)} method. But a simplification in the + * RequestMonitor object, made this unnecessary. + * @param executor + */ + @Deprecated public Query(DsfExecutor executor) { - fExecutor = executor; } + /** + * The no-argument constructor + */ + public Query() {} + public V get() throws InterruptedException, ExecutionException { return fSync.doGet(); } public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { @@ -71,7 +100,25 @@ abstract public class Query extends DsfRunnable public void run() { if (fSync.doRun()) { try { - execute(new DataRequestMonitor(fExecutor, null) { + /* + * Create the executor which is going to handle the completion of the + * request monitor. Normally a DSF executor is supplied here which + * causes the request monitor to be invoked in a new dispatch loop. + * But since the query is a synchronization object, it can handle + * the completion of the request in any thread. + * Avoiding the use of a DSF executor is very useful because queries are + * meant to be used by clients calling from non-dispatch thread, and there + * is a chance that a client may execute a query just as a session is being + * shut down. In that case, the DSF executor may throw a + * RejectedExecutionException which would have to be handled by the query. + */ + Executor rmExecutor = new Executor() { + public void execute(Runnable command) { + command.run(); + } + }; + + execute(new DataRequestMonitor(rmExecutor, null) { @Override public void handleCompleted() { if (getStatus().isOK()) fSync.doSet(getData()); diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java index 09c895fa17e..71321a735ab 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java @@ -10,6 +10,9 @@ *******************************************************************************/ package org.eclipse.dd.dsf.concurrent; +import java.util.concurrent.Executor; +import java.util.concurrent.RejectedExecutionException; + import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.Status; @@ -59,7 +62,7 @@ public class RequestMonitor { * The executor that will be used in order to invoke the handler of the results * of the request. */ - private final DsfExecutor fExecutor; + private final Executor fExecutor; /** * The request monitor which was used to call into the method that created this @@ -81,7 +84,7 @@ public class RequestMonitor { * @param parentRequestMonitor The optional parent request monitor to be invoked by * default when this request completes. Parameter may be null. */ - public RequestMonitor(DsfExecutor executor, RequestMonitor parentRequestMonitor) { + public RequestMonitor(Executor executor, RequestMonitor parentRequestMonitor) { fExecutor = executor; fParentRequestMonitor = parentRequestMonitor; } @@ -139,15 +142,19 @@ public class RequestMonitor { throw new IllegalStateException("RequestMonitor: " + this + ", done() method called more than once"); //$NON-NLS-1$//$NON-NLS-2$ } fDone = true; - fExecutor.execute(new DsfRunnable() { - public void run() { - RequestMonitor.this.handleCompleted(); - } - @Override - public String toString() { - return "Completed: " + RequestMonitor.this.toString(); //$NON-NLS-1$ - } - }); + try { + fExecutor.execute(new DsfRunnable() { + public void run() { + RequestMonitor.this.handleCompleted(); + } + @Override + public String toString() { + return "Completed: " + RequestMonitor.this.toString(); //$NON-NLS-1$ + } + }); + } catch (RejectedExecutionException e) { + handleRejectedExecutionException(); + } } /** @@ -231,7 +238,7 @@ public class RequestMonitor { fParentRequestMonitor.setMultiStatus(DsfPlugin.PLUGIN_ID, getStatus().getCode(), "Failed: " + toString(), getStatus()); //$NON-NLS-1$ fParentRequestMonitor.done(); } else { - MultiStatus logStatus = new MultiStatus(DsfPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Request for monitor: '" + this + "' resulted in an error.", null); //$NON-NLS-1$ //$NON-NLS-2$ + MultiStatus logStatus = new MultiStatus(DsfPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Request for monitor: '" + toString() + "' resulted in an error.", null); //$NON-NLS-1$ //$NON-NLS-2$ logStatus.merge(getStatus()); DsfPlugin.getDefault().getLog().log(logStatus); } @@ -250,4 +257,20 @@ public class RequestMonitor { fParentRequestMonitor.done(); } } + + /** + * Default handler for when the executor supplied in the constructor + * rejects the runnable that is submitted invoke this requrest monitor. + * This usually happens only when the executor is shutting down. + */ + protected void handleRejectedExecutionException() { + if (fParentRequestMonitor != null) { + fParentRequestMonitor.setMultiStatus(DsfPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Rejected execution exception when trying to complete the request monitor: " + toString(), getStatus()); //$NON-NLS-1$ + fParentRequestMonitor.done(); + } else { + MultiStatus logStatus = new MultiStatus(DsfPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Request for monitor: '" + toString() + "' resulted in a rejected execution exception.", null); //$NON-NLS-1$ //$NON-NLS-2$ + logStatus.merge(getStatus()); + DsfPlugin.getDefault().getLog().log(logStatus); + } + } } From c124ed7f92be4c224833e1188e87339b9e151887 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Mon, 11 Jun 2007 18:41:59 +0000 Subject: [PATCH 107/834] Clean-up assumptions in AbstractDMVMLayoutNode about the DMC type in VMC held in viewer (bug 192019). --- .../register/RegisterLayoutNode.java | 2 +- .../ui/viewmodel/AbstractVMLayoutNode.java | 6 ++++ .../viewmodel/dm/AbstractDMVMLayoutNode.java | 33 ++++++++++++++++--- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java index 09b79c84079..8756472a518 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java @@ -267,8 +267,8 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode extends Abstract return true; } + /** + * Convenience method that checks whether the given dmc context is null. If it is null, an + * appropriate error message is set in the update. + * @param dmc Data Model Context (DMC) to check. + * @param update Update to handle in case the DMC is null. + * @return true if the DMC is NOT null, indicating that it's OK to proceed. + */ + protected boolean checkDmc(IDMContext dmc, IViewerUpdate update) { + if (dmc == null) { + update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, + "No valid context found.", null)); //$NON-NLS-1$ + handleFailedUpdate(update); + return false; + } + return true; + } + + /** + * A convenience method that checks whether a given service exists. If the service does not + * exist, the update is filled in with the appropriate error message. + * @param serviceClass Service class to find. + * @param filter Service filter to use in addition to the service class name. + * @param update Update object to fill in. + * @return true if service IS found, indicating that it's OK to proceed. + */ protected boolean checkService(Class serviceClass, String filter, IViewerUpdate update) { if (getServicesTracker().getService(serviceClass, filter) == null) { update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, @@ -291,12 +316,10 @@ abstract public class AbstractDMVMLayoutNode extends Abstract */ protected void updateLabelInSessionThread(ILabelUpdate[] updates) { for (final ILabelUpdate update : updates) { - final DMVMContext vmc = (DMVMContext)update.getElement(); - if (!checkService(null, vmc.getDMC().getServiceFilter(), update)) return; - final IDMContext dmc = findDmcInPath(update.getElementPath(), fDMCClassType); + if (!checkDmc(dmc, update) || !checkService(null, dmc.getServiceFilter(), update)) return; - ((IDMService)getServicesTracker().getService(null, vmc.getDMC().getServiceFilter())).getModelData( + ((IDMService)getServicesTracker().getService(null, dmc.getServiceFilter())).getModelData( dmc, new DataRequestMonitor(getSession().getExecutor(), null) { @Override @@ -395,7 +418,7 @@ abstract public class AbstractDMVMLayoutNode extends Abstract if (dmc != null) { // Create the VM context based on the DM context from the DM event. - final IVMContext vmc = new DMVMContext(DMContexts.getAncestorOfType(event.getDMContext(), fDMCClassType)); + final IVMContext vmc = createVMContext(DMContexts.getAncestorOfType(event.getDMContext(), fDMCClassType)); final Map childNodeDeltas = getChildNodesWithDeltaFlags(event); if (childNodeDeltas.size() == 0) { From 599aa1dbb788935616c51a56c0fe20021ce1b348 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Mon, 18 Jun 2007 17:07:19 +0000 Subject: [PATCH 108/834] Committed patch with initial memory service implementation (bug 160046). --- .../dd/dsf/debug/model/DsfMemoryBlock.java | 75 ++++++++++++++++++ .../debug/model/DsfMemoryBlockRetrieval.java | 77 ++++++++++++++++--- 2 files changed, 140 insertions(+), 12 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java new file mode 100644 index 00000000000..9a7e71897fe --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.model; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.PlatformObject; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.debug.DsfDebugPlugin; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.model.IDebugTarget; +import org.eclipse.debug.core.model.IMemoryBlock; + +public class DsfMemoryBlock extends PlatformObject implements IMemoryBlock +{ + private final DsfMemoryBlockRetrieval fRetrieval; + private final String fModelId; + private final long fStartAddress; + private final byte[] fBytes; + + DsfMemoryBlock(DsfMemoryBlockRetrieval retrieval, String modelId, long startAddress, byte[] bytes) { + fRetrieval = retrieval; + fModelId = modelId; + fStartAddress = startAddress; + fBytes = bytes; + } + + public byte[] getBytes() throws DebugException { + return fBytes; + } + + public long getLength() { + return fBytes.length; + } + + public long getStartAddress() { + return fStartAddress; + } + + public void setValue(long offset, byte[] bytes) throws DebugException { + throw new DebugException(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, DebugException.NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$ + } + + public boolean supportsValueModification() { + return false; + } + + public IDebugTarget getDebugTarget() { + return null; + } + + public ILaunch getLaunch() { + return null; + } + + public String getModelIdentifier() { + return fModelId; + } + + @Override + public Object getAdapter(Class adapter) { + if (adapter.isAssignableFrom(DsfMemoryBlockRetrieval.class)) { + return fRetrieval; + } + return super.getAdapter(adapter); + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java index ffd9d525696..d6418bb0aa9 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java @@ -10,40 +10,93 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.model; +import java.util.concurrent.ExecutionException; + +import org.eclipse.cdt.utils.Addr32; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.PlatformObject; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.Query; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.debug.DsfDebugPlugin; import org.eclipse.dd.dsf.debug.service.IMemory; +import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.model.IMemoryBlock; import org.eclipse.debug.core.model.IMemoryBlockRetrieval; +import org.osgi.framework.BundleContext; +import org.osgi.framework.InvalidSyntaxException; import org.osgi.util.tracker.ServiceTracker; /** - * + * Implementation of memory access API of the Eclipse standard debug model. + *
    Note: This is only a sample implementation intended as a starting point. */ -public class DsfMemoryBlockRetrieval implements IMemoryBlockRetrieval { - +public class DsfMemoryBlockRetrieval extends PlatformObject + implements IMemoryBlockRetrieval +{ + private final String fModelId; + private final DsfSession fSession; + private final DsfExecutor fExecutor; private final IDMContext fContext; private final ServiceTracker fServiceTracker; - public DsfMemoryBlockRetrieval(IDMContext dmc) { + public DsfMemoryBlockRetrieval(String modelId, IDMContext dmc) throws DebugException { + fModelId = modelId; fContext = dmc; + fSession = DsfSession.getSession(fContext.getSessionId()); + if (fSession == null) { + throw new IllegalArgumentException("Session for context " + fContext + " is not active"); //$NON-NLS-1$ //$NON-NLS-2$ + } + fExecutor = fSession.getExecutor(); String memoryServiceFilter = - "(&" + - "(OBJECTCLASS=" + IMemory.class.getName() + ")" + - "(" + IDsfService.PROP_SESSION_ID + "=" + dmc.getSessionId() + ")" + - ")"; - fServiceTracker = new ServiceTracker(DsfDebugPlugin.getBundleContext(), memoryServiceFilter, null); + "(&" + //$NON-NLS-1$ + "(OBJECTCLASS=" + IMemory.class.getName() + ")" + //$NON-NLS-1$//$NON-NLS-2$ + "(" + IDsfService.PROP_SESSION_ID + "=" + dmc.getSessionId() + ")" + //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ + ")"; //$NON-NLS-1$ + BundleContext bundle = DsfDebugPlugin.getBundleContext(); + try { + fServiceTracker = new ServiceTracker(bundle, bundle.createFilter(memoryServiceFilter), null); + } catch (InvalidSyntaxException e) { + throw new DebugException(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, "Error creating service filter.", e)); //$NON-NLS-1$ + } fServiceTracker.open(); } - public IMemoryBlock getMemoryBlock(long startAddress, long length) throws DebugException { + public IMemoryBlock getMemoryBlock(final long startAddress, final long length) throws DebugException { + Query query = new Query() { + @Override + protected void execute(final DataRequestMonitor rm) { + IMemory memoryService = (IMemory)fServiceTracker.getService(); + if (memoryService != null) { + final byte[] buf = new byte[(int)length]; + memoryService.getMemory( + fContext, new Addr32(startAddress), 32, buf, 0, (int)length, 0, + new RequestMonitor(fExecutor, rm) { + @Override + protected void handleOK() { + rm.setData(new DsfMemoryBlock(DsfMemoryBlockRetrieval.this, fModelId, startAddress, buf)); + rm.done(); + } + }); + } + + } + }; + fExecutor.execute(query); + try { + return query.get(); + } catch (InterruptedException e) { + } catch (ExecutionException e) { + } return null; } public boolean supportsStorageRetrieval() { - return false; + return true; } - } From 453c1f7013a142715e6d7bd0c945f6f487ec66ad Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Thu, 21 Jun 2007 18:27:17 +0000 Subject: [PATCH 109/834] Bugzilla entries 183188 - IRegisters write routines 186006 - Show mnemonics with values for the bit fields 193810 - All getXXXXXdmc helper routines need to target a particular service 193811 - Need to breakout formatted read routines to support multiple services. Randy --- .../RegisterBitFieldLayoutCellModifier.java | 11 ++- .../register/RegisterBitFieldLayoutNode.java | 13 ++- .../RegisterLayoutValueCellModifier.java | 24 +++--- .../register/SyncRegisterDataAccess.java | 85 ++++++++++++++++--- 4 files changed, 101 insertions(+), 32 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutCellModifier.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutCellModifier.java index 5bb899dfda6..0fbe1911caa 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutCellModifier.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutCellModifier.java @@ -6,7 +6,8 @@ */ package org.eclipse.dd.dsf.debug.ui.viewmodel.register; -import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.dd.dsf.debug.service.IRegisters.IBitFieldDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IBitFieldDMData; @@ -14,6 +15,7 @@ import org.eclipse.dd.dsf.debug.service.IRegisters.IMnemonic; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionCellModifier; import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePreferenceStore; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; public class RegisterBitFieldLayoutCellModifier extends WatchExpressionCellModifier { @@ -35,8 +37,9 @@ public class RegisterBitFieldLayoutCellModifier extends WatchExpressionCellModif * Used to make sure we are dealing with a valid register. */ private IBitFieldDMContext getBitFieldDMC(Object element) { - if (element instanceof IAdaptable) { - return (IBitFieldDMContext)((IAdaptable)element).getAdapter(IBitFieldDMContext.class); + if (element instanceof AbstractDMVMLayoutNode.DMVMContext) { + IDMContext dmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); + return DMContexts.getAncestorOfType(dmc, IBitFieldDMContext.class); } return null; } @@ -86,7 +89,7 @@ public class RegisterBitFieldLayoutCellModifier extends WatchExpressionCellModif /* * We let the Model provider supply the current format. */ - String value = fDataAccess.getFormattedValue(fElement, fFormatPrefStore.getDefaultFormatId()); + String value = fDataAccess.getFormattedBitFieldValue(fElement, fFormatPrefStore.getDefaultFormatId()); if ( value == null ) { value = "..."; } //$NON-NLS-1$ diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java index 717e29863e2..aef1233c561 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java @@ -175,7 +175,7 @@ public class RegisterBitFieldLayoutNode extends AbstractExpressionLayoutNode dmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); + return DMContexts.getAncestorOfType(dmc, IRegisterDMContext.class); } return null; } @@ -52,7 +59,6 @@ public class RegisterLayoutValueCellModifier extends WatchExpressionCellModifier /* * Make sure we are are dealing with a valid set of information. */ - if ( getRegisterDMC(element) == null ) return false; /* @@ -79,13 +85,7 @@ public class RegisterLayoutValueCellModifier extends WatchExpressionCellModifier /* * Make sure we are working on the editable areas. */ - - /* - * Write the value in the currently requested format. Since they could - * have freeformed typed in any format this is just a guess and may not - * really accomplish anything. - */ - String value = fDataAccess.getFormattedValue(element, fFormattedValuePreferenceStore.getDefaultFormatId()); + String value = fDataAccess.getFormattedRegisterValue(element, fFormattedValuePreferenceStore.getDefaultFormatId()); if ( value == null ) { return "..."; } //$NON-NLS-1$ else { return value; } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java index 185b0f9e8fa..407c7de6d31 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java @@ -13,12 +13,13 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.register; import java.util.concurrent.ExecutionException; -import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.Query; import org.eclipse.dd.dsf.concurrent.ThreadSafeAndProhibitedFromDsfExecutor; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters; import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext; import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData; @@ -33,6 +34,7 @@ import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMData; import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; import org.osgi.framework.InvalidSyntaxException; import org.osgi.util.tracker.ServiceTracker; @@ -137,8 +139,9 @@ public class SyncRegisterDataAccess { } public IBitFieldDMContext getBitFieldDMC(Object element) { - if (element instanceof IAdaptable) { - return (IBitFieldDMContext) ((IAdaptable) element).getAdapter(IBitFieldDMContext.class); + if (element instanceof AbstractDMVMLayoutNode.DMVMContext) { + IDMContext dmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); + return DMContexts.getAncestorOfType(dmc, IBitFieldDMContext.class); } return null; } @@ -392,22 +395,26 @@ public class SyncRegisterDataAccess { } public IRegisterGroupDMContext getRegisterGroupDMC(Object element) { - if (element instanceof IAdaptable) { - return (IRegisterGroupDMContext) ((IAdaptable) element).getAdapter(IRegisterGroupDMContext.class); + if (element instanceof AbstractDMVMLayoutNode.DMVMContext) { + IDMContext dmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); + return DMContexts.getAncestorOfType(dmc, IRegisterGroupDMContext.class); } return null; } public IRegisterDMContext getRegisterDMC(Object element) { - if (element instanceof IAdaptable) { - return (IRegisterDMContext) ((IAdaptable) element).getAdapter(IRegisterDMContext.class); + if (element instanceof AbstractDMVMLayoutNode.DMVMContext) { + IDMContext dmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); + return DMContexts.getAncestorOfType(dmc, IRegisterDMContext.class); } return null; } public IFormattedDataDMContext getFormattedDMC(Object element) { - if (element instanceof IAdaptable) { - return (IFormattedDataDMContext) ((IAdaptable) element).getAdapter(IFormattedDataDMContext.class); + if (element instanceof AbstractDMVMLayoutNode.DMVMContext) { + IDMContext dmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); + IRegisterDMContext regdmc = DMContexts.getAncestorOfType(dmc, IRegisterDMContext.class); + return DMContexts.getAncestorOfType(regdmc, IFormattedDataDMContext.class); } return null; } @@ -772,7 +779,13 @@ public class SyncRegisterDataAccess { * Get the DMC and the session. If element is not an register DMC, or * session is stale, then bail out. */ - IFormattedDataDMContext dmc = getFormattedDMC(element); + IFormattedDataDMContext dmc = null; + if (element instanceof AbstractDMVMLayoutNode.DMVMContext) { + IDMContext vmcdmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); + IRegisterDMContext regdmc = DMContexts.getAncestorOfType(vmcdmc, IRegisterDMContext.class); + dmc = DMContexts.getAncestorOfType(regdmc, IFormattedDataDMContext.class); + } + if (dmc == null) return null; DsfSession session = DsfSession.getSession(dmc.getSessionId()); if (session == null) return null; @@ -799,7 +812,7 @@ public class SyncRegisterDataAccess { return null; } } - + public class GetFormattedValueValueQuery extends Query { private IFormattedDataDMContext fDmc; @@ -864,13 +877,59 @@ public class SyncRegisterDataAccess { } } - public String getFormattedValue(Object element, String formatId) { + public String getFormattedRegisterValue(Object element, String formatId) { /* * Get the DMC and the session. If element is not an register DMC, or * session is stale, then bail out. */ - IFormattedDataDMContext dmc = getFormattedDMC(element); + IFormattedDataDMContext dmc = null; + if (element instanceof AbstractDMVMLayoutNode.DMVMContext) { + IDMContext vmcdmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); + IRegisterDMContext regdmc = DMContexts.getAncestorOfType(vmcdmc, IRegisterDMContext.class); + dmc = DMContexts.getAncestorOfType(regdmc, IFormattedDataDMContext.class); + } + + if (dmc == null) return null; + DsfSession session = DsfSession.getSession(dmc.getSessionId()); + if (session == null) return null; + + /* + * Create the query to write the value to the service. Note: no need to + * guard agains RejectedExecutionException, because + * DsfSession.getSession() above would only return an active session. + */ + GetFormattedValueValueQuery query = new GetFormattedValueValueQuery(dmc, formatId); + session.getExecutor().execute(query); + + /* + * Now we have the data, go and get it. Since the call is completed now + * the ".get()" will not suspend it will immediately return with the + * data. + */ + try { + return (String) query.get(); + } catch (InterruptedException e) { + assert false; + return null; + } catch (ExecutionException e) { + return null; + } + } + + public String getFormattedBitFieldValue(Object element, String formatId) { + + /* + * Get the DMC and the session. If element is not an register DMC, or + * session is stale, then bail out. + */ + IFormattedDataDMContext dmc = null; + if (element instanceof AbstractDMVMLayoutNode.DMVMContext) { + IDMContext vmcdmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); + IBitFieldDMContext bitfielddmc = DMContexts.getAncestorOfType(vmcdmc, IBitFieldDMContext.class); + dmc = DMContexts.getAncestorOfType(bitfielddmc, IFormattedDataDMContext.class); + } + if (dmc == null) return null; DsfSession session = DsfSession.getSession(dmc.getSessionId()); if (session == null) return null; From 4ea1ca73505dfb21b260bd4c758eaaea0c29dcb2 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 27 Jun 2007 23:41:42 +0000 Subject: [PATCH 110/834] Committed patch to enable IMemoryBlockExtension support (from bug 160046). --- .../dd/dsf/debug/model/DsfMemoryBlock.java | 340 ++++++++++++++++-- .../debug/model/DsfMemoryBlockRetrieval.java | 216 ++++++++--- .../eclipse/dd/dsf/debug/service/IMemory.java | 20 ++ 3 files changed, 493 insertions(+), 83 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java index 9a7e71897fe..dd5a55867a8 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java @@ -7,64 +7,64 @@ * * Contributors: * Wind River Systems - initial API and implementation + * Ericsson Communication - upgrade IF from IMemoryBlock to IMemoryBlockExtension *******************************************************************************/ package org.eclipse.dd.dsf.debug.model; -import org.eclipse.core.runtime.IStatus; +import java.math.BigInteger; +import java.util.concurrent.ExecutionException; + +import org.eclipse.cdt.utils.Addr32; import org.eclipse.core.runtime.PlatformObject; -import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.debug.DsfDebugPlugin; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.Query; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.debug.service.IMemory; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.model.IDebugTarget; -import org.eclipse.debug.core.model.IMemoryBlock; +import org.eclipse.debug.core.model.IMemoryBlockExtension; +import org.eclipse.debug.core.model.IMemoryBlockRetrieval; +import org.eclipse.debug.core.model.MemoryByte; -public class DsfMemoryBlock extends PlatformObject implements IMemoryBlock +/** + * This class holds the memory block retrieved from the target as a result of + * a getBytes() or getBytesFromAddress() call from the platform. + */ +public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtension { private final DsfMemoryBlockRetrieval fRetrieval; private final String fModelId; + private final String fExpression; private final long fStartAddress; - private final byte[] fBytes; + private final long fLength; + private final BigInteger fBaseAddress; - DsfMemoryBlock(DsfMemoryBlockRetrieval retrieval, String modelId, long startAddress, byte[] bytes) { + /** + * Constructor + * + * @param retrieval + * @param modelId + * @param expression + * @param startAddress + * @param length + */ + DsfMemoryBlock(DsfMemoryBlockRetrieval retrieval, String modelId, String expression, long startAddress, long length) { fRetrieval = retrieval; fModelId = modelId; + fExpression = expression; fStartAddress = startAddress; - fBytes = bytes; - } - - public byte[] getBytes() throws DebugException { - return fBytes; + fBaseAddress = new BigInteger(Long.toString(startAddress)); + fLength = length; } - public long getLength() { - return fBytes.length; - } + // //////////////////////////////////////////////////////////////////////// + // IAdaptable + // //////////////////////////////////////////////////////////////////////// - public long getStartAddress() { - return fStartAddress; - } - - public void setValue(long offset, byte[] bytes) throws DebugException { - throw new DebugException(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, DebugException.NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$ - } - - public boolean supportsValueModification() { - return false; - } - - public IDebugTarget getDebugTarget() { - return null; - } - - public ILaunch getLaunch() { - return null; - } - - public String getModelIdentifier() { - return fModelId; - } - + /* (non-Javadoc) + * @see org.eclipse.core.runtime.PlatformObject#getAdapter(java.lang.Class) + */ @Override public Object getAdapter(Class adapter) { if (adapter.isAssignableFrom(DsfMemoryBlockRetrieval.class)) { @@ -72,4 +72,266 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlock } return super.getAdapter(adapter); } + + // //////////////////////////////////////////////////////////////////////// + // IDebugElement + // //////////////////////////////////////////////////////////////////////// + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IDebugElement#getDebugTarget() + */ + public IDebugTarget getDebugTarget() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IDebugElement#getModelIdentifier() + */ + public String getModelIdentifier() { + return fModelId; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IDebugElement#getLaunch() + */ + public ILaunch getLaunch() { + return null; + } + + // //////////////////////////////////////////////////////////////////////// + // IMemoryBock interface - obsoleted by IMemoryBlockExtension + // //////////////////////////////////////////////////////////////////////// + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IMemoryBlock#getStartAddress() + */ + public long getStartAddress() { + return fStartAddress; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IMemoryBlock#getLength() + */ + public long getLength() { + return fLength; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IMemoryBlock#getBytes() + */ + public byte[] getBytes() throws DebugException { + MemoryByte[] block = fetchMemoryBlock(fStartAddress, fLength); + int length = block.length; + byte[] bytes = new byte[length]; + // Extract bytes from MemoryBytes + for (int i = 0; i < length; i++) + bytes[i] = block[i].getValue(); + return bytes; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IMemoryBlock#supportsValueModification() + */ + public boolean supportsValueModification() { + return true; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IMemoryBlock#setValue(long, byte[]) + */ + public void setValue(long offset, byte[] bytes) throws DebugException { + setValue(BigInteger.valueOf(offset), bytes); + } + + // //////////////////////////////////////////////////////////////////////// + // IMemoryBlockExtension interface + // //////////////////////////////////////////////////////////////////////// + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IMemoryBlockExtension#getExpression() + */ + public String getExpression() { + return fExpression; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IMemoryBlockExtension#getBigBaseAddress() + */ + public BigInteger getBigBaseAddress() throws DebugException { + return fBaseAddress; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IMemoryBlockExtension#getMemoryBlockStartAddress() + */ + public BigInteger getMemoryBlockStartAddress() throws DebugException { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IMemoryBlockExtension#getMemoryBlockEndAddress() + */ + public BigInteger getMemoryBlockEndAddress() throws DebugException { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IMemoryBlockExtension#getBigLength() + */ + public BigInteger getBigLength() throws DebugException { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IMemoryBlockExtension#getAddressSize() + */ + public int getAddressSize() throws DebugException { + // TODO: Have the service make a trip to the back-end and + // retrieve/store that information for us + return 4; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IMemoryBlockExtension#supportBaseAddressModification() + */ + public boolean supportBaseAddressModification() throws DebugException { + return true; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IMemoryBlockExtension#supportsChangeManagement() + */ + public boolean supportsChangeManagement() { + return true; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IMemoryBlockExtension#setBaseAddress(java.math.BigInteger) + */ + public void setBaseAddress(BigInteger address) throws DebugException { + // TODO Auto-generated method stub + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IMemoryBlockExtension#getBytesFromOffset(java.math.BigInteger, long) + */ + public MemoryByte[] getBytesFromOffset(BigInteger unitOffset, long addressableUnits) throws DebugException { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IMemoryBlockExtension#getBytesFromAddress(java.math.BigInteger, long) + */ + public MemoryByte[] getBytesFromAddress(BigInteger address, long units) throws DebugException { + return fetchMemoryBlock(address.longValue(), units); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IMemoryBlockExtension#setValue(java.math.BigInteger, byte[]) + */ + public void setValue(BigInteger offset, byte[] bytes) throws DebugException { + // TODO Auto-generated method stub + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IMemoryBlockExtension#connect(java.lang.Object) + */ + public void connect(Object client) { + // TODO Auto-generated method stub + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IMemoryBlockExtension#disconnect(java.lang.Object) + */ + public void disconnect(Object client) { + // TODO Auto-generated method stub + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IMemoryBlockExtension#getConnections() + */ + public Object[] getConnections() { + // TODO Auto-generated method stub + return new Object[0]; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IMemoryBlockExtension#dispose() + */ + public void dispose() throws DebugException { + // TODO Auto-generated method stub + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IMemoryBlockExtension#getMemoryBlockRetrieval() + */ + public IMemoryBlockRetrieval getMemoryBlockRetrieval() { + return fRetrieval; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IMemoryBlockExtension#getAddressableSize() + */ + public int getAddressableSize() throws DebugException { + // TODO: Have the service make a trip to the back-end and + // retrieve/store that information for us + return 1; + } + + // //////////////////////////////////////////////////////////////////////// + // Helper functions + // //////////////////////////////////////////////////////////////////////// + + /* The real thing. Since the original call is synchronous (from a platform Job), + * we use a Query that will patiently wait for the underlying asynchronous calls + * to complete before returning. + * + * @param address + * @param length + * @return MemoryBytes[] + * @throws DebugException + */ + private MemoryByte[] fetchMemoryBlock(final long address, final long length) throws DebugException { + + /* For this first implementation, we make a few simplifying assumptions: + * - word_size = 1 (we want to read individual bytes) + * - offset = 0 + * - mode = hexadecimal (will be overridden in getMemory() anyway) + */ + final int word_size = 1; + final int offset = 0; + final int mode = 0; // TODO: Add a constant for hexadecimal mode + + // Use a Query to "synchronize" the inherently asynchronous downstream calls + Query query = new Query() { + @Override + protected void execute(final DataRequestMonitor rm) { + IMemory memoryService = (IMemory) fRetrieval.getServiceTracker().getService(); + if (memoryService != null) { + // Place holder for the result + final MemoryByte[] buffer = new MemoryByte[(int) length]; + // Go for it + memoryService.getMemory( + fRetrieval.getContext(), new Addr32(address), word_size, buffer, offset, (int) length, mode, + new RequestMonitor(fRetrieval.getExecutor(), rm) { + @Override + protected void handleOK() { + rm.setData(buffer); + rm.done(); + } + }); + } + + } + }; + fRetrieval.getExecutor().execute(query); + try { + return query.get(); + } catch (InterruptedException e) { + } catch (ExecutionException e) { + } + return null; + } + } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java index d6418bb0aa9..41574b32b49 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java @@ -7,19 +7,14 @@ * * Contributors: * Wind River Systems - initial API and implementation + * Ericsson Communication - upgrade IF from IMemoryBlockRetrieval to IMemoryBlockRetrievalExtension *******************************************************************************/ package org.eclipse.dd.dsf.debug.model; -import java.util.concurrent.ExecutionException; - -import org.eclipse.cdt.utils.Addr32; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.PlatformObject; import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfExecutor; -import org.eclipse.dd.dsf.concurrent.Query; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.debug.DsfDebugPlugin; import org.eclipse.dd.dsf.debug.service.IMemory; @@ -27,24 +22,40 @@ import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.model.IMemoryBlock; -import org.eclipse.debug.core.model.IMemoryBlockRetrieval; +import org.eclipse.debug.core.model.IMemoryBlockExtension; +import org.eclipse.debug.core.model.IMemoryBlockRetrievalExtension; import org.osgi.framework.BundleContext; import org.osgi.framework.InvalidSyntaxException; import org.osgi.util.tracker.ServiceTracker; /** * Implementation of memory access API of the Eclipse standard debug model. - *
    Note: This is only a sample implementation intended as a starting point. + * + * The IMemoryBlockRetrievalExtension is implemented for the reference + * application. This will result in getExtendedMemoryBlock() being called + * when a memory block is selected from the memory pane. + * + * However, if the 'simpler' IMemoryBlockRetrieval is to be implemented, the + * code will still be functional after trivial adjustments. In that case, the + * platform will call getMemoryBlock() instead. Note that DsfMemoryBlock will + * have to be 'downgraded' to implement IMemoryBlock (instead of IMemoryBlockExtension) + * */ -public class DsfMemoryBlockRetrieval extends PlatformObject - implements IMemoryBlockRetrieval +public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBlockRetrievalExtension { - private final String fModelId; - private final DsfSession fSession; - private final DsfExecutor fExecutor; - private final IDMContext fContext; - private final ServiceTracker fServiceTracker; + private final String fModelId; + private final DsfSession fSession; + private final DsfExecutor fExecutor; + private final IDMContext fContext; + private final ServiceTracker fServiceTracker; + /** + * Constructor + * + * @param modelId + * @param dmc + * @throws DebugException + */ public DsfMemoryBlockRetrieval(String modelId, IDMContext dmc) throws DebugException { fModelId = modelId; fContext = dmc; @@ -66,37 +77,154 @@ public class DsfMemoryBlockRetrieval extends PlatformObject } fServiceTracker.open(); } - - public IMemoryBlock getMemoryBlock(final long startAddress, final long length) throws DebugException { - Query query = new Query() { - @Override - protected void execute(final DataRequestMonitor rm) { - IMemory memoryService = (IMemory)fServiceTracker.getService(); - if (memoryService != null) { - final byte[] buf = new byte[(int)length]; - memoryService.getMemory( - fContext, new Addr32(startAddress), 32, buf, 0, (int)length, 0, - new RequestMonitor(fExecutor, rm) { - @Override - protected void handleOK() { - rm.setData(new DsfMemoryBlock(DsfMemoryBlockRetrieval.this, fModelId, startAddress, buf)); - rm.done(); - } - }); - } - - } - }; - fExecutor.execute(query); - try { - return query.get(); - } catch (InterruptedException e) { - } catch (ExecutionException e) { - } - return null; - } + // //////////////////////////////////////////////////////////////////////// + // Accessors + // //////////////////////////////////////////////////////////////////////// + + /** + * + * @return + */ + public String getModelId() { + return fModelId; + } + + /** + * + * @return + */ + public DsfSession getSession() { + return fSession; + } + + /** + * + * @return + */ + public DsfExecutor getExecutor() { + return fExecutor; + } + + /** + * + * @return + */ + public IDMContext getContext() { + return fContext; + } + + /** + * + * @return + */ + public ServiceTracker getServiceTracker() { + return fServiceTracker; + } + + // //////////////////////////////////////////////////////////////////////// + // IMemoryBlockRetrieval - obsoleted by IMemoryBlockRetrievalExtension + // //////////////////////////////////////////////////////////////////////// + + /* + * (non-Javadoc) + * @see org.eclipse.debug.core.model.IMemoryBlockRetrieval#supportsStorageRetrieval() + */ public boolean supportsStorageRetrieval() { return true; } + + /* + * (non-Javadoc) + * @see org.eclipse.debug.core.model.IMemoryBlockRetrieval#getMemoryBlock(long, long) + */ + public IMemoryBlock getMemoryBlock(final long startAddress, final long length) throws DebugException { + // The expression to display in the rendering tab + // Put here for the sake of completeness (not used with IMemoryBlock) + String expression = "0x" + Long.toHexString(startAddress); //$NON-NLS-1$ + return new DsfMemoryBlock(DsfMemoryBlockRetrieval.this, fModelId, expression, startAddress, length); + } + + // //////////////////////////////////////////////////////////////////////// + // IMemoryBlockRetrievalExtension + // //////////////////////////////////////////////////////////////////////// + + /* + * (non-Javadoc) + * @see org.eclipse.debug.core.model.IMemoryBlockRetrievalExtension#getExtendedMemoryBlock(java.lang.String, java.lang.Object) + */ + public IMemoryBlockExtension getExtendedMemoryBlock(String expression, Object context) throws DebugException { + + boolean validAddress = false; + long address = 0; + + /* See if the expression is a simple numeric value; if it is, we can + * avoid some costly processing (calling the back-end to resolve the + * expression and obtain an address) + */ + try { + // First, assume a decimal address (not too realistic but bear with us :-) + int base = 10; + int offset = 0; + + // Check for "hexadecimality" + if (expression.startsWith("0x") || expression.startsWith("0X")) { //$NON-NLS-1$//$NON-NLS-2$ + base = 16; + offset = 2; + } + + // Now, try to parse the expression. If a NumberFormatException is thrown, + // then it wasn't a simple numerical expression and we go to plan B + address = Long.parseLong(expression.substring(offset), base); + + // All right! We saved a trip to the back-end. + validAddress = true; + + } catch (NumberFormatException nfexc) { + // OK, expression is not a simple, absolute numeric value; try to resolve as expression + } + + // We have to ask the debugger to resolve the address for us + if (!validAddress) { + // [frch] Code removed until we properly hook the ExpressionService + // [frch] Code saved in lmcfrch-memory-070625.PATCH + return null; + } + + /* At this point, we only know the requested address and we have no + * idea of the memory block length. The renderer will provide this + * information when it calls getBytesFromAddress() i.e. after the + * memory block holder has been instantiated... + * + * We could try to out-smart the renderer and do some educated guess + * about the start address it will select and the length it will + * request. + * + * This would 'work' for the standard debug renderers: start address + * on a 16-byte boundary, length of 320 bytes (20 lines of 16 bytes). + * However, this is not such a great idea: a given renderer might ask + * for a block starting at any address adn length it sees fit. Therefore + * we can't make any assumption. + * + * The only safe approach is to just instantiate the IMemoryBlockExtension + * and postpone the actual memory fetch until the renderer explicitly + * asks for it (i.e. calls getBytesFromAddress()). + * + * The down side is that every time we switch renderer, for the same block, + * a trip to the target could result. + * + * However, we have an ace in our sleeve: the memory request cache should + * save us a trip to the back-end. + */ + + return new DsfMemoryBlock(DsfMemoryBlockRetrieval.this, fModelId, expression, address, 0); + } + + // //////////////////////////////////////////////////////////////////////// + // Helper functions + // //////////////////////////////////////////////////////////////////////// + + // [frch] Code removed until we properly hook the ExpressionService + // [frch] Code saved in lmcfrch-memory-070625.PATCH + } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java index df3ccbcbb4b..d1ac1282c8f 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java @@ -7,6 +7,7 @@ * * Contributors: * Wind River Systems - initial API and implementation + * Ericsson Communication - extended the API for IMemoryBlockExtension *******************************************************************************/ package org.eclipse.dd.dsf.debug.service; @@ -14,6 +15,7 @@ import org.eclipse.cdt.core.IAddress; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.debug.core.model.MemoryByte; /** * Service for accessing memory. Memory contexts are not meant to be @@ -38,5 +40,23 @@ public interface IMemory extends IDsfService { */ public void fillMemory(IDMContext ctx, IAddress addr, int word_size, byte[] value, int size, int mode, RequestMonitor requestMonitor); + + // //////////////////////////////////////////////////////////////////////// + // Replicated the base functions to support IMemoryBlockExtension + // //////////////////////////////////////////////////////////////////////// + + /** Writes the given value to the given memory location. */ + public void setMemory(IDMContext ctx, IAddress addr, + int word_size, MemoryByte[] buf, int offs, int size, int mode, RequestMonitor requestMonitor); + + /** Reads memory at the given location */ + public void getMemory(IDMContext ctx, IAddress addr, + int word_size, MemoryByte[] buf, int offs, int size, int mode, RequestMonitor requestMonitor); + + public void fillMemory(IDMContext ctx, IAddress addr, + int word_size, MemoryByte[] value, int size, int mode, RequestMonitor requestMonitor); + +// /** Reads memory at the given location */ +// public void resolveMemoryAddress(IDMContext ctx, String expression, BigInteger[] address, RequestMonitor requestMonitor); } From f5f70da342be313a1a1ad96dfd09aa5b1d8cbd2a Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Sat, 30 Jun 2007 03:22:49 +0000 Subject: [PATCH 111/834] First attempt at update policies / modes. --- .../build.properties | 3 +- .../icons/refresh.gif | Bin 0 -> 385 bytes .../org.eclipse.dd.dsf.debug.ui/plugin.xml | 151 +++++++++ .../expression/ExpressionVMProvider.java | 4 +- .../register/RegisterBitFieldLayoutNode.java | 15 +- .../register/RegisterLayoutNode.java | 61 ++-- .../register/RegisterVMProvider.java | 4 +- .../update/VMCacheRefreshAlways.java | 36 ++ .../update/VMCacheRefreshManual.java | 25 ++ .../update/VMCacheRefreshOnBreak.java | 31 ++ .../update/actions/RefreshActionDelegate.java | 44 +++ .../actions/RefreshAlwaysActionDelegate.java | 34 ++ .../actions/RefreshManualActionDelegate.java | 34 ++ .../actions/RefreshOnBreakActionDelegate.java | 34 ++ .../variable/VariableLocalsLayoutNode.java | 15 +- .../VariableSubExpressionsLayoutNode.java | 15 +- .../variable/VariableVMProvider.java | 4 +- .../META-INF/MANIFEST.MF | 6 +- .../viewmodel/dm/AbstractDMVMLayoutNode.java | 9 +- .../dm/AbstractDMVMProviderWithCache.java | 63 ++++ .../dd/dsf/ui/viewmodel/update/VMCache.java | 315 ++++++++++++++++++ .../ui/viewmodel/update/VMCacheManager.java | 105 ++++++ .../AbstractRefreshActionDelegate.java | 40 +++ 23 files changed, 999 insertions(+), 49 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/icons/refresh.gif create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshAlways.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshManual.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshOnBreak.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshActionDelegate.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshAlwaysActionDelegate.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshManualActionDelegate.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshOnBreakActionDelegate.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProviderWithCache.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCacheManager.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/actions/AbstractRefreshActionDelegate.java diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/build.properties b/plugins/org.eclipse.dd.dsf.debug.ui/build.properties index 4a2586141ff..65c7e05604b 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/build.properties +++ b/plugins/org.eclipse.dd.dsf.debug.ui/build.properties @@ -3,4 +3,5 @@ output.. = bin/ bin.includes = META-INF/,\ plugin.xml,\ about.html,\ - . + .,\ + icons/ diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/icons/refresh.gif b/plugins/org.eclipse.dd.dsf.debug.ui/icons/refresh.gif new file mode 100644 index 0000000000000000000000000000000000000000..b6b8dc6836dc1fa4b10189958fa157c4d1961b86 GIT binary patch literal 385 zcmZ?wbhEHb6krfw*v!E2|G#~Gz5V?8@&EtNpFh8T|Ni;^@7vF>x4%E%zCPam|NsB{ zfkN}=0~ripp!k!8k%57iK?lSGnZdx4xWQ9$*u4~E zOXg(ap5Vd@jp7R@Ivmik6Kx7mkdvOR^7w*EnieaQlEK=vfR>hpm;UmxSTbyPvk>6b z6)Qg|C|$tBHrLtYlOd;ny>Jt+AcM7YeqKpxUWsl + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java index 0356fc87ca3..6f569e19447 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java @@ -24,7 +24,7 @@ import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProviderWithCache; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.IExpressionsListener; import org.eclipse.debug.core.model.IExpression; @@ -35,7 +35,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationCont * */ @SuppressWarnings("restriction") -public class ExpressionVMProvider extends AbstractDMVMProvider +public class ExpressionVMProvider extends AbstractDMVMProviderWithCache implements IExpressionsListener, IFormattedValuePreferenceStore { private String fDefaultFormatId = IFormattedValues.HEX_FORMAT; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java index aef1233c561..a028a2589c3 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java @@ -43,6 +43,7 @@ import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.model.IDebugTarget; @@ -236,8 +237,9 @@ public class RegisterBitFieldLayoutNode extends AbstractExpressionLayoutNode(getSession().getExecutor(), null) { @Override public void handleCompleted() { @@ -259,7 +261,8 @@ public class RegisterBitFieldLayoutNode extends AbstractExpressionLayoutNode(getSession().getExecutor(), null) { @Override @@ -341,7 +345,8 @@ public class RegisterBitFieldLayoutNode extends AbstractExpressionLayoutNode @@ -231,25 +234,37 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode(getSession().getExecutor(), null) { - @Override - public void handleCompleted() { - if (!getStatus().isOK()) { - handleFailedUpdate(update); - return; - } - - /* - * Fill the label/column with the properly formatted data value. - */ - update.setLabel(getData().getFormattedValue(), labelIndex); - update.done(); - } - } + VMCacheManager.getVMCacheManager().getCache(RegisterLayoutNode.this.getVMProvider().getPresentationContext()) + .getModelData(regService, + valueDmc, + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + public void handleCompleted() { + if (!getStatus().isOK()) { + handleFailedUpdate(update); + return; + } + + /* + * Fill the label/column with the properly formatted data value. + */ + update.setLabel(getData().getFormattedValue(), labelIndex); + + // color based on change history + FormattedValueDMData oldData = (FormattedValueDMData) VMCacheManager.getVMCacheManager() + .getCache(RegisterLayoutNode.this.getVMProvider().getPresentationContext()) + .getArchivedModelData(valueDmc); + if(oldData != null && oldData.getFormattedValue().equals(getData().getFormattedValue())) + update.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK).getRGB(), labelIndex); + else + update.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_RED).getRGB(), labelIndex); + + update.done(); + } + }, + getSession().getExecutor() ); } } @@ -270,9 +285,10 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode(getSession().getExecutor(), null) { + VMCacheManager.getVMCacheManager().getCache(update.getPresentationContext()) + .getModelData((IDMService)getServicesTracker().getService(null, dmc.getServiceFilter()), + dmc, + new DataRequestMonitor(getSession().getExecutor(), null) { @Override protected void handleCompleted() { /* @@ -332,7 +348,8 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode(getSession().getExecutor(), null) { @Override protected void handleCompleted() { @@ -221,7 +223,8 @@ public class VariableLocalsLayoutNode extends AbstractExpressionLayoutNode(getSession().getExecutor(), null) { @Override @@ -309,7 +313,8 @@ public class VariableLocalsLayoutNode extends AbstractExpressionLayoutNode(getSession().getExecutor(), null) { @Override @@ -123,7 +125,8 @@ public class VariableSubExpressionsLayoutNode extends AbstractDMVMLayoutNode(getSession().getExecutor(), null) { @Override public void handleCompleted() { @@ -211,7 +215,8 @@ public class VariableSubExpressionsLayoutNode extends AbstractDMVMLayoutNode extends Abstract final IDMContext dmc = findDmcInPath(update.getElementPath(), fDMCClassType); if (!checkDmc(dmc, update) || !checkService(null, dmc.getServiceFilter(), update)) return; - ((IDMService)getServicesTracker().getService(null, dmc.getServiceFilter())).getModelData( - dmc, + VMCacheManager.getVMCacheManager().getCache(update.getPresentationContext()) + .getModelData((IDMService)getServicesTracker().getService(null, dmc.getServiceFilter()), + dmc, new DataRequestMonitor(getSession().getExecutor(), null) { @Override protected void handleCompleted() { @@ -350,7 +352,8 @@ abstract public class AbstractDMVMLayoutNode extends Abstract } update.done(); } - }); + }, + getExecutor()); } } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProviderWithCache.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProviderWithCache.java new file mode 100644 index 00000000000..058ac9b90bb --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProviderWithCache.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + *******************************************************************************/ + +package org.eclipse.dd.dsf.ui.viewmodel.dm; + +import org.eclipse.dd.dsf.datamodel.IDMEvent; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; +import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; + +public abstract class AbstractDMVMProviderWithCache extends AbstractDMVMProvider + implements VMCacheManager.CacheListener +{ + @DsfServiceEventHandler + public void eventDispatched(IDMEvent event) { + VMCacheManager.getVMCacheManager().getCache(getPresentationContext()).handleEvent(event); + super.eventDispatched(event); + } + + public void cacheFlushed(Object context) { + if(getPresentationContext().equals(context)) + getModelProxy().fireModelChanged(new ModelDelta(this.getRootLayoutNode().getRootObject(),IModelDelta.CONTENT)); + } + + public AbstractDMVMProviderWithCache(AbstractVMAdapter adapter, IPresentationContext presentationContext, DsfSession session) { + super(adapter, presentationContext, session); + + VMCacheManager.getVMCacheManager().addCacheListener(getPresentationContext(), this); + } + + public void update(IHasChildrenUpdate[] updates) { + super.update(VMCacheManager.getVMCacheManager().getCache(getPresentationContext()).update(updates)); + } + + public void update(IChildrenCountUpdate[] updates) { + super.update(VMCacheManager.getVMCacheManager().getCache(getPresentationContext()).update(updates)); + } + + public void update(final IChildrenUpdate[] updates) { + super.update(VMCacheManager.getVMCacheManager().getCache(getPresentationContext()).update(updates)); + } + + public void dispose() + { + VMCacheManager.getVMCacheManager().removeCacheListener(getPresentationContext(), this); + super.dispose(); + } +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java new file mode 100644 index 00000000000..57fa567b57e --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java @@ -0,0 +1,315 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + *******************************************************************************/ + +package org.eclipse.dd.dsf.ui.viewmodel.update; + +import java.util.HashMap; +import java.util.Vector; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +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.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.jface.viewers.TreePath; + +public abstract class VMCache +{ + protected HashMap fChildrenCounts = new HashMap(); + + class ChildData + { + Object child; + int offset; + + public ChildData(Object child, int offset) + { + this.child = child; + this.offset = offset; + } + } + + protected HashMap fChildren = new HashMap(); + + protected HashMap fHasChildren = new HashMap(); + + protected HashMap, IDMData> fData = new HashMap, IDMData>(); + + protected HashMap, IDMData> fDataArchive = fData; + + protected void flush(boolean archive) + { + if(archive) + fDataArchive = fData; + fData = new HashMap, IDMData>(); + fChildrenCounts.clear(); + fChildren.clear(); + fChildrenCounts.clear(); + } + + protected boolean useCache() + { + return true; + } + + public IHasChildrenUpdate[] update(IHasChildrenUpdate[] updates) { + Vector missVector = new Vector(); + for(IHasChildrenUpdate update : updates) + { + if(fHasChildren.containsKey(update.getElement()) && useCache()) + { + update.setHasChilren(fHasChildren.get(update.getElement()).booleanValue()); + update.done(); + } + else + { + missVector.addElement(update); + } + } + + updates = new IHasChildrenUpdate[missVector.size()]; + for(int i = 0; i < updates.length; i++) + { + final IHasChildrenUpdate update = missVector.elementAt(i); + updates[i] = new IHasChildrenUpdate() + { + private boolean fIsHasChildren; + + public void setHasChilren(boolean hasChildren) { + fIsHasChildren = hasChildren; + update.setHasChilren(hasChildren); + } + + public void cancel() { + update.cancel(); + } + + public void done() { + fHasChildren.put(getElement(), Boolean.valueOf(fIsHasChildren)); + update.done(); + } + + public IStatus getStatus() { + return update.getStatus(); + } + + public boolean isCanceled() { + return update.isCanceled(); + } + + public void setStatus(IStatus status) { + update.setStatus(status); + } + + public Object getElement() { + return update.getElement(); + } + + public TreePath getElementPath() { + return update.getElementPath(); + } + + public IPresentationContext getPresentationContext() { + return update.getPresentationContext(); + } + + }; + } + + return updates; + } + + public IChildrenCountUpdate[] update(IChildrenCountUpdate[] updates) + { + Vector missVector = new Vector(); + for(IChildrenCountUpdate update : updates) + { + if(fChildrenCounts.containsKey(update.getElement()) && useCache()) + { + update.setChildCount(fChildrenCounts.get(update.getElement())); + update.done(); + } + else + { + missVector.addElement(update); + } + } + + updates = new IChildrenCountUpdate[missVector.size()]; + for(int i = 0; i < updates.length; i++) + { + final IChildrenCountUpdate update = missVector.elementAt(i); + updates[i] = new IChildrenCountUpdate() + { + private int fChildCount; + + public void cancel() { + update.cancel(); + } + + public void done() { + fChildrenCounts.put(getElement(), fChildCount); + update.done(); + } + + public IStatus getStatus() { + return update.getStatus(); + } + + public boolean isCanceled() { + return update.isCanceled(); + } + + public void setStatus(IStatus status) { + update.setStatus(status); + } + + public void setChildCount(int numChildren) { + fChildCount = numChildren; + update.setChildCount(numChildren); + } + + public Object getElement() { + return update.getElement(); + } + + public TreePath getElementPath() { + return update.getElementPath(); + } + + public IPresentationContext getPresentationContext() { + return update.getPresentationContext(); + } + + }; + } + + return updates; + } + + public IChildrenUpdate[] update(IChildrenUpdate[] updates) { + Vector missVector = new Vector(); + for(IChildrenUpdate update : updates) + { + if(fChildren.containsKey(update.getElement()) && useCache()) + { + ChildData childData[] = fChildren.get(update.getElement()); + for(ChildData data : childData) + update.setChild(data.child, data.offset); + update.done(); + } + else + { + missVector.addElement(update); + } + } + + updates = new IChildrenUpdate[missVector.size()]; + for(int i = 0; i < updates.length; i++) + { + final IChildrenUpdate update = missVector.elementAt(i); + updates[i] = new IChildrenUpdate() + { + Vector fChilds = new Vector(); + + public int getLength() { + return update.getLength(); + } + + public int getOffset() { + return update.getOffset(); + } + + public void setChild(Object child, int offset) { + fChilds.addElement(new ChildData(child, offset)); + update.setChild(child, offset); + } + + public void cancel() { + update.cancel(); + } + + public void done() { + // FIXME synchronize with events? + fChildren.put(getElement(), fChilds.toArray(new ChildData[fChilds.size()])); + update.done(); + } + + public IStatus getStatus() { + return update.getStatus(); + } + + public boolean isCanceled() { + return update.isCanceled(); + } + + public void setStatus(IStatus status) { + update.setStatus(status); + } + + public Object getElement() { + return update.getElement(); + } + + public TreePath getElementPath() { + return update.getElementPath(); + } + + public IPresentationContext getPresentationContext() { + return update.getPresentationContext(); + } + + }; + } + + return updates; + } + + @SuppressWarnings("unchecked") + public void getModelData(IDMService service, final IDMContext dmc, final DataRequestMonitor rm, DsfExecutor executor) + { + if(fData.containsKey(dmc) && useCache()) + { + rm.setData( fData.get(dmc)); + rm.done(); + } + else + { + service.getModelData(dmc, + new DataRequestMonitor(executor, null) { + @Override + public void handleCompleted() { + fData.put(dmc, getData()); + rm.setData(getData()); + rm.done(); + } + } + ); + } + } + + @SuppressWarnings("unchecked") + public IDMData getArchivedModelData(IDMContext dmc) + { + return fDataArchive.get(dmc); + } + + public abstract void handleEvent(IDMEvent event); + +} + + diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCacheManager.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCacheManager.java new file mode 100644 index 00000000000..cdf60c43c41 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCacheManager.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + *******************************************************************************/ + +package org.eclipse.dd.dsf.ui.viewmodel.update; + +import java.util.HashMap; +import java.util.Vector; + +import org.eclipse.dd.dsf.datamodel.IDMEvent; + + +public class VMCacheManager +{ + private static VMCacheManager fInstance = null; + + private HashMap fAssociations = new HashMap(); + + public interface CacheListener + { + public void cacheFlushed(Object context); + } + + private HashMap> fListeners = new HashMap>(); + + public VMCacheManager() + { + } + + public static VMCacheManager getVMCacheManager() + { + if(fInstance == null) + fInstance = new VMCacheManager(); + + return fInstance; + } + + public VMCache getCache(Object context) + { + if(!fAssociations.containsKey(context)) + fAssociations.put(context, new VMCache() + { + @Override + public void handleEvent(IDMEvent event) { + flush(true); + } + + public boolean readFromCache() + { + return false; + } + }); + + return fAssociations.get(context); + } + + public void registerCache(Object context, VMCache cache) + { + fAssociations.put(context, cache); + } + + public void addCacheListener(Object context, CacheListener listener) + { + if(!fListeners.containsKey(context)) + fListeners.put(context, new Vector()); + + fListeners.get(context).addElement(listener); + } + + public void removeCacheListener(Object context, CacheListener listener) + { + if(!fListeners.containsKey(context)) + { + fListeners.get(context).removeElement(listener); + if(fListeners.get(context).isEmpty()) + fListeners.remove(context); + } + } + + private void fireCacheFlushed(Object context) + { + if(fListeners.containsKey(context)) + { + for(CacheListener listener : fListeners.get(context)) + listener.cacheFlushed(context); + } + } + + public void flush(Object context) + { + getCache(context).flush(false); + fireCacheFlushed(context); + } + +} + + + diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/actions/AbstractRefreshActionDelegate.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/actions/AbstractRefreshActionDelegate.java new file mode 100644 index 00000000000..88d0f2da26e --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/actions/AbstractRefreshActionDelegate.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + *******************************************************************************/ + +package org.eclipse.dd.dsf.ui.viewmodel.update.actions; + +import org.eclipse.dd.dsf.ui.viewmodel.update.VMCache; +import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.IViewActionDelegate; +import org.eclipse.ui.IViewPart; + +public abstract class AbstractRefreshActionDelegate implements IViewActionDelegate { + + protected IViewPart fView; + + public void init(IViewPart view) { + fView = view; + } + + public void run(IAction action) { + VMCacheManager.getVMCacheManager().registerCache(getContext(), createCache()); + } + + public void selectionChanged(IAction action, ISelection selection) { + } + + protected abstract Object getContext(); + + protected abstract VMCache createCache(); + +} From 26a73ba3b265233372021e3d02bc54fea38f5fca Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Sat, 30 Jun 2007 03:40:30 +0000 Subject: [PATCH 112/834] Temporary change history colors. Longer term, we should and will use the change color from preferences. --- .../debug/ui/viewmodel/register/RegisterLayoutNode.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java index 8f3e492bd5c..807edd3a7d9 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java @@ -58,9 +58,8 @@ import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.ICellModifier; import org.eclipse.jface.viewers.TextCellEditor; import org.eclipse.jface.viewers.TreePath; -import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; @SuppressWarnings("restriction") public class RegisterLayoutNode extends AbstractExpressionLayoutNode @@ -257,9 +256,9 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode Date: Sat, 30 Jun 2007 03:59:51 +0000 Subject: [PATCH 113/834] Update modes. --- .../debug/ui/viewmodel/variable/VariableLocalsLayoutNode.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLocalsLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLocalsLayoutNode.java index 6a765d86a51..0f966c84671 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLocalsLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLocalsLayoutNode.java @@ -424,7 +424,8 @@ public class VariableLocalsLayoutNode extends AbstractExpressionLayoutNode Date: Mon, 2 Jul 2007 21:27:05 +0000 Subject: [PATCH 114/834] Replaced IRootVMLayoutNode.getRootObject() with IVMProvider.getRootElement() (bug 195182). --- .../expression/ExpressionVMProvider.java | 6 +-- .../launch/StandardLaunchRootLayoutNode.java | 4 +- .../register/RegisterVMProvider.java | 4 +- .../variable/VariableVMProvider.java | 4 +- .../dsf/ui/viewmodel/AbstractVMAdapter.java | 24 +++++----- .../ui/viewmodel/AbstractVMLayoutNode.java | 2 +- .../dsf/ui/viewmodel/AbstractVMProvider.java | 41 +++++++++++----- .../dd/dsf/ui/viewmodel/IVMAdapter.java | 6 +++ .../dd/dsf/ui/viewmodel/IVMProvider.java | 10 ++++ .../dsf/ui/viewmodel/IVMRootLayoutNode.java | 8 ---- ...tLayoutNode.java => VMRootLayoutNode.java} | 29 ++++++----- .../viewmodel/dm/AbstractDMVMLayoutNode.java | 2 +- .../dm/AbstractDMVMProviderWithCache.java | 2 +- .../ui/viewmodel/dm/DMVMRootLayoutNode.java} | 48 +++++-------------- 14 files changed, 96 insertions(+), 94 deletions(-) rename plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/{AbstractVMRootLayoutNode.java => VMRootLayoutNode.java} (75%) rename plugins/{org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewSelectionRootLayoutNode.java => org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/DMVMRootLayoutNode.java} (69%) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java index 6f569e19447..f8579ae632a 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java @@ -11,7 +11,6 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; import org.eclipse.dd.dsf.debug.service.IFormattedValues; -import org.eclipse.dd.dsf.debug.ui.viewmodel.DebugViewSelectionRootLayoutNode; import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePreferenceStore; import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterGroupLayoutNode; import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterLayoutNode; @@ -25,6 +24,7 @@ import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProviderWithCache; +import org.eclipse.dd.dsf.ui.viewmodel.dm.DMVMRootLayoutNode; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.IExpressionsListener; import org.eclipse.debug.core.model.IExpression; @@ -71,7 +71,7 @@ public class ExpressionVMProvider extends AbstractDMVMProviderWithCache /* * Create the top level node which provides the anchor starting point. */ - IVMRootLayoutNode debugViewSelectionNode = new DebugViewSelectionRootLayoutNode(this); + IVMRootLayoutNode debugViewSelectionNode = new DMVMRootLayoutNode(this); /* * Now the Overarching management node. @@ -145,7 +145,7 @@ public class ExpressionVMProvider extends AbstractDMVMProviderWithCache if (rootLayoutNode == null) { return null; } - else if (element.equals(rootLayoutNode.getRootObject())) { + else if (element.equals(getRootElement())) { return rootLayoutNode; } else if (element instanceof IVMContext){ diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java index 38f3a669992..2ea7489c2f8 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java @@ -17,7 +17,7 @@ import java.util.Map; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; -import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMRootLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.VMRootLayoutNode; import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; @@ -35,7 +35,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; * functionality, so the default adapters should be used to retrieve the label. */ @SuppressWarnings("restriction") -public class StandardLaunchRootLayoutNode extends AbstractVMRootLayoutNode +public class StandardLaunchRootLayoutNode extends VMRootLayoutNode implements IVMRootLayoutNode { public static class LaunchesEvent { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java index da5601af972..4e114c1d2d4 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java @@ -11,13 +11,13 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.register; import org.eclipse.dd.dsf.debug.service.IFormattedValues; -import org.eclipse.dd.dsf.debug.ui.viewmodel.DebugViewSelectionRootLayoutNode; import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePreferenceStore; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProviderWithCache; +import org.eclipse.dd.dsf.ui.viewmodel.dm.DMVMRootLayoutNode; import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; @@ -43,7 +43,7 @@ public class RegisterVMProvider extends AbstractDMVMProviderWithCache implements /* * Create the top level node to deal with the root selection. */ - IVMRootLayoutNode debugViewSelection = new DebugViewSelectionRootLayoutNode(this); + IVMRootLayoutNode debugViewSelection = new DMVMRootLayoutNode(this); /* * Create the Group nodes next. They represent the first level shown in the view. diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java index f7e053639e7..82c673a30f2 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java @@ -9,13 +9,13 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.variable; import org.eclipse.dd.dsf.debug.service.IFormattedValues; -import org.eclipse.dd.dsf.debug.ui.viewmodel.DebugViewSelectionRootLayoutNode; import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePreferenceStore; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProviderWithCache; +import org.eclipse.dd.dsf.ui.viewmodel.dm.DMVMRootLayoutNode; import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; @@ -37,7 +37,7 @@ public class VariableVMProvider extends AbstractDMVMProviderWithCache implements /* * Create the top level node to deal with the root selection. */ - IVMRootLayoutNode debugViewSelection = new DebugViewSelectionRootLayoutNode(this); + IVMRootLayoutNode debugViewSelection = new DMVMRootLayoutNode(this); /* * Create the local variables nodes next. They represent the first level shown in the view. diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java index a4ecedef72f..d74c297c78f 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java @@ -67,15 +67,8 @@ abstract public class AbstractVMAdapter implements IVMAdapter return fExecutor; } - /** - * Creates a new View Model Provider for given presentation context. Returns null - * if the presentation context is not supported. - */ - @ThreadSafe - abstract protected IVMProvider createViewModelProvider(IPresentationContext context); - @ThreadSafe - private IVMProvider getViewModelProvider(IPresentationContext context) { + public IVMProvider getVMProvider(IPresentationContext context) { synchronized(fViewModelProviders) { if (fDisposed) return null; @@ -142,7 +135,7 @@ abstract public class AbstractVMAdapter implements IVMAdapter } private void callProviderWithUpdate(IViewerUpdate[] updates, int startIdx, int endIdx) { - final IVMProvider provider = getViewModelProvider(updates[0].getPresentationContext()); + final IVMProvider provider = getVMProvider(updates[0].getPresentationContext()); if (provider == null) { for (IViewerUpdate update : updates) { update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, @@ -175,7 +168,7 @@ abstract public class AbstractVMAdapter implements IVMAdapter } public IModelProxy createModelProxy(Object element, IPresentationContext context) { - IVMProvider provider = getViewModelProvider(context); + IVMProvider provider = getVMProvider(context); if (provider != null) { return provider.createModelProxy(element, context); } @@ -183,7 +176,7 @@ abstract public class AbstractVMAdapter implements IVMAdapter } public IColumnPresentation createColumnPresentation(IPresentationContext context, Object element) { - final IVMProvider provider = getViewModelProvider(context); + final IVMProvider provider = getVMProvider(context); if (provider != null) { return provider.createColumnPresentation(context, element); } @@ -191,12 +184,17 @@ abstract public class AbstractVMAdapter implements IVMAdapter } public String getColumnPresentationId(IPresentationContext context, Object element) { - final IVMProvider provider = getViewModelProvider(context); + final IVMProvider provider = getVMProvider(context); if (provider != null) { return provider.getColumnPresentationId(context, element); } return null; } - + /** + * Creates a new View Model Provider for given presentation context. Returns null + * if the presentation context is not supported. + */ + @ThreadSafe + abstract protected IVMProvider createViewModelProvider(IPresentationContext context); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java index e4e13f89850..7c5ddf8a59f 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java @@ -447,7 +447,7 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { return path.getLastSegment(); } // Calculate the root of the viewer. - return getVMProvider().getRootLayoutNode().getRootObject(); + return getVMProvider().getRootElement(); } public Object getElement() { diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java index 2372de3e1e3..2313a542c90 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java @@ -62,8 +62,21 @@ import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousLabelAdapt @SuppressWarnings("restriction") abstract public class AbstractVMProvider implements IVMProvider { + /** Reference to the VM adapter that owns this provider */ private final AbstractVMAdapter fVMAdapter; + + /** The presentation context that this provider is associated with */ private final IPresentationContext fPresentationContext; + + /** + * The current root element of this view model. This element is obtained + * from the argument to {@link #createModelProxy(Object, IPresentationContext)}. + */ + private Object fRootElement; + + /** + * + */ private ModelProxy fModelProxy = new ModelProxy(); private boolean fDisposed = false; @@ -104,10 +117,16 @@ abstract public class AbstractVMProvider implements IVMProvider } } + @ThreadSafe protected synchronized ModelProxy getModelProxy() { return fModelProxy; } + @ThreadSafe + public synchronized Object getRootElement() { + return fRootElement; + } + @ThreadSafe public IVMRootLayoutNode getRootLayoutNode() { return fRootLayoutNodeRef.get(); @@ -385,18 +404,16 @@ abstract public class AbstractVMProvider implements IVMProvider public ModelProxy createModelProxy(Object element, IPresentationContext context) { /* * Model proxy is the object that correlates events from the data model - * into view model deltas that the view can process. We only need to - * create a proxy for the root element of the tree. + * into view model deltas that the view can process. This method is called + * by the viewer when a new input object is set to the view. We need to create + * a new instance of the ModelProxy object with every call, because the viewer + * disposes the old proxy before calling this method. */ - if (getRootLayoutNode() != null && - element.equals(getRootLayoutNode().getRootObject())) - { - synchronized(this) { - fModelProxy = new ModelProxy(); - } - return fModelProxy; - } - return null; + synchronized(this) { + fRootElement = element; + fModelProxy = new ModelProxy(); + } + return fModelProxy; } /** @@ -456,7 +473,7 @@ abstract public class AbstractVMProvider implements IVMProvider if (rootLayoutNode == null) { return null; } - else if (element.equals(rootLayoutNode.getRootObject())) { + else if (element.equals(getRootElement())) { return rootLayoutNode; } else if (element instanceof IVMContext){ diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMAdapter.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMAdapter.java index 85d5e3abadd..6c82f654f10 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMAdapter.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMAdapter.java @@ -4,6 +4,7 @@ import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; /** * The View Model adapter handles the layout of a given data model within a @@ -16,4 +17,9 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactor public interface IVMAdapter extends IElementContentProvider, IModelProxyFactory, IColumnPresentationFactory { + /** + * Returns the View Model Provider that is registered for the given presentation + * context. Returns null if there is none. + */ + public IVMProvider getVMProvider(IPresentationContext presentationContext); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java index 8228dea5a4d..1e96b5b81ee 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java @@ -22,6 +22,15 @@ public interface IVMProvider */ public IVMRootLayoutNode getRootLayoutNode(); + /** + * Returns the root element of the view model. If the given view model is + * used to populate the entire contents of the view, then this is the input + * element for the viewer. If the view model is used to populate only a + * sub-tree section of the view, then this is the root element of that + * sub-tree. + */ + public Object getRootElement(); + /** * Returns the presentation context of the viewer that this provider * is configured for. @@ -32,4 +41,5 @@ public interface IVMProvider * Cleans up the resources associated with this provider. */ public void dispose(); + } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMRootLayoutNode.java index 34398603e7a..019b577ba32 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMRootLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMRootLayoutNode.java @@ -21,14 +21,6 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; @SuppressWarnings("restriction") public interface IVMRootLayoutNode extends IVMLayoutNode{ - /** - * 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 Object getRootObject(); - /** * Version of the {@link IVMLayoutNode#buildDelta(Object, ViewModelDelta, org.eclipse.dd.dsf.concurrent.RequestMonitor)} * method, which creates and returns the root node of the delta. It does diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMRootLayoutNode.java similarity index 75% rename from plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMRootLayoutNode.java rename to plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMRootLayoutNode.java index a7dfdc82e33..bfc29baab47 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMRootLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMRootLayoutNode.java @@ -21,28 +21,29 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; /** - * + * Default implementation of a root layout node. This class may be sub-classed + * to implement model-specific event handling. */ @SuppressWarnings("restriction") -abstract public class AbstractVMRootLayoutNode extends AbstractVMLayoutNode implements IVMRootLayoutNode { +public class VMRootLayoutNode extends AbstractVMLayoutNode implements IVMRootLayoutNode { - public AbstractVMRootLayoutNode(AbstractVMProvider provider) { + public VMRootLayoutNode(AbstractVMProvider provider) { super(provider); } /** - * This implementation only fulfils the requirements of the super-interface. + * This implementation only fulfills 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. + * easier to just implement it for sake of uniformity of model. */ public void updateElements(IChildrenUpdate update) { // Ignore startIdx, endIdx, since there's only one element to be had. - update.setChild(getRootObject(), 0); + update.setChild(getVMProvider().getRootElement(), 0); update.done(); } /** - * This implementation only fulfils the requirements of the super-interface. + * This implementation only fulfills 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. */ @@ -52,9 +53,9 @@ abstract public class AbstractVMRootLayoutNode extends AbstractVMLayoutNode impl } /** - * This implementation only fulfils the requirements of the super-interface. + * This implementation only fulfills 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. + * easier to just implement it for sake of uniformity of model. */ public void updateHasElements(IHasChildrenUpdate[] updates) { for (IHasChildrenUpdate update : updates) { @@ -64,9 +65,9 @@ abstract public class AbstractVMRootLayoutNode extends AbstractVMLayoutNode impl } /** - * This implementation only fulfils the requirements of the super-interface. + * This implementation only fulfills 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. + * easier to just implement it for sake of uniformity of model. */ public void updateLabel(@SuppressWarnings("unused") IVMContext vmc, ILabelUpdate update) { @@ -82,7 +83,7 @@ abstract public class AbstractVMRootLayoutNode extends AbstractVMLayoutNode impl assert childNodeDeltas.size() != 0 : "Caller should make sure that there are deltas for given event."; //$NON-NLS-1$ // Always create the rootDelta, no matter what delta flags the child nodes have. - final VMDelta rootDelta = new VMDelta(getRootObject(), IModelDelta.NO_CHANGE); + final VMDelta rootDelta = new VMDelta(getVMProvider().getRootElement(), IModelDelta.NO_CHANGE); callChildNodesToBuildDelta( childNodeDeltas, rootDelta, event, @@ -99,4 +100,8 @@ abstract public class AbstractVMRootLayoutNode extends AbstractVMLayoutNode impl } }); } + + public Object getRootObject() { + return getVMProvider().getRootElement(); + } } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java index 49629e6f888..9e591523af9 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java @@ -534,7 +534,7 @@ abstract public class AbstractDMVMLayoutNode extends Abstract } // Search the root object of the layout hierarchy. if (retVal == null) { - Object inputObject = getVMProvider().getRootLayoutNode().getRootObject(); + Object inputObject = getVMProvider().getRootElement(); if (inputObject instanceof ITreeSelection) { ITreeSelection inputSelection = (ITreeSelection)inputObject; if (inputSelection.getPaths().length == 1) { diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProviderWithCache.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProviderWithCache.java index 058ac9b90bb..79ff2ff8a05 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProviderWithCache.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProviderWithCache.java @@ -34,7 +34,7 @@ public abstract class AbstractDMVMProviderWithCache extends AbstractDMVMProvider public void cacheFlushed(Object context) { if(getPresentationContext().equals(context)) - getModelProxy().fireModelChanged(new ModelDelta(this.getRootLayoutNode().getRootObject(),IModelDelta.CONTENT)); + getModelProxy().fireModelChanged(new ModelDelta(getRootElement(),IModelDelta.CONTENT)); } public AbstractDMVMProviderWithCache(AbstractVMAdapter adapter, IPresentationContext presentationContext, DsfSession session) { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewSelectionRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/DMVMRootLayoutNode.java similarity index 69% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewSelectionRootLayoutNode.java rename to plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/DMVMRootLayoutNode.java index 0128ffaad5e..b2955c2a6cb 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/DebugViewSelectionRootLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/DMVMRootLayoutNode.java @@ -8,21 +8,16 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel; +package org.eclipse.dd.dsf.ui.viewmodel.dm; 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.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; -import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMRootLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.VMRootLayoutNode; import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode.DMVMContext; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; -import org.eclipse.debug.ui.DebugUITools; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.ui.IWorkbenchWindow; /** * This is is a standard root node which listens to the selection in Debug View. @@ -36,13 +31,11 @@ import org.eclipse.ui.IWorkbenchWindow; * whole selection. */ @SuppressWarnings("restriction") -public class DebugViewSelectionRootLayoutNode extends AbstractVMRootLayoutNode +public class DMVMRootLayoutNode extends VMRootLayoutNode implements IVMRootLayoutNode { - private final IWorkbenchWindow fWindow; - public DebugViewSelectionRootLayoutNode(AbstractVMProvider provider) { + public DMVMRootLayoutNode(AbstractVMProvider provider) { super(provider); - fWindow = DsfDebugUIPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow(); } /** @@ -91,33 +84,14 @@ public class DebugViewSelectionRootLayoutNode extends AbstractVMRootLayoutNode return super.getDeltaFlags(event); } - /** - * Returns the full selection as it came from the DebugContextManager. - * @return - */ - public ISelection getSelection() { - return DebugUITools.getDebugContextManager().getContextService(fWindow).getActiveContext(); - } - - public Object getRootObject() { - ISelection selection = getSelection(); - if (selection instanceof IStructuredSelection) { - return ((IStructuredSelection)selection).getFirstElement(); - } - return null; - } - private IDMContext getSelectedDMC() { - Object selection = getSelection(); - if (selection instanceof IStructuredSelection) { - IStructuredSelection structSelection = (IStructuredSelection)selection; - if (structSelection.getFirstElement() instanceof DMVMContext) - { - // Correct cast: (AbstractDMVMLayoutNode.DMVMContext) breaks the javac compiler - @SuppressWarnings("unchecked") - DMVMContext vmc = (DMVMContext)structSelection.getFirstElement(); - return vmc.getDMC(); - } + Object rootObject = getVMProvider().getRootElement(); + if (rootObject instanceof DMVMContext) + { + // Correct cast: (AbstractDMVMLayoutNode.DMVMContext) breaks the javac compiler + @SuppressWarnings("unchecked") + DMVMContext vmc = (DMVMContext)rootObject; + return vmc.getDMC(); } return null; } From 85c4ae5f243bfc0cbd5f75d65f3577b60027a488 Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Tue, 3 Jul 2007 16:48:52 +0000 Subject: [PATCH 115/834] Bugzilla 195291 Added GroupEvent changed for values as opposed to contents in IRegisters.java and changed the Group and Register layout nodes to properly deal with all of the defined events. --- .../register/RegisterGroupLayoutNode.java | 18 ++++++++++++---- .../register/RegisterLayoutNode.java | 21 ++++++++++++++++--- .../dd/dsf/debug/service/IRegisters.java | 3 +++ 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java index ddc7b9799f7..29ec2e7732d 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java @@ -20,6 +20,7 @@ import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMEvent; import org.eclipse.dd.dsf.debug.service.IRegisters; import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.IRegisters.IGroupChangedDMEvent; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMData; import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; @@ -204,21 +205,30 @@ public class RegisterGroupLayoutNode extends AbstractExpressionLayoutNode e) { if (e instanceof IRunControl.ISuspendedDMEvent) { return IModelDelta.CONTENT; - }else if (e instanceof IRegisters.IRegistersChangedDMEvent) { + } + else if (e instanceof IRegisters.IGroupsChangedDMEvent) { return IModelDelta.CONTENT; } + else if (e instanceof IRegisters.IGroupChangedDMEvent) { + return IModelDelta.STATE; + } return IModelDelta.NO_CHANGE; } @Override protected void buildDeltaForDMEvent(IDMEvent e, VMDelta parent, int nodeOffset, RequestMonitor rm) { if (e instanceof IRunControl.ISuspendedDMEvent) { - // Create a delta that the whole register group has changed. + // Create a delta that indicates all groups have changed parent.addFlags(IModelDelta.CONTENT); } - if (e instanceof IRegisters.IRegistersChangedDMEvent) { - parent.addNode( createVMContext(((IRegisters.IRegistersChangedDMEvent)e).getDMContext()), IModelDelta.STATE ); + else if (e instanceof IRegisters.IGroupsChangedDMEvent) { + // Create a delta that indicates all groups have changed + parent.addFlags(IModelDelta.CONTENT); } + else if (e instanceof IRegisters.IGroupChangedDMEvent) { + // Create a delta that indicates that specific group changed + parent.addNode( createVMContext(((IGroupChangedDMEvent)e).getDMContext()), IModelDelta.STATE ); + } super.buildDeltaForDMEvent(e, parent, nodeOffset, rm); } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java index 807edd3a7d9..e3e9c065f2e 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java @@ -386,20 +386,35 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode e) { if (e instanceof IRunControl.ISuspendedDMEvent) { return IModelDelta.CONTENT; - } else if (e instanceof IRegisters.IRegisterChangedDMEvent) { - return IModelDelta.STATE; + } + else if (e instanceof IRegisters.IRegistersChangedDMEvent) { + return IModelDelta.CONTENT; + } + else if (e instanceof IRegisters.IRegisterChangedDMEvent) { + /* + * Logically one would think that STATE should be specified here. But we specifiy CONTENT + * as well so that if there are subregisters ( BIT FIELDS ) they will be forced to update + * and show new values when the total register changes. + */ + return IModelDelta.CONTENT | IModelDelta.STATE; } return IModelDelta.NO_CHANGE; } @Override protected void buildDeltaForDMEvent(IDMEvent e, VMDelta parent, int nodeOffset, RequestMonitor rm) { + if (e instanceof IRunControl.ISuspendedDMEvent) { // Create a delta that the whole register group has changed. parent.addFlags(IModelDelta.CONTENT); } + + if (e instanceof IRegisters.IRegistersChangedDMEvent) { + parent.addFlags(IModelDelta.CONTENT);; + } + if (e instanceof IRegisters.IRegisterChangedDMEvent) { - parent.addNode( createVMContext(((IRegisterChangedDMEvent)e).getDMContext()), IModelDelta.STATE ); + parent.addNode( createVMContext(((IRegisterChangedDMEvent)e).getDMContext()), IModelDelta.CONTENT | IModelDelta.STATE ); } super.buildDeltaForDMEvent(e, parent, nodeOffset, rm); diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java index d443b167419..46812eb93bf 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java @@ -29,6 +29,9 @@ public interface IRegisters extends IFormattedValues { public String getName(); } + /** Event indicating values for the group have changed. */ + public interface IGroupChangedDMEvent extends IDMEvent {} + /** Event indicating registers in a group have changed. */ public interface IRegistersChangedDMEvent extends IDMEvent {} From 0c7d4ed117e7b4e47e65dc7f2a0b93e0557e0230 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Tue, 3 Jul 2007 23:43:26 +0000 Subject: [PATCH 116/834] 159683 update mode --- .../dd/dsf/ui/viewmodel/update/VMCache.java | 290 ++++++++---------- 1 file changed, 126 insertions(+), 164 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java index 57fa567b57e..4ef941b5573 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java @@ -12,38 +12,32 @@ package org.eclipse.dd.dsf.ui.viewmodel.update; import java.util.HashMap; +import java.util.List; import java.util.Vector; +import java.util.concurrent.Executor; -import org.eclipse.core.runtime.IStatus; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor; import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.MultiRequestMonitor; 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.ui.viewmodel.VMElementsCountUpdate; +import org.eclipse.dd.dsf.ui.viewmodel.VMElementsUpdate; +import org.eclipse.dd.dsf.ui.viewmodel.VMHasElementsUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; -import org.eclipse.jface.viewers.TreePath; public abstract class VMCache { + protected Executor fExecutor = new DefaultDsfExecutor(); + protected HashMap fChildrenCounts = new HashMap(); - class ChildData - { - Object child; - int offset; - - public ChildData(Object child, int offset) - { - this.child = child; - this.offset = offset; - } - } - - protected HashMap fChildren = new HashMap(); + protected HashMap> fChildren = new HashMap>(); protected HashMap fHasChildren = new HashMap(); @@ -66,6 +60,7 @@ public abstract class VMCache return true; } + @SuppressWarnings("restriction") public IHasChildrenUpdate[] update(IHasChildrenUpdate[] updates) { Vector missVector = new Vector(); for(IHasChildrenUpdate update : updates) @@ -85,54 +80,22 @@ public abstract class VMCache for(int i = 0; i < updates.length; i++) { final IHasChildrenUpdate update = missVector.elementAt(i); - updates[i] = new IHasChildrenUpdate() - { - private boolean fIsHasChildren; - - public void setHasChilren(boolean hasChildren) { - fIsHasChildren = hasChildren; - update.setHasChilren(hasChildren); - } - - public void cancel() { - update.cancel(); - } - - public void done() { - fHasChildren.put(getElement(), Boolean.valueOf(fIsHasChildren)); - update.done(); - } - - public IStatus getStatus() { - return update.getStatus(); - } - - public boolean isCanceled() { - return update.isCanceled(); - } - - public void setStatus(IStatus status) { - update.setStatus(status); - } - - public Object getElement() { - return update.getElement(); - } - - public TreePath getElementPath() { - return update.getElementPath(); - } - - public IPresentationContext getPresentationContext() { - return update.getPresentationContext(); - } - - }; + updates[i] = new VMHasElementsUpdate(update, new DataRequestMonitor(fExecutor, null) + { + @Override + protected void handleCompleted() + { + fHasChildren.put(update.getElement(), this.getData()); + update.setHasChilren(getData()); + update.done(); + } + }); } return updates; } + @SuppressWarnings("restriction") public IChildrenCountUpdate[] update(IChildrenCountUpdate[] updates) { Vector missVector = new Vector(); @@ -153,129 +116,128 @@ public abstract class VMCache for(int i = 0; i < updates.length; i++) { final IChildrenCountUpdate update = missVector.elementAt(i); - updates[i] = new IChildrenCountUpdate() - { - private int fChildCount; - - public void cancel() { - update.cancel(); - } - - public void done() { - fChildrenCounts.put(getElement(), fChildCount); - update.done(); - } - - public IStatus getStatus() { - return update.getStatus(); - } - - public boolean isCanceled() { - return update.isCanceled(); - } - - public void setStatus(IStatus status) { - update.setStatus(status); - } - - public void setChildCount(int numChildren) { - fChildCount = numChildren; - update.setChildCount(numChildren); - } - - public Object getElement() { - return update.getElement(); - } - - public TreePath getElementPath() { - return update.getElementPath(); - } - - public IPresentationContext getPresentationContext() { - return update.getPresentationContext(); - } - - }; + updates[i] = new VMElementsCountUpdate(update, new DataRequestMonitor(fExecutor, null) + { + @Override + protected void handleCompleted() + { + fChildrenCounts.put(update.getElement(), this.getData()); + update.setChildCount(this.getData()); + update.done(); + } + }); } return updates; } + @SuppressWarnings("restriction") public IChildrenUpdate[] update(IChildrenUpdate[] updates) { - Vector missVector = new Vector(); - for(IChildrenUpdate update : updates) + Vector updatesEntirelyMissingFromCache = new Vector(); + for(final IChildrenUpdate update : updates) { if(fChildren.containsKey(update.getElement()) && useCache()) { - ChildData childData[] = fChildren.get(update.getElement()); - for(ChildData data : childData) - update.setChild(data.child, data.offset); - update.done(); + Vector childrenMissingFromCache = new Vector(); + for(int i = update.getOffset(); i < update.getOffset() + update.getLength(); i++) + childrenMissingFromCache.addElement(i); + childrenMissingFromCache.removeAll(fChildren.get(update.getElement()).keySet()); + + if(childrenMissingFromCache.size() > 0) + { + // perform a partial update; we only have some of the children of the update request + + final HashMap>,IChildrenUpdate> associationsRequestMonitorToChildUpdate + = new HashMap>,IChildrenUpdate>(); + + final MultiRequestMonitor>> childrenMultiRequestMon = + new MultiRequestMonitor>>(fExecutor, null) { + @Override + protected void handleCompleted() { + // Status is OK, only if all request monitors are OK. + if (getStatus().isOK()) + { + for (DataRequestMonitor> monitor : getRequestMonitors()) + { + int offset = associationsRequestMonitorToChildUpdate.get(monitor).getOffset(); + for(Object child : monitor.getData()) + update.setChild(child, offset++); + } + } else { + update.setStatus(getStatus()); + } + update.done(); + } + }; + + while(childrenMissingFromCache.size() > 0) + { + int offset = childrenMissingFromCache.elementAt(0); + childrenMissingFromCache.removeElementAt(0); + int length = 1; + while(childrenMissingFromCache.size() > 0 && childrenMissingFromCache.elementAt(0) == offset + length) + { + length++; + childrenMissingFromCache.removeElementAt(0); + } + + DataRequestMonitor> partialUpdateMonitor = new DataRequestMonitor>(fExecutor, null) + { + @Override + protected void handleCompleted() + { + + childrenMultiRequestMon.requestMonitorDone(this); + } + }; + + final IChildrenUpdate partialUpdate = new VMElementsUpdate(update, update.getOffset(), update.getLength(), + childrenMultiRequestMon.add(partialUpdateMonitor)); + + associationsRequestMonitorToChildUpdate.put(partialUpdateMonitor, partialUpdate); + + updatesEntirelyMissingFromCache.add(partialUpdate); + + } + } + else + { + // we have all of the children in cache; return from cache + for(int position = update.getOffset(); position < update.getOffset() + update.getLength(); position++) + update.setChild(fChildren.get(update.getElement()).get(position), position); + update.done(); + } } else { - missVector.addElement(update); + updatesEntirelyMissingFromCache.addElement(update); } } - updates = new IChildrenUpdate[missVector.size()]; + updates = new IChildrenUpdate[updatesEntirelyMissingFromCache.size()]; for(int i = 0; i < updates.length; i++) { - final IChildrenUpdate update = missVector.elementAt(i); - updates[i] = new IChildrenUpdate() - { - Vector fChilds = new Vector(); - - public int getLength() { - return update.getLength(); - } - - public int getOffset() { - return update.getOffset(); - } - - public void setChild(Object child, int offset) { - fChilds.addElement(new ChildData(child, offset)); - update.setChild(child, offset); - } - - public void cancel() { - update.cancel(); - } - - public void done() { - // FIXME synchronize with events? - fChildren.put(getElement(), fChilds.toArray(new ChildData[fChilds.size()])); - update.done(); - } - - public IStatus getStatus() { - return update.getStatus(); - } - - public boolean isCanceled() { - return update.isCanceled(); - } - - public void setStatus(IStatus status) { - update.setStatus(status); - } - - public Object getElement() { - return update.getElement(); - } - - public TreePath getElementPath() { - return update.getElementPath(); - } - - public IPresentationContext getPresentationContext() { - return update.getPresentationContext(); - } - - }; + final IChildrenUpdate update = updatesEntirelyMissingFromCache.elementAt(i); + updates[i] = new VMElementsUpdate(update, update.getOffset(), update.getLength(), + new DataRequestMonitor>(fExecutor, null) + { + @Override + protected void handleCompleted() + { + for(int j = 0; j < update.getLength(); j++) + { + if(!fChildren.containsKey(update.getElement())) + fChildren.put(update.getElement(), new HashMap()); + + fChildren.get(update.getElement()).put(update.getOffset() + j, getData().get(j)); + + update.setChild(getData().get(j), update.getOffset() + j); + } + update.done(); + } + }); } - + return updates; } From f96b483d1f1684cff83ba1d9fae87af66bcf3488 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Tue, 3 Jul 2007 23:58:09 +0000 Subject: [PATCH 117/834] 159683 update modes --- .../src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java index 4ef941b5573..4c42bcae0f7 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java @@ -16,6 +16,7 @@ import java.util.List; import java.util.Vector; import java.util.concurrent.Executor; +import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor; import org.eclipse.dd.dsf.concurrent.DsfExecutor; @@ -242,6 +243,7 @@ public abstract class VMCache } @SuppressWarnings("unchecked") + @ConfinedToDsfExecutor("DsfSession.getSession(dmc.getSessionId()).getExecutor()") public void getModelData(IDMService service, final IDMContext dmc, final DataRequestMonitor rm, DsfExecutor executor) { if(fData.containsKey(dmc) && useCache()) From 4c037411259fed7c7bb41f04941a2990d114faf3 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Wed, 4 Jul 2007 00:12:38 +0000 Subject: [PATCH 118/834] 159683 --- .../src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java index 4c42bcae0f7..4bf9f513496 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java @@ -192,7 +192,7 @@ public abstract class VMCache } }; - final IChildrenUpdate partialUpdate = new VMElementsUpdate(update, update.getOffset(), update.getLength(), + final IChildrenUpdate partialUpdate = new VMElementsUpdate(update, offset, length, childrenMultiRequestMon.add(partialUpdateMonitor)); associationsRequestMonitorToChildUpdate.put(partialUpdateMonitor, partialUpdate); From d50ed203b6795d433686d3c52e46b01412f0ed24 Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Thu, 5 Jul 2007 20:40:37 +0000 Subject: [PATCH 119/834] Bugzilla 159683 Fixed the cache manager to it was checking the status before dereferencing getdata(0 which migit be null. --- .../src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java index 4bf9f513496..eb2123e4e51 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java @@ -120,7 +120,7 @@ public abstract class VMCache updates[i] = new VMElementsCountUpdate(update, new DataRequestMonitor(fExecutor, null) { @Override - protected void handleCompleted() + protected void handleOK() { fChildrenCounts.put(update.getElement(), this.getData()); update.setChildCount(this.getData()); @@ -223,7 +223,7 @@ public abstract class VMCache new DataRequestMonitor>(fExecutor, null) { @Override - protected void handleCompleted() + protected void handleOK() { for(int j = 0; j < update.getLength(); j++) { @@ -256,7 +256,7 @@ public abstract class VMCache service.getModelData(dmc, new DataRequestMonitor(executor, null) { @Override - public void handleCompleted() { + public void handleOK() { fData.put(dmc, getData()); rm.setData(getData()); rm.done(); From ac373103f4e0d7660a3088fcc97b93d889290c5f Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Thu, 5 Jul 2007 23:51:14 +0000 Subject: [PATCH 120/834] 159683 --- .../debug/ui/viewmodel/register/RegisterGroupLayoutNode.java | 3 +++ .../src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java index 29ec2e7732d..0df27e05459 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java @@ -34,6 +34,7 @@ import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.model.IDebugTarget; @@ -222,6 +223,8 @@ public class RegisterGroupLayoutNode extends AbstractExpressionLayoutNode, IDMData>(); fChildrenCounts.clear(); fChildren.clear(); - fChildrenCounts.clear(); + fHasChildren.clear(); } protected boolean useCache() From 9a1a5ad41c2177eed08a66367269276986a28bbe Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Fri, 6 Jul 2007 05:32:54 +0000 Subject: [PATCH 121/834] 159683 update modes --- .../META-INF/MANIFEST.MF | 7 +-- .../AbstractDebugDMVMProviderWithCache.java | 43 ++++++++++++++++++ .../expression/ExpressionVMProvider.java | 4 +- .../register/RegisterVMProvider.java | 4 +- .../update/VMCacheRefreshAlways.java | 8 ---- .../variable/VariableVMProvider.java | 4 +- .../dm/AbstractDMVMProviderWithCache.java | 6 +++ .../dd/dsf/ui/viewmodel/update/VMCache.java | 44 ++++++++++++++----- .../ui/viewmodel/update/VMCacheManager.java | 10 ++++- 9 files changed, 99 insertions(+), 31 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/dm/AbstractDebugDMVMProviderWithCache.java diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF index 1a96a0189b8..5dcf58db94e 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF @@ -21,12 +21,13 @@ Require-Bundle: org.eclipse.ui, Eclipse-LazyStart: true Export-Package: org.eclipse.dd.dsf.debug.ui, + org.eclipse.dd.dsf.debug.ui.actions, + org.eclipse.dd.dsf.debug.ui.sourcelookup, org.eclipse.dd.dsf.debug.ui.viewmodel, + org.eclipse.dd.dsf.debug.ui.viewmodel.dm, org.eclipse.dd.dsf.debug.ui.viewmodel.expression, org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport, org.eclipse.dd.dsf.debug.ui.viewmodel.launch, org.eclipse.dd.dsf.debug.ui.viewmodel.register, - org.eclipse.dd.dsf.debug.ui.viewmodel.variable, - org.eclipse.dd.dsf.debug.ui.sourcelookup, - org.eclipse.dd.dsf.debug.ui.actions + org.eclipse.dd.dsf.debug.ui.viewmodel.variable Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/dm/AbstractDebugDMVMProviderWithCache.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/dm/AbstractDebugDMVMProviderWithCache.java new file mode 100644 index 00000000000..2b539869fba --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/dm/AbstractDebugDMVMProviderWithCache.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + *******************************************************************************/ + +package org.eclipse.dd.dsf.debug.ui.viewmodel.dm; + +import org.eclipse.dd.dsf.debug.ui.viewmodel.update.VMCacheRefreshAlways; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProviderWithCache; +import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; + + + +/* + * The purpose of this class is to satisfy package structure requirements while enabling VM update modes. + * The non-debug centric VMCacheManager and VMCache live under org.eclipse.dd.dsf.*. The debug data view + * caches (VMCacheRefreshAlways/Manual/OnBreak) live under org.eclipse.dd.dsf.debug.* because of their + * awareness of debug specific events. There is a need to instantiate a default (always) cache on view + * startup. AbstractDMVMProviderWithCache would be a good place to accomplish this task, but like the + * VMCacheManager, this class cannot access the *dsf.debug* VMCacheRefreshAlways. AbstractDebugDMVMProviderWithCache + * is meant to solve this problem. + */ + +public class AbstractDebugDMVMProviderWithCache extends + AbstractDMVMProviderWithCache +{ + @SuppressWarnings("restriction") + public AbstractDebugDMVMProviderWithCache(AbstractVMAdapter adapter, IPresentationContext presentationContext, DsfSession session) { + super(adapter, presentationContext, session); + + VMCacheManager.getVMCacheManager().registerCache(presentationContext, new VMCacheRefreshAlways()); + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java index f8579ae632a..dec091dce23 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java @@ -11,6 +11,7 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; import org.eclipse.dd.dsf.debug.service.IFormattedValues; +import org.eclipse.dd.dsf.debug.ui.viewmodel.dm.AbstractDebugDMVMProviderWithCache; import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePreferenceStore; import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterGroupLayoutNode; import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterLayoutNode; @@ -23,7 +24,6 @@ import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProviderWithCache; import org.eclipse.dd.dsf.ui.viewmodel.dm.DMVMRootLayoutNode; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.IExpressionsListener; @@ -35,7 +35,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationCont * */ @SuppressWarnings("restriction") -public class ExpressionVMProvider extends AbstractDMVMProviderWithCache +public class ExpressionVMProvider extends AbstractDebugDMVMProviderWithCache implements IExpressionsListener, IFormattedValuePreferenceStore { private String fDefaultFormatId = IFormattedValues.HEX_FORMAT; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java index 4e114c1d2d4..704ec332c13 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java @@ -11,12 +11,12 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.register; import org.eclipse.dd.dsf.debug.service.IFormattedValues; +import org.eclipse.dd.dsf.debug.ui.viewmodel.dm.AbstractDebugDMVMProviderWithCache; import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePreferenceStore; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProviderWithCache; import org.eclipse.dd.dsf.ui.viewmodel.dm.DMVMRootLayoutNode; import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; @@ -25,7 +25,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationCont * Provides the VIEW MODEL for the DEBUG MODEL REGISTER view. */ @SuppressWarnings("restriction") -public class RegisterVMProvider extends AbstractDMVMProviderWithCache implements IFormattedValuePreferenceStore +public class RegisterVMProvider extends AbstractDebugDMVMProviderWithCache implements IFormattedValuePreferenceStore { /* * Current default for register formatting. diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshAlways.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshAlways.java index f3a2e9bcdd2..bdb3557c6ff 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshAlways.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshAlways.java @@ -25,12 +25,4 @@ public class VMCacheRefreshAlways extends VMCache flush(true); } - @Override - protected boolean useCache() { - return false; - } - - - - } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java index 82c673a30f2..3d5bd3ac6ad 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java @@ -9,19 +9,19 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.variable; import org.eclipse.dd.dsf.debug.service.IFormattedValues; +import org.eclipse.dd.dsf.debug.ui.viewmodel.dm.AbstractDebugDMVMProviderWithCache; import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePreferenceStore; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProviderWithCache; import org.eclipse.dd.dsf.ui.viewmodel.dm.DMVMRootLayoutNode; import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; @SuppressWarnings("restriction") -public class VariableVMProvider extends AbstractDMVMProviderWithCache implements +public class VariableVMProvider extends AbstractDebugDMVMProviderWithCache implements IColumnPresentationFactory, IFormattedValuePreferenceStore { private String defaultFormatId = IFormattedValues.NATURAL_FORMAT; diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProviderWithCache.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProviderWithCache.java index 79ff2ff8a05..e8348bbc935 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProviderWithCache.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProviderWithCache.java @@ -27,11 +27,13 @@ public abstract class AbstractDMVMProviderWithCache extends AbstractDMVMProvider implements VMCacheManager.CacheListener { @DsfServiceEventHandler + @Override public void eventDispatched(IDMEvent event) { VMCacheManager.getVMCacheManager().getCache(getPresentationContext()).handleEvent(event); super.eventDispatched(event); } + @SuppressWarnings("restriction") public void cacheFlushed(Object context) { if(getPresentationContext().equals(context)) getModelProxy().fireModelChanged(new ModelDelta(getRootElement(),IModelDelta.CONTENT)); @@ -43,18 +45,22 @@ public abstract class AbstractDMVMProviderWithCache extends AbstractDMVMProvider VMCacheManager.getVMCacheManager().addCacheListener(getPresentationContext(), this); } + @Override public void update(IHasChildrenUpdate[] updates) { super.update(VMCacheManager.getVMCacheManager().getCache(getPresentationContext()).update(updates)); } + @Override public void update(IChildrenCountUpdate[] updates) { super.update(VMCacheManager.getVMCacheManager().getCache(getPresentationContext()).update(updates)); } + @Override public void update(final IChildrenUpdate[] updates) { super.update(VMCacheManager.getVMCacheManager().getCache(getPresentationContext()).update(updates)); } + @Override public void dispose() { VMCacheManager.getVMCacheManager().removeCacheListener(getPresentationContext(), this); diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java index 0f5d4a23187..f5f8e8e4227 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java @@ -56,17 +56,25 @@ public abstract class VMCache fHasChildren.clear(); } - protected boolean useCache() + protected boolean isCacheReadEnabled() + { + return true; + } + + protected boolean isCacheWriteEnabled() { return true; } @SuppressWarnings("restriction") public IHasChildrenUpdate[] update(IHasChildrenUpdate[] updates) { + if(!isCacheReadEnabled()) + return updates; + Vector missVector = new Vector(); for(IHasChildrenUpdate update : updates) { - if(fHasChildren.containsKey(update.getElement()) && useCache()) + if(fHasChildren.containsKey(update.getElement()) && isCacheReadEnabled()) { update.setHasChilren(fHasChildren.get(update.getElement()).booleanValue()); update.done(); @@ -86,7 +94,8 @@ public abstract class VMCache @Override protected void handleCompleted() { - fHasChildren.put(update.getElement(), this.getData()); + if(isCacheWriteEnabled()) + fHasChildren.put(update.getElement(), this.getData()); update.setHasChilren(getData()); update.done(); } @@ -99,10 +108,13 @@ public abstract class VMCache @SuppressWarnings("restriction") public IChildrenCountUpdate[] update(IChildrenCountUpdate[] updates) { + if(!isCacheReadEnabled()) + return updates; + Vector missVector = new Vector(); for(IChildrenCountUpdate update : updates) { - if(fChildrenCounts.containsKey(update.getElement()) && useCache()) + if(fChildrenCounts.containsKey(update.getElement()) && isCacheReadEnabled()) { update.setChildCount(fChildrenCounts.get(update.getElement())); update.done(); @@ -122,7 +134,8 @@ public abstract class VMCache @Override protected void handleOK() { - fChildrenCounts.put(update.getElement(), this.getData()); + if(isCacheWriteEnabled()) + fChildrenCounts.put(update.getElement(), this.getData()); update.setChildCount(this.getData()); update.done(); } @@ -134,10 +147,13 @@ public abstract class VMCache @SuppressWarnings("restriction") public IChildrenUpdate[] update(IChildrenUpdate[] updates) { + if(!isCacheReadEnabled()) + return updates; + Vector updatesEntirelyMissingFromCache = new Vector(); for(final IChildrenUpdate update : updates) { - if(fChildren.containsKey(update.getElement()) && useCache()) + if(fChildren.containsKey(update.getElement()) && isCacheReadEnabled()) { Vector childrenMissingFromCache = new Vector(); for(int i = update.getOffset(); i < update.getOffset() + update.getLength(); i++) @@ -227,10 +243,13 @@ public abstract class VMCache { for(int j = 0; j < update.getLength(); j++) { - if(!fChildren.containsKey(update.getElement())) - fChildren.put(update.getElement(), new HashMap()); - - fChildren.get(update.getElement()).put(update.getOffset() + j, getData().get(j)); + if(isCacheWriteEnabled()) + { + if(!fChildren.containsKey(update.getElement())) + fChildren.put(update.getElement(), new HashMap()); + + fChildren.get(update.getElement()).put(update.getOffset() + j, getData().get(j)); + } update.setChild(getData().get(j), update.getOffset() + j); } @@ -246,7 +265,7 @@ public abstract class VMCache @ConfinedToDsfExecutor("DsfSession.getSession(dmc.getSessionId()).getExecutor()") public void getModelData(IDMService service, final IDMContext dmc, final DataRequestMonitor rm, DsfExecutor executor) { - if(fData.containsKey(dmc) && useCache()) + if(fData.containsKey(dmc) && isCacheReadEnabled()) { rm.setData( fData.get(dmc)); rm.done(); @@ -257,7 +276,8 @@ public abstract class VMCache new DataRequestMonitor(executor, null) { @Override public void handleOK() { - fData.put(dmc, getData()); + if(isCacheWriteEnabled()) + fData.put(dmc, getData()); rm.setData(getData()); rm.done(); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCacheManager.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCacheManager.java index cdf60c43c41..3b612df1ad9 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCacheManager.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCacheManager.java @@ -49,10 +49,16 @@ public class VMCacheManager { @Override public void handleEvent(IDMEvent event) { - flush(true); } - public boolean readFromCache() + @Override + public boolean isCacheReadEnabled() + { + return false; + } + + @Override + public boolean isCacheWriteEnabled() { return false; } From bd8ee802caf624c39a5577394bddb4c208f65a64 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Fri, 6 Jul 2007 18:24:41 +0000 Subject: [PATCH 122/834] 159683 --- .../dd/dsf/ui/viewmodel/update/VMCache.java | 74 +++++++++++++------ 1 file changed, 51 insertions(+), 23 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java index f5f8e8e4227..82ebfe9e33e 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java @@ -16,6 +16,7 @@ import java.util.List; import java.util.Vector; import java.util.concurrent.Executor; +import org.eclipse.core.runtime.IStatus; import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor; @@ -132,13 +133,15 @@ public abstract class VMCache updates[i] = new VMElementsCountUpdate(update, new DataRequestMonitor(fExecutor, null) { @Override - protected void handleOK() - { - if(isCacheWriteEnabled()) - fChildrenCounts.put(update.getElement(), this.getData()); - update.setChildCount(this.getData()); + protected void handleCompleted() { + if(getStatus().isOK()) + { + if(isCacheWriteEnabled()) + fChildrenCounts.put(update.getElement(), this.getData()); + update.setChildCount(this.getData()); + } update.done(); - } + } }); } @@ -239,22 +242,25 @@ public abstract class VMCache new DataRequestMonitor>(fExecutor, null) { @Override - protected void handleOK() + protected void handleCompleted() { - for(int j = 0; j < update.getLength(); j++) + if(getStatus().isOK()) { - if(isCacheWriteEnabled()) - { - if(!fChildren.containsKey(update.getElement())) - fChildren.put(update.getElement(), new HashMap()); + for(int j = 0; j < update.getLength(); j++) + { + if(isCacheWriteEnabled()) + { + if(!fChildren.containsKey(update.getElement())) + fChildren.put(update.getElement(), new HashMap()); + + fChildren.get(update.getElement()).put(update.getOffset() + j, getData().get(j)); + } - fChildren.get(update.getElement()).put(update.getOffset() + j, getData().get(j)); - } - - update.setChild(getData().get(j), update.getOffset() + j); + update.setChild(getData().get(j), update.getOffset() + j); + } } update.done(); - } + } }); } @@ -275,12 +281,34 @@ public abstract class VMCache service.getModelData(dmc, new DataRequestMonitor(executor, null) { @Override - public void handleOK() { - if(isCacheWriteEnabled()) - fData.put(dmc, getData()); - rm.setData(getData()); - rm.done(); - } + protected void handleCompleted() { + if(getStatus().isOK()) + { + if(isCacheWriteEnabled()) + fData.put(dmc, getData()); + rm.setData(getData()); + } + rm.done(); + } + + @Override + public synchronized void setCanceled(boolean canceled) { + rm.setCanceled(canceled); + super.setCanceled(canceled); + } + + @Override + public void setMultiStatus(String pluginId, int code, + String message, IStatus subStatus) { + rm.setMultiStatus(pluginId, code, message, subStatus); + super.setMultiStatus(pluginId, code, message, subStatus); + } + + @Override + public synchronized void setStatus(IStatus status) { + rm.setStatus(status); + super.setStatus(status); + } } ); } From b838894fc867ba47e174acde0c62913b501cf71d Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Fri, 6 Jul 2007 20:36:30 +0000 Subject: [PATCH 123/834] Bugzilla entry 195703 AbstractVMlayoutNode.java Perform a update.done() even if the update has been cancelled. AbstractVMProvider.java Perform a update.done() even if the update has been cancelled. VMelementsCountUpdate.java Change assert to allow for the cancelling of the update VMHasElementsUpdate.java Change assert to allow for the cancelling of the update. VMViewerUpdate.java Create a negative status when an update is cancelled. Otherwise the getData() will be called and used when there is no valid data. Randy Rohrbach 781-364-2226 --- .../dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java | 5 ++++- .../dd/dsf/ui/viewmodel/AbstractVMProvider.java | 11 +++++++---- .../dd/dsf/ui/viewmodel/VMElementsCountUpdate.java | 2 +- .../dd/dsf/ui/viewmodel/VMHasElementsUpdate.java | 2 +- .../eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java | 5 +++++ 5 files changed, 18 insertions(+), 7 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java index 7c5ddf8a59f..37024d81c3a 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java @@ -330,7 +330,10 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { * that the layout node depends on, are not available. */ protected boolean checkUpdate(IViewerUpdate update) { - if (update.isCanceled()) return false; + if (update.isCanceled()) { + update.done(); + return false; + } if (fDisposed) { handleFailedUpdate(update); return false; diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java index 2313a542c90..63e16d44853 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java @@ -159,7 +159,7 @@ abstract public class AbstractVMProvider implements IVMProvider if (layoutNode == null) { // Stale update, most likely as a result of the layout nodes being // changed. Just ignore it. - if (!update.isCanceled()) update.done(); + update.done(); continue; } if (!nodeUpdatesMap.containsKey(layoutNode)) { @@ -240,7 +240,10 @@ abstract public class AbstractVMProvider implements IVMProvider public void update(final IChildrenCountUpdate[] updates) { for (final IChildrenCountUpdate update : updates) { - if (update.isCanceled()) continue; + if (update.isCanceled()) { + update.done(); + continue; + } getChildrenCountsForNode( update, @@ -346,7 +349,7 @@ abstract public class AbstractVMProvider implements IVMProvider final IVMLayoutNode layoutNode = getLayoutNodeForElement(update.getElement()); if (layoutNode == null) { // Stale update. Just ignore. - if (!update.isCanceled()) update.done(); + update.done(); return; } @@ -356,7 +359,7 @@ abstract public class AbstractVMProvider implements IVMProvider new MultiRequestMonitor(getExecutor(), null) { @Override protected void handleCompleted() { - if (!update.isCanceled()) update.done(); + update.done(); } }; diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMElementsCountUpdate.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMElementsCountUpdate.java index 8c599f90e10..2ae96edb483 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMElementsCountUpdate.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMElementsCountUpdate.java @@ -34,7 +34,7 @@ public class VMElementsCountUpdate extends VMViewerUpdate implements IChildrenCo @Override public void done() { - assert fCountRequestMonitor.getData() != null || !fCountRequestMonitor.getStatus().isOK(); + assert isCanceled() || fCountRequestMonitor.getData() != null || !fCountRequestMonitor.getStatus().isOK(); super.done(); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMHasElementsUpdate.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMHasElementsUpdate.java index 2153473ff11..b466b8d5717 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMHasElementsUpdate.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMHasElementsUpdate.java @@ -34,7 +34,7 @@ public class VMHasElementsUpdate extends VMViewerUpdate implements IHasChildrenU @Override public void done() { - assert fHasElemsRequestMonitor.getData() != null || !fHasElemsRequestMonitor.getStatus().isOK(); + assert isCanceled() || fHasElemsRequestMonitor.getData() != null || !fHasElemsRequestMonitor.getStatus().isOK(); super.done(); } } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java index 6512fb3ec4d..2da11734ebc 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java @@ -13,7 +13,9 @@ package org.eclipse.dd.dsf.ui.viewmodel; import java.util.concurrent.RejectedExecutionException; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.ui.DsfUIPlugin; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; @@ -46,6 +48,9 @@ public class VMViewerUpdate implements IViewerUpdate { public void done() { try { + if ( isCanceled() ) { + fRequestMonitor.setStatus(new Status( IStatus.CANCEL, DsfUIPlugin.PLUGIN_ID," Update was cancelled") ); //$NON-NLS-1$ + } fRequestMonitor.done(); } catch (RejectedExecutionException e) { // Ignore } From b3130f8c32473e221d5a8d15a22d7295eb49288d Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Fri, 6 Jul 2007 21:47:16 +0000 Subject: [PATCH 124/834] Bugzilla 159683 Added flushing the caches when the cell editing changes the values of fields. --- .../ui/viewmodel/register/RegisterBitFieldLayoutNode.java | 8 ++++++++ .../ui/viewmodel/register/RegisterGroupLayoutNode.java | 4 ++++ .../debug/ui/viewmodel/register/RegisterLayoutNode.java | 5 +++++ 3 files changed, 17 insertions(+) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java index a028a2589c3..ff4fbcac72e 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java @@ -398,6 +398,14 @@ public class RegisterBitFieldLayoutNode extends AbstractExpressionLayoutNode Date: Fri, 6 Jul 2007 22:35:03 +0000 Subject: [PATCH 125/834] Bugzilla 195703 Found another place where the status needs to be checked. Randy --- .../org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java index 63e16d44853..b9c33513651 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java @@ -386,8 +386,10 @@ abstract public class AbstractVMProvider implements IVMProvider elementsMultiRequestMon.add(new DataRequestMonitor>(getExecutor(), null) { @Override protected void handleCompleted() { - for (int i = 0; i < elementsLength; i++) { - update.setChild(getData().get(i), elementsStartIdx + nodeStartIdx + i); + if (getStatus().isOK()) { + for (int i = 0; i < elementsLength; i++) { + update.setChild(getData().get(i), elementsStartIdx + nodeStartIdx + i); + } } elementsMultiRequestMon.requestMonitorDone(this); } From 4fb38140396b9a7f367c3463e1d6d12a183c8f41 Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Tue, 10 Jul 2007 02:48:20 +0000 Subject: [PATCH 126/834] Bugzilla 195920 --- .../ui/viewmodel/register/RegisterLayoutNode.java | 5 +++++ .../eclipse/dd/dsf/ui/viewmodel/VMElementsUpdate.java | 11 ++++++++++- .../eclipse/dd/dsf/ui/viewmodel/update/VMCache.java | 9 ++++++--- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java index edeceaf6d0e..75e500242cd 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java @@ -388,6 +388,11 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode> rm = (DataRequestMonitor>)fRequestMonitor; - rm.setData(fElements); + if (fElements.size() == fLength) { + rm.setData(fElements); + } else { + rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, "Incomplete elements of updates", null)); //$NON-NLS-1$ + } super.done(); } + } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java index 82ebfe9e33e..d6b7d60dc9e 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java @@ -95,9 +95,12 @@ public abstract class VMCache @Override protected void handleCompleted() { - if(isCacheWriteEnabled()) - fHasChildren.put(update.getElement(), this.getData()); - update.setHasChilren(getData()); + if(getStatus().isOK()) + { + if(isCacheWriteEnabled()) + fHasChildren.put(update.getElement(), this.getData()); + update.setHasChilren(getData()); + } update.done(); } }); From 7d9261861d96a6e7973fb2f364067438ec647d6b Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Thu, 12 Jul 2007 20:47:39 +0000 Subject: [PATCH 127/834] Bugzilla 196336 RegisterBitFieldLayoutNode.java RegisterGroupLayoutNode.java RegisterLayoutNode.java VariableLocalsLayoutNode.java Bugzilla 196373 VariableLocalsLayoutNode.java Bugzilla 196381 VariableSubExpressionsLayoutNode.java Also removed odds and ends comments and warnings in these files - general cleanup. --- .../register/RegisterBitFieldLayoutNode.java | 2 +- .../register/RegisterGroupLayoutNode.java | 9 ++++++ .../register/RegisterLayoutNode.java | 2 +- .../variable/VariableLocalsLayoutNode.java | 17 ++++++----- .../VariableSubExpressionsLayoutNode.java | 29 +++++++++++++------ 5 files changed, 40 insertions(+), 19 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java index ff4fbcac72e..ff4e6c98588 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java @@ -313,7 +313,7 @@ public class RegisterBitFieldLayoutNode extends AbstractExpressionLayoutNode e) { if (e instanceof IRunControl.ISuspendedDMEvent) { return IModelDelta.CONTENT; - // } else if (e instanceof IRegisters.IRegisterChangedDMEvent) { - // return IModelDelta.STATE; } + return IModelDelta.NO_CHANGE; } @@ -453,11 +458,7 @@ public class VariableLocalsLayoutNode extends AbstractExpressionLayoutNode { + @SuppressWarnings("unused") private SyncVariableDataAccess fSyncVariableDataAccess; public VariableSubExpressionsLayoutNode(AbstractVMProvider provider, DsfSession session, SyncVariableDataAccess syncVariableDataAccess) { @@ -59,7 +60,6 @@ public class VariableSubExpressionsLayoutNode extends AbstractDMVMLayoutNode e) { if (e instanceof IRunControl.ISuspendedDMEvent) { return IModelDelta.CONTENT; -// } else if (e instanceof IRegisters.IExpressionsChangedDMEvent) { -// return IModelDelta.STATE; } + else if (e instanceof IExpressions.IExpressionChangedDMEvent) { + /* + * Flush the cache. + */ + VMCacheManager.getVMCacheManager().flush(super.getVMProvider().getPresentationContext()); + + /* + * Logically one would think that STATE should be specified here. But we specifiy CONTENT + * as well so that if there sub expressions which are affected in some way ( such as with + * an expanded union then they will show the changes also. + */ + return IModelDelta.CONTENT | IModelDelta.STATE; + } + return IModelDelta.NO_CHANGE; } @@ -299,9 +309,10 @@ public class VariableSubExpressionsLayoutNode extends AbstractDMVMLayoutNode Date: Sat, 14 Jul 2007 03:04:58 +0000 Subject: [PATCH 128/834] Fixed a bug causing RequestMonitor.done() to be called twice (bug 196527). --- .../eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java index 9e591523af9..8b49e0d2ed2 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java @@ -453,7 +453,7 @@ abstract public class AbstractDMVMLayoutNode extends Abstract // Check for an empty list of elements. If it's empty then we // don't have to call the children nodes, so return here. // No need to propagate error, there's no means or need to display it. - if (!getStatus().isOK()) { + if (!getStatus().isOK() || getData().isEmpty()) { requestMonitor.done(); return; } @@ -466,6 +466,7 @@ abstract public class AbstractDMVMLayoutNode extends Abstract if (i == getData().size()) { // Element not found, no need to generate the delta. requestMonitor.done(); + return; } VMDelta delta = parentDelta.addNode(vmc, nodeOffset + i, IModelDelta.NO_CHANGE); From 003f06ca0b7f4c00e72035fea33de5fd98209dae Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Tue, 17 Jul 2007 00:11:09 +0000 Subject: [PATCH 129/834] Bugzilla 196757 VariableLayoutNode.java - created VariableLocalsLayoutNode.java - deleted VariableSubExpressionsLayoutNode.java - deleted VariableVMProvider.java - changed to use VariableLayoutNode ExpressionVMProvider.java - changed to use VariableLayoutNode VMElementsUpdate.java - support -1 on data mining Bugzilla 196756 RegisterGroupLayoutNode.java - handle more events/cleanup RegisterLayoutNode.java - handle more events/cleanup --- .../expression/ExpressionVMProvider.java | 13 +- .../register/RegisterGroupLayoutNode.java | 13 +- .../register/RegisterLayoutNode.java | 4 + ...ayoutNode.java => VariableLayoutNode.java} | 339 +++++++++++------- .../VariableSubExpressionsLayoutNode.java | 318 ---------------- .../variable/VariableVMProvider.java | 10 +- .../dd/dsf/ui/viewmodel/VMElementsUpdate.java | 2 +- 7 files changed, 234 insertions(+), 465 deletions(-) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/{VariableLocalsLayoutNode.java => VariableLayoutNode.java} (78%) delete mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableSubExpressionsLayoutNode.java diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java index dec091dce23..ae77ee808ae 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java @@ -17,8 +17,7 @@ import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterGroupLayoutNode; import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterLayoutNode; import org.eclipse.dd.dsf.debug.ui.viewmodel.register.SyncRegisterDataAccess; import org.eclipse.dd.dsf.debug.ui.viewmodel.variable.SyncVariableDataAccess; -import org.eclipse.dd.dsf.debug.ui.viewmodel.variable.VariableLocalsLayoutNode; -import org.eclipse.dd.dsf.debug.ui.viewmodel.variable.VariableSubExpressionsLayoutNode; +import org.eclipse.dd.dsf.debug.ui.viewmodel.variable.VariableLayoutNode; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; @@ -87,11 +86,11 @@ public class ExpressionVMProvider extends AbstractDebugDMVMProviderWithCache registerGroupNode.setChildNodes(new IVMLayoutNode[] { registerNode }); /* - * Create the local variables nodes next. They represent the first level shown in the view. + * Create the support for the SubExpressions. Anything which is brought into the expressions + * view comes in as a fully qualified expression so we go directly to the SubExpression layout + * node. */ - IExpressionLayoutNode localsNode = new VariableLocalsLayoutNode(this, this, getSession(), syncvarDataAccess); - IVMLayoutNode subExpressioNode = new VariableSubExpressionsLayoutNode(this, getSession(), syncvarDataAccess); - localsNode.setChildNodes(new IVMLayoutNode[] { subExpressioNode }); + IExpressionLayoutNode subExpressioNode = new VariableLayoutNode(this, this, getSession(), syncvarDataAccess); /* * Tell the expression node which subnodes it will directly support. It is very important @@ -104,7 +103,7 @@ public class ExpressionVMProvider extends AbstractDebugDMVMProviderWithCache * assume what it was passed was for it and the real node which wants to handle it would be * left out in the cold. */ - expressionManagerNode.setExpressionLayoutNodes(new IExpressionLayoutNode[] { registerGroupNode, localsNode }); + expressionManagerNode.setExpressionLayoutNodes(new IExpressionLayoutNode[] { registerGroupNode, subExpressioNode }); /* * Let the work know which is the top level node. diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java index bd98e1cbcf1..13bb314d2e4 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java @@ -60,8 +60,7 @@ public class RegisterGroupLayoutNode extends AbstractExpressionLayoutNode dmc) { @@ -123,8 +122,7 @@ public class RegisterGroupLayoutNode extends AbstractExpressionLayoutNode implements IElementEditor { +public class VariableLayoutNode extends AbstractExpressionLayoutNode implements IElementEditor { + + /** + * List of child nodes containing only a reference to this. This is what enables the view model + * provider to know about the recursive nature of subexpression nodes. + */ + private final IVMLayoutNode[] fChildLayoutNodes = { this }; + + @Override + public IVMLayoutNode[] getChildLayoutNodes() { + return fChildLayoutNodes; + } + + @Override + public int getDeltaFlags(Object e) { + /* + * @see buildDelta() + */ + + if (e instanceof IRunControl.ISuspendedDMEvent) { + return IModelDelta.CONTENT; + } + + if ( e instanceof IExpressions.IExpressionChangedDMEvent) { + return IModelDelta.STATE; + } + + return IModelDelta.NO_CHANGE; + } + + @Override + public void buildDelta(final Object event, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) { + + if (event instanceof IRunControl.ISuspendedDMEvent) { + parentDelta.addFlags(IModelDelta.CONTENT); + } + else if ( event instanceof IExpressions.IExpressionChangedDMEvent) { + /* + * Flush the cache. + */ + VMCacheManager.getVMCacheManager().flush(super.getVMProvider().getPresentationContext()); + + /* + * Logically one would think that STATE should be specified here. But we specifiy CONTENT + * as well so that if there sub expressions which are affected in some way ( such as with + * an expanded union then they will show the changes also. + */ + parentDelta.addNode( createVMContext(((IExpressions.IExpressionChangedDMEvent)event).getDMContext()), IModelDelta.CONTENT | IModelDelta.STATE ); + } + + requestMonitor.done(); + } + private final IFormattedValuePreferenceStore fFormattedPrefStore; private final SyncVariableDataAccess fSyncVariableDataAccess; - protected class VariableLocalsVMC extends DMVMContext implements IFormattedValueVMContext, IVariable { + protected class VariableExpressionVMC extends DMVMContext implements IFormattedValueVMContext, IVariable { private IExpression fExpression; - public VariableLocalsVMC(IDMContext dmc) { + public VariableExpressionVMC(IDMContext dmc) { super(dmc); } @@ -88,7 +141,7 @@ public class VariableLocalsLayoutNode extends AbstractExpressionLayoutNode dmc) { - return new VariableLocalsVMC(dmc); + return new VariableExpressionVMC(dmc); } /** @@ -239,8 +291,6 @@ public class VariableLocalsLayoutNode extends AbstractExpressionLayoutNode rm) { + /* + * Since we are overriding "getElementForExpression" we do not need to do anything here. But + * we are forced to supply this routine because it is abstract in the extending class. + */ + } + + public int getExpressionLength(String expression) { + /* + * Since we are overriding "getElementForExpression" we do not need to do anything here. + * We just assume the entire expression is for us. + */ + return expression.length() ; + } + + @Override + protected void updateElementsInSessionThread(final IChildrenUpdate update) { + // Get the data model context object for the current node in the hierarchy. + + final IExpressionDMContext expressionDMC = findDmcInPath(update.getElementPath(), IExpressionDMContext.class); + + if ( expressionDMC != null ) { + getSubexpressionsUpdateElementsInSessionThread( update ); + } + else { + getLocalsUpdateElementsInSessionThread( update ); + } + } + + private void getSubexpressionsUpdateElementsInSessionThread(final IChildrenUpdate update) { + + final IExpressionDMContext expressionDMC = findDmcInPath(update.getElementPath(), IExpressionDMContext.class); + + if ( expressionDMC != null ) { + + // Get the services we need to use. + + final IExpressions expressionService = getServicesTracker().getService(IExpressions.class); + + if (expressionService == null) { + handleFailedUpdate(update); + return; + } + + final DsfExecutor dsfExecutor = getSession().getExecutor(); + + // Call IExpressions.getSubExpressions() to get an Iterable of IExpressionDMContext objects representing + // the sub-expressions of the expression represented by the current expression node. + + final DataRequestMonitor> rm = + new DataRequestMonitor>(dsfExecutor, null) { + @Override + public void handleCompleted() { + if (!getStatus().isOK()) { + handleFailedUpdate(update); + return; + } + + // Fill the update with the the IExpressionDMContext objects returned by + // IExpressions.getSubExpressions(). + + List subExpressionDMCList = (List)getData(); + IExpressionDMContext[] subExpressionDMCArray = new IExpressionDMContext[subExpressionDMCList.size()]; + Iterator iter = subExpressionDMCList.iterator(); + + int i = 0; + while (iter.hasNext()) { + subExpressionDMCArray[i++] = iter.next(); + } + + fillUpdateWithVMCs(update, subExpressionDMCArray); + update.done(); + } + }; + + // Make the asynchronous call to IExpressions.getSubExpressions(). The results are processed in the + // DataRequestMonitor.handleCompleted() above. + + expressionService.getSubExpressions(expressionDMC, rm); + } + } + + private void getLocalsUpdateElementsInSessionThread(final IChildrenUpdate update) { + final IFrameDMContext frameDmc = findDmcInPath(update.getElementPath(), IFrameDMContext.class); - //final ISymbolDMContext symbolDmc = - // findDmcInPath(update.getElementPath(), ISymbolDMContext.class); // Get the services we need to use. final IExpressions expressionService = getServicesTracker().getService(IExpressions.class); final IStack stackFrameService = getServicesTracker().getService(IStack.class); - if (execDmc == null || frameDmc == null || expressionService == null || stackFrameService == null) { + if ( frameDmc == null || expressionService == null || stackFrameService == null) { handleFailedUpdate(update); return; } @@ -430,8 +611,8 @@ public class VariableLocalsLayoutNode extends AbstractExpressionLayoutNode e) { - if (e instanceof IRunControl.ISuspendedDMEvent) { - return IModelDelta.CONTENT; - } - - return IModelDelta.NO_CHANGE; - } - - @Override - protected void buildDeltaForDMEvent(IDMEvent e, VMDelta parent, - int nodeOffset, RequestMonitor requestMonitor) { - if (e instanceof IRunControl.ISuspendedDMEvent) { - // Create a delta that the whole register group has changed. - parent.addFlags(IModelDelta.CONTENT); - } - - super.buildDeltaForDMEvent(e, parent, nodeOffset, requestMonitor); - } - - public CellEditor getCellEditor(IPresentationContext context, String columnId, Object element, Composite parent) { - if (IDebugVMConstants.COLUMN_ID__VALUE.equals(columnId)) { - return new TextCellEditor(parent); - } - else if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(columnId)) { - return new TextCellEditor(parent); - } - - return null; - } - - public ICellModifier getCellModifier(IPresentationContext context, Object element) { - return new VariableLayoutValueCellModifier(fFormattedPrefStore, fSyncVariableDataAccess); - } - - @Override - public void getElementForExpression(final IChildrenUpdate update, final String expressionText, final IExpression expression) { - - /* - * Create a valid DMC for this entered expression. - */ - final IFrameDMContext frameDmc = findDmcInPath(update.getElementPath(), IFrameDMContext.class); - final IExpressions expressionService = getServicesTracker().getService(IExpressions.class); - - IExpressionDMContext expressionDMC = expressionService.createExpression(frameDmc, expressionText); - - /* - * Now create the valid VMC which wrappers it. - */ - IVMContext vmc = createVMContext(expressionDMC); - - /* - * Associate this expression with the newly valid DMC and return this VMC back up the chain of command - * so it will be used when displaying the value in the expression view. - */ - associateExpression(vmc, expression); - update.setChild(vmc, 0); - update.done(); - } - - @Override - protected void associateExpression(Object element, IExpression expression) { - if (element instanceof VariableLocalsVMC) { - ((VariableLocalsVMC)element).setExpression(expression); - } - } - - @Override - protected int getDeltaFlagsForExpressionPart(Object event) { - if (event instanceof IRunControl.ISuspendedDMEvent) { - return IModelDelta.CONTENT; - } - - return IModelDelta.NO_CHANGE; - } - - @Override - protected void testContextForExpression(Object element, String expression, DataRequestMonitor rm) { - /* - * Since we are overriding "getElementForExpression" we do not need to do anything here. But - * we are forced to supply this routine because it is abstract in the extending class. - */ - } - - public int getExpressionLength(String expression) { - /* - * Since we are overriding "getElementForExpression" we do not need to do anything here. - * We just assume the entire expression is for us. - */ - return expression.length() ; - } } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableSubExpressionsLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableSubExpressionsLayoutNode.java deleted file mode 100644 index 7331c7eac31..00000000000 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableSubExpressionsLayoutNode.java +++ /dev/null @@ -1,318 +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.ui.viewmodel.variable; - -import java.util.Iterator; -import java.util.List; - -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.DsfExecutor; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.datamodel.IDMEvent; -import org.eclipse.dd.dsf.datamodel.IDMService; -import org.eclipse.dd.dsf.debug.service.IExpressions; -import org.eclipse.dd.dsf.debug.service.IFormattedValues; -import org.eclipse.dd.dsf.debug.service.IRunControl; -import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; -import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMData; -import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext; -import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData; -import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; -import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; -import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; -import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; -import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; -import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; -import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; -import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; - -@SuppressWarnings("restriction") -public class VariableSubExpressionsLayoutNode extends AbstractDMVMLayoutNode { - - @SuppressWarnings("unused") - private SyncVariableDataAccess fSyncVariableDataAccess; - - public VariableSubExpressionsLayoutNode(AbstractVMProvider provider, DsfSession session, SyncVariableDataAccess syncVariableDataAccess) { - super(provider, session, IExpressions.IExpressionDMContext.class); - fSyncVariableDataAccess = syncVariableDataAccess; - } - - /** - * List of child nodes containing only a reference to this. This is what enables the view model - * provider to know about the recursive nature of subexpression nodes. - */ - private final IVMLayoutNode[] fChildLayoutNodes = { this }; - - @Override - public IVMLayoutNode[] getChildLayoutNodes() { - return fChildLayoutNodes; - } - - /** - * We override this method because we now need to perform an extra level of data fetch to get the - * formatted value of the expression. - * - * @return void - */ - @Override - protected void updateLabelInSessionThread(ILabelUpdate[] updates) { - for (final ILabelUpdate update : updates) { - - final IExpressionDMContext dmc = findDmcInPath(update.getElementPath(), IExpressions.IExpressionDMContext.class); - - VMCacheManager.getVMCacheManager().getCache(update.getPresentationContext()) - .getModelData((IDMService)getServicesTracker().getService(null, dmc.getServiceFilter()), - dmc, - new DataRequestMonitor(getSession().getExecutor(), null) { - @Override - protected void handleCompleted() { - // Check that the request was evaluated and data is still valid. The request could - // fail if the state of the service changed during the request, but the view model - // has not been updated yet. - - if (!getStatus().isOK() || !getData().isValid()) { - assert getStatus().isOK() || - getStatus().getCode() != IDsfService.INTERNAL_ERROR || - getStatus().getCode() != IDsfService.NOT_SUPPORTED; - handleFailedUpdate(update); - return; - } - - // If columns are configured, extract the selected values for each understood column. - // First, we fill all of those columns which can be filled without extra data mining. - // We also note if we do have to do extra data mining. Any columns need to set the - // processing flag so we know we have further work to do. If there are more columns - // which need data extraction they need to be added in both "for" loops. - - String[] localColumns = update.getPresentationContext().getColumns(); - if (localColumns == null) - localColumns = new String[] { IDebugVMConstants.COLUMN_ID__NAME }; - - boolean weAreExtractingFormattedData = false; - - for (int idx = 0; idx < localColumns.length; idx++) { - if (IDebugVMConstants.COLUMN_ID__NAME.equals(localColumns[idx])) { - update.setLabel(getData().getName(), idx); - } else if (IDebugVMConstants.COLUMN_ID__TYPE.equals(localColumns[idx])) { - update.setLabel(getData().getTypeName(), idx); - } else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(localColumns[idx])) { - weAreExtractingFormattedData = true; - } else if (IDebugVMConstants.COLUMN_ID__DESCRIPTION.equals(localColumns[idx])) { - update.setLabel("", idx); //$NON-NLS-1$ - } - } - - if ( ! weAreExtractingFormattedData ) { - update.done(); - } else { - for (int idx = 0; idx < localColumns.length; idx++) { - if (IDebugVMConstants.COLUMN_ID__VALUE.equals(localColumns[idx])) { - updateFormattedExpressionValue(update, idx, dmc); - } - } - } - } - }, - getExecutor() - ); - } - } - - /** - * Private data access routine which performs the extra level of data access needed to - * get the formatted data value for a specific register. - */ - private void updateFormattedExpressionValue(final ILabelUpdate update, final int labelIndex, - final IExpressionDMContext dmc) - { - final IExpressions expressionService = getServicesTracker().getService(IExpressions.class); - /* - * PREFPAGE : We are using a default format until the preference page is created - * - * First select the format to be used. This involves checking so see that the preference - * page format is supported by the register service. If the format is not supported then - * we will pick the first available format. - */ - - final String preferencePageFormatId = IFormattedValues.NATURAL_FORMAT; - - expressionService.getAvailableFormattedValues( - dmc, - new DataRequestMonitor(getSession().getExecutor(), null) { - @Override - public void handleCompleted() { - if (!getStatus().isOK()) { - handleFailedUpdate(update); - return; - } - - /* - * See if the desired format is supported. - */ - String[] formatIds = getData(); - String finalFormatId = IFormattedValues.NATURAL_FORMAT; - boolean requestedFormatIsSupported = false; - - for ( String fId : formatIds ) { - if ( preferencePageFormatId.equals(fId) ) { - // The desired format is supported. - - finalFormatId = preferencePageFormatId; - requestedFormatIsSupported = true; - break; - } - } - - if ( ! requestedFormatIsSupported ) { - /* - * Desired format is not supported. If there are any formats supported - * then use the first available. - */ - if ( formatIds.length != 0 ) { - finalFormatId = formatIds[0]; - } - else { - // Expression service does not support any format. - - handleFailedUpdate(update); - return; - } - } - - /* - * Format has been validated. Get the formatted value. - */ - FormattedValueDMContext valueDmc = expressionService.getFormattedValue(dmc, finalFormatId); - - VMCacheManager.getVMCacheManager().getCache(update.getPresentationContext()) - .getModelData(expressionService, - valueDmc, - new DataRequestMonitor(getSession().getExecutor(), null) { - @Override - public void handleCompleted() { - if (!getStatus().isOK()) { - handleFailedUpdate(update); - return; - } - - /* - * Fill the label/column with the properly formatted data value. - */ - update.setLabel(getData().getFormattedValue(), labelIndex); - update.done(); - } - }, - getExecutor() - ); - } - } - ); - } - - @Override - protected void updateElementsInSessionThread(final IChildrenUpdate update) { - // Get the data model context object for the current node in the hierarchy. - - final IExpressionDMContext expressionDMC = findDmcInPath(update.getElementPath(), IExpressionDMContext.class); - - // ISSUE: Do we need to explicitly get the IExecutionDMContext and ISymbolDMContext since they - // should be in the parent chain of the IFrameDMContext object? - - final IExecutionDMContext execDmc = findDmcInPath(update.getElementPath(), IExecutionDMContext.class); - final IFrameDMContext frameDmc = findDmcInPath(update.getElementPath(), IFrameDMContext.class); - //final ISymbolDMContext symbolDmc = findDmcInPath(update.getElementPath(), ISymbolDMContext.class); - - // Get the services we need to use. - - final IExpressions expressionService = getServicesTracker().getService(IExpressions.class); - - if (execDmc == null || frameDmc == null || expressionService == null) { - handleFailedUpdate(update); - return; - } - - final DsfExecutor dsfExecutor = getSession().getExecutor(); - - // Call IExpressions.getSubExpressions() to get an Iterable of IExpressionDMContext objects representing - // the sub-expressions of the expression represented by the current expression node. - - final DataRequestMonitor> rm = - new DataRequestMonitor>(dsfExecutor, null) { - @Override - public void handleCompleted() { - if (!getStatus().isOK()) { - handleFailedUpdate(update); - return; - } - - // Fill the update with the the IExpressionDMContext objects returned by - // IExpressions.getSubExpressions(). - - List subExpressionDMCList = (List)getData(); - IExpressionDMContext[] subExpressionDMCArray = new IExpressionDMContext[subExpressionDMCList.size()]; - Iterator iter = subExpressionDMCList.iterator(); - - int i = 0; - while (iter.hasNext()) { - subExpressionDMCArray[i++] = iter.next(); - } - - fillUpdateWithVMCs(update, subExpressionDMCArray); - update.done(); - } - }; - - // Make the asynchronous call to IExpressions.getSubExpressions(). The results are processed in the - // DataRequestMonitor.handleCompleted() above. - - expressionService.getSubExpressions(expressionDMC, rm); - } - - @Override - protected int getNodeDeltaFlagsForDMEvent(IDMEvent e) { - if (e instanceof IRunControl.ISuspendedDMEvent) { - return IModelDelta.CONTENT; - } - else if (e instanceof IExpressions.IExpressionChangedDMEvent) { - /* - * Flush the cache. - */ - VMCacheManager.getVMCacheManager().flush(super.getVMProvider().getPresentationContext()); - - /* - * Logically one would think that STATE should be specified here. But we specifiy CONTENT - * as well so that if there sub expressions which are affected in some way ( such as with - * an expanded union then they will show the changes also. - */ - return IModelDelta.CONTENT | IModelDelta.STATE; - } - - return IModelDelta.NO_CHANGE; - } - - @Override - protected void buildDeltaForDMEvent(IDMEvent e, VMDelta parent, int nodeOffset, RequestMonitor requestMonitor) { - if (e instanceof IRunControl.ISuspendedDMEvent) { - // Create a delta that the whole register group has changed. - parent.addFlags(IModelDelta.CONTENT); - } - else if (e instanceof IExpressions.IExpressionChangedDMEvent) { - parent.addNode( createVMContext(((IExpressions.IExpressionChangedDMEvent)e).getDMContext()), IModelDelta.CONTENT | IModelDelta.STATE ); - } - - super.buildDeltaForDMEvent(e, parent, nodeOffset, requestMonitor); - } -} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java index 3d5bd3ac6ad..e7927efd87d 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java @@ -39,17 +39,11 @@ public class VariableVMProvider extends AbstractDebugDMVMProviderWithCache imple */ IVMRootLayoutNode debugViewSelection = new DMVMRootLayoutNode(this); - /* - * Create the local variables nodes next. They represent the first level shown in the view. - */ - IVMLayoutNode localsNode = new VariableLocalsLayoutNode(this, this, getSession(), varAccess); - debugViewSelection.setChildNodes(new IVMLayoutNode[] { localsNode }); - /* * Create the next level which represents members of structs/unions/enums and elements of arrays. */ - IVMLayoutNode subExpressioNode = new VariableSubExpressionsLayoutNode(this, getSession(), varAccess); - localsNode.setChildNodes(new IVMLayoutNode[] { subExpressioNode }); + IVMLayoutNode subExpressioNode = new VariableLayoutNode(this, this, getSession(), varAccess); + debugViewSelection.setChildNodes(new IVMLayoutNode[] { subExpressioNode }); /* * Now set this schema set as the layout set. diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMElementsUpdate.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMElementsUpdate.java index 23afa9d036f..796edc4a6a3 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMElementsUpdate.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMElementsUpdate.java @@ -75,7 +75,7 @@ public class VMElementsUpdate extends VMViewerUpdate implements IChildrenUpdate public void done() { @SuppressWarnings("unchecked") DataRequestMonitor> rm = (DataRequestMonitor>)fRequestMonitor; - if (fElements.size() == fLength) { + if (fElements.size() == fLength || fLength == -1 ) { rm.setData(fElements); } else { rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, "Incomplete elements of updates", null)); //$NON-NLS-1$ From 2088e2a8a708308461572caca8dc875dd2daec28 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 17 Jul 2007 22:20:30 +0000 Subject: [PATCH 130/834] Added flushing of the VM cache when the expression list is changed (bug 185635). --- .../ui/viewmodel/expression/ExpressionManagerLayoutNode.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerLayoutNode.java index d658cf26866..8fb621184bc 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerLayoutNode.java @@ -22,6 +22,7 @@ import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.VMElementsUpdate; +import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.IExpressionManager; import org.eclipse.debug.core.model.IExpression; @@ -295,6 +296,7 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode public void buildDelta(final Object event, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) { // Add a flag if the list of expressions has changed. if (event instanceof ExpressionsChangedEvent) { + VMCacheManager.getVMCacheManager().flush(super.getVMProvider().getPresentationContext()); parentDelta.addFlags(IModelDelta.CONTENT); } From af5370f876e9d60894a71079a62971aa7c16aa00 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 17 Jul 2007 22:22:14 +0000 Subject: [PATCH 131/834] Added a fix for expression view event processing and added coloring of changed variable values (bug 159695). --- .../variable/VariableLayoutNode.java | 41 +++++++++++-------- .../dsf/debug/service/IFormattedValues.java | 5 +++ 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java index 58606baecad..cfb10c32299 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java @@ -50,6 +50,8 @@ import org.eclipse.debug.core.model.IDebugTarget; import org.eclipse.debug.core.model.IExpression; import org.eclipse.debug.core.model.IValue; import org.eclipse.debug.core.model.IVariable; +import org.eclipse.debug.internal.ui.DebugUIPlugin; +import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementEditor; import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; @@ -344,7 +346,7 @@ public class VariableLayoutNode extends AbstractExpressionLayoutNode rm) { /* - * Create a valid DMC for this entered expression. + * Create a valid DMC for this entered expression. */ - final IFrameDMContext frameDmc = findDmcInPath(update.getElementPath(), IFrameDMContext.class); - final IExpressions expressionService = getServicesTracker().getService(IExpressions.class); + final IFrameDMContext frameDmc = findDmcInPath(update.getElementPath(), IFrameDMContext.class); + final IExpressions expressionService = getServicesTracker().getService(IExpressions.class); - IExpressionDMContext expressionDMC = expressionService.createExpression(frameDmc, expressionText); + IExpressionDMContext expressionDMC = expressionService.createExpression(frameDmc, expressionPartText); /* * Now create the valid VMC which wrappers it. */ IVMContext vmc = createVMContext(expressionDMC); - - /* - * Associate this expression with the newly valid DMC and return this VMC back up the chain of command - * so it will be used when displaying the value in the expression view. - */ - associateExpression(vmc, expression); - update.setChild(vmc, 0); - update.done(); + rm.setData(vmc); + rm.done(); } @Override diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java index 7b2d1e3b0e1..5ccac0a39ea 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java @@ -87,6 +87,11 @@ public interface IFormattedValues extends IDMService { public int hashCode() { return baseHashCode() + getFormatID().hashCode(); } + + @Override + public String toString() { + return super.toString() + ".format(" + getFormatID() + ")"; + } } public static class FormattedValueDMData implements IDMData { From 9ea8fb6e7e95655dadea27b50389b945d1c610fa Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 17 Jul 2007 22:23:54 +0000 Subject: [PATCH 132/834] Fixed color of changed register value to match the platform preferences (bug 159692). --- .../ui/viewmodel/register/RegisterLayoutNode.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java index 517aa9df778..a0703820281 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java @@ -47,6 +47,8 @@ import org.eclipse.debug.core.model.IExpression; import org.eclipse.debug.core.model.IValue; import org.eclipse.debug.core.model.IVariable; import org.eclipse.debug.internal.ui.DebugPluginImages; +import org.eclipse.debug.internal.ui.DebugUIPlugin; +import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementEditor; import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; @@ -58,7 +60,6 @@ import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.ICellModifier; import org.eclipse.jface.viewers.TextCellEditor; import org.eclipse.jface.viewers.TreePath; -import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.widgets.Composite; @SuppressWarnings("restriction") @@ -255,11 +256,12 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode Date: Fri, 20 Jul 2007 22:39:43 +0000 Subject: [PATCH 133/834] Committed patch adding initial implementation of multi-threading (bug 160038). --- .../debug/ui/actions/DsfTerminateCommand.java | 4 +- .../launch/StackFramesLayoutNode.java | 33 +++++++----- .../dsf/debug/service/INativeProcesses.java | 51 +++++++++++++++---- .../dd/dsf/debug/service/IRunControl.java | 12 +++-- 4 files changed, 69 insertions(+), 31 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfTerminateCommand.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfTerminateCommand.java index 5f1af3cd6a9..9cf33ac0894 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfTerminateCommand.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfTerminateCommand.java @@ -71,7 +71,7 @@ public class DsfTerminateCommand implements ITerminateHandler { } else { // Check the teriminate. processes.canTerminate( - processes.getThreadForExecutionContext(dmc), + processes.getProcessForDebugContext(dmc), new DataRequestMonitor(fExecutor, null) { @Override public void handleCompleted() { @@ -93,7 +93,7 @@ public class DsfTerminateCommand implements ITerminateHandler { fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) { @Override public void doExecute() { getProcesses().terminate( - getProcesses().getThreadForExecutionContext(getContext()), new RequestMonitor(fExecutor, null)); + getProcesses().getProcessForDebugContext(getContext()), new RequestMonitor(fExecutor, null)); } }); return false; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java index 6968cc8d6b6..95f0fe97a9f 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java @@ -19,7 +19,10 @@ 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.IContainerSuspendedDMEvent; import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent; 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; @@ -91,7 +94,8 @@ public class StackFramesLayoutNode extends AbstractDMVMLayoutNode= 1) { fCachedOldFrameVMCs[0] = topFrameVmc; - for (int i = 0; i < fCachedOldFrameVMCs.length; i++) update.setChild(fCachedOldFrameVMCs[i], i); + for (int i = 0; i < fCachedOldFrameVMCs.length; i++) + update.setChild(fCachedOldFrameVMCs[i], i); } else { update.setChild(topFrameVmc, 0); } @@ -209,10 +214,10 @@ public class StackFramesLayoutNode extends AbstractDMVMLayoutNode e) { // This node generates delta if the timers have changed, or if the // label has changed. - if (e instanceof IRunControl.ISuspendedDMEvent) { + if (e instanceof ISuspendedDMEvent) { return IModelDelta.CONTENT | IModelDelta.EXPAND | IModelDelta.SELECT; - } else if (e instanceof IRunControl.IResumedDMEvent) { - if (((IRunControl.IResumedDMEvent)e).getReason() == StateChangeReason.STEP) { + } else if (e instanceof IResumedDMEvent) { + if (((IResumedDMEvent)e).getReason() == StateChangeReason.STEP) { return IModelDelta.STATE; } else { return IModelDelta.CONTENT; @@ -225,10 +230,12 @@ public class StackFramesLayoutNode extends AbstractDMVMLayoutNode e, final VMDelta parent, final int nodeOffset, final RequestMonitor rm) { - if (e instanceof IRunControl.ISuspendedDMEvent) { - buildDeltaForSuspendedEvent((IRunControl.ISuspendedDMEvent)e, parent, nodeOffset, rm); - } else if (e instanceof IRunControl.IResumedDMEvent) { - buildDeltaForResumedEvent((IRunControl.IResumedDMEvent)e, parent, nodeOffset, rm); + if (e instanceof IContainerSuspendedDMEvent) { + buildDeltaForSuspendedEvent((ISuspendedDMEvent)e, ((IContainerSuspendedDMEvent)e).getTriggeringContext(), parent, nodeOffset, rm); + } else if (e instanceof ISuspendedDMEvent) { + buildDeltaForSuspendedEvent((ISuspendedDMEvent)e, ((ISuspendedDMEvent)e).getDMContext(), parent, nodeOffset, rm); + } else if (e instanceof IResumedDMEvent) { + buildDeltaForResumedEvent((IResumedDMEvent)e, parent, nodeOffset, rm); } else if (e instanceof IStepQueueManager.ISteppingTimedOutEvent) { buildDeltaForSteppingTimedOutEvent((IStepQueueManager.ISteppingTimedOutEvent)e, parent, nodeOffset, rm); } else { @@ -237,7 +244,7 @@ public class StackFramesLayoutNode extends AbstractDMVMLayoutNode {} - public interface IProcessDMContext extends IThreadDMContext {} + public interface IProcessDMContext extends IDMContext {} /** - * 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. + * Interface for thread and process object data. */ public interface IThreadDMData extends IDMData { String getName(); String getId(); boolean isDebuggerAttached(); - IDMContext getDebuggingContext(); + IDMContext getDebugContext(); } - + + /** + * Interface for thread and process object data. + */ + public interface IProcessDMData extends IDMData { + String getName(); + String getId(); + boolean isDebuggerAttached(); + IDMContext getDebugContext(); + } + /** * Event indicating that process data has changed. */ - public interface ProcessChangedDMEvent extends IDMEvent {} + public interface IProcessChangedDMEvent extends IDMEvent {} - public IThreadDMContext getThreadForExecutionContext(IExecutionDMContext execCtx); + public interface IProcessStartedEvent extends IDMEvent> { + IProcessDMContext getProcess(); + } + + public interface IProcessExitedEvent extends IDMEvent> { + IProcessDMContext getProcess(); + } + + /** + * Returns a thread for the corresponding context. null if no corresponding + * thread exists. + * @param execCtx + * @return + */ + public IThreadDMContext getThreadForDebugContext(IDMContext execCtx); + + /** + * Returns a process context corresponding to the given context. null if no + * corresponding process exists. + */ + public IProcessDMContext getProcessForDebugContext(IDMContext execCtx); + /** * Retrieves the current list of processes running on target. * @param rm Request completion monitor, to be filled in with array of process contexts. @@ -86,12 +114,13 @@ public interface INativeProcesses extends IDMService { * @param thread Thread or process to terminate. * @param rm Return token. */ - void canTerminate(IThreadDMContext thread, DataRequestMonitor rm); + void canTerminate(IDMContext ctx, DataRequestMonitor rm); /** * Terminates the selected process or thread. * @param thread Thread or process to terminate. * @param rm Request completion monitor, indicates success or failure. */ - void terminate(IThreadDMContext thread, RequestMonitor requestMonitor); + void terminate(IDMContext ctx, RequestMonitor requestMonitor); + } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java index 4d23e119a8c..07b8da2aa52 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java @@ -39,6 +39,7 @@ public interface IRunControl extends IDMService * for execution cotnexts, which by itself can perform run-control * operations. */ + public interface IContainerDMContext extends IExecutionDMContext {} /** Flag indicating reason context state change. */ @@ -50,16 +51,17 @@ public interface IRunControl extends IDMService public interface ISuspendedDMEvent extends IDMEvent { StateChangeReason getReason(); } + public interface IResumedDMEvent extends IDMEvent { StateChangeReason getReason(); } - public interface IContainerSuspendedDMEvent extends IDMEvent { - StateChangeReason getReason(); + + public interface IContainerSuspendedDMEvent extends ISuspendedDMEvent { + IExecutionDMContext getTriggeringContext(); } - public interface IContainerResumedDMEvent extends IDMEvent { - StateChangeReason getReason(); + + public interface IContainerResumedDMEvent extends IResumedDMEvent { } - /** * Indicates that a new execution context (thread) was started. The DMC * for the event is the container of the new exec context. From ee7f2cd0f01e952968df49cfe5ba1443cc229881 Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Fri, 20 Jul 2007 23:24:38 +0000 Subject: [PATCH 134/834] Bugzilla 186010 & 196756 IFormattedValues.java Reorganized ordering of format ids. IDebugVMConstants.java Added location in Presentation context where the format id is stored. AbstractExpressionLAyoutNode.java cleanup warnings. AbstractSetFormatStyke.java New abstract implementation which deals with the format menu handling. FormattedValuePreferenceStore.java Default singleton preference storage implementation IFormattedValuePreferenceStore.java Changed interfaces to be presentation context id based. SetDefaultFormatBinary.java SetDefaultFormatOctal.java SetDefaultFormatHex.java SetDefaultFormatNatural.java Changed to use the new abstract implementation class All cell editors were changed to use the new preference storage interfaces. All VM providers were changed to use the default preference store. All Layout Nodes were changed to use the new prference store interfaces. RefreshActionDelegate.java RefreshAlwaysActionDelegate.java RefreshManualActionDelegate.java RefreshOnBreakActionDelegate.java Cleaned up warnings. VMCache.java VMCacheManager.java Cleaned up warnings. AbstractVMLayoutNode.java made getVMprovider method public IVMLayoutNode.java Added getVMProvider method AbstractVMProvider.java Added refresh() implementation IVMprovider.java Added refresh() method declaration Added getVMAdapter() method declaration AbstractDMVMproviderWithCache.java Cleanup warnings. FileLayoutNode.java Added getVMprovider implementation. --- .../debug/ui/viewmodel/IDebugVMConstants.java | 7 + .../expression/ExpressionVMProvider.java | 22 +- .../formatsupport/AbstractSetFormatStyle.java | 220 ++++++++++++++++++ .../FormattedValuePreferenceStore.java | 42 ++++ .../IFormattedValuePreferenceStore.java | 14 +- .../formatsupport/SetDefaultFormatBinary.java | 35 +-- .../formatsupport/SetDefaultFormatHex.java | 35 +-- .../SetDefaultFormatNatural.java | 35 +-- .../formatsupport/SetDefaultFormatOctal.java | 36 +-- .../RegisterBitFieldLayoutCellModifier.java | 37 ++- .../register/RegisterBitFieldLayoutNode.java | 3 +- .../register/RegisterLayoutNode.java | 62 +++-- .../RegisterLayoutValueCellModifier.java | 45 +++- .../register/RegisterVMProvider.java | 19 +- .../update/actions/RefreshActionDelegate.java | 8 +- .../actions/RefreshAlwaysActionDelegate.java | 12 +- .../actions/RefreshManualActionDelegate.java | 12 +- .../actions/RefreshOnBreakActionDelegate.java | 12 +- .../variable/VariableLayoutNode.java | 4 +- .../VariableLayoutValueCellModifier.java | 63 +++-- .../variable/VariableVMProvider.java | 26 +-- .../dsf/debug/service/IFormattedValues.java | 6 +- .../ui/viewmodel/AbstractVMLayoutNode.java | 2 +- .../dsf/ui/viewmodel/AbstractVMProvider.java | 27 +++ .../dd/dsf/ui/viewmodel/IVMLayoutNode.java | 5 +- .../dd/dsf/ui/viewmodel/IVMProvider.java | 11 + .../dm/AbstractDMVMProviderWithCache.java | 3 +- .../dd/dsf/ui/viewmodel/update/VMCache.java | 2 + .../ui/viewmodel/update/VMCacheManager.java | 3 +- 29 files changed, 544 insertions(+), 264 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/AbstractSetFormatStyle.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/FormattedValuePreferenceStore.java diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/IDebugVMConstants.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/IDebugVMConstants.java index 3b0b9432139..e381f8d40b7 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/IDebugVMConstants.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/IDebugVMConstants.java @@ -3,6 +3,9 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel; import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; public interface IDebugVMConstants { + /** + * Standard across the board column IDs. + */ public static final String ID = DsfDebugUIPlugin.PLUGIN_ID + ".VARIABLES_COLUMN_PRESENTATION_ID"; //$NON-NLS-1$ public static final String COLUMN_ID__NAME = DsfDebugUIPlugin.PLUGIN_ID + ".COLUMN_ID__NAME"; //$NON-NLS-1$ public static final String COLUMN_ID__TYPE = DsfDebugUIPlugin.PLUGIN_ID + ".COLUMN_ID__TYPE"; //$NON-NLS-1$ @@ -10,4 +13,8 @@ public interface IDebugVMConstants { public static final String COLUMN_ID__DESCRIPTION = DsfDebugUIPlugin.PLUGIN_ID + ".COLUMN_ID__DESCRIPTION"; //$NON-NLS-1$ public static final String COLUMN_ID__EXPRESSION = DsfDebugUIPlugin.PLUGIN_ID + ".COLUMN_ID__EXPRESSION"; //$NON-NLS-1$ + /** + * Location of the current format in the IPresentationContext data store. + */ + public final static String CURRENT_FORMAT_STORAGE = "CurrentNumericStyle" ; //$NON-NLS-1$ } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java index ae77ee808ae..b7e56356f52 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java @@ -10,9 +10,8 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; -import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.dd.dsf.debug.ui.viewmodel.dm.AbstractDebugDMVMProviderWithCache; -import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePreferenceStore; +import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.FormattedValuePreferenceStore; import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterGroupLayoutNode; import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterLayoutNode; import org.eclipse.dd.dsf.debug.ui.viewmodel.register.SyncRegisterDataAccess; @@ -34,11 +33,8 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationCont * */ @SuppressWarnings("restriction") -public class ExpressionVMProvider extends AbstractDebugDMVMProviderWithCache - implements IExpressionsListener, IFormattedValuePreferenceStore +public class ExpressionVMProvider extends AbstractDebugDMVMProviderWithCache implements IExpressionsListener { - private String fDefaultFormatId = IFormattedValues.HEX_FORMAT; - public static class ExpressionsChangedEvent { enum Type {ADDED, CHANGED, REMOVED} public final Type fType; @@ -82,7 +78,7 @@ public class ExpressionVMProvider extends AbstractDebugDMVMProviderWithCache * The expression view wants to support fully all of the components of the register view. */ IExpressionLayoutNode registerGroupNode = new RegisterGroupLayoutNode(this, getSession(), syncRegDataAccess); - IVMLayoutNode registerNode = new RegisterLayoutNode(this, this, getSession(), syncRegDataAccess); + IVMLayoutNode registerNode = new RegisterLayoutNode(FormattedValuePreferenceStore.getDefault(), this, getSession(), syncRegDataAccess); registerGroupNode.setChildNodes(new IVMLayoutNode[] { registerNode }); /* @@ -90,7 +86,9 @@ public class ExpressionVMProvider extends AbstractDebugDMVMProviderWithCache * view comes in as a fully qualified expression so we go directly to the SubExpression layout * node. */ - IExpressionLayoutNode subExpressioNode = new VariableLayoutNode(this, this, getSession(), syncvarDataAccess); + IExpressionLayoutNode subExpressioNode = + + new VariableLayoutNode(FormattedValuePreferenceStore.getDefault(), this, getSession(), syncvarDataAccess); /* * Tell the expression node which subnodes it will directly support. It is very important @@ -164,12 +162,4 @@ public class ExpressionVMProvider extends AbstractDebugDMVMProviderWithCache public void expressionsRemoved(IExpression[] expressions) { handleEvent(new ExpressionsChangedEvent(ExpressionsChangedEvent.Type.REMOVED, expressions)); } - - public String getDefaultFormatId() { - return fDefaultFormatId; - } - - public void setDefaultFormatId(String id) { - fDefaultFormatId = id; - } } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/AbstractSetFormatStyle.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/AbstractSetFormatStyle.java new file mode 100644 index 00000000000..6c481b6e325 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/AbstractSetFormatStyle.java @@ -0,0 +1,220 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.dd.dsf.debug.service.IFormattedValues; +import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; +import org.eclipse.dd.dsf.ui.viewmodel.IVMAdapter; +import org.eclipse.dd.dsf.ui.viewmodel.IVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode.DMVMContext; +import org.eclipse.debug.core.model.IDebugElement; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer; +import org.eclipse.debug.ui.AbstractDebugView; +import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.debug.ui.contexts.DebugContextEvent; +import org.eclipse.debug.ui.contexts.IDebugContextListener; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.ui.IViewActionDelegate; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IViewSite; + +@SuppressWarnings("restriction") +public class AbstractSetFormatStyle implements IViewActionDelegate, IDebugContextListener { + + /* + * Local private storage. + */ + private IViewPart fpart = null; + private Object fViewInput = null; + private IAction fAction = null; + + /* + * This routine is meant to be overidden so extenders of this class tell us what + * to use for the default. + */ + protected String getFormatStyle() { + return IFormattedValues.NATURAL_FORMAT; + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.IViewActionDelegate#init(org.eclipse.ui.IViewPart) + */ + public void init(IViewPart view) { + /* + * Save the view information for later reference and data retrieval. + */ + fpart = view; + + /* + * Get the current selection from the DebugView so we can determine if we want this menu action to be live or not. + */ + IViewSite site = (IViewSite) view.getSite(); + String combinedViewId = site.getId() + (site.getSecondaryId() != null ? (":" + site.getSecondaryId()) : ""); //$NON-NLS-1$ //$NON-NLS-2$ + + DebugUITools.getDebugContextManager().getContextService(view.getSite().getWorkbenchWindow()).addPostDebugContextListener(this, combinedViewId); + ISelection sel = DebugUITools.getDebugContextManager().getContextService(view.getSite().getWorkbenchWindow()).getActiveContext(); + + if ( sel instanceof IStructuredSelection ) { + /* + * Save the view selection as well so we can later determine if we want our action to be valid or not. + */ + fViewInput = ( (IStructuredSelection) sel ).getFirstElement(); + } + } + + /* + * (non-Javadoc) + * @see org.eclipse.debug.ui.contexts.IDebugContextListener#debugContextChanged(org.eclipse.debug.ui.contexts.DebugContextEvent) + */ + public void debugContextChanged(DebugContextEvent event) { + /* + * This handler is called whenever a selection in the debug view is changed. So here is + * where we will know when we need to reenable the menu actions. + */ + ISelection sel = event.getContext(); + + if (sel instanceof IStructuredSelection) { + fViewInput = ((IStructuredSelection)sel).getFirstElement(); + } + + /* + * Update the current state of affairs. + */ + update(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction) + */ + @SuppressWarnings("restriction") + public void run(IAction action) { + + /* + * Make sure we have a valid set of information. Otherwise we cannot go forward. + */ + if ( fpart instanceof AbstractDebugView && fViewInput != null ) + { + Viewer viewer = ( (AbstractDebugView) fpart).getViewer(); + + /* + * Now we need to make sure this is one of the Flexible Hierarchy viewws. + */ + if ( viewer instanceof TreeModelViewer ) { + /* + * Get the presentation context and see if there is a numeric property there. If so then this + * is a view implementation which supports changing the format. + */ + TreeModelViewer treeViewer = (TreeModelViewer) viewer; + IPresentationContext context = treeViewer.getPresentationContext(); + + /* + * Store the new style. So it will be picked up by the view when the view changes. + */ + context.setProperty( IDebugVMConstants.CURRENT_FORMAT_STORAGE, getFormatStyle() ); + + /* + * Now go tell the view to update. We do so by finding the VM provider for this view + * and telling it to redraw the entire view. + */ + if (fViewInput instanceof IAdaptable) { + IVMAdapter adapter = (IVMAdapter) ((IAdaptable)fViewInput).getAdapter(IVMAdapter.class); + + if ( adapter != null ) { + IVMProvider provider = adapter.getVMProvider(context); + + if ( provider != null ) { + /* + * "null" means redraw the entire view. + */ + provider.refresh( null ); + } + } + } + } + } + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection) + */ + public void selectionChanged(IAction action, ISelection selection) { + + /* + * Since we are creating a generic central handler ( "update" ). It needs to get the + * action information later. + */ + fAction = action; + + /* + * We need to what our input is. This will either be a selection from the debug view + * or something selected in our view. + */ + if (selection instanceof IStructuredSelection) { + + Object element = ( (IStructuredSelection) selection ).getFirstElement(); + + if ( element instanceof DMVMContext ) { fViewInput = element; } + else { + /* + * We deliberately do nothing here. A valid structured selection has already been + * selected. It comes from the Debug View and is a valid Debug Element. We do not + * want to overwrite it. + */ + } + + } else { + fViewInput = null; + } + update(); + } + + /* + * This is the common processing routine which is called from the various selection routines. + * Its job is to determine if we are valid for OCD and if so what is the proper execution dmc + * we should be operating on + */ + + private void update() { + + if ( fAction != null ) { + /* + * If the element is a debug view context selection then we want to be active since + * a possible OCD selection is there. We will let the connection type determine if + * we are active or not. + */ + if ( fViewInput instanceof IDebugElement ) + { + fAction.setEnabled(true); + } + else if ( fViewInput instanceof DMVMContext ) + { + fAction.setEnabled(true); + } + else { + /* + * It is not us and we will mark ourselves not available. Remember on reselection will + * will renable again. The Debug View change handler we have will deal with being moved + * back into the picture. + */ + fAction.setEnabled(false); + } + } + } +} + diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/FormattedValuePreferenceStore.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/FormattedValuePreferenceStore.java new file mode 100644 index 00000000000..0fb2f060a64 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/FormattedValuePreferenceStore.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * 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.formatsupport; + +import org.eclipse.dd.dsf.debug.service.IFormattedValues; +import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; + +/** + * Provides default implementation of preference storage. + */ +@SuppressWarnings("restriction") +public class FormattedValuePreferenceStore implements IFormattedValuePreferenceStore { + + private static IFormattedValuePreferenceStore fgSingletonReference; + + public static IFormattedValuePreferenceStore getDefault() { + if (fgSingletonReference == null) { + fgSingletonReference = new FormattedValuePreferenceStore(); + } + return fgSingletonReference; + } + + @SuppressWarnings("restriction") + public String getCurrentNumericFormat( IPresentationContext context ) { + + Object prop = context.getProperty( IDebugVMConstants.CURRENT_FORMAT_STORAGE ); + + if ( prop != null ) { + return (String) prop; + } + return IFormattedValues.NATURAL_FORMAT; + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/IFormattedValuePreferenceStore.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/IFormattedValuePreferenceStore.java index f7b14c4b33f..14af52bc5e7 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/IFormattedValuePreferenceStore.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/IFormattedValuePreferenceStore.java @@ -10,11 +10,19 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; + /** * */ + +@SuppressWarnings("restriction") public interface IFormattedValuePreferenceStore { - public String getDefaultFormatId(); - - public void setDefaultFormatId(String id); + /* + * Retrieves for the specified Presentation Context the configured format. + * + * @param context Specified Presentation Context + * @return Format ID. + */ + public String getCurrentNumericFormat( IPresentationContext context ); } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatBinary.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatBinary.java index f945ab4a8e0..d0af577d3f1 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatBinary.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatBinary.java @@ -11,37 +11,12 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport; import org.eclipse.dd.dsf.debug.service.IFormattedValues; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.ui.IViewActionDelegate; -import org.eclipse.ui.IViewPart; -/** - * - */ -public class SetDefaultFormatBinary implements IViewActionDelegate { +@SuppressWarnings("restriction") +public class SetDefaultFormatBinary extends AbstractSetFormatStyle { - private IFormattedValueVMContext fFormattedValueVMC; - - public void init(IViewPart view) { + @Override + protected String getFormatStyle() { + return IFormattedValues.BINARY_FORMAT; } - - public void run(IAction action) { - if (fFormattedValueVMC != null) { - fFormattedValueVMC.getPreferenceStore().setDefaultFormatId(IFormattedValues.BINARY_FORMAT); - } - } - - public void selectionChanged(IAction action, ISelection selection) { - fFormattedValueVMC = null; - if (selection instanceof IStructuredSelection) { - Object element = ((IStructuredSelection)selection).getFirstElement(); - if (element instanceof IFormattedValueVMContext) { - fFormattedValueVMC = ((IFormattedValueVMContext)element); - } - } - action.setEnabled(fFormattedValueVMC != null); - } - } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatHex.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatHex.java index edfb9d85be9..3a34e7b9a92 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatHex.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatHex.java @@ -11,37 +11,12 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport; import org.eclipse.dd.dsf.debug.service.IFormattedValues; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.ui.IViewActionDelegate; -import org.eclipse.ui.IViewPart; -/** - * - */ -public class SetDefaultFormatHex implements IViewActionDelegate { +@SuppressWarnings("restriction") +public class SetDefaultFormatHex extends AbstractSetFormatStyle { - private IFormattedValueVMContext fFormattedValueVMC; - - public void init(IViewPart view) { + @Override + protected String getFormatStyle() { + return IFormattedValues.HEX_FORMAT; } - - public void run(IAction action) { - if (fFormattedValueVMC != null) { - fFormattedValueVMC.getPreferenceStore().setDefaultFormatId(IFormattedValues.HEX_FORMAT); - } - } - - public void selectionChanged(IAction action, ISelection selection) { - fFormattedValueVMC = null; - if (selection instanceof IStructuredSelection) { - Object element = ((IStructuredSelection)selection).getFirstElement(); - if (element instanceof IFormattedValueVMContext) { - fFormattedValueVMC = ((IFormattedValueVMContext)element); - } - } - action.setEnabled(fFormattedValueVMC != null); - } - } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatNatural.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatNatural.java index 52498992215..6d42e9a7365 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatNatural.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatNatural.java @@ -11,37 +11,12 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport; import org.eclipse.dd.dsf.debug.service.IFormattedValues; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.ui.IViewActionDelegate; -import org.eclipse.ui.IViewPart; -/** - * - */ -public class SetDefaultFormatNatural implements IViewActionDelegate { +@SuppressWarnings("restriction") +public class SetDefaultFormatNatural extends AbstractSetFormatStyle { - private IFormattedValueVMContext fFormattedValueVMC; - - public void init(IViewPart view) { + @Override + protected String getFormatStyle() { + return IFormattedValues.NATURAL_FORMAT; } - - public void run(IAction action) { - if (fFormattedValueVMC != null) { - fFormattedValueVMC.getPreferenceStore().setDefaultFormatId(IFormattedValues.NATURAL_FORMAT); - } - } - - public void selectionChanged(IAction action, ISelection selection) { - fFormattedValueVMC = null; - if (selection instanceof IStructuredSelection) { - Object element = ((IStructuredSelection)selection).getFirstElement(); - if (element instanceof IFormattedValueVMContext) { - fFormattedValueVMC = ((IFormattedValueVMContext)element); - } - } - action.setEnabled(fFormattedValueVMC != null); - } - } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatOctal.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatOctal.java index 67641c4d511..34f0f9b75f8 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatOctal.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatOctal.java @@ -11,37 +11,13 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport; import org.eclipse.dd.dsf.debug.service.IFormattedValues; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.ui.IViewActionDelegate; -import org.eclipse.ui.IViewPart; -/** - * - */ -public class SetDefaultFormatOctal implements IViewActionDelegate { +@SuppressWarnings("restriction") +public class SetDefaultFormatOctal extends AbstractSetFormatStyle { - private IFormattedValueVMContext fFormattedValueVMC; - - public void init(IViewPart view) { + @Override + protected String getFormatStyle() { + return IFormattedValues.OCTAL_FORMAT; } - - public void run(IAction action) { - if (fFormattedValueVMC != null) { - fFormattedValueVMC.getPreferenceStore().setDefaultFormatId(IFormattedValues.OCTAL_FORMAT); - } - } - - public void selectionChanged(IAction action, ISelection selection) { - fFormattedValueVMC = null; - if (selection instanceof IStructuredSelection) { - Object element = ((IStructuredSelection)selection).getFirstElement(); - if (element instanceof IFormattedValueVMContext) { - fFormattedValueVMC = ((IFormattedValueVMContext)element); - } - } - action.setEnabled(fFormattedValueVMC != null); - } - } + diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutCellModifier.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutCellModifier.java index 0fbe1911caa..ca6743d766a 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutCellModifier.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutCellModifier.java @@ -15,8 +15,11 @@ import org.eclipse.dd.dsf.debug.service.IRegisters.IMnemonic; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionCellModifier; import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePreferenceStore; +import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +@SuppressWarnings("restriction") public class RegisterBitFieldLayoutCellModifier extends WatchExpressionCellModifier { public static enum BitFieldEditorStyle { NOTHING, BITFIELDCOMBO, BITFIELDTEXT } @@ -85,11 +88,25 @@ public class RegisterBitFieldLayoutCellModifier extends WatchExpressionCellModif if ( element != fElement ) return false; if ( fStyle == BitFieldEditorStyle.BITFIELDTEXT ) { - /* * We let the Model provider supply the current format. */ - String value = fDataAccess.getFormattedBitFieldValue(fElement, fFormatPrefStore.getDefaultFormatId()); + String formatId; + + if ( element instanceof IVMContext) { + /* + * Find the presentation context and then use it to get the current desired format. + */ + IVMContext ctx = (IVMContext) element; + IPresentationContext presCtx = ctx.getLayoutNode().getVMProvider().getPresentationContext(); + + formatId = fFormatPrefStore.getCurrentNumericFormat(presCtx); + } + else { + formatId = IFormattedValues.NATURAL_FORMAT; + } + + String value = fDataAccess.getFormattedBitFieldValue(fElement, formatId); if ( value == null ) { value = "..."; } //$NON-NLS-1$ @@ -132,7 +149,21 @@ public class RegisterBitFieldLayoutCellModifier extends WatchExpressionCellModif /* * We let the Model provider supply the current format. */ - fDataAccess.writeBitField(element, (String) value, IFormattedValues.HEX_FORMAT); + String formatId; + + if ( element instanceof IVMContext) { + /* + * Find the presentation context and then use it to get the current desired format. + */ + IVMContext ctx = (IVMContext) element; + IPresentationContext presCtx = ctx.getLayoutNode().getVMProvider().getPresentationContext(); + + formatId = fFormatPrefStore.getCurrentNumericFormat(presCtx); + } + else { + formatId = IFormattedValues.NATURAL_FORMAT; + } + fDataAccess.writeBitField(element, (String) value, formatId); } } else { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java index ff4e6c98588..72ba3a00cdb 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java @@ -185,7 +185,8 @@ public class RegisterBitFieldLayoutNode extends AbstractExpressionLayoutNode(getSession().getExecutor(), null) { @@ -200,7 +201,7 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode(getSession().getExecutor(), null) { - @Override - public void handleCompleted() { - if (!getStatus().isOK()) { - handleFailedUpdate(update); - return; - } - - /* - * Fill the label/column with the properly formatted data value. - */ - update.setLabel(getData().getFormattedValue(), labelIndex); - - // color based on change history - FormattedValueDMData oldData = (FormattedValueDMData) VMCacheManager.getVMCacheManager() - .getCache(RegisterLayoutNode.this.getVMProvider().getPresentationContext()) - .getArchivedModelData(valueDmc); - if(oldData != null && !oldData.getFormattedValue().equals(getData().getFormattedValue())) { - update.setBackground( - DebugUIPlugin.getPreferenceColor( - IInternalDebugUIConstants.PREF_CHANGED_VALUE_BACKGROUND).getRGB(), - labelIndex); - } - update.done(); + VMCacheManager.getVMCacheManager().getCache( context ).getModelData(regService, + valueDmc, + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + public void handleCompleted() { + if (!getStatus().isOK()) { + handleFailedUpdate(update); + return; } - }, - getSession().getExecutor() + /* + * Fill the label/column with the properly formatted data value. + */ + update.setLabel(getData().getFormattedValue(), labelIndex); + + // color based on change history + FormattedValueDMData oldData = (FormattedValueDMData) VMCacheManager.getVMCacheManager() + .getCache(context).getArchivedModelData(valueDmc); + if(oldData != null && !oldData.getFormattedValue().equals(getData().getFormattedValue())) { + update.setBackground( + DebugUIPlugin.getPreferenceColor( + IInternalDebugUIConstants.PREF_CHANGED_VALUE_BACKGROUND).getRGB(), + labelIndex); + } + update.done(); + } + }, + getSession().getExecutor() ); } } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutValueCellModifier.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutValueCellModifier.java index f953b1f5124..d0e0f6a7d23 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutValueCellModifier.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutValueCellModifier.java @@ -10,16 +10,19 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.viewmodel.register; - import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMData; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionCellModifier; import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePreferenceStore; +import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +@SuppressWarnings("restriction") public class RegisterLayoutValueCellModifier extends WatchExpressionCellModifier { private SyncRegisterDataAccess fDataAccess = null; @@ -83,9 +86,26 @@ public class RegisterLayoutValueCellModifier extends WatchExpressionCellModifier */ if ( IDebugVMConstants.COLUMN_ID__VALUE.equals(property) ) { /* - * Make sure we are working on the editable areas. + * We let the Model provider supply the current format. */ - String value = fDataAccess.getFormattedRegisterValue(element, fFormattedValuePreferenceStore.getDefaultFormatId()); + String formatId; + + if ( element instanceof IVMContext) { + /* + * Find the presentation context and then use it to get the current desired format. + */ + IVMContext ctx = (IVMContext) element; + IPresentationContext presCtx = ctx.getLayoutNode().getVMProvider().getPresentationContext(); + + formatId = fFormattedValuePreferenceStore.getCurrentNumericFormat(presCtx); + } + else { + formatId = IFormattedValues.NATURAL_FORMAT; + } + + String value = + + fDataAccess.getFormattedRegisterValue(element, formatId); if ( value == null ) { return "..."; } //$NON-NLS-1$ else { return value; } @@ -105,9 +125,24 @@ public class RegisterLayoutValueCellModifier extends WatchExpressionCellModifier if (value instanceof String) { /* - * PREFPAGE : We are using a default format until the preference page is created. + * We let the Model provider supply the current format. */ - fDataAccess.writeRegister(element, (String) value, fFormattedValuePreferenceStore.getDefaultFormatId()); + String formatId; + + if ( element instanceof IVMContext) { + /* + * Find the presentation context and then use it to get the current desired format. + */ + IVMContext ctx = (IVMContext) element; + IPresentationContext presCtx = ctx.getLayoutNode().getVMProvider().getPresentationContext(); + + formatId = fFormattedValuePreferenceStore.getCurrentNumericFormat(presCtx); + } + else { + formatId = IFormattedValues.NATURAL_FORMAT; + } + + fDataAccess.writeRegister(element, (String) value, formatId); } } else { super.modify(element, property, value); diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java index 704ec332c13..f2b0b6bf103 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java @@ -10,9 +10,8 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.viewmodel.register; -import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.dd.dsf.debug.ui.viewmodel.dm.AbstractDebugDMVMProviderWithCache; -import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePreferenceStore; +import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.FormattedValuePreferenceStore; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; @@ -25,13 +24,11 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationCont * Provides the VIEW MODEL for the DEBUG MODEL REGISTER view. */ @SuppressWarnings("restriction") -public class RegisterVMProvider extends AbstractDebugDMVMProviderWithCache implements IFormattedValuePreferenceStore +public class RegisterVMProvider extends AbstractDebugDMVMProviderWithCache { /* * Current default for register formatting. */ - private String fDefaultFormatId = IFormattedValues.HEX_FORMAT; - public RegisterVMProvider(AbstractVMAdapter adapter, IPresentationContext context, DsfSession session) { super(adapter, context, session); @@ -54,13 +51,13 @@ public class RegisterVMProvider extends AbstractDebugDMVMProviderWithCache imple /* * Create the next level which is the registers themselves. */ - IVMLayoutNode registerNode = new RegisterLayoutNode(this, this, getSession(), regAccess); + IVMLayoutNode registerNode = new RegisterLayoutNode(FormattedValuePreferenceStore.getDefault(), this, getSession(), regAccess); registerGroupNode.setChildNodes(new IVMLayoutNode[] { registerNode }); /* * Create the next level which is the bitfield level. */ - IVMLayoutNode bitFieldNode = new RegisterBitFieldLayoutNode(this, this, getSession(), regAccess); + IVMLayoutNode bitFieldNode = new RegisterBitFieldLayoutNode(FormattedValuePreferenceStore.getDefault(), this, getSession(), regAccess); registerNode.setChildNodes(new IVMLayoutNode[] { bitFieldNode }); /* @@ -78,12 +75,4 @@ public class RegisterVMProvider extends AbstractDebugDMVMProviderWithCache imple public String getColumnPresentationId(IPresentationContext context, Object element) { return RegisterColumnPresentation.ID; } - - public String getDefaultFormatId() { - return fDefaultFormatId; - } - - public void setDefaultFormatId(String id) { - fDefaultFormatId = id; - } } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshActionDelegate.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshActionDelegate.java index f75643f824e..ac227900b5c 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshActionDelegate.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshActionDelegate.java @@ -19,6 +19,7 @@ import org.eclipse.jface.viewers.ISelection; import org.eclipse.ui.IViewActionDelegate; import org.eclipse.ui.IViewPart; +@SuppressWarnings("restriction") public class RefreshActionDelegate implements IViewActionDelegate { protected IViewPart fView; @@ -32,13 +33,10 @@ protected IViewPart fView; } public void selectionChanged(IAction action, ISelection selection) { - } - private Object getContext() + private Object getContext() { - return ((TreeModelViewer) ((AbstractDebugView) fView).getViewer()) - .getPresentationContext(); + return ((TreeModelViewer) ((AbstractDebugView) fView).getViewer()).getPresentationContext(); } - } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshAlwaysActionDelegate.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshAlwaysActionDelegate.java index 8dfe0d5dd87..7ad9dbb6278 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshAlwaysActionDelegate.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshAlwaysActionDelegate.java @@ -17,18 +17,18 @@ import org.eclipse.dd.dsf.ui.viewmodel.update.actions.AbstractRefreshActionDeleg import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer; import org.eclipse.debug.ui.AbstractDebugView; +@SuppressWarnings("restriction") public class RefreshAlwaysActionDelegate extends AbstractRefreshActionDelegate { - - public Object getContext() + @Override + public Object getContext() { - return ((TreeModelViewer) ((AbstractDebugView) fView).getViewer()) - .getPresentationContext(); + return ((TreeModelViewer) ((AbstractDebugView) fView).getViewer()).getPresentationContext(); } - public VMCache createCache() + @Override + public VMCache createCache() { return new VMCacheRefreshAlways(); } - } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshManualActionDelegate.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshManualActionDelegate.java index 0b442de2ae6..5a70cb5bac6 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshManualActionDelegate.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshManualActionDelegate.java @@ -17,18 +17,18 @@ import org.eclipse.dd.dsf.ui.viewmodel.update.actions.AbstractRefreshActionDeleg import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer; import org.eclipse.debug.ui.AbstractDebugView; +@SuppressWarnings("restriction") public class RefreshManualActionDelegate extends AbstractRefreshActionDelegate { - - public Object getContext() + @Override + public Object getContext() { - return ((TreeModelViewer) ((AbstractDebugView) fView).getViewer()) - .getPresentationContext(); + return ((TreeModelViewer) ((AbstractDebugView) fView).getViewer()).getPresentationContext(); } - public VMCache createCache() + @Override + public VMCache createCache() { return new VMCacheRefreshManual(); } - } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshOnBreakActionDelegate.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshOnBreakActionDelegate.java index d4c4d9a0e2b..21addc0a634 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshOnBreakActionDelegate.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshOnBreakActionDelegate.java @@ -17,18 +17,18 @@ import org.eclipse.dd.dsf.ui.viewmodel.update.actions.AbstractRefreshActionDeleg import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer; import org.eclipse.debug.ui.AbstractDebugView; +@SuppressWarnings("restriction") public class RefreshOnBreakActionDelegate extends AbstractRefreshActionDelegate { - - public Object getContext() + @Override + public Object getContext() { - return ((TreeModelViewer) ((AbstractDebugView) fView).getViewer()) - .getPresentationContext(); + return ((TreeModelViewer) ((AbstractDebugView) fView).getViewer()).getPresentationContext(); } - public VMCache createCache() + @Override + public VMCache createCache() { return new VMCacheRefreshOnBreak(); } - } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java index cfb10c32299..89440bdd65e 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java @@ -297,8 +297,8 @@ public class VariableLayoutNode extends AbstractExpressionLayoutNode extends IDMContext {} @@ -30,8 +30,8 @@ public interface IFormattedValues extends IDMService { */ public final static String HEX_FORMAT = "HEX.Format" ; //$NON-NLS-1$ public final static String OCTAL_FORMAT = "OCTAL.Format" ; //$NON-NLS-1$ - public final static String BINARY_FORMAT = "BINARY.Format" ; //$NON-NLS-1$ public final static String NATURAL_FORMAT = "NATURAL.Format" ; //$NON-NLS-1$ + public final static String BINARY_FORMAT = "BINARY.Format" ; //$NON-NLS-1$ /** * Retrieves the available formats that the given data is available in. @@ -90,7 +90,7 @@ public interface IFormattedValues extends IDMService { @Override public String toString() { - return super.toString() + ".format(" + getFormatID() + ")"; + return super.toString() + ".format(" + getFormatID() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ } } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java index 37024d81c3a..0542927d929 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java @@ -60,7 +60,7 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { return fProvider.getExecutor(); } - protected AbstractVMProvider getVMProvider() { + public IVMProvider getVMProvider() { return fProvider; } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java index b9c33513651..8bdec75ce00 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java @@ -139,6 +139,33 @@ abstract public class AbstractVMProvider implements IVMProvider fRootLayoutNodeRef.get().dispose(); } } + + /** + * Allows other subsystems to force the layout mode associated with the specified + * VM context to refresh. If null is passed then the RootLayoutNode is told to refresh. + */ + public void refresh(final IVMContext element) { + try { + getExecutor().execute(new Runnable() { + public void run() { + if (isDisposed()) return; + + if ( element == null ) { + VMDelta rootDelta = new VMDelta(getRootElement(), IModelDelta.CONTENT); + getModelProxy().fireModelChangedNonDispatch(rootDelta); + } + else { + VMDelta elementDelta = new VMDelta(element, IModelDelta.CONTENT); + getModelProxy().fireModelChangedNonDispatch(elementDelta); + } + + }}); + } catch (RejectedExecutionException e) { + // Ignore. This exception could be thrown if the provider is being + // shut down. + } + return; + } protected boolean isDisposed() { return fDisposed; diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMLayoutNode.java index d21487c7192..fc0ce2ae030 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMLayoutNode.java @@ -33,6 +33,10 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; @SuppressWarnings("restriction") public interface IVMLayoutNode { + /** + * Retrieves the associated VM Provider. + */ + public IVMProvider getVMProvider(); /** * Retrieves information whether for a given path in the viewer, @@ -56,7 +60,6 @@ public interface IVMLayoutNode */ public void updateElementCount(IChildrenCountUpdate update); - /** * Retrieves the element objects of this node for the given path in the * viewer, and for the given range of indexes.
    diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java index 1e96b5b81ee..66fcaa216a0 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java @@ -16,6 +16,11 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationCont public interface IVMProvider extends IElementContentProvider, IModelProxyFactory, IColumnPresentationFactory { + /** + * Returns the VM Adapter associated with the provider. + */ + public IVMAdapter getVMAdapter(); + /** * Returns the root layout node that is configured in this provider. * It may return null, if a root node is not yet configured. @@ -37,6 +42,12 @@ public interface IVMProvider */ public IPresentationContext getPresentationContext(); + /** + * Allows other subsystems to force the layout mode associated with the specified + * VM context to refresh. If null is passed then the RootLayoutNode is told to refresh. + */ + public void refresh(IVMContext element); + /** * Cleans up the resources associated with this provider. */ diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProviderWithCache.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProviderWithCache.java index e8348bbc935..be6e704df7e 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProviderWithCache.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProviderWithCache.java @@ -23,6 +23,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationCont import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; +@SuppressWarnings("restriction") public abstract class AbstractDMVMProviderWithCache extends AbstractDMVMProvider implements VMCacheManager.CacheListener { @@ -39,7 +40,7 @@ public abstract class AbstractDMVMProviderWithCache extends AbstractDMVMProvider getModelProxy().fireModelChanged(new ModelDelta(getRootElement(),IModelDelta.CONTENT)); } - public AbstractDMVMProviderWithCache(AbstractVMAdapter adapter, IPresentationContext presentationContext, DsfSession session) { + public AbstractDMVMProviderWithCache(AbstractVMAdapter adapter, IPresentationContext presentationContext, DsfSession session) { super(adapter, presentationContext, session); VMCacheManager.getVMCacheManager().addCacheListener(getPresentationContext(), this); diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java index d6b7d60dc9e..2635efb6ba7 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java @@ -33,6 +33,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpd import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; +@SuppressWarnings("restriction") public abstract class VMCache { protected Executor fExecutor = new DefaultDsfExecutor(); @@ -323,6 +324,7 @@ public abstract class VMCache return fDataArchive.get(dmc); } + @SuppressWarnings("unchecked") public abstract void handleEvent(IDMEvent event); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCacheManager.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCacheManager.java index 3b612df1ad9..ecbb5270141 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCacheManager.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCacheManager.java @@ -47,7 +47,8 @@ public class VMCacheManager if(!fAssociations.containsKey(context)) fAssociations.put(context, new VMCache() { - @Override + @SuppressWarnings("unchecked") + @Override public void handleEvent(IDMEvent event) { } From f96dd96b9ad626f4e68f9d0087d3267f7a02ee8c Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Wed, 25 Jul 2007 18:03:10 +0000 Subject: [PATCH 135/834] Bugzillas 197843 & 197844 --- .../AbstractDebugDMVMProviderWithCache.java | 3 +- .../launch/StandardLaunchRootLayoutNode.java | 1 + .../update/VMCacheRefreshAlways.java | 6 ++-- .../update/VMCacheRefreshManual.java | 7 ++--- .../update/VMCacheRefreshOnBreak.java | 1 + .../variable/VariableLayoutNode.java | 28 ++++++++++++++++++- 6 files changed, 35 insertions(+), 11 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/dm/AbstractDebugDMVMProviderWithCache.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/dm/AbstractDebugDMVMProviderWithCache.java index 2b539869fba..c0557044656 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/dm/AbstractDebugDMVMProviderWithCache.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/dm/AbstractDebugDMVMProviderWithCache.java @@ -30,10 +30,11 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationCont * is meant to solve this problem. */ +@SuppressWarnings("restriction") public class AbstractDebugDMVMProviderWithCache extends AbstractDMVMProviderWithCache { - @SuppressWarnings("restriction") + public AbstractDebugDMVMProviderWithCache(AbstractVMAdapter adapter, IPresentationContext presentationContext, DsfSession session) { super(adapter, presentationContext, session); diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java index 2ea7489c2f8..7b3516ced4d 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java @@ -133,6 +133,7 @@ public class StandardLaunchRootLayoutNode extends VMRootLayoutNode } } + @Override public Object getRootObject() { return fLaunch; } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshAlways.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshAlways.java index bdb3557c6ff..676048a8fcd 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshAlways.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshAlways.java @@ -15,14 +15,12 @@ import org.eclipse.dd.dsf.datamodel.IDMEvent; import org.eclipse.dd.dsf.debug.service.IRunControl; import org.eclipse.dd.dsf.ui.viewmodel.update.VMCache; - public class VMCacheRefreshAlways extends VMCache { - - @Override + @SuppressWarnings("unchecked") + @Override public void handleEvent(IDMEvent event) { if(event instanceof IRunControl.ISuspendedDMEvent) flush(true); } - } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshManual.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshManual.java index d02afb0976e..8d707b517d7 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshManual.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshManual.java @@ -16,10 +16,7 @@ import org.eclipse.dd.dsf.ui.viewmodel.update.VMCache; public class VMCacheRefreshManual extends VMCache { - + @SuppressWarnings("unchecked") @Override - public void handleEvent(IDMEvent event) { - - } - + public void handleEvent(IDMEvent event) {} } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshOnBreak.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshOnBreak.java index 3e3f86783d9..a1cdc3b6160 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshOnBreak.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshOnBreak.java @@ -18,6 +18,7 @@ import org.eclipse.dd.dsf.ui.viewmodel.update.VMCache; public class VMCacheRefreshOnBreak extends VMCache { + @SuppressWarnings("unchecked") @Override public void handleEvent(IDMEvent event) { if(event instanceof IRunControl.ISuspendedDMEvent) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java index 89440bdd65e..26857075ca1 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java @@ -237,7 +237,33 @@ public class VariableLayoutNode extends AbstractExpressionLayoutNode Date: Fri, 27 Jul 2007 18:25:34 +0000 Subject: [PATCH 136/834] [160038] Committed patch 74701 with changes to running/suspended events. --- .../src/org/eclipse/dd/dsf/debug/service/IRunControl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java index 07b8da2aa52..54237082d3c 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java @@ -7,6 +7,7 @@ * * Contributors: * Wind River Systems - initial API and implementation + * Ericsson - Modified for additional functionality *******************************************************************************/ package org.eclipse.dd.dsf.debug.service; @@ -43,7 +44,7 @@ public interface IRunControl extends IDMService public interface IContainerDMContext extends IExecutionDMContext {} /** Flag indicating reason context state change. */ - public enum StateChangeReason { UNKNOWN, USER_REQUEST, STEP, BREAKPOINT, EXCEPTION, CONTAINER }; + public enum StateChangeReason { UNKNOWN, USER_REQUEST, STEP, BREAKPOINT, EXCEPTION, CONTAINER, WATCHPOINT, SIGNAL, SHAREDLIB, ERROR }; /** * Events signaling a state changes. From ac6017aeb9afbb098c3c23669961e820791a33d8 Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Tue, 31 Jul 2007 05:09:31 +0000 Subject: [PATCH 137/834] Bugzilla 198353 --- .../org.eclipse.core.resources.prefs | 3 + .../org.eclipse.dd.dsf.debug.ui/plugin.xml | 8 +- .../detailpanesupport/DetailPane.java | 1007 +++++++++++++++++ .../detailpanesupport/DetailPaneFactory.java | 76 ++ .../viewmodel/detailpanesupport/Messages.java | 32 + .../detailpanesupport/TextViewerAction.java | 86 ++ .../detailpanesupport/messages.properties | 3 + 7 files changed, 1214 insertions(+), 1 deletion(-) create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/.settings/org.eclipse.core.resources.prefs create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPane.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPaneFactory.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/Messages.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/TextViewerAction.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/messages.properties diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/.settings/org.eclipse.core.resources.prefs b/plugins/org.eclipse.dd.dsf.debug.ui/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 00000000000..6f616043918 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,3 @@ +#Fri Jul 27 14:30:56 EDT 2007 +eclipse.preferences.version=1 +encoding//src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/messages.properties=8859_1 diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml index 3c72cc6419c..4d8023afd96 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml +++ b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml @@ -202,6 +202,12 @@ - + + + + diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPane.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPane.java new file mode 100644 index 00000000000..da6c3849eaf --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPane.java @@ -0,0 +1,1007 @@ +/******************************************************************************* + * Copyright (c) 2006, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Randy Rohrbach (Wind River Systems, Inc.) - extended implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel.detailpanesupport; + +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.commands.operations.IUndoContext; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.debug.service.IExpressions; +import org.eclipse.dd.dsf.debug.service.IFormattedValues; +import org.eclipse.dd.dsf.debug.service.IRegisters; +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.IFormattedDataDMContext; +import org.eclipse.dd.dsf.debug.service.IRegisters.IBitFieldDMContext; +import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext; +import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode.DMVMContext; +import org.eclipse.debug.core.model.IDebugElement; +import org.eclipse.debug.core.model.IValue; +import org.eclipse.debug.internal.ui.DebugUIPlugin; +import org.eclipse.debug.internal.ui.IDebugHelpContextIds; +import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; +import org.eclipse.debug.internal.ui.LazyModelPresentation; +import org.eclipse.debug.internal.ui.VariablesViewModelPresentation; +import org.eclipse.debug.internal.ui.actions.variables.details.DetailPaneMaxLengthAction; +import org.eclipse.debug.internal.ui.actions.variables.details.DetailPaneWordWrapAction; +import org.eclipse.debug.internal.ui.preferences.IDebugPreferenceConstants; +import org.eclipse.debug.internal.ui.views.variables.StatusLineContributionItem; +import org.eclipse.debug.internal.ui.views.variables.details.DetailMessages; +import org.eclipse.debug.ui.IDebugUIConstants; +import org.eclipse.debug.ui.IDebugView; +import org.eclipse.debug.ui.IDetailPane; +import org.eclipse.debug.ui.IValueDetailListener; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IStatusLineManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.Document; +import org.eclipse.jface.text.DocumentEvent; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IDocumentListener; +import org.eclipse.jface.text.IFindReplaceTarget; +import org.eclipse.jface.text.ITextOperationTarget; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.IUndoManager; +import org.eclipse.jface.text.IUndoManagerExtension; +import org.eclipse.jface.text.source.SourceViewer; +import org.eclipse.jface.text.source.SourceViewerConfiguration; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.events.FocusAdapter; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.ui.IViewSite; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.IWorkbenchPartSite; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.actions.ActionFactory; +import org.eclipse.ui.operations.OperationHistoryActionHandler; +import org.eclipse.ui.operations.RedoActionHandler; +import org.eclipse.ui.operations.UndoActionHandler; +import org.eclipse.ui.progress.WorkbenchJob; +import org.eclipse.ui.texteditor.IAbstractTextEditorHelpContextIds; +import org.eclipse.ui.texteditor.ITextEditorActionConstants; +import org.eclipse.ui.texteditor.IUpdate; +import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds; + +@SuppressWarnings("restriction") +public class DetailPane implements IDetailPane, IAdaptable, IPropertyChangeListener { + + /** + * The IWorkbenchPartSite that the details area (and the + * variables view) belongs to. + */ + private IWorkbenchPartSite fWorkbenchPartSite; + + /** + * Map of actions. Keys are strings, values + * are IAction. + */ + private Map fActionMap = new HashMap(); + + /** + * Collection to track actions that should be updated when selection occurs. + */ + private List fSelectionActions = new ArrayList(); + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.IDetailPane#init(org.eclipse.ui.IWorkbenchPartSite) + */ + public void init(IWorkbenchPartSite workbench) { + fWorkbenchPartSite = workbench; + + } + + /** + * Adds an action to the Map storing actions. Removes it if action is null. + * + * @param actionID The ID of the action, used as the key in the Map + * @param action The action associated with the ID + */ + protected void setAction(String actionID, IAction action) { + if (action == null) { + fActionMap.remove(actionID); + } else { + fActionMap.put(actionID, action); + } + } + + /** + * Adds the given action to the global action handler for the ViewSite. + * A call to updateActionBars() must be called after changes + * to propagate changes through the workbench. + * + * @param actionID The ID of the action + * @param action The action to be set globally + */ + protected void setGlobalAction(String actionID, IAction action){ + getViewSite().getActionBars().setGlobalActionHandler(actionID, action); + } + + /** + * Adds the given action to the list of actions that will be updated when + * updateSelectionDependentActions() is called. If the string + * is null it will not be added to the list. + * + * @param actionID The ID of the action which should be updated + */ + protected void setSelectionDependantAction(String actionID){ + if (actionID != null) fSelectionActions.add(actionID); + } + + /** + * Gets the action out of the map, casts it to an IAction + * + * @param actionID The ID of the action to find + * @return The action associated with the ID or null if none is found. + */ + protected IAction getAction(String actionID) { + return fActionMap.get(actionID); + } + + /** + * Calls the update method of the action with the given action ID. + * The action must exist in the action map and must be an instance of + * IUpdate + * + * @param actionId The ID of the action to update + */ + protected void updateAction(String actionId) { + IAction action= getAction(actionId); + if (action instanceof IUpdate) { + ((IUpdate) action).update(); + } + } + + /** + * Iterates through the list of selection dependent actions and + * updates them. Use setSelectionDependentAction(String actionID) + * to add an action to the list. The action must have been added to the known + * actions map by calling setAction(String actionID, IAction action) + * before it can be updated by this method. + */ + protected void updateSelectionDependentActions() { + Iterator iterator= fSelectionActions.iterator(); + while (iterator.hasNext()) { + updateAction(iterator.next()); + } + } + + /** + * Gets the view site for this view. May be null if this detail pane + * is not part of a view. + * + * @return The site for this view or null + */ + protected IViewSite getViewSite(){ + if (fWorkbenchPartSite == null){ + return null; + } else { + return (IViewSite) fWorkbenchPartSite.getPart().getSite(); + } + } + + /** + * Gets the workbench part site for this view. May be null if this detail pane + * is not part of a view. + * + * @return The workbench part site or null + */ + protected IWorkbenchPartSite getWorkbenchPartSite() { + return fWorkbenchPartSite; + } + + /** + * Returns whether this detail pane is being displayed in a view with a workbench part site. + * + * @return whether this detail pane is being displayed in a view with a workbench part site. + */ + protected boolean isInView(){ + return fWorkbenchPartSite != null; + } + + /** + * These are the IDs for the actions in the context menu + */ + protected static final String DETAIL_COPY_ACTION = ActionFactory.COPY.getId() + ".SourceDetailPane"; //$NON-NLS-1$ + protected static final String DETAIL_SELECT_ALL_ACTION = IDebugView.SELECT_ALL_ACTION + ".SourceDetailPane"; //$NON-NLS-1$ + protected static final String DETAIL_WORD_WRAP_ACTION = IDebugPreferenceConstants.PREF_DETAIL_PANE_WORD_WRAP; + protected static final String DETAIL_MAX_LENGTH_ACTION = "MaxLength"; //$NON-NLS-1$ + + /** + * The ID, name and description of this pane are stored in constants so that the class + * does not have to be instantiated to access them. + */ + public static final String ID = DetailMessages.DefaultDetailPane_0; + public static final String NAME = DetailMessages.DefaultDetailPane_1; + public static final String DESCRIPTION = DetailMessages.DefaultDetailPane_57; + + /** + * Data structure for the position label value. + */ + private static class PositionLabelValue { + + public int fValue; + + @Override + public String toString() { + return String.valueOf(fValue); + } + } + + /** + * Internal interface for a cursor listener. I.e. aggregation + * of mouse and key listener. + * @since 3.0 + */ + interface ICursorListener extends MouseListener, KeyListener { + } + + /** + * Job to compute the details for a selection + */ + class DetailJob extends Job implements IValueDetailListener { + + private IStructuredSelection fElements; + private boolean fFirst = true; + private IProgressMonitor fMonitor; + + public DetailJob(IStructuredSelection elements) { + super("compute variable details"); //$NON-NLS-1$ + setSystem(true); + fElements = elements; + } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor) + */ + @SuppressWarnings("unchecked") + @Override + protected IStatus run(IProgressMonitor monitor) { + fMonitor = monitor; + Iterator iterator = fElements.iterator(); + while (iterator.hasNext()) { + if (monitor.isCanceled()) { + break; + } + Object element = iterator.next(); + + /* + * Make sure this is an element we want to deal with. + */ + if ( element instanceof DMVMContext) { + IFormattedValues service = null; + IFormattedDataDMContext dmc = null ; + + /* + * We are specifically looking to support the following Data Model Contexts + * + * IRegisterDMContext + * IBitFieldDMContext + * IExpressionDMContext + * + * At first you might think that we should just use the service which is + * associated with the dmc. But there are implementations where the data + * model contexts are extended but the services do not extend each other + * ( this is the case with the WindRiver OCD extensions for example ). + * + * So here we specifically look for the service which knows how to deal + * with the formatted data. + */ + + DsfServicesTracker tracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), ((DMVMContext) element).getDMC().getSessionId()); + + IRegisterDMContext regDmc = DMContexts.getAncestorOfType(((DMVMContext) element).getDMC(), IRegisterDMContext.class); + + if ( regDmc != null ) { + dmc = regDmc ; + service = tracker.getService(IRegisters.class); + } + else { + IBitFieldDMContext bitfieldDmc = DMContexts.getAncestorOfType(((DMVMContext) element).getDMC(), IBitFieldDMContext.class); + + if ( bitfieldDmc != null ) { + dmc = bitfieldDmc ; + service = tracker.getService(IRegisters.class); + } + else { + IExpressionDMContext exprDmc = DMContexts.getAncestorOfType(((DMVMContext) element).getDMC(), IExpressionDMContext.class); + + if ( exprDmc != null ) { + dmc = exprDmc ; + service = tracker.getService(IExpressions.class); + } + } + } + + /* + * If the desired Data Model Context is null then we are not going to + * process this data. + */ + if ( dmc == null ) return Status.OK_STATUS; + + /* + * Now that we can process this one. Find out how many formats we can + * show this in. We will choose to show all of the supported formats. + * Since we are doing this in the background and the debug engines do + * typically cache the results so producing multiple formats will not + * typically be a burden. We should probably consider perhaps doing a + * preference where they can select what formats they want to show. + */ + final IFormattedDataDMContext finalDmc = dmc; + final IFormattedValues finalService = service; + + final DataRequestMonitor getAvailableFormatsDone = + new DataRequestMonitor(finalService.getSession().getExecutor(), null) { + @Override + protected void handleOK() { + /* + * Now we have a set of formats for each one fire up an independent + * asynchronous request to get the data in that format. We do not + * go through the cache manager here because when the values are + * edited and written the cache is bypassed. + */ + String[] formats = getData(); + for ( final String str : formats ) { + /* + * Format has been validated. Get the formatted value. + */ + final FormattedValueDMContext valueDmc = finalService.getFormattedValue(finalDmc, str); + finalService.getModelData( + valueDmc, + new DataRequestMonitor(finalService.getSession().getExecutor(), null) { + @Override + public void handleCompleted() { + if (getStatus().isOK()) { + /* + * Show the information indicating the format. + */ + if ( str == IFormattedValues.HEX_FORMAT) { + detailComputed(null, "Hex.... : " + getData().getFormattedValue()); //$NON-NLS-1$ + } + else if ( str == IFormattedValues.OCTAL_FORMAT) { + detailComputed(null, "Octal.. : " + getData().getFormattedValue()); //$NON-NLS-1$ + } + else if ( str == IFormattedValues.NATURAL_FORMAT) { + detailComputed(null, "Natural : " + getData().getFormattedValue()); //$NON-NLS-1$ + } + else if ( str == IFormattedValues.BINARY_FORMAT) { + detailComputed(null, "Binary. : " + getData().getFormattedValue()); //$NON-NLS-1$ + } + else { + detailComputed(null, "Other.. : " + getData().getFormattedValue()); //$NON-NLS-1$ + } + } + } + } + ); + } + } + }; + + /* + * Get the supported formats. + */ + finalService.getExecutor().submit(new Runnable() { + public void run() { + finalService.getAvailableFormattedValues(finalDmc, getAvailableFormatsDone); + } + } + ); + } + } + + return Status.OK_STATUS; + } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.jobs.Job#canceling() + */ + @Override + protected void canceling() { + super.canceling(); + synchronized (this) { + notifyAll(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.IValueDetailListener#detailComputed(org.eclipse.debug.core.model.IValue, java.lang.String) + */ + public void detailComputed(IValue value, final String result) { + if (!fMonitor.isCanceled()) { + WorkbenchJob append = new WorkbenchJob("append details") { //$NON-NLS-1$ + @Override + public IStatus runInUIThread(IProgressMonitor monitor) { + if (!fMonitor.isCanceled()) { + String insert = result; + int length = 0; + if (!fFirst) { + length = getDetailDocument().getLength(); + } + if (length > 0) { + insert = "\n" + result; //$NON-NLS-1$ + } + try { + int max = DebugUIPlugin.getDefault().getPreferenceStore().getInt(IDebugUIConstants.PREF_MAX_DETAIL_LENGTH); + if (max > 0 && insert.length() > max) { + insert = insert.substring(0, max) + "..."; //$NON-NLS-1$ + } + if (fFirst) { + getDetailDocument().set(insert); + fFirst = false; + } else { + getDetailDocument().replace(length, 0,insert); + } + } catch (BadLocationException e) { + DebugUIPlugin.log(e); + } + } + return Status.OK_STATUS; + } + }; + append.setSystem(true); + append.schedule(); + } + synchronized (this) { + notifyAll(); + } + } + } + + /** + * The model presentation used to produce the string details for a + * selected variable. + */ + private VariablesViewModelPresentation fModelPresentation; + private String fDebugModelIdentifier; + + /** + * Controls the status line while the details area has focus. + * Displays the current cursor position in the text (line:character). + */ + private StatusLineContributionItem fStatusLineItem; + + /** + * The source viewer in which the computed string detail + * of selected variables will be displayed. + */ + private SourceViewer fSourceViewer; + + /** + * The last selection displayed in the source viewer. + */ + private IStructuredSelection fLastDisplayed = null; + + /** + * Variables used to create the detailed information for a selection + */ + private IDocument fDetailDocument; + private DetailJob fDetailJob = null; + private final String fPositionLabelPattern = DetailMessages.DefaultDetailPane_56; + private final PositionLabelValue fLineLabel = new PositionLabelValue(); + private final PositionLabelValue fColumnLabel = new PositionLabelValue(); + private final Object[] fPositionLabelPatternArguments = new Object[] {fLineLabel, fColumnLabel }; + private ICursorListener fCursorListener; + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.IDetailPane#createControl(org.eclipse.swt.widgets.Composite) + */ + public Control createControl(Composite parent) { + + fModelPresentation = new VariablesViewModelPresentation(); + + createSourceViewer(parent); + + if (isInView()){ + createViewSpecificComponents(); + createActions(); + DebugUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this); + JFaceResources.getFontRegistry().addListener(this); + } + + return fSourceViewer.getControl(); + } + + /** + * Creates the source viewer in the given parent composite + * + * @param parent Parent composite to create the source viewer in + */ + private void createSourceViewer(Composite parent) { + + // Create & configure a SourceViewer + fSourceViewer = new SourceViewer(parent, null, SWT.V_SCROLL | SWT.H_SCROLL); + fSourceViewer.setDocument(getDetailDocument()); + fSourceViewer.getTextWidget().setFont(JFaceResources.getFont(IInternalDebugUIConstants.DETAIL_PANE_FONT)); + fSourceViewer.getTextWidget().setWordWrap(DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IDebugPreferenceConstants.PREF_DETAIL_PANE_WORD_WRAP)); + fSourceViewer.setEditable(false); + PlatformUI.getWorkbench().getHelpSystem().setHelp(fSourceViewer.getTextWidget(), IDebugHelpContextIds.DETAIL_PANE); + Control control = fSourceViewer.getControl(); + GridData gd = new GridData(GridData.FILL_BOTH); + control.setLayoutData(gd); + } + + /** + * Creates listeners and other components that should only be added to the + * source viewer when this detail pane is inside a view. + */ + private void createViewSpecificComponents(){ + + // Add a document listener so actions get updated when the document changes + getDetailDocument().addDocumentListener(new IDocumentListener() { + public void documentAboutToBeChanged(DocumentEvent event) {} + public void documentChanged(DocumentEvent event) { + updateSelectionDependentActions(); + } + }); + + // Add the selection listener so selection dependent actions get updated. + fSourceViewer.getSelectionProvider().addSelectionChangedListener(new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent event) { + updateSelectionDependentActions(); + } + }); + + // Add a focus listener to update actions when details area gains focus + fSourceViewer.getControl().addFocusListener(new FocusAdapter() { + @Override + public void focusGained(FocusEvent e) { + + getViewSite().setSelectionProvider(fSourceViewer.getSelectionProvider()); + + setGlobalAction(IDebugView.SELECT_ALL_ACTION, getAction(DETAIL_SELECT_ALL_ACTION)); + setGlobalAction(IDebugView.COPY_ACTION, getAction(DETAIL_COPY_ACTION)); + + getViewSite().getActionBars().updateActionBars(); + } + + @Override + public void focusLost(FocusEvent e) { + + getViewSite().setSelectionProvider(null); + + setGlobalAction(IDebugView.SELECT_ALL_ACTION, null); + setGlobalAction(IDebugView.COPY_ACTION, null); + + getViewSite().getActionBars().updateActionBars(); + } + }); + + // Create a status line item displaying the current cursor location + fStatusLineItem = new StatusLineContributionItem("ModeContributionItem"); //$NON-NLS-1$ + IStatusLineManager manager= getViewSite().getActionBars().getStatusLineManager(); + manager.add(fStatusLineItem); + fSourceViewer.getTextWidget().addMouseListener(getCursorListener()); + fSourceViewer.getTextWidget().addKeyListener(getCursorListener()); + + // Add a context menu to the detail area + createDetailContextMenu(fSourceViewer.getTextWidget()); + } + + /** + * Creates the actions to add to the context menu + */ + private void createActions() { + + TextViewerAction textAction= new TextViewerAction(fSourceViewer, ITextOperationTarget.SELECT_ALL); + textAction.configureAction(DetailMessages.DefaultDetailPane_Select__All_5, "", ""); //$NON-NLS-1$ //$NON-NLS-2$ + textAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.SELECT_ALL); + PlatformUI.getWorkbench().getHelpSystem().setHelp(textAction, IDebugHelpContextIds.DETAIL_PANE_SELECT_ALL_ACTION); + setAction(DETAIL_SELECT_ALL_ACTION, textAction); + + textAction= new TextViewerAction(fSourceViewer, ITextOperationTarget.COPY); + textAction.configureAction(DetailMessages.DefaultDetailPane__Copy_8, "", ""); //$NON-NLS-1$ //$NON-NLS-2$ + textAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.COPY); + PlatformUI.getWorkbench().getHelpSystem().setHelp(textAction, IDebugHelpContextIds.DETAIL_PANE_COPY_ACTION); + setAction(DETAIL_COPY_ACTION, textAction); + + setSelectionDependantAction(DETAIL_COPY_ACTION); + + updateSelectionDependentActions(); + + IAction action = new DetailPaneWordWrapAction(fSourceViewer); + setAction(DETAIL_WORD_WRAP_ACTION, action); + + action = new DetailPaneMaxLengthAction(fSourceViewer.getControl().getShell()); + setAction(DETAIL_MAX_LENGTH_ACTION,action); + } + + /** + * Create the context menu particular to the detail pane. Note that anyone + * wishing to contribute an action to this menu must use + * IDebugUIConstants.VARIABLE_VIEW_DETAIL_ID as the + * targetID in the extension XML. + */ + protected void createDetailContextMenu(Control menuControl) { + MenuManager menuMgr= new MenuManager(); + menuMgr.setRemoveAllWhenShown(true); + menuMgr.addMenuListener(new IMenuListener() { + public void menuAboutToShow(IMenuManager mgr) { + fillDetailContextMenu(mgr); + } + }); + Menu menu= menuMgr.createContextMenu(menuControl); + menuControl.setMenu(menu); + + getViewSite().registerContextMenu(IDebugUIConstants.VARIABLE_VIEW_DETAIL_ID, menuMgr, fSourceViewer.getSelectionProvider()); + } + + /** + * Adds items to the detail pane's context menu including any extension defined + * actions. + * + * @param menu The menu to add the item to. + */ + protected void fillDetailContextMenu(IMenuManager menu) { + + menu.add(new Separator(IDebugUIConstants.VARIABLE_GROUP)); + menu.add(new Separator()); + menu.add(getAction(DETAIL_COPY_ACTION)); + menu.add(getAction(DETAIL_SELECT_ALL_ACTION)); + menu.add(new Separator()); + menu.add(getAction(DETAIL_WORD_WRAP_ACTION)); + menu.add(getAction(DETAIL_MAX_LENGTH_ACTION)); + menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.IDetailPane#display(org.eclipse.jface.viewers.IStructuredSelection) + */ + public void display(IStructuredSelection selection) { + + if (selection == null){ + clearSourceViewer(); + return; + } + + fLastDisplayed = selection; + + if (selection.isEmpty()){ + clearSourceViewer(); + return; + } + + Object firstElement = selection.getFirstElement(); + if (firstElement != null && firstElement instanceof IDebugElement) { + String modelID = ((IDebugElement)firstElement).getModelIdentifier(); + setDebugModel(modelID); + } + + synchronized (this) { + if (fDetailJob != null) { + fDetailJob.cancel(); + } + fDetailJob = new DetailJob(selection); + fDetailJob.schedule(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.IDetailPane#setFocus() + */ + public boolean setFocus(){ + if (fSourceViewer != null){ + fSourceViewer.getTextWidget().setFocus(); + return true; + } + return false; + } + + /* + * + */ + public void dispose(){ + fActionMap.clear(); + fSelectionActions.clear(); + + if (fDetailJob != null) fDetailJob.cancel(); + if (fModelPresentation != null) fModelPresentation.dispose(); + fDebugModelIdentifier = null; // Setting this to null makes sure the source viewer is reconfigured with the model presentation after disposal + if (fSourceViewer != null && fSourceViewer.getControl() != null) fSourceViewer.getControl().dispose(); + + if (isInView()){ + disposeUndoRedoAction(ITextEditorActionConstants.UNDO); + disposeUndoRedoAction(ITextEditorActionConstants.REDO); + + getViewSite().getActionBars().getStatusLineManager().remove(fStatusLineItem); + + DebugUIPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this); + JFaceResources.getFontRegistry().removeListener(this); + } + } + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.IDetailPane#getDescription() + */ + public String getDescription() { + return DESCRIPTION; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.IDetailPane#getID() + */ + public String getID() { + return ID; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.IDetailPane#getName() + */ + public String getName() { + return NAME; + } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) + */ + @SuppressWarnings("unchecked") + public Object getAdapter(Class required) { + if (IFindReplaceTarget.class.equals(required)) { + return fSourceViewer.getFindReplaceTarget(); + } + if (ITextViewer.class.equals(required)) { + return fSourceViewer; + } + return null; + } + + /** + * Lazily instantiate and return a Document for the detail pane text viewer. + */ + protected IDocument getDetailDocument() { + if (fDetailDocument == null) { + fDetailDocument = new Document(); + } + return fDetailDocument; + } + + /** + * Clears the source viewer, removes all text. + */ + protected void clearSourceViewer(){ + if (fDetailJob != null) { + fDetailJob.cancel(); + } + fLastDisplayed = null; + fDetailDocument.set(""); //$NON-NLS-1$ + fSourceViewer.setEditable(false); + } + + /** + * Configures the details viewer for the debug model + * currently being displayed + */ + protected void configureDetailsViewer() { + LazyModelPresentation mp = (LazyModelPresentation)fModelPresentation.getPresentation(getDebugModel()); + SourceViewerConfiguration svc = null; + if (mp != null) { + try { + svc = mp.newDetailsViewerConfiguration(); + } catch (CoreException e) { + DebugUIPlugin.errorDialog(fSourceViewer.getControl().getShell(), DetailMessages.DefaultDetailPane_Error_1, DetailMessages.DefaultDetailPane_2, e); + } + } + + if (svc == null) { + svc = new SourceViewerConfiguration(); + fSourceViewer.setEditable(false); + } + fSourceViewer.unconfigure(); + fSourceViewer.configure(svc); + + if (isInView()){ + createUndoRedoActions(); + } + } + + /** + * @return The formatted string describing cursor position + */ + protected String getCursorPosition() { + + if (fSourceViewer == null) { + return ""; //$NON-NLS-1$ + } + + StyledText styledText= fSourceViewer.getTextWidget(); + int caret= styledText.getCaretOffset(); + IDocument document= fSourceViewer.getDocument(); + + if (document == null) { + return ""; //$NON-NLS-1$ + } + + try { + + int line= document.getLineOfOffset(caret); + + int lineOffset= document.getLineOffset(line); + int tabWidth= styledText.getTabs(); + int column= 0; + for (int i= lineOffset; i < caret; i++) + if ('\t' == document.getChar(i)) { + column += tabWidth - (tabWidth == 0 ? 0 : column % tabWidth); + } else { + column++; + } + + fLineLabel.fValue= line + 1; + fColumnLabel.fValue= column + 1; + return MessageFormat.format(fPositionLabelPattern, fPositionLabelPatternArguments); + + } catch (BadLocationException x) { + return ""; //$NON-NLS-1$ + } + } + + /** + * Returns this view's "cursor" listener to be installed on the view's + * associated details viewer. This listener is listening to key and mouse button events. + * It triggers the updating of the status line. + * + * @return the listener + */ + private ICursorListener getCursorListener() { + if (fCursorListener == null) { + fCursorListener= new ICursorListener() { + + public void keyPressed(KeyEvent e) { + fStatusLineItem.setText(getCursorPosition()); + } + + public void keyReleased(KeyEvent e) { + } + + public void mouseDoubleClick(MouseEvent e) { + } + + public void mouseDown(MouseEvent e) { + } + + public void mouseUp(MouseEvent e) { + fStatusLineItem.setText(getCursorPosition()); + } + }; + } + return fCursorListener; + } + + /** + * Returns the identifier of the debug model being displayed + * in this view, or null if none. + * + * @return debug model identifier + */ + protected String getDebugModel() { + return fDebugModelIdentifier; + } + + /** + * Sets the identifier of the debug model being displayed + * in this view, or null if none. + * + * @param id debug model identifier of the type of debug + * elements being displayed in this view + */ + protected void setDebugModel(String id) { + if (id != fDebugModelIdentifier) { + fDebugModelIdentifier = id; + configureDetailsViewer(); + } + } + + /** + * Creates this editor's undo/re-do actions. + *

    + * Subclasses may override or extend.

    + * + * @since 3.2 + */ + protected void createUndoRedoActions() { + disposeUndoRedoAction(ITextEditorActionConstants.UNDO); + disposeUndoRedoAction(ITextEditorActionConstants.REDO); + IUndoContext undoContext= getUndoContext(); + if (undoContext != null) { + // Use actions provided by global undo/re-do + + // Create the undo action + OperationHistoryActionHandler undoAction= new UndoActionHandler(getViewSite(), undoContext); + PlatformUI.getWorkbench().getHelpSystem().setHelp(undoAction, IAbstractTextEditorHelpContextIds.UNDO_ACTION); + undoAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.UNDO); + setAction(ITextEditorActionConstants.UNDO, undoAction); + setGlobalAction(ITextEditorActionConstants.UNDO, undoAction); + + // Create the re-do action. + OperationHistoryActionHandler redoAction= new RedoActionHandler(getViewSite(), undoContext); + PlatformUI.getWorkbench().getHelpSystem().setHelp(redoAction, IAbstractTextEditorHelpContextIds.REDO_ACTION); + redoAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.REDO); + setAction(ITextEditorActionConstants.REDO, redoAction); + setGlobalAction(ITextEditorActionConstants.REDO, redoAction); + + getViewSite().getActionBars().updateActionBars(); + } + } + + /** + * Disposes of the action with the specified ID + * + * @param actionId the ID of the action to disposed + */ + protected void disposeUndoRedoAction(String actionId) { + OperationHistoryActionHandler action = (OperationHistoryActionHandler) getAction(actionId); + if (action != null) { + action.dispose(); + setAction(actionId, null); + } + } + + /** + * Returns this editor's viewer's undo manager undo context. + * + * @return the undo context or null if not available + * @since 3.2 + */ + private IUndoContext getUndoContext() { + IUndoManager undoManager= fSourceViewer.getUndoManager(); + if (undoManager instanceof IUndoManagerExtension) + return ((IUndoManagerExtension)undoManager).getUndoContext(); + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent) + */ + public void propertyChange(PropertyChangeEvent event) { + String propertyName= event.getProperty(); + if (propertyName.equals(IInternalDebugUIConstants.DETAIL_PANE_FONT)) { + fSourceViewer.getTextWidget().setFont(JFaceResources.getFont(IInternalDebugUIConstants.DETAIL_PANE_FONT)); + } else if (propertyName.equals(IDebugUIConstants.PREF_MAX_DETAIL_LENGTH)) { + display(fLastDisplayed); + } else if (propertyName.equals(IDebugPreferenceConstants.PREF_DETAIL_PANE_WORD_WRAP)) { + fSourceViewer.getTextWidget().setWordWrap(DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IDebugPreferenceConstants.PREF_DETAIL_PANE_WORD_WRAP)); + getAction(DETAIL_WORD_WRAP_ACTION).setChecked(DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IDebugPreferenceConstants.PREF_DETAIL_PANE_WORD_WRAP)); + } + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPaneFactory.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPaneFactory.java new file mode 100644 index 00000000000..d35cec533cd --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPaneFactory.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Randy Rohrbach (Wind River Systems, Inc.) - initial implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel.detailpanesupport; + +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.debug.ui.IDetailPane; +import org.eclipse.debug.ui.IDetailPaneFactory; +import org.eclipse.jface.viewers.IStructuredSelection; + +/** + * This provides a simple Detail Pane Factory for the core debug views for DSF. + */ + +@SuppressWarnings("restriction") +public class DetailPaneFactory implements IDetailPaneFactory { + + public static final String DETAIL_PANE_ID = Messages.getString("DetailPaneFactory.0"); //$NON-NLS-1$ + public static final String DETAIL_PANE_NAME = Messages.getString("DetailPaneFactory.1"); //$NON-NLS-1$ + public static final String DETAIL_PANE_DESC = Messages.getString("DetailPaneFactory.2"); //$NON-NLS-1$ + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.views.variables.IDetailsFactory#createDetailsArea(java.lang.String) + */ + public IDetailPane createDetailPane(String id) { + return new DetailPane(); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.views.variables.IDetailsFactory#getDetailsTypes(org.eclipse.jface.viewers.IStructuredSelection) + */ + @SuppressWarnings("unchecked") + public Set getDetailPaneTypes(IStructuredSelection selection) { + Set possibleIDs = new HashSet(1); + possibleIDs.add(DETAIL_PANE_ID); + return possibleIDs; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.IDetailPaneFactory#getDefaultDetailPane(java.util.Set, org.eclipse.jface.viewers.IStructuredSelection) + */ + public String getDefaultDetailPane(IStructuredSelection selection) { + return DETAIL_PANE_ID; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.views.variables.IDetailsFactory#getName(java.lang.String) + */ + public String getDetailPaneName(String id) { + if (id.equals(DETAIL_PANE_ID)){ + return DETAIL_PANE_NAME; + } + return null; + } + + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.views.variables.IDetailsFactory#getDescription(java.lang.String) + */ + public String getDetailPaneDescription(String id) { + if (id.equals(DETAIL_PANE_ID)){ + return DETAIL_PANE_DESC; + } + return null; + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/Messages.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/Messages.java new file mode 100644 index 00000000000..5d278c057f6 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/Messages.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Randy Rohrbach (Wind River Systems, Inc.) - initial implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel.detailpanesupport; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +public class Messages { + private static final String BUNDLE_NAME = "org.eclipse.dd.dsf.debug.ui.viewmodel.detailpanesupport.messages"; //$NON-NLS-1$ + + private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle + .getBundle(BUNDLE_NAME); + + private Messages() { + } + + public static String getString(String key) { + try { + return RESOURCE_BUNDLE.getString(key); + } catch (MissingResourceException e) { + return '!' + key + '!'; + } + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/TextViewerAction.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/TextViewerAction.java new file mode 100644 index 00000000000..7cd6bafbc15 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/TextViewerAction.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2006, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Randy Rohrbach (Wind River Systems, Inc.) - extended implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel.detailpanesupport; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.text.ITextOperationTarget; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.ui.texteditor.IUpdate; + +/** + * Common function for actions that operate on a text viewer. + *

    + * Clients may subclass this class. + *

    + * @since 3.0 + */ +public class TextViewerAction extends Action implements IUpdate { + + private int fOperationCode= -1; + private ITextOperationTarget fOperationTarget; + + /** + * Constructs a new action in the given text viewer with + * the specified operation code. + * + * @param viewer + * @param operationCode + */ + public TextViewerAction(ITextViewer viewer, int operationCode) { + fOperationCode= operationCode; + fOperationTarget= viewer.getTextOperationTarget(); + update(); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IUpdate#update() + * + * Updates the enabled state of the action. + * Fires a property change if the enabled state changes. + * + * @see org.eclipse.jface.action.Action#firePropertyChange(String, Object, Object) + */ + public void update() { + + boolean wasEnabled= isEnabled(); + boolean isEnabled= (fOperationTarget != null && fOperationTarget.canDoOperation(fOperationCode)); + setEnabled(isEnabled); + + if (wasEnabled != isEnabled) { + firePropertyChange(ENABLED, wasEnabled ? Boolean.TRUE : Boolean.FALSE, isEnabled ? Boolean.TRUE : Boolean.FALSE); + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.action.IAction#run() + */ + @Override + public void run() { + if (fOperationCode != -1 && fOperationTarget != null) { + fOperationTarget.doOperation(fOperationCode); + } + } + + /** + * Configures this action with a label, tool tip, and description. + * + * @param text action label + * @param toolTipText action tool tip + * @param description action description + */ + public void configureAction(String text, String toolTipText, String description) { + setText(text); + setToolTipText(toolTipText); + setDescription(description); + } +} + diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/messages.properties b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/messages.properties new file mode 100644 index 00000000000..5d99640c01d --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/messages.properties @@ -0,0 +1,3 @@ +DetailPaneFactory.0=DSF Default Detail Pane +DetailPaneFactory.1=DSF Default Viewer +DetailPaneFactory.2=This is the default detail pane representation for DSF assisted views From 1c13dd4b56869c8806f170ee094e19a8272e5207 Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Tue, 31 Jul 2007 15:48:37 +0000 Subject: [PATCH 138/834] [[https://bugs.eclipse.org/bugs/show_bug.cgi?id=198422 ]] Bugzilla 198422. --- .../detailpanesupport/DetailPane.java | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPane.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPane.java index da6c3849eaf..c92ba8b1745 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPane.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPane.java @@ -328,21 +328,27 @@ public class DetailPane implements IDetailPane, IAdaptable, IPropertyChangeListe * * So here we specifically look for the service which knows how to deal * with the formatted data. + * + * Please note that the order or searching for the ancestor is important. + * A BitField Data Model Context will have a Register Data Model Context + * as its parent so if we search for a Register DMC first when we actually + * have a BitField DMC we will get the register and show the value of the + * register not the bit field. */ DsfServicesTracker tracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), ((DMVMContext) element).getDMC().getSessionId()); - IRegisterDMContext regDmc = DMContexts.getAncestorOfType(((DMVMContext) element).getDMC(), IRegisterDMContext.class); - - if ( regDmc != null ) { - dmc = regDmc ; + IBitFieldDMContext bitfieldDmc = DMContexts.getAncestorOfType(((DMVMContext) element).getDMC(), IBitFieldDMContext.class); + + if ( bitfieldDmc != null ) { + dmc = bitfieldDmc ; service = tracker.getService(IRegisters.class); } else { - IBitFieldDMContext bitfieldDmc = DMContexts.getAncestorOfType(((DMVMContext) element).getDMC(), IBitFieldDMContext.class); + IRegisterDMContext regDmc = DMContexts.getAncestorOfType(((DMVMContext) element).getDMC(), IRegisterDMContext.class); - if ( bitfieldDmc != null ) { - dmc = bitfieldDmc ; + if ( regDmc != null ) { + dmc = regDmc ; service = tracker.getService(IRegisters.class); } else { From 8a30df00b7f072d0dee959a893f4a88007aac63b Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Sun, 12 Aug 2007 03:57:50 +0000 Subject: [PATCH 139/834] Bugzilla 199662. --- .../update/actions/RefreshActionDelegate.java | 102 +++++++++++++++++- .../dm/AbstractDMVMProviderWithCache.java | 4 + 2 files changed, 102 insertions(+), 4 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshActionDelegate.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshActionDelegate.java index ac227900b5c..b3786a50a78 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshActionDelegate.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshActionDelegate.java @@ -11,25 +11,119 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.update.actions; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.dd.dsf.ui.viewmodel.IVMAdapter; +import org.eclipse.dd.dsf.ui.viewmodel.IVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProviderWithCache; import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer; import org.eclipse.debug.ui.AbstractDebugView; +import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.debug.ui.contexts.DebugContextEvent; +import org.eclipse.debug.ui.contexts.IDebugContextListener; import org.eclipse.jface.action.IAction; import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.Viewer; import org.eclipse.ui.IViewActionDelegate; import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IViewSite; @SuppressWarnings("restriction") -public class RefreshActionDelegate implements IViewActionDelegate { +public class RefreshActionDelegate implements IViewActionDelegate, IDebugContextListener { -protected IViewPart fView; + protected IViewPart fView = null; + private Object fViewInput = null; public void init(IViewPart view) { - fView = view; + /* + * Save the view information for later reference and data retrieval. + */ + fView = view; + + /* + * Get the current selection from the DebugView so we can determine if we want this menu action to be live or not. + */ + IViewSite site = (IViewSite) view.getSite(); + String combinedViewId = site.getId() + (site.getSecondaryId() != null ? (":" + site.getSecondaryId()) : ""); //$NON-NLS-1$ //$NON-NLS-2$ + + DebugUITools.getDebugContextManager().getContextService(view.getSite().getWorkbenchWindow()).addPostDebugContextListener(this, combinedViewId); + ISelection sel = DebugUITools.getDebugContextManager().getContextService(view.getSite().getWorkbenchWindow()).getActiveContext(); + + if ( sel instanceof IStructuredSelection ) { + /* + * Save the view selection as well so we can later determine if we want our action to be valid or not. + */ + fViewInput = ( (IStructuredSelection) sel ).getFirstElement(); + } } + + /* + * (non-Javadoc) + * @see org.eclipse.debug.ui.contexts.IDebugContextListener#debugContextChanged(org.eclipse.debug.ui.contexts.DebugContextEvent) + */ + public void debugContextChanged(DebugContextEvent event) { + /* + * This handler is called whenever a selection in the debug view is changed. So here is + * where we will know when we need to reenable the menu actions. + */ + ISelection sel = event.getContext(); + + if (sel instanceof IStructuredSelection) { + fViewInput = ((IStructuredSelection)sel).getFirstElement(); + } + } public void run(IAction action) { - VMCacheManager.getVMCacheManager().flush(getContext()); + /* + * Make sure we have a valid set of information. Otherwise we cannot go forward. + */ + if ( fView instanceof AbstractDebugView && fViewInput != null ) + { + Viewer viewer = ( (AbstractDebugView) fView).getViewer(); + + /* + * Now we need to make sure this is one of the Flexible Hierarchy viewws. + */ + if ( viewer instanceof TreeModelViewer ) { + /* + * Get the presentation context and see if there is a numeric property there. If so then this + * is a view implementation which supports changing the format. + */ + TreeModelViewer treeViewer = (TreeModelViewer) viewer; + IPresentationContext context = treeViewer.getPresentationContext(); + + /* + * Now go tell the view to update. We do so by finding the VM provider for this view + * and telling it to redraw the entire view. + */ + if (fViewInput instanceof IAdaptable) { + IVMAdapter adapter = (IVMAdapter) ((IAdaptable)fViewInput).getAdapter(IVMAdapter.class); + + if ( adapter != null ) { + IVMProvider provider = adapter.getVMProvider(context); + + if ( provider != null ) { + + if ( provider instanceof AbstractDMVMProviderWithCache ) { + AbstractDMVMProviderWithCache prov = (AbstractDMVMProviderWithCache) provider; + + prov.flush(); + return; + } + } + } + } + } + } + + /* + * As a fallback we will flush the cache without involving the provider if it for some + * reason does not measure up. + */ + + VMCacheManager.getVMCacheManager().flush(getContext()); } public void selectionChanged(IAction action, ISelection selection) { diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProviderWithCache.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProviderWithCache.java index be6e704df7e..09a13baf573 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProviderWithCache.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProviderWithCache.java @@ -45,6 +45,10 @@ public abstract class AbstractDMVMProviderWithCache extends AbstractDMVMProvider VMCacheManager.getVMCacheManager().addCacheListener(getPresentationContext(), this); } + + public void flush() { + VMCacheManager.getVMCacheManager().flush(getPresentationContext()); + } @Override public void update(IHasChildrenUpdate[] updates) { From 582657cf050d138f1b25cbbec890b0893f6f4a39 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 14 Aug 2007 23:08:11 +0000 Subject: [PATCH 140/834] [160046] Committed memory service patch from 7/27/07. --- .../dd/dsf/debug/model/DsfMemoryBlock.java | 209 ++++++--- .../debug/model/DsfMemoryBlockRetrieval.java | 399 +++++++++++------- .../eclipse/dd/dsf/debug/service/IMemory.java | 49 +-- 3 files changed, 422 insertions(+), 235 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java index dd5a55867a8..a6027c0bd0c 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java @@ -7,20 +7,26 @@ * * Contributors: * Wind River Systems - initial API and implementation - * Ericsson Communication - upgrade IF from IMemoryBlock to IMemoryBlockExtension + * Ericsson Communication - upgrade IF to IMemoryBlockExtension + * Ericsson Communication - added support for 64 bit processors *******************************************************************************/ package org.eclipse.dd.dsf.debug.model; import java.math.BigInteger; import java.util.concurrent.ExecutionException; +import java.util.concurrent.RejectedExecutionException; -import org.eclipse.cdt.utils.Addr32; import org.eclipse.core.runtime.PlatformObject; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.Query; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.debug.service.IMemory; +import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.IMemory.MemoryChangedEvent; +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; +import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.model.IDebugTarget; import org.eclipse.debug.core.model.IMemoryBlockExtension; @@ -28,34 +34,46 @@ import org.eclipse.debug.core.model.IMemoryBlockRetrieval; import org.eclipse.debug.core.model.MemoryByte; /** - * This class holds the memory block retrieved from the target as a result of - * a getBytes() or getBytesFromAddress() call from the platform. + * This class manages the memory block retrieved from the target as a result + * of a getBytesFromAddress() call from the platform. + * + * It performs its read/write functions using the MemoryService. */ -public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtension +public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtension { private final DsfMemoryBlockRetrieval fRetrieval; - private final String fModelId; - private final String fExpression; - private final long fStartAddress; - private final long fLength; - private final BigInteger fBaseAddress; - + private final String fModelId; + private final String fExpression; + private final BigInteger fStartAddress; + private BigInteger fEndAddress; + private long fLength = 0; + /** - * Constructor + * Constructor. * - * @param retrieval - * @param modelId - * @param expression - * @param startAddress - * @param length + * @param retrieval - the MemoryBlockRetrieval (session context) + * @param modelId - + * @param expression - the displayed expression + * @param startAddress - the actual memory block start address + * @param length - the memory block length (could be 0) */ - DsfMemoryBlock(DsfMemoryBlockRetrieval retrieval, String modelId, String expression, long startAddress, long length) { - fRetrieval = retrieval; - fModelId = modelId; - fExpression = expression; + DsfMemoryBlock(DsfMemoryBlockRetrieval retrieval, String modelId, String expression, BigInteger startAddress, long length) { + fRetrieval = retrieval; + fModelId = modelId; + fExpression = expression; fStartAddress = startAddress; - fBaseAddress = new BigInteger(Long.toString(startAddress)); - fLength = length; + fEndAddress = startAddress.add(BigInteger.valueOf(length)); + fLength = length; + + try { + fRetrieval.getExecutor().execute(new Runnable() { + public void run() { + fRetrieval.getSession().addServiceEventListener(DsfMemoryBlock.this, null); + } + }); + } catch(RejectedExecutionException e) { + // Session is shut down. + } } // //////////////////////////////////////////////////////////////////////// @@ -65,7 +83,8 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens /* (non-Javadoc) * @see org.eclipse.core.runtime.PlatformObject#getAdapter(java.lang.Class) */ - @Override + @SuppressWarnings("unchecked") + @Override public Object getAdapter(Class adapter) { if (adapter.isAssignableFrom(DsfMemoryBlockRetrieval.class)) { return fRetrieval; @@ -81,6 +100,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens * @see org.eclipse.debug.core.model.IDebugElement#getDebugTarget() */ public IDebugTarget getDebugTarget() { + // FRCH: return fRetrieval.getDebugTarget(); return null; } @@ -95,6 +115,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens * @see org.eclipse.debug.core.model.IDebugElement#getLaunch() */ public ILaunch getLaunch() { + // FRCH: return fRetrieval.getDebugTarget().getLaunch(); return null; } @@ -106,13 +127,20 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens * @see org.eclipse.debug.core.model.IMemoryBlock#getStartAddress() */ public long getStartAddress() { - return fStartAddress; + // Warning: doesn't support 64-bit addresses + long address = fStartAddress.longValue(); + if (fStartAddress.equals(BigInteger.valueOf(address))) + return address; + + // FRCH: Should we throw an exception instead? + return 0; } /* (non-Javadoc) * @see org.eclipse.debug.core.model.IMemoryBlock#getLength() */ public long getLength() { + // Warning: could return 0 return fLength; } @@ -124,7 +152,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens int length = block.length; byte[] bytes = new byte[length]; // Extract bytes from MemoryBytes - for (int i = 0; i < length; i++) + for (int i : bytes) bytes[i] = block[i].getValue(); return bytes; } @@ -140,7 +168,10 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens * @see org.eclipse.debug.core.model.IMemoryBlock#setValue(long, byte[]) */ public void setValue(long offset, byte[] bytes) throws DebugException { - setValue(BigInteger.valueOf(offset), bytes); + if (offset <= Integer.MAX_VALUE) + writeMemoryBlock((int) offset, bytes); + + // FRCH: Should we throw an exception if offset is too large? } // //////////////////////////////////////////////////////////////////////// @@ -158,13 +189,14 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens * @see org.eclipse.debug.core.model.IMemoryBlockExtension#getBigBaseAddress() */ public BigInteger getBigBaseAddress() throws DebugException { - return fBaseAddress; + return fStartAddress; } /* (non-Javadoc) * @see org.eclipse.debug.core.model.IMemoryBlockExtension#getMemoryBlockStartAddress() */ public BigInteger getMemoryBlockStartAddress() throws DebugException { + // "null" indicates that memory can be retrieved at addresses lower than the block base address return null; } @@ -172,6 +204,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens * @see org.eclipse.debug.core.model.IMemoryBlockExtension#getMemoryBlockEndAddress() */ public BigInteger getMemoryBlockEndAddress() throws DebugException { + // "null" indicates that memory can be retrieved at addresses higher the block base address return null; } @@ -179,15 +212,15 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens * @see org.eclipse.debug.core.model.IMemoryBlockExtension#getBigLength() */ public BigInteger getBigLength() throws DebugException { - return null; + // -1 indicates that memory block is unbounded + return BigInteger.ONE.negate(); } /* (non-Javadoc) * @see org.eclipse.debug.core.model.IMemoryBlockExtension#getAddressSize() */ public int getAddressSize() throws DebugException { - // TODO: Have the service make a trip to the back-end and - // retrieve/store that information for us + // FRCH: return fRetrieval.getDebugTarget().getAddressSize(); return 4; } @@ -195,14 +228,14 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens * @see org.eclipse.debug.core.model.IMemoryBlockExtension#supportBaseAddressModification() */ public boolean supportBaseAddressModification() throws DebugException { - return true; + return false; } /* (non-Javadoc) * @see org.eclipse.debug.core.model.IMemoryBlockExtension#supportsChangeManagement() */ public boolean supportsChangeManagement() { - return true; + return false; } /* (non-Javadoc) @@ -215,23 +248,29 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens /* (non-Javadoc) * @see org.eclipse.debug.core.model.IMemoryBlockExtension#getBytesFromOffset(java.math.BigInteger, long) */ - public MemoryByte[] getBytesFromOffset(BigInteger unitOffset, long addressableUnits) throws DebugException { - // TODO Auto-generated method stub - return null; + public MemoryByte[] getBytesFromOffset(BigInteger offset, long units) throws DebugException { + return getBytesFromAddress(fStartAddress.add(offset), units); } /* (non-Javadoc) * @see org.eclipse.debug.core.model.IMemoryBlockExtension#getBytesFromAddress(java.math.BigInteger, long) */ public MemoryByte[] getBytesFromAddress(BigInteger address, long units) throws DebugException { - return fetchMemoryBlock(address.longValue(), units); + fLength = units; + fEndAddress = fStartAddress.add(BigInteger.valueOf(units)); + return fetchMemoryBlock(address, units); } /* (non-Javadoc) * @see org.eclipse.debug.core.model.IMemoryBlockExtension#setValue(java.math.BigInteger, byte[]) */ public void setValue(BigInteger offset, byte[] bytes) throws DebugException { - // TODO Auto-generated method stub + // Ensure that the offset can be cast into an int + int offs = offset.intValue(); + if (offset.equals(BigInteger.valueOf(offs))) + writeMemoryBlock(offs, bytes); + + // FRCH: Should we throw an exception if offset is too large? } /* (non-Javadoc) @@ -260,7 +299,15 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens * @see org.eclipse.debug.core.model.IMemoryBlockExtension#dispose() */ public void dispose() throws DebugException { - // TODO Auto-generated method stub + try { + fRetrieval.getExecutor().execute(new Runnable() { + public void run() { + fRetrieval.getSession().removeServiceEventListener(DsfMemoryBlock.this); + } + }); + } catch(RejectedExecutionException e) { + // Session is shut down. + } } /* (non-Javadoc) @@ -274,8 +321,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens * @see org.eclipse.debug.core.model.IMemoryBlockExtension#getAddressableSize() */ public int getAddressableSize() throws DebugException { - // TODO: Have the service make a trip to the back-end and - // retrieve/store that information for us + // FRCH: return fRetrieval.getDebugTarget().getAddressableSize(); return 1; } @@ -283,25 +329,25 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens // Helper functions // //////////////////////////////////////////////////////////////////////// - /* The real thing. Since the original call is synchronous (from a platform Job), - * we use a Query that will patiently wait for the underlying asynchronous calls - * to complete before returning. - * - * @param address - * @param length - * @return MemoryBytes[] - * @throws DebugException - */ - private MemoryByte[] fetchMemoryBlock(final long address, final long length) throws DebugException { + /* + * The real thing. Since the original call is synchronous (from a platform + * Job), we use a Query that will patiently wait for the underlying + * asynchronous calls to complete before returning. + * + * @param address @param length @return MemoryByte[] @throws DebugException + */ + private MemoryByte[] fetchMemoryBlock(final BigInteger address, final long length) throws DebugException { - /* For this first implementation, we make a few simplifying assumptions: + /* FRCH: Fix the loose ends... + * + * For this first implementation, we make a few simplifying assumptions: * - word_size = 1 (we want to read individual bytes) - * - offset = 0 - * - mode = hexadecimal (will be overridden in getMemory() anyway) + * - offset = 0 + * - mode = 0 (will be overridden in getMemory() anyway) */ final int word_size = 1; - final int offset = 0; - final int mode = 0; // TODO: Add a constant for hexadecimal mode + final int offset = 0; + final int mode = 0; // Use a Query to "synchronize" the inherently asynchronous downstream calls Query query = new Query() { @@ -313,7 +359,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens final MemoryByte[] buffer = new MemoryByte[(int) length]; // Go for it memoryService.getMemory( - fRetrieval.getContext(), new Addr32(address), word_size, buffer, offset, (int) length, mode, + fRetrieval.getContext(), address, word_size, buffer, offset, (int) length, mode, new RequestMonitor(fRetrieval.getExecutor(), rm) { @Override protected void handleOK() { @@ -334,4 +380,53 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens return null; } + @DsfServiceEventHandler + public void eventDispatched(MemoryChangedEvent e) { + handleMemoryChange(e.getAddress()); + } + + @DsfServiceEventHandler + public void eventDispatched(IRunControl.ISuspendedDMEvent e) { + handleMemoryChange(BigInteger.ZERO); + } + + /* Writes an array of bytes to memory. + * + * @param offset + * @param bytes + * @throws DebugException + */ + private void writeMemoryBlock(final int offset, final byte[] bytes) throws DebugException { + + final int word_size = 1; + final int mode = 0; + + IMemory memoryService = (IMemory) fRetrieval.getServiceTracker().getService(); + if (memoryService != null) { + memoryService.setMemory( + fRetrieval.getContext(), fStartAddress, word_size, bytes, offset, bytes.length, mode, + new RequestMonitor(fRetrieval.getExecutor(), null) { + @Override + protected void handleOK() { + handleMemoryChange(fStartAddress); + } + }); + } + } + + /** + * @param address + * @param length + */ + public void handleMemoryChange(BigInteger address) { + // Check if the change affects this particular block (0 is universal) + if (address.equals(BigInteger.ZERO) || + ((fStartAddress.compareTo(address) != 1) && (fEndAddress.compareTo(address) == 1))) + { + // Notify the event listeners + DebugEvent debugEvent = new DebugEvent(this, DebugEvent.CHANGE, DebugEvent.CONTENT); + DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { debugEvent }); + } + } + } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java index 41574b32b49..f759650742a 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java @@ -7,17 +7,32 @@ * * Contributors: * Wind River Systems - initial API and implementation - * Ericsson Communication - upgrade IF from IMemoryBlockRetrieval to IMemoryBlockRetrievalExtension + * Ericsson Communication - upgrade IF to IMemoryBlockRetrievalExtension + * Ericsson Communication - added Expression evaluation + * Ericsson Communication - added support for 64 bit processors + * Ericsson Communication - added support for event handling *******************************************************************************/ package org.eclipse.dd.dsf.debug.model; +import java.math.BigInteger; +import java.util.concurrent.ExecutionException; + +import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.PlatformObject; import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.Query; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.debug.DsfDebugPlugin; +import org.eclipse.dd.dsf.debug.service.IExpressions; +import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.dd.dsf.debug.service.IMemory; +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMData; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.debug.core.DebugException; @@ -30,79 +45,103 @@ import org.osgi.util.tracker.ServiceTracker; /** * Implementation of memory access API of the Eclipse standard debug model. - * - * The IMemoryBlockRetrievalExtension is implemented for the reference - * application. This will result in getExtendedMemoryBlock() being called - * when a memory block is selected from the memory pane. + * + * The DsfMemoryBlockRetrieval is not an actual memory block but rather a + * reference to the memory address space for an execution context (e.g. a + * process) within a debug session. From this debug 'context', memory blocks + * can then be read/written. + * + * Note: For the reference application, The IMemoryBlockRetrievalExtension + * is implemented. This will result in getExtendedMemoryBlock() being called + * when a memory block is selected from the platform memory pane. * * However, if the 'simpler' IMemoryBlockRetrieval is to be implemented, the - * code will still be functional after trivial adjustments. In that case, the - * platform will call getMemoryBlock() instead. Note that DsfMemoryBlock will - * have to be 'downgraded' to implement IMemoryBlock (instead of IMemoryBlockExtension) + * code will still be functional after some trivial adjustments. * */ -public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBlockRetrievalExtension +public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBlockRetrievalExtension { - private final String fModelId; - private final DsfSession fSession; - private final DsfExecutor fExecutor; - private final IDMContext fContext; - private final ServiceTracker fServiceTracker; - - /** - * Constructor - * - * @param modelId - * @param dmc - * @throws DebugException - */ - public DsfMemoryBlockRetrieval(String modelId, IDMContext dmc) throws DebugException { - fModelId = modelId; - fContext = dmc; - fSession = DsfSession.getSession(fContext.getSessionId()); - if (fSession == null) { - throw new IllegalArgumentException("Session for context " + fContext + " is not active"); //$NON-NLS-1$ //$NON-NLS-2$ - } - fExecutor = fSession.getExecutor(); - String memoryServiceFilter = - "(&" + //$NON-NLS-1$ - "(OBJECTCLASS=" + IMemory.class.getName() + ")" + //$NON-NLS-1$//$NON-NLS-2$ - "(" + IDsfService.PROP_SESSION_ID + "=" + dmc.getSessionId() + ")" + //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ - ")"; //$NON-NLS-1$ - BundleContext bundle = DsfDebugPlugin.getBundleContext(); - try { - fServiceTracker = new ServiceTracker(bundle, bundle.createFilter(memoryServiceFilter), null); - } catch (InvalidSyntaxException e) { - throw new DebugException(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, "Error creating service filter.", e)); //$NON-NLS-1$ - } - fServiceTracker.open(); - } + private final String fModelId; + private final DsfSession fSession; + private final DsfExecutor fExecutor; + private IDMContext fContext; + private final ServiceTracker fMemoryServiceTracker; + private final ServiceTracker fExpressionServiceTracker; - // //////////////////////////////////////////////////////////////////////// - // Accessors - // //////////////////////////////////////////////////////////////////////// - /** + * Constructor * - * @return + * @param modelId + * @param dmc + * @throws DebugException */ - public String getModelId() { - return fModelId; + public DsfMemoryBlockRetrieval(String modelId, IDMContext dmc) throws DebugException { + + fModelId = modelId; + fContext = dmc; + fSession = DsfSession.getSession(fContext.getSessionId()); + if (fSession == null) { + throw new IllegalArgumentException( + "Session for context " + fContext + " is not active"); //$NON-NLS-1$ //$NON-NLS-2$ + } + fExecutor = fSession.getExecutor(); + BundleContext bundle = DsfDebugPlugin.getBundleContext(); + + // Here we chose to use 2 distinct service trackers instead of an + // amalgamated one because it is less error prone (and we are lazy). + + // Create a tracker for the MemoryService + String memoryServiceFilter = "(&" + //$NON-NLS-1$ + "(OBJECTCLASS=" //$NON-NLS-1$ + + IMemory.class.getName() + + ")" + //$NON-NLS-1$ + "(" + IDsfService.PROP_SESSION_ID //$NON-NLS-1$ + + "=" + dmc.getSessionId() + ")" + //$NON-NLS-1$//$NON-NLS-2$ + ")"; //$NON-NLS-1$ + + try { + fMemoryServiceTracker = new ServiceTracker( + bundle, bundle.createFilter(memoryServiceFilter), null); + } catch (InvalidSyntaxException e) { + throw new DebugException(new Status(IStatus.ERROR, + DsfDebugPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, + "Error creating service filter.", e)); //$NON-NLS-1$ + } + fMemoryServiceTracker.open(); + + // Create a tracker for the ExpressionService + String expressionServiceFilter = "(&" + //$NON-NLS-1$ + "(OBJECTCLASS=" //$NON-NLS-1$ + + IExpressions.class.getName() + + ")" + //$NON-NLS-1$ + "(" + IDsfService.PROP_SESSION_ID //$NON-NLS-1$ + + "=" + dmc.getSessionId() + ")" + //$NON-NLS-1$//$NON-NLS-2$ + ")"; //$NON-NLS-1$ + + try { + fExpressionServiceTracker = new ServiceTracker( + bundle, bundle.createFilter(expressionServiceFilter), null); + } catch (InvalidSyntaxException e) { + throw new DebugException(new Status(IStatus.ERROR, + DsfDebugPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, + "Error creating service filter.", e)); //$NON-NLS-1$ + } + fExpressionServiceTracker.open(); } - /** - * - * @return - */ - public DsfSession getSession() { - return fSession; - } + // //////////////////////////////////////////////////////////////////////// + // Accessors + // //////////////////////////////////////////////////////////////////////// + public DsfSession getSession() { + return fSession; + } + /** * * @return */ - public DsfExecutor getExecutor() { + public DsfExecutor getExecutor() { return fExecutor; } @@ -110,121 +149,177 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl * * @return */ - public IDMContext getContext() { + public IDMContext getContext() { return fContext; } - /** + /** * * @return */ - public ServiceTracker getServiceTracker() { - return fServiceTracker; + public ServiceTracker getServiceTracker() { + return fMemoryServiceTracker; } - // //////////////////////////////////////////////////////////////////////// - // IMemoryBlockRetrieval - obsoleted by IMemoryBlockRetrievalExtension - // //////////////////////////////////////////////////////////////////////// - - /* - * (non-Javadoc) - * @see org.eclipse.debug.core.model.IMemoryBlockRetrieval#supportsStorageRetrieval() - */ - public boolean supportsStorageRetrieval() { - return true; - } + // //////////////////////////////////////////////////////////////////////// + // IMemoryBlockRetrieval - obsoleted by IMemoryBlockRetrievalExtension + // //////////////////////////////////////////////////////////////////////// - /* - * (non-Javadoc) - * @see org.eclipse.debug.core.model.IMemoryBlockRetrieval#getMemoryBlock(long, long) - */ - public IMemoryBlock getMemoryBlock(final long startAddress, final long length) throws DebugException { - // The expression to display in the rendering tab - // Put here for the sake of completeness (not used with IMemoryBlock) - String expression = "0x" + Long.toHexString(startAddress); //$NON-NLS-1$ - return new DsfMemoryBlock(DsfMemoryBlockRetrieval.this, fModelId, expression, startAddress, length); - } - - // //////////////////////////////////////////////////////////////////////// - // IMemoryBlockRetrievalExtension - // //////////////////////////////////////////////////////////////////////// - - /* + /* * (non-Javadoc) - * @see org.eclipse.debug.core.model.IMemoryBlockRetrievalExtension#getExtendedMemoryBlock(java.lang.String, java.lang.Object) + * + * @see org.eclipse.debug.core.model.IMemoryBlockRetrieval#supportsStorageRetrieval() */ - public IMemoryBlockExtension getExtendedMemoryBlock(String expression, Object context) throws DebugException { + public boolean supportsStorageRetrieval() { + return true; + } - boolean validAddress = false; - long address = 0; + /* + * (non-Javadoc) + * + * @see org.eclipse.debug.core.model.IMemoryBlockRetrieval#getMemoryBlock(long, + * long) + */ + public IMemoryBlock getMemoryBlock(final long startAddress, final long length) throws DebugException { + // The expression to display in the rendering tab + // Put here for the sake of completeness (not used with IMemoryBlockExtension) + String expression = "0x" + Long.toHexString(startAddress); //$NON-NLS-1$ + return new DsfMemoryBlock(this, fModelId, expression, BigInteger.valueOf(startAddress), length); + } - /* See if the expression is a simple numeric value; if it is, we can - * avoid some costly processing (calling the back-end to resolve the - * expression and obtain an address) - */ - try { - // First, assume a decimal address (not too realistic but bear with us :-) - int base = 10; - int offset = 0; + // //////////////////////////////////////////////////////////////////////// + // IMemoryBlockRetrievalExtension + // //////////////////////////////////////////////////////////////////////// - // Check for "hexadecimality" - if (expression.startsWith("0x") || expression.startsWith("0X")) { //$NON-NLS-1$//$NON-NLS-2$ - base = 16; - offset = 2; - } + /* + * (non-Javadoc) + * + * @see org.eclipse.debug.core.model.IMemoryBlockRetrievalExtension#getExtendedMemoryBlock(java.lang.String, + * java.lang.Object) + */ + @SuppressWarnings("unchecked") + public IMemoryBlockExtension getExtendedMemoryBlock(String expression, Object context) throws DebugException { - // Now, try to parse the expression. If a NumberFormatException is thrown, - // then it wasn't a simple numerical expression and we go to plan B - address = Long.parseLong(expression.substring(offset), base); + // The block start address (supports 64-bit processors) + BigInteger blockAddress; - // All right! We saved a trip to the back-end. - validAddress = true; + /* + * See if the expression is a simple numeric value; if it is, we can + * avoid some costly processing (calling the back-end to resolve the + * expression and obtain an address) + */ + try { + // First, assume a decimal address + int base = 10; + int offset = 0; - } catch (NumberFormatException nfexc) { - // OK, expression is not a simple, absolute numeric value; try to resolve as expression - } + // Check for "hexadecimality" + if (expression.startsWith("0x") || expression.startsWith("0X")) { //$NON-NLS-1$//$NON-NLS-2$ + base = 16; + offset = 2; + } + // Check for "octality" + else if (expression.startsWith("0")) { //$NON-NLS-1$ + base = 8; + offset = 1; + } - // We have to ask the debugger to resolve the address for us - if (!validAddress) { - // [frch] Code removed until we properly hook the ExpressionService - // [frch] Code saved in lmcfrch-memory-070625.PATCH - return null; - } + // Now, try to parse the expression. If a NumberFormatException is + // thrown, then it wasn't a simple numerical expression and we go + // to plan B (attempt an expression evaluation) + blockAddress = new BigInteger(expression.substring(offset), base); - /* At this point, we only know the requested address and we have no - * idea of the memory block length. The renderer will provide this - * information when it calls getBytesFromAddress() i.e. after the - * memory block holder has been instantiated... - * - * We could try to out-smart the renderer and do some educated guess - * about the start address it will select and the length it will - * request. - * - * This would 'work' for the standard debug renderers: start address - * on a 16-byte boundary, length of 320 bytes (20 lines of 16 bytes). - * However, this is not such a great idea: a given renderer might ask - * for a block starting at any address adn length it sees fit. Therefore - * we can't make any assumption. - * - * The only safe approach is to just instantiate the IMemoryBlockExtension - * and postpone the actual memory fetch until the renderer explicitly - * asks for it (i.e. calls getBytesFromAddress()). - * - * The down side is that every time we switch renderer, for the same block, - * a trip to the target could result. - * - * However, we have an ace in our sleeve: the memory request cache should - * save us a trip to the back-end. - */ + } catch (NumberFormatException nfexc) { + // OK, expression is not a simple, absolute numeric value; + // try to resolve as an expression. + // In case of failure, simply return 'null' - return new DsfMemoryBlock(DsfMemoryBlockRetrieval.this, fModelId, expression, address, 0); - } + // Drill for the actual DMC + IDMContext dmc = null; + if (context instanceof IAdaptable) { + dmc = (IDMContext)((IAdaptable)context).getAdapter(IDMContext.class); + } - // //////////////////////////////////////////////////////////////////////// - // Helper functions - // //////////////////////////////////////////////////////////////////////// + if (dmc == null) { + return null; + } + // Update the DMC + fContext = dmc; - // [frch] Code removed until we properly hook the ExpressionService - // [frch] Code saved in lmcfrch-memory-070625.PATCH + // Resolve the expression + blockAddress = resolveMemoryAddress(fContext, expression); + if (blockAddress == null) + return null; + } + + /* + * At this point, we only resolved the requested memory block + * start address and we have no idea of the block's length. + * + * The renderer will provide this information when it calls + * getBytesFromAddress() i.e. after the memory block holder has + * been instantiated. + * + * The down side is that every time we switch renderer, for the + * same memory block, a trip to the target could result. However, + * the memory request cache should save the day. + */ + + return new DsfMemoryBlock(this, fModelId, expression, blockAddress, 0); + } + + // //////////////////////////////////////////////////////////////////////// + // Helper functions + // //////////////////////////////////////////////////////////////////////// + + private BigInteger resolveMemoryAddress(final IDMContext idmContext, final String expression) throws DebugException { + + // Use a Query to "synchronize" the inherently asynchronous downstream calls + Query query = new Query() { + @Override + protected void execute(final DataRequestMonitor rm) { + // Lookup for the ExpressionService + final IExpressions expressionService = (IExpressions) fExpressionServiceTracker.getService(); + if (expressionService != null) { + // Create the expression + final IExpressionDMContext expressionDMC = expressionService.createExpression(idmContext, expression); + expressionService.getModelData(expressionDMC, new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + // Evaluate the expression - request HEX since it works in every case + String formatId = IFormattedValues.HEX_FORMAT; + FormattedValueDMContext valueDmc = expressionService.getFormattedValue(expressionDMC, formatId); + expressionService.getModelData( + valueDmc, + new DataRequestMonitor(getExecutor(), null) { + @Override + protected void handleOK() { + // Store the result + FormattedValueDMData data = getData(); + if (data.isValid()) { + String value = data.getFormattedValue().substring(2); // Strip the "0x" + rm.setData(new BigInteger(value, 16)); + } + rm.done(); + } + } + ); + } + }); + } + + } + }; + fExecutor.execute(query); + try { + // The happy case + return query.get(); + } catch (InterruptedException e) { + } catch (ExecutionException e) { + } + + // The error case + return null; + } } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java index d1ac1282c8f..c38dd7851d0 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java @@ -8,10 +8,12 @@ * Contributors: * Wind River Systems - initial API and implementation * Ericsson Communication - extended the API for IMemoryBlockExtension + * Ericsson Communication - added support for 64 bit processors *******************************************************************************/ package org.eclipse.dd.dsf.debug.service; -import org.eclipse.cdt.core.IAddress; +import java.math.BigInteger; + import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.service.IDsfService; @@ -24,13 +26,26 @@ import org.eclipse.debug.core.model.MemoryByte; */ public interface IMemory extends IDsfService { - /** Writes the given value to the given memory location. */ - public void setMemory(IDMContext ctx, IAddress addr, - int word_size, byte[] buf, int offs, int size, int mode, RequestMonitor requestMonitor); + public class MemoryChangedEvent { + BigInteger fAddress; + public MemoryChangedEvent(BigInteger address) { + fAddress = address; + } + + public BigInteger getAddress() { + return fAddress; + } + } + + /** Reads memory at the given location */ - public void getMemory(IDMContext ctx, IAddress addr, - int word_size, byte[] buf, int offs, int size, int mode, RequestMonitor requestMonitor); + public void getMemory(IDMContext ctx, BigInteger addr, + int word_size, MemoryByte[] buf, int offs, int size, int mode, RequestMonitor rm); + + /** Writes the given value to the given memory location. */ + public void setMemory(IDMContext ctx, BigInteger addr, + int word_size, byte[] buf, int offs, int size, int mode, RequestMonitor rm); /** * Fill target memory with given pattern. @@ -38,25 +53,7 @@ public interface IMemory extends IDsfService { * Parameter 0 of sequent 'done' is assigned with Throwable if * there was an error. */ - public void fillMemory(IDMContext ctx, IAddress addr, - int word_size, byte[] value, int size, int mode, RequestMonitor requestMonitor); + public void fillMemory(IDMContext ctx, BigInteger addr, + int word_size, byte[] value, int size, int mode, RequestMonitor rm); - // //////////////////////////////////////////////////////////////////////// - // Replicated the base functions to support IMemoryBlockExtension - // //////////////////////////////////////////////////////////////////////// - - /** Writes the given value to the given memory location. */ - public void setMemory(IDMContext ctx, IAddress addr, - int word_size, MemoryByte[] buf, int offs, int size, int mode, RequestMonitor requestMonitor); - - /** Reads memory at the given location */ - public void getMemory(IDMContext ctx, IAddress addr, - int word_size, MemoryByte[] buf, int offs, int size, int mode, RequestMonitor requestMonitor); - - public void fillMemory(IDMContext ctx, IAddress addr, - int word_size, MemoryByte[] value, int size, int mode, RequestMonitor requestMonitor); - -// /** Reads memory at the given location */ -// public void resolveMemoryAddress(IDMContext ctx, String expression, BigInteger[] address, RequestMonitor requestMonitor); - } From 6acfb42d4a39a4c5d9e2a14fb29b3a485de7aaaf Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Tue, 14 Aug 2007 23:29:33 +0000 Subject: [PATCH 141/834] 159683 --- .../update/VMCacheRefreshAlways.java | 10 ++++++++ .../update/VMCacheRefreshManual.java | 10 ++++++++ .../update/VMCacheRefreshOnBreak.java | 10 ++++++++ .../actions/RefreshAlwaysActionDelegate.java | 3 ++- .../actions/RefreshManualActionDelegate.java | 3 ++- .../actions/RefreshOnBreakActionDelegate.java | 3 ++- .../dd/dsf/ui/viewmodel/update/VMCache.java | 24 +++++++++++++++++++ 7 files changed, 60 insertions(+), 3 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshAlways.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshAlways.java index 676048a8fcd..a5f8070440c 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshAlways.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshAlways.java @@ -17,6 +17,16 @@ import org.eclipse.dd.dsf.ui.viewmodel.update.VMCache; public class VMCacheRefreshAlways extends VMCache { + public VMCacheRefreshAlways() + { + super(); + } + + public VMCacheRefreshAlways(VMCache oldCache) + { + super(oldCache); + } + @SuppressWarnings("unchecked") @Override public void handleEvent(IDMEvent event) { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshManual.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshManual.java index 8d707b517d7..86a1723fb2d 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshManual.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshManual.java @@ -16,6 +16,16 @@ import org.eclipse.dd.dsf.ui.viewmodel.update.VMCache; public class VMCacheRefreshManual extends VMCache { + public VMCacheRefreshManual() + { + super(); + } + + public VMCacheRefreshManual(VMCache oldCache) + { + super(oldCache); + } + @SuppressWarnings("unchecked") @Override public void handleEvent(IDMEvent event) {} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshOnBreak.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshOnBreak.java index a1cdc3b6160..9819ea70a8c 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshOnBreak.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshOnBreak.java @@ -18,6 +18,16 @@ import org.eclipse.dd.dsf.ui.viewmodel.update.VMCache; public class VMCacheRefreshOnBreak extends VMCache { + public VMCacheRefreshOnBreak() + { + super(); + } + + public VMCacheRefreshOnBreak(VMCache oldCache) + { + super(oldCache); + } + @SuppressWarnings("unchecked") @Override public void handleEvent(IDMEvent event) { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshAlwaysActionDelegate.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshAlwaysActionDelegate.java index 7ad9dbb6278..2631f78607e 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshAlwaysActionDelegate.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshAlwaysActionDelegate.java @@ -13,6 +13,7 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.update.actions; import org.eclipse.dd.dsf.debug.ui.viewmodel.update.VMCacheRefreshAlways; import org.eclipse.dd.dsf.ui.viewmodel.update.VMCache; +import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager; import org.eclipse.dd.dsf.ui.viewmodel.update.actions.AbstractRefreshActionDelegate; import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer; import org.eclipse.debug.ui.AbstractDebugView; @@ -29,6 +30,6 @@ public class RefreshAlwaysActionDelegate extends AbstractRefreshActionDelegate @Override public VMCache createCache() { - return new VMCacheRefreshAlways(); + return new VMCacheRefreshAlways(VMCacheManager.getVMCacheManager().getCache(getContext())); } } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshManualActionDelegate.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshManualActionDelegate.java index 5a70cb5bac6..7aabf2e3197 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshManualActionDelegate.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshManualActionDelegate.java @@ -13,6 +13,7 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.update.actions; import org.eclipse.dd.dsf.debug.ui.viewmodel.update.VMCacheRefreshManual; import org.eclipse.dd.dsf.ui.viewmodel.update.VMCache; +import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager; import org.eclipse.dd.dsf.ui.viewmodel.update.actions.AbstractRefreshActionDelegate; import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer; import org.eclipse.debug.ui.AbstractDebugView; @@ -29,6 +30,6 @@ public class RefreshManualActionDelegate extends AbstractRefreshActionDelegate @Override public VMCache createCache() { - return new VMCacheRefreshManual(); + return new VMCacheRefreshManual(VMCacheManager.getVMCacheManager().getCache(getContext())); } } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshOnBreakActionDelegate.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshOnBreakActionDelegate.java index 21addc0a634..b6eda44fc0b 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshOnBreakActionDelegate.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshOnBreakActionDelegate.java @@ -13,6 +13,7 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.update.actions; import org.eclipse.dd.dsf.debug.ui.viewmodel.update.VMCacheRefreshOnBreak; import org.eclipse.dd.dsf.ui.viewmodel.update.VMCache; +import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager; import org.eclipse.dd.dsf.ui.viewmodel.update.actions.AbstractRefreshActionDelegate; import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer; import org.eclipse.debug.ui.AbstractDebugView; @@ -29,6 +30,6 @@ public class RefreshOnBreakActionDelegate extends AbstractRefreshActionDelegate @Override public VMCache createCache() { - return new VMCacheRefreshOnBreak(); + return new VMCacheRefreshOnBreak(VMCacheManager.getVMCacheManager().getCache(getContext())); } } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java index 2635efb6ba7..3622c0b995b 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java @@ -48,6 +48,30 @@ public abstract class VMCache protected HashMap, IDMData> fDataArchive = fData; + public HashMap[] getCacheData() + { + return new HashMap[] { fHasChildren, fChildrenCounts, fChildren, fData, fDataArchive }; + } + + public VMCache() + { + + } + + public VMCache(VMCache oldCache) + { + if(oldCache != null) + { + HashMap oldCacheData[] = oldCache.getCacheData(); + + fHasChildren = oldCacheData[0]; + fChildrenCounts = oldCacheData[1]; + fChildren = oldCacheData[2]; + fData = oldCacheData[3]; + fDataArchive = oldCacheData[4]; + } + } + protected void flush(boolean archive) { if(archive) From 6847c2c2ebcac7a5a17e6c50b1c528339b310cf2 Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Wed, 15 Aug 2007 19:11:42 +0000 Subject: [PATCH 142/834] Bugzilla 199631. --- .../detailpanesupport/DetailPane.java | 66 +++++++++++++++++-- .../detailpanesupport/DetailPaneFactory.java | 19 +++--- .../viewmodel/detailpanesupport/Messages.java | 3 +- 3 files changed, 71 insertions(+), 17 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPane.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPane.java index c92ba8b1745..9d910f1d37f 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPane.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPane.java @@ -39,8 +39,11 @@ import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext; import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode.DMVMContext; +import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.model.IDebugElement; +import org.eclipse.debug.core.model.IExpression; import org.eclipse.debug.core.model.IValue; +import org.eclipse.debug.core.model.IVariable; import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.internal.ui.IDebugHelpContextIds; import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; @@ -49,8 +52,10 @@ import org.eclipse.debug.internal.ui.VariablesViewModelPresentation; import org.eclipse.debug.internal.ui.actions.variables.details.DetailPaneMaxLengthAction; import org.eclipse.debug.internal.ui.actions.variables.details.DetailPaneWordWrapAction; import org.eclipse.debug.internal.ui.preferences.IDebugPreferenceConstants; +import org.eclipse.debug.internal.ui.views.variables.IndexedValuePartition; import org.eclipse.debug.internal.ui.views.variables.StatusLineContributionItem; import org.eclipse.debug.internal.ui.views.variables.details.DetailMessages; +import org.eclipse.debug.ui.IDebugModelPresentation; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.debug.ui.IDebugView; import org.eclipse.debug.ui.IDetailPane; @@ -284,13 +289,16 @@ public class DetailPane implements IDetailPane, IAdaptable, IPropertyChangeListe class DetailJob extends Job implements IValueDetailListener { private IStructuredSelection fElements; + private IDebugModelPresentation fModel; private boolean fFirst = true; private IProgressMonitor fMonitor; + private boolean fComputed = false; - public DetailJob(IStructuredSelection elements) { + public DetailJob(IStructuredSelection elements, IDebugModelPresentation model) { super("compute variable details"); //$NON-NLS-1$ setSystem(true); fElements = elements; + fModel = model; } /* (non-Javadoc) @@ -299,6 +307,7 @@ public class DetailPane implements IDetailPane, IAdaptable, IPropertyChangeListe @SuppressWarnings("unchecked") @Override protected IStatus run(IProgressMonitor monitor) { + String message = null; fMonitor = monitor; Iterator iterator = fElements.iterator(); while (iterator.hasNext()) { @@ -436,6 +445,49 @@ public class DetailPane implements IDetailPane, IAdaptable, IPropertyChangeListe } ); } + else { + IValue val = null; + if (element instanceof IVariable) { + try { + val = ((IVariable)element).getValue(); + } catch (DebugException e) { + detailComputed(null, e.getStatus().getMessage()); + } + } else if (element instanceof IExpression) { + val = ((IExpression)element).getValue(); + } + // When selecting a index partition, clear the pane + if (val instanceof IndexedValuePartition) { + detailComputed(null, ""); //$NON-NLS-1$ + val = null; + } + if (element instanceof String) { + message = (String) element; + } + if (val != null && !monitor.isCanceled()) { + fModel.computeDetail(val, this); + synchronized (this) { + try { + // wait for a max of 30 seconds for result, then cancel + wait(30000); + if (!fComputed) { + fMonitor.setCanceled(true); + } + } catch (InterruptedException e) { + break; + } + } + } + } + // If no details were computed for the selected variable, clear the pane + // or use the message, if the variable was a java.lang.String + if (!fComputed){ + if (message == null) { + detailComputed(null,""); //$NON-NLS-1$ + } else { + detailComputed(null, message); + } + } } return Status.OK_STATUS; @@ -719,7 +771,7 @@ public class DetailPane implements IDetailPane, IAdaptable, IPropertyChangeListe if (fDetailJob != null) { fDetailJob.cancel(); } - fDetailJob = new DetailJob(selection); + fDetailJob = new DetailJob(selection, fModelPresentation); fDetailJob.schedule(); } } @@ -758,25 +810,29 @@ public class DetailPane implements IDetailPane, IAdaptable, IPropertyChangeListe } } +// public static final String DSF_DETAIL_PANE_ID = Messages.getString("DetailPaneFactory.0"); //$NON-NLS-1$ +// public static final String DSF_DETAIL_PANE_NAME = Messages.getString("DetailPaneFactory.1"); //$NON-NLS-1$ +// public static final String DSF_DETAIL_PANE_DESC = Messages.getString("DetailPaneFactory.2"); //$NON-NLS-1$ + /* (non-Javadoc) * @see org.eclipse.debug.ui.IDetailPane#getDescription() */ public String getDescription() { - return DESCRIPTION; + return DetailPaneFactory.DSF_DETAIL_PANE_DESC; } /* (non-Javadoc) * @see org.eclipse.debug.ui.IDetailPane#getID() */ public String getID() { - return ID; + return DetailPaneFactory.DSF_DETAIL_PANE_ID; } /* (non-Javadoc) * @see org.eclipse.debug.ui.IDetailPane#getName() */ public String getName() { - return NAME; + return DetailPaneFactory.DSF_DETAIL_PANE_NAME; } /* (non-Javadoc) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPaneFactory.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPaneFactory.java index d35cec533cd..caaa13079a4 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPaneFactory.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPaneFactory.java @@ -24,9 +24,9 @@ import org.eclipse.jface.viewers.IStructuredSelection; @SuppressWarnings("restriction") public class DetailPaneFactory implements IDetailPaneFactory { - public static final String DETAIL_PANE_ID = Messages.getString("DetailPaneFactory.0"); //$NON-NLS-1$ - public static final String DETAIL_PANE_NAME = Messages.getString("DetailPaneFactory.1"); //$NON-NLS-1$ - public static final String DETAIL_PANE_DESC = Messages.getString("DetailPaneFactory.2"); //$NON-NLS-1$ + public static final String DSF_DETAIL_PANE_ID = Messages.getString("DetailPaneFactory.0"); //$NON-NLS-1$ + public static final String DSF_DETAIL_PANE_NAME = Messages.getString("DetailPaneFactory.1"); //$NON-NLS-1$ + public static final String DSF_DETAIL_PANE_DESC = Messages.getString("DetailPaneFactory.2"); //$NON-NLS-1$ /* (non-Javadoc) * @see org.eclipse.debug.internal.ui.views.variables.IDetailsFactory#createDetailsArea(java.lang.String) @@ -41,7 +41,7 @@ public class DetailPaneFactory implements IDetailPaneFactory { @SuppressWarnings("unchecked") public Set getDetailPaneTypes(IStructuredSelection selection) { Set possibleIDs = new HashSet(1); - possibleIDs.add(DETAIL_PANE_ID); + possibleIDs.add(DSF_DETAIL_PANE_ID); return possibleIDs; } @@ -49,26 +49,25 @@ public class DetailPaneFactory implements IDetailPaneFactory { * @see org.eclipse.debug.ui.IDetailPaneFactory#getDefaultDetailPane(java.util.Set, org.eclipse.jface.viewers.IStructuredSelection) */ public String getDefaultDetailPane(IStructuredSelection selection) { - return DETAIL_PANE_ID; + return DSF_DETAIL_PANE_ID; } /* (non-Javadoc) * @see org.eclipse.debug.internal.ui.views.variables.IDetailsFactory#getName(java.lang.String) */ public String getDetailPaneName(String id) { - if (id.equals(DETAIL_PANE_ID)){ - return DETAIL_PANE_NAME; + if (id.equals(DSF_DETAIL_PANE_ID)){ + return DSF_DETAIL_PANE_NAME; } return null; } - /* (non-Javadoc) * @see org.eclipse.debug.internal.ui.views.variables.IDetailsFactory#getDescription(java.lang.String) */ public String getDetailPaneDescription(String id) { - if (id.equals(DETAIL_PANE_ID)){ - return DETAIL_PANE_DESC; + if (id.equals(DSF_DETAIL_PANE_ID)){ + return DSF_DETAIL_PANE_DESC; } return null; } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/Messages.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/Messages.java index 5d278c057f6..ba14f79459a 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/Messages.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/Messages.java @@ -16,8 +16,7 @@ import java.util.ResourceBundle; public class Messages { private static final String BUNDLE_NAME = "org.eclipse.dd.dsf.debug.ui.viewmodel.detailpanesupport.messages"; //$NON-NLS-1$ - private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle - .getBundle(BUNDLE_NAME); + private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME); private Messages() { } From dc3e238402fb30b11240fdb4582716c7c88d7fff Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Mon, 20 Aug 2007 15:25:39 +0000 Subject: [PATCH 143/834] Bugzilla 200566 - providing type and attribute information for registers and bitfields in the expressions view. --- .../register/RegisterBitFieldLayoutNode.java | 14 ++++++++++++++ .../register/RegisterGroupLayoutNode.java | 2 ++ .../viewmodel/register/RegisterLayoutNode.java | 16 ++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java index 72ba3a00cdb..34d3095e54d 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java @@ -323,6 +323,20 @@ public class RegisterBitFieldLayoutNode extends AbstractExpressionLayoutNode Date: Mon, 20 Aug 2007 17:19:14 +0000 Subject: [PATCH 144/834] Bugzilla 200568 IFormattedValues.java - Added DECIMAL_FORMAT format ID. DetailPane.java - Added displaying DECIMNAL_FORMAT display output. SetDefautlFormatDecimal.java - new menu action for setting style to DECIMAL_FORMAT plugin.xml for org.eclipse.dd.dsf.debug.ui - Added complete set of format selections for the Register View MIRegisters.java - Added support for all format types. --- .../org.eclipse.dd.dsf.debug.ui/plugin.xml | 51 +++++++++++++++++++ .../detailpanesupport/DetailPane.java | 3 ++ .../SetDefaultFormatDecimal.java | 22 ++++++++ .../dsf/debug/service/IFormattedValues.java | 7 +-- 4 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatDecimal.java diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml index 4d8023afd96..3c4464e8077 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml +++ b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml @@ -209,5 +209,56 @@ id="org.eclipse.dd.dsf.debug.ui.viewmodel.detailPaneFactory"> + + + + + + + + + + + + + + + + diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPane.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPane.java index 9d910f1d37f..4c860a6b4bd 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPane.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPane.java @@ -424,6 +424,9 @@ public class DetailPane implements IDetailPane, IAdaptable, IPropertyChangeListe else if ( str == IFormattedValues.BINARY_FORMAT) { detailComputed(null, "Binary. : " + getData().getFormattedValue()); //$NON-NLS-1$ } + else if ( str == IFormattedValues.DECIMAL_FORMAT) { + detailComputed(null, "Decimal : " + getData().getFormattedValue()); //$NON-NLS-1$ + } else { detailComputed(null, "Other.. : " + getData().getFormattedValue()); //$NON-NLS-1$ } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatDecimal.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatDecimal.java new file mode 100644 index 00000000000..8e0baca3c27 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatDecimal.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * 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.formatsupport; + +import org.eclipse.dd.dsf.debug.service.IFormattedValues; + +@SuppressWarnings("restriction") +public class SetDefaultFormatDecimal extends AbstractSetFormatStyle { + + @Override + protected String getFormatStyle() { + return IFormattedValues.DECIMAL_FORMAT; + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java index 30307a3f407..88c601e33d1 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java @@ -28,10 +28,11 @@ public interface IFormattedValues extends IDMService { * specifically available from the backend are what is returned from the * getID() method. */ - public final static String HEX_FORMAT = "HEX.Format" ; //$NON-NLS-1$ - public final static String OCTAL_FORMAT = "OCTAL.Format" ; //$NON-NLS-1$ + public final static String HEX_FORMAT = "HEX.Format" ; //$NON-NLS-1$ + public final static String OCTAL_FORMAT = "OCTAL.Format" ; //$NON-NLS-1$ public final static String NATURAL_FORMAT = "NATURAL.Format" ; //$NON-NLS-1$ - public final static String BINARY_FORMAT = "BINARY.Format" ; //$NON-NLS-1$ + public final static String BINARY_FORMAT = "BINARY.Format" ; //$NON-NLS-1$ + public final static String DECIMAL_FORMAT = "DECIMAL.Format" ; //$NON-NLS-1$ /** * Retrieves the available formats that the given data is available in. From 8634b729f046eb5889f83b7947dcb8f93241313d Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Mon, 20 Aug 2007 18:51:54 +0000 Subject: [PATCH 145/834] Removed extra format options for now. I need to talk to Pawel about this. If they are here and in Wind River Commercial product the menu options appear twice. So we should add them to the Open Source and remove them from the commercial. We can discuss at the next open source meeting. For now though I am removing them for the time being. Randy --- .../org.eclipse.dd.dsf.debug.ui/plugin.xml | 51 ------------------- 1 file changed, 51 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml index 3c4464e8077..93dcaa70862 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml +++ b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml @@ -210,55 +210,4 @@ - - - - - - - - - - - - - - - - From f09b8034f8e0e06316d1bb8be48c85e763cacd02 Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Wed, 22 Aug 2007 22:29:11 +0000 Subject: [PATCH 146/834] Bugzilla 200876. --- .../dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java index 26857075ca1..1fbfe5e87bb 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java @@ -121,7 +121,7 @@ public class VariableLayoutNode extends AbstractExpressionLayoutNode Date: Sun, 2 Sep 2007 04:07:54 +0000 Subject: [PATCH 147/834] Bugzilla 201996 --- .../register/RegisterBitFieldLayoutNode.java | 36 +++++++++++++---- .../register/RegisterLayoutNode.java | 39 ++++++++++++++----- 2 files changed, 58 insertions(+), 17 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java index 34d3095e54d..ee413c11160 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java @@ -398,20 +398,42 @@ public class RegisterBitFieldLayoutNode extends AbstractExpressionLayoutNode e) { - if (e instanceof IRunControl.ISuspendedDMEvent) { - return IModelDelta.CONTENT; - } else if (e instanceof IRegisters.IBitFieldChangedDMEvent) { + // In theory we want each node to act independently in terms of events. It might be + // the case that we would only have elements of this type at the root level. It is + // the case that the current layout model always starts with the GROUPS followed by + // REGISTERS followed by BITFIELDS. But if we do this when a run-control event has + // occured we generate a DELTA for every element, which can create a massive list + // of entries all of which say update the entire view. So for now we will just have + // the GROUP LAYOUT node do this. Later we need to revisit the logic and make sure + // there is a way for the nodes to operate independently and efficiently. + // + //if (e instanceof IRunControl.ISuspendedDMEvent) { + // return IModelDelta.CONTENT; + //} + + if (e instanceof IRegisters.IBitFieldChangedDMEvent) { return IModelDelta.STATE; } + return IModelDelta.NO_CHANGE; } @Override protected void buildDeltaForDMEvent(IDMEvent e, VMDelta parent, int nodeOffset, RequestMonitor rm) { - if (e instanceof IRunControl.ISuspendedDMEvent) { - // Create a delta that the whole register group has changed. - parent.addFlags(IModelDelta.CONTENT); - } + // In theory we want each node to act independently in terms of events. It might be + // the case that we would only have elements of this type at the root level. It is + // the case that the current layout model always starts with the GROUPS followed by + // REGISTERS followed by BITFIELDS. But if we do this when a run-control event has + // occured we generate a DELTA for every element, which can create a massive list + // of entries all of which say update the entire view. So for now we will just have + // the GROUP LAYOUT node do this. Later we need to revisit the logic and make sure + // there is a way for the nodes to operate independently and efficiently. + // + // if (e instanceof IRunControl.ISuspendedDMEvent) { + // // Create a delta that the whole register group has changed. + // parent.addFlags(IModelDelta.CONTENT); + // } + if (e instanceof IRegisters.IBitFieldChangedDMEvent) { /* * Flush the cache. diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java index 2d8e4e33b37..5c93622eaa4 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java @@ -400,10 +400,20 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode e) { - if (e instanceof IRunControl.ISuspendedDMEvent) { - return IModelDelta.CONTENT; - } - else if (e instanceof IRegisters.IRegistersChangedDMEvent) { + // In theory we want each node to act independently in terms of events. It might be + // the case that we would only have elements of this type at the root level. It is + // the case that the current layout model always starts with the GROUPS followed by + // REGISTERS followed by BITFIELDS. But if we do this when a run-control event has + // occured we generate a DELTA for every element, which can create a massive list + // of entries all of which say update the entire view. So for now we will just have + // the GROUP LAYOUT node do this. Later we need to revisit the logic and make sure + // there is a way for the nodes to operate independently and efficiently. + // + // if (e instanceof IRunControl.ISuspendedDMEvent) { + // return IModelDelta.CONTENT; + // } + + if (e instanceof IRegisters.IRegistersChangedDMEvent) { /* * Flush the cache. */ @@ -411,7 +421,8 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode e, VMDelta parent, int nodeOffset, RequestMonitor rm) { - - if (e instanceof IRunControl.ISuspendedDMEvent) { - // Create a delta that the whole register group has changed. - parent.addFlags(IModelDelta.CONTENT); - } + // In theory we want each node to act independently in terms of events. It might be + // the case that we would only have elements of this type at the root level. It is + // the case that the current layout model always starts with the GROUPS followed by + // REGISTERS followed by BITFIELDS. But if we do this when a run-control event has + // occured we generate a DELTA for every element, which can create a massive list + // of entries all of which say update the entire view. So for now we will just have + // the GROUP LAYOUT node do this. Later we need to revisit the logic and make sure + // there is a way for the nodes to operate independently and efficiently. + // + // if (e instanceof IRunControl.ISuspendedDMEvent) { + // // Create a delta that the whole register group has changed. + // parent.addFlags(IModelDelta.CONTENT); + // } if (e instanceof IRegisters.IRegistersChangedDMEvent) { parent.addFlags(IModelDelta.CONTENT);; From d96a8c57e6ebf8d8441848660349b7ac3cd99273 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Tue, 4 Sep 2007 21:23:45 +0000 Subject: [PATCH 148/834] https://bugs.eclipse.org/bugs/show_bug.cgi?id=202109 --- .../dd/dsf/ui/viewmodel/VMElementsUpdate.java | 2 +- .../viewmodel/dm/AbstractDMVMLayoutNode.java | 4 +- .../dd/dsf/ui/viewmodel/update/VMCache.java | 42 +++++++++++++++++-- 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMElementsUpdate.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMElementsUpdate.java index 796edc4a6a3..4de36383354 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMElementsUpdate.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMElementsUpdate.java @@ -29,7 +29,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentPr public class VMElementsUpdate extends VMViewerUpdate implements IChildrenUpdate { private final int fOffset; private final int fLength; - private final List fElements; + protected final List fElements; public VMElementsUpdate(IChildrenUpdate clientUpdate, int offset, int length, DataRequestMonitor> requestMonitor) { super(clientUpdate, requestMonitor); diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java index 8b49e0d2ed2..7ddb7a4f513 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java @@ -504,7 +504,9 @@ abstract public class AbstractDMVMLayoutNode extends Abstract protected void fillUpdateWithVMCs(IChildrenUpdate update, IDMContext[] dmcs) { int startIdx = update.getOffset() != -1 ? update.getOffset() : 0; int endIdx = update.getLength() != -1 ? startIdx + update.getLength() : dmcs.length; - for (int i = startIdx; i < endIdx; i++) { + // Ted: added bounds limitation of dmcs.length + // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=202109 + for (int i = startIdx; i < endIdx && i < dmcs.length; i++) { update.setChild(createVMContext(dmcs[i]), i); } } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java index 3622c0b995b..0e3f337c41e 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java @@ -272,9 +272,9 @@ public abstract class VMCache @Override protected void handleCompleted() { - if(getStatus().isOK()) + if(getData() != null) { - for(int j = 0; j < update.getLength(); j++) + for(int j = 0; j < getData().size(); j++) { if(isCacheWriteEnabled()) { @@ -289,7 +289,43 @@ public abstract class VMCache } update.done(); } - }); + }) + { + /* See https://bugs.eclipse.org/bugs/show_bug.cgi?id=202109 + * + * A flexible hierarchy bug/optimization causes query with incorrect + * IChildrenUpdate[] array length. + * + * We found this while deleting a register node. Example: + * + * the register view displays: + * PC + * EAX + * EBX + * ECX + * EDX + * + * we delete EBX and force a context refresh. + * + * flexible hierarchy queries for IChildrenUpdate[5] and IChildrenCountUpdate at + * the same time. + * + * VMElementsUpdate, used by VMCache to wrap the IChildrenUpdate, generates an + * IStatus.ERROR with message "Incomplete elements of updates" when fElements + * count (provided by service) does not match the length provided by the original + * update query. + * + * Workaround, respect getData() != null instead of IStatus.OK, override + * VMElementsUpdate.done() to set elements regardless of count + */ + @Override + public void done() { + @SuppressWarnings("unchecked") + DataRequestMonitor> rm = (DataRequestMonitor>)fRequestMonitor; + rm.setData(fElements); + super.done(); + } + }; } return updates; From a89a6117aa0ccffc18005a980a771a63d41460b0 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Wed, 5 Sep 2007 22:17:43 +0000 Subject: [PATCH 149/834] Bug 202342 --- .../variable/VariableLayoutNode.java | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java index 1fbfe5e87bb..3805cf3ffcf 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java @@ -77,6 +77,8 @@ public class VariableLayoutNode extends AbstractExpressionLayoutNode 0) + { + stringValueBuf.append(" "); + stringValueBuf.append(stringValue.length() > MAX_STRING_VALUE_LENGTH ? stringValue.substring(0, MAX_STRING_VALUE_LENGTH) : stringValue); + } + update.setLabel(stringValueBuf.toString(), labelIndex); // Color based on change history FormattedValueDMData oldData = (FormattedValueDMData) VMCacheManager.getVMCacheManager() .getCache(VariableLayoutNode.this.getVMProvider().getPresentationContext()) .getArchivedModelData(valueDmc); - if (oldData != null && !oldData.getFormattedValue().equals(getData().getFormattedValue())) { + + IExpressionDMData oldDMData = (IExpressionDMData) VMCacheManager.getVMCacheManager().getCache(update.getPresentationContext()).getArchivedModelData(dmc); + String oldStringValue = oldDMData == null ? null : oldDMData.getStringValue(); + + // highlight the value if either the value (address) has changed or the string (memory at the value) has changed + if ((oldData != null && !oldData.getFormattedValue().equals(getData().getFormattedValue())) + || (oldStringValue != null && !oldStringValue.equals(stringValue))) { update.setBackground( DebugUIPlugin.getPreferenceColor( IInternalDebugUIConstants.PREF_CHANGED_VALUE_BACKGROUND).getRGB(), From 0f827f7b2bf81f96f6f303b7a0f8bff283a6470e Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 7 Sep 2007 15:42:51 +0000 Subject: [PATCH 150/834] [159683] Added a few comments and fixed a couple of warnings while reviewing changes. --- .../dd/dsf/ui/viewmodel/update/VMCache.java | 155 ++++++++++-------- 1 file changed, 85 insertions(+), 70 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java index 0e3f337c41e..de182ab99db 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java @@ -48,9 +48,9 @@ public abstract class VMCache protected HashMap, IDMData> fDataArchive = fData; - public HashMap[] getCacheData() + public HashMap[] getCacheData() { - return new HashMap[] { fHasChildren, fChildrenCounts, fChildren, fData, fDataArchive }; + return new HashMap[] { fHasChildren, fChildrenCounts, fChildren, fData, fDataArchive }; } public VMCache() @@ -58,17 +58,19 @@ public abstract class VMCache } - public VMCache(VMCache oldCache) + // Suppress warnings related to the lost type information in getCacheData() + @SuppressWarnings("unchecked") + public VMCache(VMCache oldCache) { if(oldCache != null) { - HashMap oldCacheData[] = oldCache.getCacheData(); + HashMap oldCacheData[] = oldCache.getCacheData(); - fHasChildren = oldCacheData[0]; - fChildrenCounts = oldCacheData[1]; - fChildren = oldCacheData[2]; - fData = oldCacheData[3]; - fDataArchive = oldCacheData[4]; + fHasChildren = (HashMap)oldCacheData[0]; + fChildrenCounts = (HashMap)oldCacheData[1]; + fChildren = (HashMap>)oldCacheData[2]; + fData = (HashMap, IDMData>)oldCacheData[3]; + fDataArchive = (HashMap, IDMData>)oldCacheData[4]; } } @@ -81,12 +83,23 @@ public abstract class VMCache fChildren.clear(); fHasChildren.clear(); } - + + /** + * Returns whether the data in this cache should used when servicing + * view updates. If this method returns false all updates will be + * sent to the view model, although the retrieved data should still + * be stored in the cache if {@link #isCacheWriteEnabled()} returns true. + * @return + */ protected boolean isCacheReadEnabled() { return true; } + /** + * Returns true if data retrieved from the view model should be cached. + * If this returns false, then the state of the cache is frozen. + */ protected boolean isCacheWriteEnabled() { return true; @@ -266,66 +279,68 @@ public abstract class VMCache for(int i = 0; i < updates.length; i++) { final IChildrenUpdate update = updatesEntirelyMissingFromCache.elementAt(i); - updates[i] = new VMElementsUpdate(update, update.getOffset(), update.getLength(), - new DataRequestMonitor>(fExecutor, null) - { - @Override - protected void handleCompleted() - { - if(getData() != null) - { - for(int j = 0; j < getData().size(); j++) - { - if(isCacheWriteEnabled()) - { - if(!fChildren.containsKey(update.getElement())) - fChildren.put(update.getElement(), new HashMap()); - - fChildren.get(update.getElement()).put(update.getOffset() + j, getData().get(j)); - } - - update.setChild(getData().get(j), update.getOffset() + j); - } - } - update.done(); - } - }) - { - /* See https://bugs.eclipse.org/bugs/show_bug.cgi?id=202109 - * - * A flexible hierarchy bug/optimization causes query with incorrect - * IChildrenUpdate[] array length. - * - * We found this while deleting a register node. Example: - * - * the register view displays: - * PC - * EAX - * EBX - * ECX - * EDX - * - * we delete EBX and force a context refresh. - * - * flexible hierarchy queries for IChildrenUpdate[5] and IChildrenCountUpdate at - * the same time. - * - * VMElementsUpdate, used by VMCache to wrap the IChildrenUpdate, generates an - * IStatus.ERROR with message "Incomplete elements of updates" when fElements - * count (provided by service) does not match the length provided by the original - * update query. - * - * Workaround, respect getData() != null instead of IStatus.OK, override - * VMElementsUpdate.done() to set elements regardless of count - */ - @Override - public void done() { - @SuppressWarnings("unchecked") - DataRequestMonitor> rm = (DataRequestMonitor>)fRequestMonitor; - rm.setData(fElements); - super.done(); - } - }; + updates[i] = + new VMElementsUpdate( + update, update.getOffset(), update.getLength(), + new DataRequestMonitor>(fExecutor, null) + { + @Override + protected void handleCompleted() + { + if(getData() != null) + { + for(int j = 0; j < getData().size(); j++) + { + if(isCacheWriteEnabled()) + { + if(!fChildren.containsKey(update.getElement())) + fChildren.put(update.getElement(), new HashMap()); + + fChildren.get(update.getElement()).put(update.getOffset() + j, getData().get(j)); + } + + update.setChild(getData().get(j), update.getOffset() + j); + } + } + update.done(); + } + }) + { + /* See https://bugs.eclipse.org/bugs/show_bug.cgi?id=202109 + * + * A flexible hierarchy bug/optimization causes query with incorrect + * IChildrenUpdate[] array length. + * + * We found this while deleting a register node. Example: + * + * the register view displays: + * PC + * EAX + * EBX + * ECX + * EDX + * + * we delete EBX and force a context refresh. + * + * flexible hierarchy queries for IChildrenUpdate[5] and IChildrenCountUpdate at + * the same time. + * + * VMElementsUpdate, used by VMCache to wrap the IChildrenUpdate, generates an + * IStatus.ERROR with message "Incomplete elements of updates" when fElements + * count (provided by service) does not match the length provided by the original + * update query. + * + * Workaround, respect getData() != null instead of IStatus.OK, override + * VMElementsUpdate.done() to set elements regardless of count + */ + @Override + public void done() { + @SuppressWarnings("unchecked") + DataRequestMonitor> rm = (DataRequestMonitor>)fRequestMonitor; + rm.setData(fElements); + super.done(); + } + }; } return updates; From 3b1658988447133e72f890b3426c0b7f586562ac Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Mon, 10 Sep 2007 21:54:33 +0000 Subject: [PATCH 151/834] [187718, 185870] Applied patch simplifying the expressions interface. --- .../variable/VariableLayoutNode.java | 22 ++------ .../dd/dsf/debug/service/IExpressions.java | 55 ++++++++++++------- 2 files changed, 39 insertions(+), 38 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java index 3805cf3ffcf..5b3942fa2fc 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java @@ -10,7 +10,6 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.variable; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; import org.eclipse.core.runtime.CoreException; @@ -192,7 +191,7 @@ public class VariableLayoutNode extends AbstractExpressionLayoutNode> rm = - new DataRequestMonitor>(dsfExecutor, null) { + final DataRequestMonitor rm = + new DataRequestMonitor(dsfExecutor, null) { @Override public void handleCompleted() { if (!getStatus().isOK()) { handleFailedUpdate(update); return; } - - // Fill the update with the the IExpressionDMContext objects returned by - // IExpressions.getSubExpressions(). - - List subExpressionDMCList = (List)getData(); - IExpressionDMContext[] subExpressionDMCArray = new IExpressionDMContext[subExpressionDMCList.size()]; - Iterator iter = subExpressionDMCList.iterator(); - - int i = 0; - while (iter.hasNext()) { - subExpressionDMCArray[i++] = iter.next(); - } - - fillUpdateWithVMCs(update, subExpressionDMCArray); + fillUpdateWithVMCs(update, getData()); update.done(); } }; diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java index a23ac975104..c959988c262 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java @@ -29,7 +29,7 @@ import org.eclipse.dd.dsf.datamodel.IDMService; public interface IExpressions extends IDMService, IFormattedValues { /** - * Expression context. Since some expressions have children, expression contexts can be have an + * Expression context. Since some expressions have children, expression contexts can have an * arbitrary number of parents of type IExpressionDMContext. */ public interface IExpressionDMContext extends IFormattedDataDMContext { @@ -37,14 +37,6 @@ public interface IExpressions extends IDMService, IFormattedValues { * Returns a fully qualified expression string represented by this context. This * expression string is the same as the string that is sent to the debug engine to be * evaluated in context of a stack frame, thread, or a symbol context. - * @return - */ - String getQualifiedExpression(); - - /** - * If this expression is a sub-expression of another expression, this method returns - * the expression relative to the parent of this expression. Otherwise this method - * will return the same string as {@link #getQualifiedExpression()}. */ String getExpression(); } @@ -79,9 +71,9 @@ public interface IExpressions extends IDMService, IFormattedValues { } /** - * ISSUE: Should this method be named getExpression() instead? - * - * @return The original expression string that was supplied to IExpressions.createExpression(). + * If this expression is a sub-expression of another expression, this method returns + * the expression relative to the parent of this expression. Otherwise this method + * will return the same string as {@link #getExpression()}. */ String getName(); @@ -113,7 +105,7 @@ public interface IExpressions extends IDMService, IFormattedValues { * of bits in the field. For other types, this is 8 times the number of bytes in the value. */ int getBitCount(); - + /** * @return A string containing the value of the expression as returned by the debugger backend. */ @@ -123,8 +115,6 @@ public interface IExpressions extends IDMService, IFormattedValues { * @return An IAddress object representing the memory address of the value of the expression (if it * has one). Non-lvalues do not have memory addresses (e.g., "x + 5"). When the expression * has no address, this method returns an IAddress object on which isZero() returns true. - * ISSUE: It would be nice if there was a method IAddress.isValid() which could return false - * in this case. */ IAddress getAddress(); @@ -148,10 +138,10 @@ public interface IExpressions extends IDMService, IFormattedValues { interface IExpressionChangedDMEvent extends IDMEvent {} /** - * Returns the data model context object for the specified expression in the context of + * Returns the data model context object for the specified expression in the context * specified by ctx. * - * @param symbolsDmc: Context in which to evaluate the expression. This context could include the + * @param ctx: Context in which to evaluate the expression. This context could include the * PC location, stack frame, thread, or just a symbol context. * * @param expression: The expression to evaluate. @@ -167,11 +157,36 @@ public interface IExpressions extends IDMService, IFormattedValues { * * @param exprCtx: The data model context representing an expression. * - * @param rm: The return parameter is an Iterable because it's possible that the sub-expressions as - * members of an array which could be very large. + * @param rm: Request completion monitor containing an array of all sub-expressions */ - void getSubExpressions(IExpressionDMContext exprCtx, DataRequestMonitor> rm); + void getSubExpressions(IExpressionDMContext exprCtx, DataRequestMonitor rm); + + /** + * Retrieves a particular range of sub-expressions of the given expression. + * Sub-expressions are fields of a struct, union, or class, the enumerators + * of an enumeration, and the element of an array. + * + * @param exprCtx: The data model context representing an expression. + * startIndex: Index of the first sub-expression to retrieve + * length: Total number of sub-expressions to retrieve + * + * @param rm: Request completion monitor containing an array of the requested + * range of sub-expressions + */ + void getSubExpressions(IExpressionDMContext exprCtx, int startIndex, int length, + DataRequestMonitor rm); + /** + * Retrieves the number of sub-expressions of the given expression. Sub-expressions are fields of a struct, union, + * or class, the enumerators of an enumeration, and the element of an array. + * + * @param exprCtx: The data model context representing an expression. + * + * @param rm: Request completion monitor containing the number of sub-expressions + * of the specified expression + */ + void getSubExpressionCount(IExpressionDMContext exprCtx, DataRequestMonitor rm); + /** * For object oriented languages, this method returns the expressions representing base types of * the given expression type. From 595a773de84aa6d34183e2462c02339dfb7c1c95 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Wed, 12 Sep 2007 18:25:24 +0000 Subject: [PATCH 152/834] 203117 - update modes moved from context menus to action menus; toolbar buttons for always and manual modes with artwork from ted --- .../icons/refreshalways.gif | Bin 0 -> 358 bytes .../icons/refreshmanual.gif | Bin 0 -> 244 bytes .../org.eclipse.dd.dsf.debug.ui/plugin.xml | 235 +++++++++--------- 3 files changed, 120 insertions(+), 115 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/icons/refreshalways.gif create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/icons/refreshmanual.gif diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/icons/refreshalways.gif b/plugins/org.eclipse.dd.dsf.debug.ui/icons/refreshalways.gif new file mode 100644 index 0000000000000000000000000000000000000000..2c508633881b458cb7c64a7343a9510ff9d81e3c GIT binary patch literal 358 zcmZ?wbhEHb6krfwSZdCoU}>amXQbh3so`O(3q*ddh9Kl+5$0zR7Oa=0q?lf*l2N6e zRjri^L^axZH9Gm#x&<}$@%F*JHud%P^Xu)4mq*N>A3uM7{rvg!@6WfNbg+Kf;mVEc zHqJlZxa?&6{{8dUotwD++{CSyW^TJQbH}AQJ1)&Vc6;4%5L$oi&bs4w)}Ow=<^O&A ztIrNyeSYZnt24J>pZWja{`u$I|Nqbb|NlP&ZlL&+g^_{5ot;$J;YT8+YtGoBz!GW`p2~Q)irRnP_zj*)upxia87Da2e@q3--HJ%kdeS80o6>`>-+b f8W_oFs44_9@@VU7iYvn8?Wbc>DT#`}sgLKYsp<8T04Y&!0d4{(SrW`{(c9zyI{< z)Bo?=|Njp}^Z)<<57tC1q4<-9k%2*;K?kG(WG4e_p@MSPVGFkSQxa|C>D z*4sYGC$E&41M?q#wr1mCXQ>ltPhgN|?CI^P=yILpnpre)@|3Qk8Iz_@l~-i21^{yu BP^|y} literal 0 HcmV?d00001 diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml index 93dcaa70862..b0b880bf600 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml +++ b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml @@ -50,121 +50,6 @@ verticalRulerPreferenceValue="true"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Date: Fri, 14 Sep 2007 17:46:28 +0000 Subject: [PATCH 153/834] added icons filenames to plugin.xml --- plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml index b0b880bf600..7a9f78f174e 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml +++ b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml @@ -101,6 +101,7 @@ Date: Fri, 28 Sep 2007 20:52:47 +0000 Subject: [PATCH 154/834] [204955] Fixed the bug in use of the counting request monitor. --- .../ui/viewmodel/expression/AbstractExpressionLayoutNode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionLayoutNode.java index 6f686cc0b8e..723ab82f081 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionLayoutNode.java @@ -274,7 +274,7 @@ public abstract class AbstractExpressionLayoutNode extends Ab childNode.getDeltaFlagsForExpression(expressionRemainder, event) != IModelDelta.NO_CHANGE) { childNode.buildDeltaForExpression( - expression, elementIdx, expressionRemainder, event, parentDelta, path, rm); + expression, elementIdx, expressionRemainder, event, parentDelta, path, countingRm); childRmCount++; // The child node will call update.done(); } From e4e9401c924144bd7b0bcf4f7c8d6e5af7dc6f91 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 28 Sep 2007 21:44:46 +0000 Subject: [PATCH 155/834] [204964] Fixed CountingRequestMinotor bug. --- .../AbstractExpressionLayoutNode.java | 6 +- .../ExpressionManagerLayoutNode.java | 14 +---- .../concurrent/CountingRequestMonitor.java | 58 ++++++++++++++----- 3 files changed, 47 insertions(+), 31 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionLayoutNode.java index 723ab82f081..10e75b9a990 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionLayoutNode.java @@ -281,11 +281,7 @@ public abstract class AbstractExpressionLayoutNode extends Ab } } - if (childRmCount > 0) { - countingRm.setCount(childRmCount); - } else { - countingRm.done(); - } + countingRm.setDoneCount(childRmCount); } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerLayoutNode.java index 8fb621184bc..ff4d7c6f2f7 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerLayoutNode.java @@ -179,12 +179,8 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode } } - // If no expressions were parsed, we're finished. - if (expressionRmCount > 0) { - multiRm.setCount(expressionRmCount); - } else { - multiRm.done(); - } + // Set the count to the counting RM. + multiRm.setDoneCount(expressionRmCount); } public void update(ILabelUpdate[] updates) { @@ -323,11 +319,7 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode buildDeltaForExpressionCallCount++; } - if (buildDeltaForExpressionCallCount != 0) { - multiRm.setCount(buildDeltaForExpressionCallCount); - } else { - requestMonitor.done(); - } + multiRm.setDoneCount(buildDeltaForExpressionCallCount); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/CountingRequestMonitor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/CountingRequestMonitor.java index 6b1bb09585b..0fabdafb7da 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/CountingRequestMonitor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/CountingRequestMonitor.java @@ -18,46 +18,74 @@ import org.eclipse.dd.dsf.DsfPlugin; /** * Utility class to collect multiple request monitor results of commands * that are initiated simultaneously. The usage is as follows: - *
    - *     final MultiRequestMonitor multiRequestMon = new MultiRequestMonitor(fExecutor, null) { 
    + * 
    + *     final CountingRequestMonitor countingRm = new CountingRequestMonitor(fExecutor, null) { 
      *         public void handleCompleted() {
      *             System.out.println("All complete, errors=" + !getStatus().isOK());
      *         }
      *     };
      *     
    - *     for (int i = 0; i < 10; i++) {
    - *         service.call(i, multiRequestMon.addRequestMonitor(
    - *             new RequestMonitor(fExecutor, null) {
    - *                 public void handleCompleted() {
    - *                     System.out.println(Integer.toString(i) + " complete");
    - *                     multiRequestMon.requestMonitorDone(this);
    - *                }
    - *             }));
    + *     int count = 0;
    + *     for (int i : elements) {
    + *         service.call(i, countingRm);
    + *         count++;
      *     }
    - * 
    + * + * countingRm.setDoneCount(count); + *
    */ public class CountingRequestMonitor extends RequestMonitor { + /** + * Counter tracking the remaining number of times that the done() method + * needs to be called before this request monitor is actually done. + */ private int fDoneCounter; + + /** + * Flag indicating whether the initial count has been set on this monitor. + */ + private boolean fInitialCountSet = false; public CountingRequestMonitor(Executor executor, RequestMonitor parentRequestMonitor) { super(executor, parentRequestMonitor); setStatus(new MultiStatus(DsfPlugin.PLUGIN_ID, 0, "Collective status for set of sub-operations.", null)); //$NON-NLS-1$ } - public void setCount(int count) { - fDoneCounter = count; + /** + * Sets the number of times that this request monitor needs to be called + * before this monitor is truly considered done. This method must be called + * exactly once in the life cycle of each counting request monitor. + * @param count Number of times that done() has to be called to mark the request + * monitor as complete. If count is '0', then the counting request monitor is + * marked as done immediately. + */ + public synchronized void setDoneCount(int count) { + assert !fInitialCountSet; + fInitialCountSet = true; + fDoneCounter += count; + if (fDoneCounter <= 0) { + assert fDoneCounter == 0; // Mismatch in the count. + super.done(); + } } + /** + * Called to indicate that one of the calls using this monitor is finished. + * Only when done is called the number of times corresponding to the + * count, the request monitor will be considered complete. This method can be + * called before {@link #setDoneCount(int)}. + */ @Override public synchronized void done() { fDoneCounter--; - if (fDoneCounter <= 0) { + if (fInitialCountSet && fDoneCounter <= 0) { + assert fDoneCounter == 0; // Mismatch in the count. super.done(); } } @Override public String toString() { - return "Multi-RequestMonitor: " + getStatus().toString(); //$NON-NLS-1$ + return "CountingRequestMonitor: " + getStatus().toString(); //$NON-NLS-1$ } } From 167b797c27aae20a9eba75deaf66b05de183d4fa Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Mon, 1 Oct 2007 13:42:00 +0000 Subject: [PATCH 156/834] Updates to the ExpressionService --- .../src/org/eclipse/dd/dsf/debug/service/IStack.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java index a0c2364f036..19c07e5a516 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java @@ -87,4 +87,13 @@ public interface IStack extends IDMService { * Retrieves variables local to the stack frame. */ void getLocals(IDMContext frameCtx, DataRequestMonitor rm); + + /** + * Retrieves the stack depth of the specified stack frame. + */ + void getStackDepth(DataRequestMonitor rm); + + void getStackDepth(int maxDepth, DataRequestMonitor rm); + + } From 441f6bc65b88845be3672fe21b9c9abcccdc8f3c Mon Sep 17 00:00:00 2001 From: Francois Chouinard Date: Mon, 1 Oct 2007 21:06:54 +0000 Subject: [PATCH 157/834] Update of the Memory Service. Includes JUnit test suite. --- .../dd/dsf/debug/model/DsfMemoryBlock.java | 208 +++++++++--------- .../debug/model/DsfMemoryBlockRetrieval.java | 14 +- .../eclipse/dd/dsf/debug/service/IMemory.java | 110 +++++++-- 3 files changed, 205 insertions(+), 127 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java index a6027c0bd0c..20bcfe08c85 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java @@ -13,9 +13,11 @@ package org.eclipse.dd.dsf.debug.model; import java.math.BigInteger; +import java.util.ArrayList; import java.util.concurrent.ExecutionException; import java.util.concurrent.RejectedExecutionException; +import org.eclipse.cdt.utils.Addr64; import org.eclipse.core.runtime.PlatformObject; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.Query; @@ -41,29 +43,35 @@ import org.eclipse.debug.core.model.MemoryByte; */ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtension { + private final ILaunch fLaunch; + private final IDebugTarget fDebugTarget; private final DsfMemoryBlockRetrieval fRetrieval; - private final String fModelId; - private final String fExpression; - private final BigInteger fStartAddress; - private BigInteger fEndAddress; - private long fLength = 0; + private final String fModelId; + private final String fExpression; + protected BigInteger fBaseAddress; + protected long fLength; + + private ArrayList fConnections = new ArrayList(); + private boolean isEnabled; /** * Constructor. * * @param retrieval - the MemoryBlockRetrieval (session context) * @param modelId - - * @param expression - the displayed expression - * @param startAddress - the actual memory block start address + * @param expression - the displayed expression in the UI + * @param address - the actual memory block start address * @param length - the memory block length (could be 0) */ - DsfMemoryBlock(DsfMemoryBlockRetrieval retrieval, String modelId, String expression, BigInteger startAddress, long length) { - fRetrieval = retrieval; - fModelId = modelId; - fExpression = expression; - fStartAddress = startAddress; - fEndAddress = startAddress.add(BigInteger.valueOf(length)); - fLength = length; + DsfMemoryBlock(DsfMemoryBlockRetrieval retrieval, String modelId, String expression, BigInteger address, long length) { + + fLaunch = null; // TODO: fRetrieval.getLaunch(); + fDebugTarget = null; // TODO: fRetrieval.getDebugTarget(); + fRetrieval = retrieval; + fModelId = modelId; + fExpression = expression; + fBaseAddress = address; + fLength = length; try { fRetrieval.getExecutor().execute(new Runnable() { @@ -71,7 +79,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens fRetrieval.getSession().addServiceEventListener(DsfMemoryBlock.this, null); } }); - } catch(RejectedExecutionException e) { + } catch (RejectedExecutionException e) { // Session is shut down. } } @@ -100,8 +108,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens * @see org.eclipse.debug.core.model.IDebugElement#getDebugTarget() */ public IDebugTarget getDebugTarget() { - // FRCH: return fRetrieval.getDebugTarget(); - return null; + return fDebugTarget; } /* (non-Javadoc) @@ -115,8 +122,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens * @see org.eclipse.debug.core.model.IDebugElement#getLaunch() */ public ILaunch getLaunch() { - // FRCH: return fRetrieval.getDebugTarget().getLaunch(); - return null; + return fLaunch; } // //////////////////////////////////////////////////////////////////////// @@ -127,12 +133,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens * @see org.eclipse.debug.core.model.IMemoryBlock#getStartAddress() */ public long getStartAddress() { - // Warning: doesn't support 64-bit addresses - long address = fStartAddress.longValue(); - if (fStartAddress.equals(BigInteger.valueOf(address))) - return address; - - // FRCH: Should we throw an exception instead? + // Not implemented (obsolete) return 0; } @@ -140,38 +141,31 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens * @see org.eclipse.debug.core.model.IMemoryBlock#getLength() */ public long getLength() { - // Warning: could return 0 - return fLength; + // Not implemented (obsolete) + return 0; } /* (non-Javadoc) * @see org.eclipse.debug.core.model.IMemoryBlock#getBytes() */ public byte[] getBytes() throws DebugException { - MemoryByte[] block = fetchMemoryBlock(fStartAddress, fLength); - int length = block.length; - byte[] bytes = new byte[length]; - // Extract bytes from MemoryBytes - for (int i : bytes) - bytes[i] = block[i].getValue(); - return bytes; + // Not implemented (obsolete) + return new byte[0]; } /* (non-Javadoc) * @see org.eclipse.debug.core.model.IMemoryBlock#supportsValueModification() */ public boolean supportsValueModification() { - return true; + // return fDebugTarget.supportsValueModification(this); + return true; } /* (non-Javadoc) * @see org.eclipse.debug.core.model.IMemoryBlock#setValue(long, byte[]) */ public void setValue(long offset, byte[] bytes) throws DebugException { - if (offset <= Integer.MAX_VALUE) - writeMemoryBlock((int) offset, bytes); - - // FRCH: Should we throw an exception if offset is too large? + // Not implemented (obsolete) } // //////////////////////////////////////////////////////////////////////// @@ -189,14 +183,14 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens * @see org.eclipse.debug.core.model.IMemoryBlockExtension#getBigBaseAddress() */ public BigInteger getBigBaseAddress() throws DebugException { - return fStartAddress; + return fBaseAddress; } /* (non-Javadoc) * @see org.eclipse.debug.core.model.IMemoryBlockExtension#getMemoryBlockStartAddress() */ public BigInteger getMemoryBlockStartAddress() throws DebugException { - // "null" indicates that memory can be retrieved at addresses lower than the block base address + // Null indicates that memory can be retrieved at addresses lower than the block base address return null; } @@ -204,7 +198,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens * @see org.eclipse.debug.core.model.IMemoryBlockExtension#getMemoryBlockEndAddress() */ public BigInteger getMemoryBlockEndAddress() throws DebugException { - // "null" indicates that memory can be retrieved at addresses higher the block base address + // Null indicates that memory can be retrieved at addresses higher the block base address return null; } @@ -213,14 +207,19 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens */ public BigInteger getBigLength() throws DebugException { // -1 indicates that memory block is unbounded - return BigInteger.ONE.negate(); + return BigInteger.valueOf(-1); } /* (non-Javadoc) * @see org.eclipse.debug.core.model.IMemoryBlockExtension#getAddressSize() */ public int getAddressSize() throws DebugException { - // FRCH: return fRetrieval.getDebugTarget().getAddressSize(); +// // TODO: +// try { +// return fDebugTarget.getAddressSize(); +// } catch (CoreException e) { +// throw new DebugException(e.getStatus()); +// } return 4; } @@ -228,6 +227,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens * @see org.eclipse.debug.core.model.IMemoryBlockExtension#supportBaseAddressModification() */ public boolean supportBaseAddressModification() throws DebugException { + // TODO: return fDebugTarget.supportBaseAddressModification(this); return false; } @@ -235,6 +235,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens * @see org.eclipse.debug.core.model.IMemoryBlockExtension#supportsChangeManagement() */ public boolean supportsChangeManagement() { + // Let the UI handle block content modification return false; } @@ -242,14 +243,14 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens * @see org.eclipse.debug.core.model.IMemoryBlockExtension#setBaseAddress(java.math.BigInteger) */ public void setBaseAddress(BigInteger address) throws DebugException { - // TODO Auto-generated method stub + fBaseAddress = address; } /* (non-Javadoc) * @see org.eclipse.debug.core.model.IMemoryBlockExtension#getBytesFromOffset(java.math.BigInteger, long) */ public MemoryByte[] getBytesFromOffset(BigInteger offset, long units) throws DebugException { - return getBytesFromAddress(fStartAddress.add(offset), units); + return getBytesFromAddress(fBaseAddress.add(offset), units); } /* (non-Javadoc) @@ -257,42 +258,50 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens */ public MemoryByte[] getBytesFromAddress(BigInteger address, long units) throws DebugException { fLength = units; - fEndAddress = fStartAddress.add(BigInteger.valueOf(units)); - return fetchMemoryBlock(address, units); + MemoryByte[] block = fetchMemoryBlock(address, units); + return block; } /* (non-Javadoc) * @see org.eclipse.debug.core.model.IMemoryBlockExtension#setValue(java.math.BigInteger, byte[]) */ public void setValue(BigInteger offset, byte[] bytes) throws DebugException { - // Ensure that the offset can be cast into an int - int offs = offset.intValue(); - if (offset.equals(BigInteger.valueOf(offs))) - writeMemoryBlock(offs, bytes); - - // FRCH: Should we throw an exception if offset is too large? + writeMemoryBlock(offset.longValue(), bytes); } /* (non-Javadoc) * @see org.eclipse.debug.core.model.IMemoryBlockExtension#connect(java.lang.Object) */ public void connect(Object client) { - // TODO Auto-generated method stub + if (!fConnections.contains(client)) + fConnections.add(client); + if (fConnections.size() == 1) + enable(); } /* (non-Javadoc) * @see org.eclipse.debug.core.model.IMemoryBlockExtension#disconnect(java.lang.Object) */ public void disconnect(Object client) { - // TODO Auto-generated method stub + if (fConnections.contains(client)) + fConnections.remove(client); + if (fConnections.size() == 0) + disable(); } /* (non-Javadoc) * @see org.eclipse.debug.core.model.IMemoryBlockExtension#getConnections() */ public Object[] getConnections() { - // TODO Auto-generated method stub - return new Object[0]; + return fConnections.toArray(); + } + + private void enable() { + isEnabled = true; + } + + private void disable() { + isEnabled = false; } /* (non-Javadoc) @@ -305,7 +314,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens fRetrieval.getSession().removeServiceEventListener(DsfMemoryBlock.this); } }); - } catch(RejectedExecutionException e) { + } catch (RejectedExecutionException e) { // Session is shut down. } } @@ -321,7 +330,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens * @see org.eclipse.debug.core.model.IMemoryBlockExtension#getAddressableSize() */ public int getAddressableSize() throws DebugException { - // FRCH: return fRetrieval.getDebugTarget().getAddressableSize(); + // TODO: return fDebugTarget.getAddressableSize(); return 1; } @@ -334,55 +343,50 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens * Job), we use a Query that will patiently wait for the underlying * asynchronous calls to complete before returning. * - * @param address @param length @return MemoryByte[] @throws DebugException + * @param bigAddress + * @param length + * @return MemoryByte[] + * @throws DebugException */ - private MemoryByte[] fetchMemoryBlock(final BigInteger address, final long length) throws DebugException { + private MemoryByte[] fetchMemoryBlock(BigInteger bigAddress, final long length) throws DebugException { - /* FRCH: Fix the loose ends... - * - * For this first implementation, we make a few simplifying assumptions: - * - word_size = 1 (we want to read individual bytes) - * - offset = 0 - * - mode = 0 (will be overridden in getMemory() anyway) - */ + // For the IAddress interface + final Addr64 address = new Addr64(bigAddress); final int word_size = 1; - final int offset = 0; - final int mode = 0; - + // Use a Query to "synchronize" the inherently asynchronous downstream calls Query query = new Query() { @Override protected void execute(final DataRequestMonitor rm) { IMemory memoryService = (IMemory) fRetrieval.getServiceTracker().getService(); if (memoryService != null) { - // Place holder for the result - final MemoryByte[] buffer = new MemoryByte[(int) length]; // Go for it memoryService.getMemory( - fRetrieval.getContext(), address, word_size, buffer, offset, (int) length, mode, - new RequestMonitor(fRetrieval.getExecutor(), rm) { - @Override - protected void handleOK() { - rm.setData(buffer); - rm.done(); - } - }); - } + fRetrieval.getContext(), address, 0, word_size, (int) length, + new DataRequestMonitor(fRetrieval.getExecutor(), rm) { + @Override + protected void handleOK() { + rm.setData(getData()); + rm.done(); + } + }); + } - } - }; + } + }; fRetrieval.getExecutor().execute(query); try { return query.get(); } catch (InterruptedException e) { } catch (ExecutionException e) { } + return null; } @DsfServiceEventHandler public void eventDispatched(MemoryChangedEvent e) { - handleMemoryChange(e.getAddress()); + handleMemoryChange(e.getAddress().getValue()); } @DsfServiceEventHandler @@ -396,32 +400,38 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens * @param bytes * @throws DebugException */ - private void writeMemoryBlock(final int offset, final byte[] bytes) throws DebugException { + private void writeMemoryBlock(final long offset, final byte[] bytes) throws DebugException { + // For the IAddress interface + final Addr64 address = new Addr64(fBaseAddress); final int word_size = 1; - final int mode = 0; - IMemory memoryService = (IMemory) fRetrieval.getServiceTracker().getService(); + final IMemory memoryService = (IMemory) fRetrieval.getServiceTracker().getService(); if (memoryService != null) { - memoryService.setMemory( - fRetrieval.getContext(), fStartAddress, word_size, bytes, offset, bytes.length, mode, - new RequestMonitor(fRetrieval.getExecutor(), null) { - @Override - protected void handleOK() { - handleMemoryChange(fStartAddress); - } - }); + memoryService.getExecutor().execute(new Runnable() { + public void run() { + memoryService.setMemory( + fRetrieval.getContext(), address, offset, word_size, bytes.length, bytes, + new RequestMonitor(fRetrieval.getExecutor(), null) { + @Override + protected void handleOK() { + // handleMemoryChange(fBaseAddress); + } + }); + } + }); } } - /** + /** * @param address * @param length */ public void handleMemoryChange(BigInteger address) { // Check if the change affects this particular block (0 is universal) + BigInteger fEndAddress = fBaseAddress.add(BigInteger.valueOf(fLength)); if (address.equals(BigInteger.ZERO) || - ((fStartAddress.compareTo(address) != 1) && (fEndAddress.compareTo(address) == 1))) + ((fBaseAddress.compareTo(address) != 1) && (fEndAddress.compareTo(address) == 1))) { // Notify the event listeners DebugEvent debugEvent = new DebugEvent(this, DebugEvent.CHANGE, DebugEvent.CONTENT); diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java index f759650742a..7d69e327032 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java @@ -181,7 +181,7 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl * long) */ public IMemoryBlock getMemoryBlock(final long startAddress, final long length) throws DebugException { - // The expression to display in the rendering tab + // The expression to display in the rendering tab (in hex by convention) // Put here for the sake of completeness (not used with IMemoryBlockExtension) String expression = "0x" + Long.toHexString(startAddress); //$NON-NLS-1$ return new DsfMemoryBlock(this, fModelId, expression, BigInteger.valueOf(startAddress), length); @@ -240,6 +240,7 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl dmc = (IDMContext)((IAdaptable)context).getAdapter(IDMContext.class); } + // TODO: throw an exception if (dmc == null) { return null; } @@ -249,6 +250,7 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl // Resolve the expression blockAddress = resolveMemoryAddress(fContext, expression); if (blockAddress == null) + // TODO: throw an exception return null; } @@ -277,13 +279,13 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl // Use a Query to "synchronize" the inherently asynchronous downstream calls Query query = new Query() { @Override - protected void execute(final DataRequestMonitor rm) { + protected void execute(final DataRequestMonitor drm) { // Lookup for the ExpressionService final IExpressions expressionService = (IExpressions) fExpressionServiceTracker.getService(); if (expressionService != null) { // Create the expression final IExpressionDMContext expressionDMC = expressionService.createExpression(idmContext, expression); - expressionService.getModelData(expressionDMC, new DataRequestMonitor(getExecutor(), rm) { + expressionService.getModelData(expressionDMC, new DataRequestMonitor(getExecutor(), drm) { @Override protected void handleOK() { // Evaluate the expression - request HEX since it works in every case @@ -298,9 +300,9 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl FormattedValueDMData data = getData(); if (data.isValid()) { String value = data.getFormattedValue().substring(2); // Strip the "0x" - rm.setData(new BigInteger(value, 16)); + drm.setData(new BigInteger(value, 16)); } - rm.done(); + drm.done(); } } ); @@ -315,7 +317,9 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl // The happy case return query.get(); } catch (InterruptedException e) { + // TODO: throw an exception } catch (ExecutionException e) { + // TODO: throw an exception } // The error case diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java index c38dd7851d0..f0d683bb96b 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java @@ -7,13 +7,13 @@ * * Contributors: * Wind River Systems - initial API and implementation - * Ericsson Communication - extended the API for IMemoryBlockExtension - * Ericsson Communication - added support for 64 bit processors + * Ericsson AB - extended the API for IMemoryBlockExtension + * Ericsson AB - added support for 64 bit processors *******************************************************************************/ package org.eclipse.dd.dsf.debug.service; -import java.math.BigInteger; - +import org.eclipse.cdt.core.IAddress; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.service.IDsfService; @@ -25,35 +25,99 @@ import org.eclipse.debug.core.model.MemoryByte; * IDMService interface. */ public interface IMemory extends IDsfService { - - public class MemoryChangedEvent { - BigInteger fAddress; - public MemoryChangedEvent(BigInteger address) { + /** + * Event generated every time a byte is modified. + * + * A client wishing to receive such events has to register as a service + * event listener and implement the corresponding dispatchEvent method. + * + * E.g.: + * + * MyMemoryBlock(MIRunControl fRunControl) + * { + * ... + * fRunControl.getSession().addServiceEventListener(MyMemoryBlock.this, null); + * ... + * } + * + * @DsfServiceEventHandler + * public void eventDispatched(MemoryChangedEvent e) { + * IAddress address = e.getAddress(); + * // do whatever... + * } + */ + public class MemoryChangedEvent { + IAddress fAddress; + + public MemoryChangedEvent(IAddress address) { fAddress = address; } - public BigInteger getAddress() { + public IAddress getAddress() { return fAddress; } } - - /** Reads memory at the given location */ - public void getMemory(IDMContext ctx, BigInteger addr, - int word_size, MemoryByte[] buf, int offs, int size, int mode, RequestMonitor rm); - - /** Writes the given value to the given memory location. */ - public void setMemory(IDMContext ctx, BigInteger addr, - int word_size, byte[] buf, int offs, int size, int mode, RequestMonitor rm); + /** + * Reads a memory block from the target. + * + * An asynchronous memory read request at [address] + [offset] for + * [count] memory items, each of size [word_size] bytes, will be + * issued to the target. The result will be stored in [drm] upon + * completion of the call. + * + * The [drm] result buffer will be of size [word_size] * [count]. The + * successfully read bytes will have their MemoryByte.READABLE flag + * set while the bytes in error (unreachable/bad memory) will have their + * flag byte set to 0. The bytes will respect the target "endianness". + * + * @param context the context of the target memory block + * @param address the memory block address (on the target) + * @param offset the offset from the start address + * @param word_size the size, in bytes, of an addressable item + * @param count the number of data elements to read + * @param drm the asynchronous data request monitor + */ + public void getMemory(IDMContext context, IAddress address, long offset, + int word_size, int count, DataRequestMonitor drm); /** - * Fill target memory with given pattern. - * 'size' is number of bytes to fill. - * Parameter 0 of sequent 'done' is assigned with Throwable if - * there was an error. + * Writes a memory block on the target. + * + * An asynchronous memory write request at [address] + [offset] for + * [count] * [word_size] bytes will be issued to the target. + * + * The [buffer] must hold at least [count] * [word_size] bytes. + * + * A MemoryChangedEvent will be generated for the range of addresses. + * + * @param context the context of the target memory block + * @param address the memory block address (on the target) + * @param offset the offset from the start address + * @param word_size the size, in bytes, of an addressable item + * @param count the number of data elements to write + * @param buffer the source buffer + * @param rm the asynchronous data request monitor */ - public void fillMemory(IDMContext ctx, BigInteger addr, - int word_size, byte[] value, int size, int mode, RequestMonitor rm); + public void setMemory(IDMContext context, IAddress address, long offset, + int word_size, int count, byte[] buffer, RequestMonitor rm); + + /** + * Writes [pattern] at memory [address] + [offset], [count] times. + * + * A MemoryChangedEvent will be generated for the range of addresses. + * + * @param context the context of the target memory block + * @param address the memory block address (on the target) + * @param offset the offset from the start address + * @param word_size the size, in bytes, of an addressable item + * @param count the number of data elements to write + * @param pattern the offset in the result buffer + * @param buffer the source buffer + * @param rm the asynchronous data request monitor + */ + public void fillMemory(IDMContext context, IAddress address, long offset, + int word_size, int count, byte[] pattern, RequestMonitor rm); } From 2bbc801bdf0daa4fdeef05dfdc93e14e208163f6 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 3 Oct 2007 14:34:26 +0000 Subject: [PATCH 158/834] [205288] Fixes to canceled update mis-handling. --- .../eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java | 5 ++++- .../dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java | 2 +- .../dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java index d77cfa1a26d..3ad8a811f20 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java @@ -60,7 +60,10 @@ public abstract class DsfCommandRunnable extends DsfRunnable { } public final void run() { - if (fRequest.isCanceled()) return; + if (fRequest.isCanceled()) { + fRequest.done(); + return; + } if (getContext() == null) { fRequest.setStatus(makeError("Selected object does not support run control.", null)); //$NON-NLS-1$ } else if (getRunControl() == null) { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java index 5c93622eaa4..91ce2b85734 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java @@ -282,7 +282,7 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode extends Abstract protected void updateHasElementsInSessionThread(IHasChildrenUpdate[] updates) { for (final IHasChildrenUpdate update : updates) { - if (!checkUpdate(update)) return; + if (!checkUpdate(update)) continue; updateElementsInSessionThread( new ElementsUpdate( @@ -318,7 +318,7 @@ abstract public class AbstractDMVMLayoutNode extends Abstract protected void updateLabelInSessionThread(ILabelUpdate[] updates) { for (final ILabelUpdate update : updates) { final IDMContext dmc = findDmcInPath(update.getElementPath(), fDMCClassType); - if (!checkDmc(dmc, update) || !checkService(null, dmc.getServiceFilter(), update)) return; + if (!checkDmc(dmc, update) || !checkService(null, dmc.getServiceFilter(), update)) continue; VMCacheManager.getVMCacheManager().getCache(update.getPresentationContext()) .getModelData((IDMService)getServicesTracker().getService(null, dmc.getServiceFilter()), From 29b939c50d264c96aa1a2be0f93b70aac0456c7f Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 3 Oct 2007 17:18:00 +0000 Subject: [PATCH 159/834] [205318] Added additional entries in logged stack traces of runnables executed by the executor. --- .../dd/dsf/concurrent/DefaultDsfExecutor.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java index c809f8bb522..9860699b246 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java @@ -170,8 +170,12 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor traceBuilder.append(dsfExecutable.fCreatedBy.fSequenceNumber); } if (dsfExecutable.fCreatedAt != null) { - traceBuilder.append(" at "); //$NON-NLS-1$ + traceBuilder.append("\n at "); //$NON-NLS-1$ traceBuilder.append(dsfExecutable.fCreatedAt.fStackTraceElements[0].toString()); + for (int i = 1; i < dsfExecutable.fCreatedAt.fStackTraceElements.length && i < 3; i++) { + traceBuilder.append("\n "); //$NON-NLS-1$ + traceBuilder.append(dsfExecutable.fCreatedAt.fStackTraceElements[i].toString()); + } } } } @@ -182,6 +186,12 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor traceBuilder.append(" by #"); //$NON-NLS-1$ traceBuilder.append(fSubmittedBy.fSequenceNumber); } + traceBuilder.append("\n at "); //$NON-NLS-1$ + traceBuilder.append(fSubmittedAt.fStackTraceElements[0].toString()); + for (int i = 1; i < fSubmittedAt.fStackTraceElements.length && i < 3; i++) { + traceBuilder.append("\n "); //$NON-NLS-1$ + traceBuilder.append(fSubmittedAt.fStackTraceElements[i].toString()); + } traceBuilder.append(" at "); //$NON-NLS-1$ traceBuilder.append(fSubmittedAt.fStackTraceElements[0].toString()); From 0ff106c599d00352070c14ef9913f4ba15627d45 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 3 Oct 2007 17:42:31 +0000 Subject: [PATCH 160/834] [205325] Initial source lookup service from Ottawa coding camp. --- .../dd/dsf/debug/service/ISourceLookup.java | 29 ++++++------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISourceLookup.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISourceLookup.java index 9f48bd058c3..066f620ae25 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISourceLookup.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISourceLookup.java @@ -12,8 +12,9 @@ package org.eclipse.dd.dsf.debug.service; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; 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.service.IDsfService; -import org.eclipse.debug.core.sourcelookup.ISourceContainer; /** * Service for mapping debugger paths to host paths. This service is needed @@ -22,30 +23,18 @@ import org.eclipse.debug.core.sourcelookup.ISourceContainer; * interfaces could be sufficient. */ public interface ISourceLookup extends IDsfService { - - public interface ISourceLookupResult { - Object getSourceObject(); - ISourceContainer getMatchingContainer(); - } - - public interface IDebuggerPathLookupResult { - String getDebuggerPath(); - ISourceContainer getMatchingContainer(); - } - - /** - * Initializes the given context with the given list of source lookup - * containers. - */ - void initializeSourceContainers(IDMContext ctx, ISourceContainer[] containers); + + public interface ISourceLookupDMContext extends IDMContext {} + + public interface ISourceLookupChangedDMEvent extends IDMEvent {} /** * Retrieves the host source object for given debugger path string. */ - void getSource(IDMContext ctx, String debuggerPath, boolean searchDuplicates, DataRequestMonitor rm); + void getSource(IDMContext ctx, String debuggerPath, DataRequestMonitor rm); /** - * Retrieves the debugger path string(s) for given host source object. + * Retrieves the debugger path string for given host source object. */ - void getDebuggerPath(IDMContext ctx, Object source, boolean searchDuplicates, DataRequestMonitor rm); + void getDebuggerPath(IDMContext ctx, Object source, DataRequestMonitor rm); } From ebd8d1632bf6f3a443f321364a2f1e07b2e2ebd5 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Sun, 7 Oct 2007 01:17:08 +0000 Subject: [PATCH 161/834] [205645] --- .../icons/refreshonbreak.gif | Bin 0 -> 331 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/icons/refreshonbreak.gif diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/icons/refreshonbreak.gif b/plugins/org.eclipse.dd.dsf.debug.ui/icons/refreshonbreak.gif new file mode 100644 index 0000000000000000000000000000000000000000..f16fbb072f88b42f912a69c98718f72625be0714 GIT binary patch literal 331 zcmZ?wbhEHb6krfwSZcamXQbh3so`O(3q*ddh9Kl+5$0zR7Oa=0q?lf*l2N6e zRjri^L^axZH9Gm#x&<}$@%F*JHud%P^Xu)4mq*N>A3uM7{rvg!@6WfNbg+Kf;mVEc zHqJlZxa?&6{{8dUotwD++{CSyW^TJQbH}AQJ1)&Vc6;4%5L$oi&bs4w)}Ow=<^O&A ztIrNyeSYZnt24J>pZWja{`u$I|Nqbbj~6KZ<1R@}aR6eyywnl~#h)yU3=H-RIt)Mn z@*)FU%qy%1;iG|pKQs~j1u0hFAn A`2YX_ literal 0 HcmV?d00001 From 4d45b0a3c472c192ff88732da8b81e35f6cea0b6 Mon Sep 17 00:00:00 2001 From: Francois Chouinard Date: Sun, 7 Oct 2007 19:43:55 +0000 Subject: [PATCH 162/834] Improvements for the following bugs: Bug200620: Added a memory cache Bug205341: Updated the MemocryChangedEvent --- .../dd/dsf/debug/model/DsfMemoryBlock.java | 43 ++++++++++++++++--- .../eclipse/dd/dsf/debug/service/IMemory.java | 21 ++++++--- 2 files changed, 50 insertions(+), 14 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java index 20bcfe08c85..9dde56e7f3a 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java @@ -17,14 +17,17 @@ import java.util.ArrayList; import java.util.concurrent.ExecutionException; import java.util.concurrent.RejectedExecutionException; +import org.eclipse.cdt.core.IAddress; import org.eclipse.cdt.utils.Addr64; import org.eclipse.core.runtime.PlatformObject; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.Query; import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.debug.service.IMemory; import org.eclipse.dd.dsf.debug.service.IRunControl; import org.eclipse.dd.dsf.debug.service.IMemory.MemoryChangedEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.DebugException; @@ -235,7 +238,8 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens * @see org.eclipse.debug.core.model.IMemoryBlockExtension#supportsChangeManagement() */ public boolean supportsChangeManagement() { - // Let the UI handle block content modification + // TODO: UI is a bit lazy. Implement change management ourselves. + // return true; return false; } @@ -354,20 +358,20 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens final Addr64 address = new Addr64(bigAddress); final int word_size = 1; - // Use a Query to "synchronize" the inherently asynchronous downstream calls + // Use a Query to synchronize the downstream calls Query query = new Query() { @Override - protected void execute(final DataRequestMonitor rm) { + protected void execute(final DataRequestMonitor drm) { IMemory memoryService = (IMemory) fRetrieval.getServiceTracker().getService(); if (memoryService != null) { // Go for it memoryService.getMemory( fRetrieval.getContext(), address, 0, word_size, (int) length, - new DataRequestMonitor(fRetrieval.getExecutor(), rm) { + new DataRequestMonitor(fRetrieval.getExecutor(), drm) { @Override protected void handleOK() { - rm.setData(getData()); - rm.done(); + drm.setData(getData()); + drm.done(); } }); } @@ -378,7 +382,9 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens try { return query.get(); } catch (InterruptedException e) { + System.out.println("Interrupted Exception"); //$NON-NLS-1$ } catch (ExecutionException e) { + System.out.println("Execution Exception"); //$NON-NLS-1$ } return null; @@ -386,11 +392,33 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens @DsfServiceEventHandler public void eventDispatched(MemoryChangedEvent e) { - handleMemoryChange(e.getAddress().getValue()); + + // Find the container of the event + IContainerDMContext eventContext = DMContexts.getAncestorOfType(e.getContext(), IContainerDMContext.class); + if (eventContext == null) { + return; + } + + // Find the container of the block + IContainerDMContext blockContext = DMContexts.getAncestorOfType(fRetrieval.getContext(), IContainerDMContext.class); + if (blockContext == null) { + // Should not happen: throw an exception + return; + } + + // Check if we are in the same address space + if (eventContext != blockContext) { + return; + } + + IAddress[] addresses = e.getAddresses(); + for (int i = 0; i < addresses.length; i++) + handleMemoryChange(addresses[i].getValue()); } @DsfServiceEventHandler public void eventDispatched(IRunControl.ISuspendedDMEvent e) { + // TODO: Check if we are in the right context handleMemoryChange(BigInteger.ZERO); } @@ -428,6 +456,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens * @param length */ public void handleMemoryChange(BigInteger address) { + // Check if the change affects this particular block (0 is universal) BigInteger fEndAddress = fBaseAddress.add(BigInteger.valueOf(fLength)); if (address.equals(BigInteger.ZERO) || diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java index f0d683bb96b..f45732ef9cd 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java @@ -43,19 +43,26 @@ public interface IMemory extends IDsfService { * * @DsfServiceEventHandler * public void eventDispatched(MemoryChangedEvent e) { - * IAddress address = e.getAddress(); + * IDMContext context = e.getContext(); + * IAddress[] addresses = e.getAddresses(); * // do whatever... * } */ public class MemoryChangedEvent { - IAddress fAddress; - - public MemoryChangedEvent(IAddress address) { - fAddress = address; + IAddress[] fAddresses; + IDMContext fContext; + + public MemoryChangedEvent(IDMContext context, IAddress[] addresses) { + fContext = context; + fAddresses = addresses; } - public IAddress getAddress() { - return fAddress; + public IDMContext getContext() { + return fContext; + } + + public IAddress[] getAddresses() { + return fAddresses; } } From de03bba29b88ea311acd937585747ad5fa763b25 Mon Sep 17 00:00:00 2001 From: Francois Chouinard Date: Fri, 12 Oct 2007 02:41:05 +0000 Subject: [PATCH 163/834] Management of memory delats between debugger steps. --- .../dd/dsf/debug/model/DsfMemoryBlock.java | 185 ++++++++++++------ .../debug/model/DsfMemoryBlockRetrieval.java | 26 +-- 2 files changed, 141 insertions(+), 70 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java index 9dde56e7f3a..12ed63f41c9 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java @@ -9,6 +9,8 @@ * Wind River Systems - initial API and implementation * Ericsson Communication - upgrade IF to IMemoryBlockExtension * Ericsson Communication - added support for 64 bit processors + * Ericsson Communication - added support for changed bytes + * Ericsson Communication - better management of exceptions *******************************************************************************/ package org.eclipse.dd.dsf.debug.model; @@ -19,11 +21,14 @@ import java.util.concurrent.RejectedExecutionException; import org.eclipse.cdt.core.IAddress; import org.eclipse.cdt.utils.Addr64; +import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.PlatformObject; +import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.Query; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.debug.DsfDebugPlugin; import org.eclipse.dd.dsf.debug.service.IMemory; import org.eclipse.dd.dsf.debug.service.IRunControl; import org.eclipse.dd.dsf.debug.service.IMemory.MemoryChangedEvent; @@ -52,10 +57,13 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens private final String fModelId; private final String fExpression; protected BigInteger fBaseAddress; - protected long fLength; + protected int fLength; + private MemoryByte[] fBlock; private ArrayList fConnections = new ArrayList(); - private boolean isEnabled; + + @SuppressWarnings("unused") + private boolean isEnabled; /** * Constructor. @@ -74,8 +82,9 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens fModelId = modelId; fExpression = expression; fBaseAddress = address; - fLength = length; - + fLength = (int) length; + fBlock = null; + try { fRetrieval.getExecutor().execute(new Runnable() { public void run() { @@ -160,7 +169,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens * @see org.eclipse.debug.core.model.IMemoryBlock#supportsValueModification() */ public boolean supportsValueModification() { - // return fDebugTarget.supportsValueModification(this); + // TODO: return fDebugTarget.supportsValueModification(this); return true; } @@ -217,7 +226,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens * @see org.eclipse.debug.core.model.IMemoryBlockExtension#getAddressSize() */ public int getAddressSize() throws DebugException { -// // TODO: +// TODO: // try { // return fDebugTarget.getAddressSize(); // } catch (CoreException e) { @@ -238,9 +247,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens * @see org.eclipse.debug.core.model.IMemoryBlockExtension#supportsChangeManagement() */ public boolean supportsChangeManagement() { - // TODO: UI is a bit lazy. Implement change management ourselves. - // return true; - return false; + return true; } /* (non-Javadoc) @@ -261,9 +268,65 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens * @see org.eclipse.debug.core.model.IMemoryBlockExtension#getBytesFromAddress(java.math.BigInteger, long) */ public MemoryByte[] getBytesFromAddress(BigInteger address, long units) throws DebugException { - fLength = units; + MemoryByte[] block = fetchMemoryBlock(address, units); - return block; + int newLength = (block != null) ? block.length : 0; + + // Flag the changed bytes + if (fBlock != null && newLength > 0) { + int offset = fBaseAddress.compareTo(address); + switch (offset) { + case -1: + { + offset = -offset; + int length = Math.min(fLength - offset, newLength); + for (int i = 0; i < length; i += 4) { + boolean changed = false; + for (int j = i; j < (i + 4) && j < length; j++) { + block[j].setFlags(fBlock[offset + j].getFlags()); + if (block[j].getValue() != fBlock[offset + j].getValue()) + changed = true; + } + if (changed) + for (int j = i; j < (i + 4) && j < length; j++) { + block[j].setHistoryKnown(true); + block[j].setChanged(true); + } + } + break; + } + + case 0: + case 1: + { + int length = Math.min(newLength - offset, fLength); + for (int i = 0; i < length; i += 4) { + boolean changed = false; + for (int j = i; j < (i + 4) && j < length; j++) { + block[offset + j].setFlags(fBlock[j].getFlags()); + if (block[offset + j].getValue() != fBlock[j].getValue()) + changed = true; + } + if (changed) + for (int j = i; j < (i + 4) && j < length; j++) { + block[offset + j].setHistoryKnown(true); + block[offset + j].setChanged(true); + } + } + break; + } + + default: + break; + } + } + + // Update the internal state + fBlock = block; + fBaseAddress = address; + fLength = newLength; + + return fBlock; } /* (non-Javadoc) @@ -319,7 +382,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens } }); } catch (RejectedExecutionException e) { - // Session is shut down. + // Session is down. } } @@ -338,9 +401,9 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens return 1; } - // //////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// // Helper functions - // //////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// /* * The real thing. Since the original call is synchronous (from a platform @@ -379,50 +442,21 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens } }; fRetrieval.getExecutor().execute(query); - try { + + try { return query.get(); } catch (InterruptedException e) { - System.out.println("Interrupted Exception"); //$NON-NLS-1$ + throw new DebugException(new Status(IStatus.ERROR, + DsfDebugPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, + "Error reading memory block (InterruptedException)", e)); //$NON-NLS-1$ } catch (ExecutionException e) { - System.out.println("Execution Exception"); //$NON-NLS-1$ + throw new DebugException(new Status(IStatus.ERROR, + DsfDebugPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, + "Error reading memory block (ExecutionException)", e)); //$NON-NLS-1$ } - - return null; } - @DsfServiceEventHandler - public void eventDispatched(MemoryChangedEvent e) { - - // Find the container of the event - IContainerDMContext eventContext = DMContexts.getAncestorOfType(e.getContext(), IContainerDMContext.class); - if (eventContext == null) { - return; - } - - // Find the container of the block - IContainerDMContext blockContext = DMContexts.getAncestorOfType(fRetrieval.getContext(), IContainerDMContext.class); - if (blockContext == null) { - // Should not happen: throw an exception - return; - } - - // Check if we are in the same address space - if (eventContext != blockContext) { - return; - } - - IAddress[] addresses = e.getAddresses(); - for (int i = 0; i < addresses.length; i++) - handleMemoryChange(addresses[i].getValue()); - } - - @DsfServiceEventHandler - public void eventDispatched(IRunControl.ISuspendedDMEvent e) { - // TODO: Check if we are in the right context - handleMemoryChange(BigInteger.ZERO); - } - - /* Writes an array of bytes to memory. + /* Writes an array of bytes to memory. * * @param offset * @param bytes @@ -440,17 +474,52 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens public void run() { memoryService.setMemory( fRetrieval.getContext(), address, offset, word_size, bytes.length, bytes, - new RequestMonitor(fRetrieval.getExecutor(), null) { - @Override - protected void handleOK() { - // handleMemoryChange(fBaseAddress); - } - }); + new RequestMonitor(fRetrieval.getExecutor(), null)); } }); } } + /////////////////////////////////////////////////////////////////////////// + // Event Handlers + /////////////////////////////////////////////////////////////////////////// + + @DsfServiceEventHandler + public void eventDispatched(IRunControl.ISuspendedDMEvent e) { + + // Clear the "Changed" flags after each run/resume/step + for (int i = 0; i < fLength; i++) + fBlock[i].setChanged(false); + + // Generate the MemoryChangedEvents + handleMemoryChange(BigInteger.ZERO); + } + + @DsfServiceEventHandler + public void eventDispatched(MemoryChangedEvent e) { + + // Find the container of the event + IContainerDMContext eventContext = DMContexts.getAncestorOfType(e.getContext(), IContainerDMContext.class); + if (eventContext == null) { + return; + } + + // Find the container of the block + IContainerDMContext blockContext = DMContexts.getAncestorOfType(fRetrieval.getContext(), IContainerDMContext.class); + if (blockContext == null) { + return; + } + + // Check if we are in the same address space + if (eventContext != blockContext) { + return; + } + + IAddress[] addresses = e.getAddresses(); + for (int i = 0; i < addresses.length; i++) + handleMemoryChange(addresses[i].getValue()); + } + /** * @param address * @param length diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java index 7d69e327032..e67483bad5c 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java @@ -240,18 +240,18 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl dmc = (IDMContext)((IAdaptable)context).getAdapter(IDMContext.class); } - // TODO: throw an exception if (dmc == null) { - return null; - } - // Update the DMC + return null; + } + + // Update the DMC fContext = dmc; // Resolve the expression blockAddress = resolveMemoryAddress(fContext, expression); - if (blockAddress == null) - // TODO: throw an exception + if (blockAddress == null) { return null; + } } /* @@ -317,13 +317,15 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl // The happy case return query.get(); } catch (InterruptedException e) { - // TODO: throw an exception - } catch (ExecutionException e) { - // TODO: throw an exception - } + throw new DebugException(new Status(IStatus.ERROR, + DsfDebugPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, + "Error evaluating memory address (InterruptedException).", e)); //$NON-NLS-1$ - // The error case - return null; + } catch (ExecutionException e) { + throw new DebugException(new Status(IStatus.ERROR, + DsfDebugPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, + "Error evaluating memory address (ExecutionException).", e)); //$NON-NLS-1$ + } } } From 7233f702b8e6b56ed1f9eede931025135026ce60 Mon Sep 17 00:00:00 2001 From: Francois Chouinard Date: Sun, 14 Oct 2007 20:41:05 +0000 Subject: [PATCH 164/834] Memory block offset fix when comparing 2 blocks to determine the changed bytes between debug steps. --- .../src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java index 12ed63f41c9..828882bc35e 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java @@ -274,11 +274,10 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens // Flag the changed bytes if (fBlock != null && newLength > 0) { - int offset = fBaseAddress.compareTo(address); - switch (offset) { + switch (fBaseAddress.compareTo(address)) { case -1: { - offset = -offset; + int offset = address.subtract(fBaseAddress).intValue(); int length = Math.min(fLength - offset, newLength); for (int i = 0; i < length; i += 4) { boolean changed = false; @@ -299,6 +298,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens case 0: case 1: { + int offset = fBaseAddress.subtract(address).intValue(); int length = Math.min(newLength - offset, fLength); for (int i = 0; i < length; i += 4) { boolean changed = false; From df21b47db18cae411e0cb2e9740ba4e08b8fa951 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 16 Oct 2007 00:15:37 +0000 Subject: [PATCH 165/834] [206400] Fix for invalid selection in Debug view when stepping. --- .../launch/StackFramesLayoutNode.java | 67 +++++++++++-------- 1 file changed, 40 insertions(+), 27 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java index 95f0fe97a9f..cb5a105de49 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java @@ -14,6 +14,7 @@ import java.util.List; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMEvent; import org.eclipse.dd.dsf.debug.service.IRunControl; @@ -231,9 +232,14 @@ public class StackFramesLayoutNode extends AbstractDMVMLayoutNode e, final VMDelta parent, final int nodeOffset, final RequestMonitor rm) { if (e instanceof IContainerSuspendedDMEvent) { - buildDeltaForSuspendedEvent((ISuspendedDMEvent)e, ((IContainerSuspendedDMEvent)e).getTriggeringContext(), parent, nodeOffset, rm); + IExecutionDMContext threadDmc = null; + if (parent.getElement() instanceof AbstractDMVMLayoutNode.DMVMContext) { + threadDmc = DMContexts.getAncestorOfType( ((DMVMContext)parent.getElement()).getDMC(), IExecutionDMContext.class); + } + buildDeltaForSuspendedEvent((ISuspendedDMEvent)e, threadDmc, ((IContainerSuspendedDMEvent)e).getTriggeringContext(), parent, nodeOffset, rm); } else if (e instanceof ISuspendedDMEvent) { - buildDeltaForSuspendedEvent((ISuspendedDMEvent)e, ((ISuspendedDMEvent)e).getDMContext(), parent, nodeOffset, rm); + IExecutionDMContext execDmc = ((ISuspendedDMEvent)e).getDMContext(); + buildDeltaForSuspendedEvent((ISuspendedDMEvent)e, execDmc, execDmc, parent, nodeOffset, rm); } else if (e instanceof IResumedDMEvent) { buildDeltaForResumedEvent((IResumedDMEvent)e, parent, nodeOffset, rm); } else if (e instanceof IStepQueueManager.ISteppingTimedOutEvent) { @@ -244,7 +250,7 @@ public class StackFramesLayoutNode extends AbstractDMVMLayoutNode>(getSession().getExecutor(), null) { - @Override - public void handleCompleted() { - if (getStatus().isOK() && getData().size() != 0) { - parent.addNode( getData().get(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().size() >= 2) { - parent.addNode( getData().get(1), IModelDelta.STATE); - } - } - // Even in case of errors, call super-class to complete building of the delta. - StackFramesLayoutNode.super.buildDeltaForDMEvent(e, parent, nodeOffset, rm); - } - }, - parent) - ); + // Check if we are building a delta for the thread that triggered the event. + // Only then expand the stack frames and select the top one. + if (executionCtx.equals(triggeringCtx)) { + // 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( + new ElementsUpdate( + new DataRequestMonitor>(getSession().getExecutor(), null) { + @Override + public void handleCompleted() { + if (getStatus().isOK() && getData().size() != 0) { + parent.addNode( getData().get(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().size() >= 2) { + parent.addNode( getData().get(1), IModelDelta.STATE); + } + } + // Even in case of errors, call super-class to complete building of the delta. + StackFramesLayoutNode.super.buildDeltaForDMEvent(e, parent, nodeOffset, rm); + } + }, + parent) + ); + } else { + // Don't forget to call the super class to complete building the delta (and call child nodes.) + StackFramesLayoutNode.super.buildDeltaForDMEvent(e, parent, nodeOffset, rm); + } } private void buildDeltaForResumedEvent(final IResumedDMEvent e, final VMDelta parent, final int nodeOffset, final RequestMonitor rm) { From 732160a2a547efa63c5e695d1cd0b37bedc8328d Mon Sep 17 00:00:00 2001 From: Francois Chouinard Date: Wed, 17 Oct 2007 20:10:55 +0000 Subject: [PATCH 166/834] Fixes following Pawel's comments. --- .../dd/dsf/debug/model/DsfMemoryBlock.java | 93 +++++++++++-------- .../debug/model/DsfMemoryBlockRetrieval.java | 45 ++++++--- .../eclipse/dd/dsf/debug/service/IMemory.java | 9 +- 3 files changed, 89 insertions(+), 58 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java index 828882bc35e..7809fb2273c 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java @@ -56,8 +56,10 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens private final DsfMemoryBlockRetrieval fRetrieval; private final String fModelId; private final String fExpression; - protected BigInteger fBaseAddress; - protected int fLength; + private final BigInteger fBaseAddress; + + private BigInteger fBlockAddress; + private int fLength; private MemoryByte[] fBlock; private ArrayList fConnections = new ArrayList(); @@ -76,14 +78,17 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens */ DsfMemoryBlock(DsfMemoryBlockRetrieval retrieval, String modelId, String expression, BigInteger address, long length) { - fLaunch = null; // TODO: fRetrieval.getLaunch(); - fDebugTarget = null; // TODO: fRetrieval.getDebugTarget(); + fLaunch = retrieval.getLaunch(); + fDebugTarget = retrieval.getDebugTarget(); fRetrieval = retrieval; fModelId = modelId; fExpression = expression; fBaseAddress = address; - fLength = (int) length; - fBlock = null; + + // Current block information + fBlockAddress = address; + fLength = (int) length; + fBlock = null; try { fRetrieval.getExecutor().execute(new Runnable() { @@ -169,8 +174,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens * @see org.eclipse.debug.core.model.IMemoryBlock#supportsValueModification() */ public boolean supportsValueModification() { - // TODO: return fDebugTarget.supportsValueModification(this); - return true; + return fRetrieval.supportsValueModification(); } /* (non-Javadoc) @@ -226,21 +230,14 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens * @see org.eclipse.debug.core.model.IMemoryBlockExtension#getAddressSize() */ public int getAddressSize() throws DebugException { -// TODO: -// try { -// return fDebugTarget.getAddressSize(); -// } catch (CoreException e) { -// throw new DebugException(e.getStatus()); -// } - return 4; + return fRetrieval.getAddressSize(); } /* (non-Javadoc) * @see org.eclipse.debug.core.model.IMemoryBlockExtension#supportBaseAddressModification() */ public boolean supportBaseAddressModification() throws DebugException { - // TODO: return fDebugTarget.supportBaseAddressModification(this); - return false; + return fRetrieval.supportBaseAddressModification(); } /* (non-Javadoc) @@ -254,14 +251,14 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens * @see org.eclipse.debug.core.model.IMemoryBlockExtension#setBaseAddress(java.math.BigInteger) */ public void setBaseAddress(BigInteger address) throws DebugException { - fBaseAddress = address; + fBlockAddress = address; } /* (non-Javadoc) * @see org.eclipse.debug.core.model.IMemoryBlockExtension#getBytesFromOffset(java.math.BigInteger, long) */ public MemoryByte[] getBytesFromOffset(BigInteger offset, long units) throws DebugException { - return getBytesFromAddress(fBaseAddress.add(offset), units); + return getBytesFromAddress(fBlockAddress.add(offset), units); } /* (non-Javadoc) @@ -274,10 +271,10 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens // Flag the changed bytes if (fBlock != null && newLength > 0) { - switch (fBaseAddress.compareTo(address)) { + switch (fBlockAddress.compareTo(address)) { case -1: { - int offset = address.subtract(fBaseAddress).intValue(); + int offset = address.subtract(fBlockAddress).intValue(); int length = Math.min(fLength - offset, newLength); for (int i = 0; i < length; i += 4) { boolean changed = false; @@ -298,7 +295,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens case 0: case 1: { - int offset = fBaseAddress.subtract(address).intValue(); + int offset = fBlockAddress.subtract(address).intValue(); int length = Math.min(newLength - offset, fLength); for (int i = 0; i < length; i += 4) { boolean changed = false; @@ -323,7 +320,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens // Update the internal state fBlock = block; - fBaseAddress = address; + fBlockAddress = address; fLength = newLength; return fBlock; @@ -397,8 +394,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens * @see org.eclipse.debug.core.model.IMemoryBlockExtension#getAddressableSize() */ public int getAddressableSize() throws DebugException { - // TODO: return fDebugTarget.getAddressableSize(); - return 1; + return fRetrieval.getAddressableSize(); } /////////////////////////////////////////////////////////////////////////// @@ -421,7 +417,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens final Addr64 address = new Addr64(bigAddress); final int word_size = 1; - // Use a Query to synchronize the downstream calls + // Use a Query to synchronise the downstream calls Query query = new Query() { @Override protected void execute(final DataRequestMonitor drm) { @@ -437,10 +433,10 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens drm.done(); } }); - } - } - }; + + } + }; fRetrieval.getExecutor().execute(query); try { @@ -468,16 +464,33 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens final Addr64 address = new Addr64(fBaseAddress); final int word_size = 1; - final IMemory memoryService = (IMemory) fRetrieval.getServiceTracker().getService(); - if (memoryService != null) { - memoryService.getExecutor().execute(new Runnable() { - public void run() { + // Use a Query to synchronise the downstream calls + Query query = new Query() { + @Override + protected void execute(final DataRequestMonitor drm) { + IMemory memoryService = (IMemory) fRetrieval.getServiceTracker().getService(); + if (memoryService != null) { + // Go for it memoryService.setMemory( - fRetrieval.getContext(), address, offset, word_size, bytes.length, bytes, - new RequestMonitor(fRetrieval.getExecutor(), null)); - } - }); - } + fRetrieval.getContext(), address, offset, word_size, bytes.length, bytes, + new RequestMonitor(fRetrieval.getExecutor(), null)); + } + + } + }; + fRetrieval.getExecutor().execute(query); + + try { + query.get(); + } catch (InterruptedException e) { + throw new DebugException(new Status(IStatus.ERROR, + DsfDebugPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, + "Error writing memory block (InterruptedException)", e)); //$NON-NLS-1$ + } catch (ExecutionException e) { + throw new DebugException(new Status(IStatus.ERROR, + DsfDebugPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, + "Error writing memory block (ExecutionException)", e)); //$NON-NLS-1$ + } } /////////////////////////////////////////////////////////////////////////// @@ -527,9 +540,9 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens public void handleMemoryChange(BigInteger address) { // Check if the change affects this particular block (0 is universal) - BigInteger fEndAddress = fBaseAddress.add(BigInteger.valueOf(fLength)); + BigInteger fEndAddress = fBlockAddress.add(BigInteger.valueOf(fLength)); if (address.equals(BigInteger.ZERO) || - ((fBaseAddress.compareTo(address) != 1) && (fEndAddress.compareTo(address) == 1))) + ((fBlockAddress.compareTo(address) != 1) && (fEndAddress.compareTo(address) == 1))) { // Notify the event listeners DebugEvent debugEvent = new DebugEvent(this, DebugEvent.CHANGE, DebugEvent.CONTENT); diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java index e67483bad5c..4820e38f1da 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java @@ -36,6 +36,8 @@ import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.model.IDebugTarget; import org.eclipse.debug.core.model.IMemoryBlock; import org.eclipse.debug.core.model.IMemoryBlockExtension; import org.eclipse.debug.core.model.IMemoryBlockRetrievalExtension; @@ -137,30 +139,47 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl return fSession; } - /** - * - * @return - */ public DsfExecutor getExecutor() { return fExecutor; } - /** - * - * @return - */ public IDMContext getContext() { return fContext; } - /** - * - * @return - */ public ServiceTracker getServiceTracker() { return fMemoryServiceTracker; } + // //////////////////////////////////////////////////////////////////////// + // Launch/Target specific information + // To be completed + // //////////////////////////////////////////////////////////////////////// + + public ILaunch getLaunch() { + return null; + } + + public IDebugTarget getDebugTarget() { + return null; + } + + public int getAddressSize() { + return 4; + } + + public int getAddressableSize() { + return 1; + } + + public boolean supportsValueModification() { + return true; + } + + public boolean supportBaseAddressModification() { + return false; + } + // //////////////////////////////////////////////////////////////////////// // IMemoryBlockRetrieval - obsoleted by IMemoryBlockRetrievalExtension // //////////////////////////////////////////////////////////////////////// @@ -276,7 +295,7 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl private BigInteger resolveMemoryAddress(final IDMContext idmContext, final String expression) throws DebugException { - // Use a Query to "synchronize" the inherently asynchronous downstream calls + // Use a Query to "synchronise" the downstream calls Query query = new Query() { @Override protected void execute(final DataRequestMonitor drm) { diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java index f45732ef9cd..c8abbffe41e 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java @@ -27,10 +27,10 @@ import org.eclipse.debug.core.model.MemoryByte; public interface IMemory extends IDsfService { /** - * Event generated every time a byte is modified. + * Event generated every time a range of bytes is modified. * * A client wishing to receive such events has to register as a service - * event listener and implement the corresponding dispatchEvent method. + * event listener and implement the corresponding eventDispatched method. * * E.g.: * @@ -119,9 +119,8 @@ public interface IMemory extends IDsfService { * @param address the memory block address (on the target) * @param offset the offset from the start address * @param word_size the size, in bytes, of an addressable item - * @param count the number of data elements to write - * @param pattern the offset in the result buffer - * @param buffer the source buffer + * @param count the number of times [pattern] will be written + * @param pattern the source buffer * @param rm the asynchronous data request monitor */ public void fillMemory(IDMContext context, IAddress address, long offset, From 4e553d325016ac56808f48540393b9dcb7193318 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Fri, 19 Oct 2007 20:00:25 +0000 Subject: [PATCH 167/834] Fix for bug 206931 which cleans up IFormattedValues --- .../detailpanesupport/DetailPane.java | 4 ++-- .../register/RegisterBitFieldLayoutNode.java | 4 ++-- .../register/RegisterLayoutNode.java | 4 ++-- .../register/SyncRegisterDataAccess.java | 4 ++-- .../variable/SyncVariableDataAccess.java | 4 ++-- .../variable/VariableLayoutNode.java | 4 ++-- .../debug/model/DsfMemoryBlockRetrieval.java | 2 +- .../dsf/debug/service/IFormattedValues.java | 23 ++++++++----------- 8 files changed, 23 insertions(+), 26 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPane.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPane.java index 4c860a6b4bd..309057757ad 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPane.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPane.java @@ -402,7 +402,7 @@ public class DetailPane implements IDetailPane, IAdaptable, IPropertyChangeListe /* * Format has been validated. Get the formatted value. */ - final FormattedValueDMContext valueDmc = finalService.getFormattedValue(finalDmc, str); + final FormattedValueDMContext valueDmc = finalService.getFormattedValueContext(finalDmc, str); finalService.getModelData( valueDmc, new DataRequestMonitor(finalService.getSession().getExecutor(), null) { @@ -443,7 +443,7 @@ public class DetailPane implements IDetailPane, IAdaptable, IPropertyChangeListe */ finalService.getExecutor().submit(new Runnable() { public void run() { - finalService.getAvailableFormattedValues(finalDmc, getAvailableFormatsDone); + finalService.getAvailableFormats(finalDmc, getAvailableFormatsDone); } } ); diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java index ee413c11160..5a4cde99f6d 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java @@ -188,7 +188,7 @@ public class RegisterBitFieldLayoutNode extends AbstractExpressionLayoutNode(getSession().getExecutor(), null) { @Override @@ -236,7 +236,7 @@ public class RegisterBitFieldLayoutNode extends AbstractExpressionLayoutNode(getSession().getExecutor(), null) { @Override @@ -235,7 +235,7 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode(session.getExecutor(), rm) { @Override @@ -850,7 +850,7 @@ public class SyncRegisterDataAccess { * Convert to the proper formatting DMC then go get the formatted value. */ - FormattedValueDMContext formDmc = service.getFormattedValue(fDmc, fFormatId); + FormattedValueDMContext formDmc = service.getFormattedValueContext(fDmc, fFormatId); service.getModelData(formDmc, new DataRequestMonitor( session.getExecutor(), rm) { @Override diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java index d309c83ef0e..b2ca3cb0107 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java @@ -323,7 +323,7 @@ public class SyncVariableDataAccess { /* * Write the bit field using a string/format style. */ - service.getAvailableFormattedValues( + service.getAvailableFormats( fDmc, new DataRequestMonitor(session.getExecutor(), rm) { @Override @@ -423,7 +423,7 @@ public class SyncVariableDataAccess { * Convert to the proper formatting DMC then go get the formatted value. */ - FormattedValueDMContext formDmc = service.getFormattedValue(fDmc, fFormatId); + FormattedValueDMContext formDmc = service.getFormattedValueContext(fDmc, fFormatId); service.getModelData(formDmc, new DataRequestMonitor(session.getExecutor(), rm) { @Override diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java index 5b3942fa2fc..52f36f58a3a 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java @@ -327,7 +327,7 @@ public class VariableLayoutNode extends AbstractExpressionLayoutNode(getSession().getExecutor(), null) { @Override @@ -373,7 +373,7 @@ public class VariableLayoutNode extends AbstractExpressionLayoutNode(getExecutor(), null) { diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java index 88c601e33d1..dbff3af9fed 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java @@ -23,9 +23,9 @@ public interface IFormattedValues extends IDMService { public interface IFormattedDataDMContext extends IDMContext {} /** - * These strings represent the standard known formats for any bit stream + * These strings represent the standard known formats for any bit stream * which needs to be formatted. These ID's as well as others which may be - * specifically available from the backend are what is returned from the + * specifically available from the backend are what is returned from the * getID() method. */ public final static String HEX_FORMAT = "HEX.Format" ; //$NON-NLS-1$ @@ -35,26 +35,23 @@ public interface IFormattedValues extends IDMService { public final static String DECIMAL_FORMAT = "DECIMAL.Format" ; //$NON-NLS-1$ /** - * Retrieves the available formats that the given data is available in. + * Retrieves the formats that the given data is available in. * This method is asynchronous because the service may need to retrieve - * information from the back end in order to determine what formats are + * information from the backend in order to determine what formats are * available for the given data context. * - * @param dmc Context for which to retrieve available formatted values. + * @param dmc Context for which to retrieve available formats. * @param rm Completion monitor returns an array of support formatIds. */ - public void getAvailableFormattedValues(IFormattedDataDMContext dmc, DataRequestMonitor rm); + public void getAvailableFormats(IFormattedDataDMContext dmc, DataRequestMonitor rm); /** - * Retrieves the available formats that the given data is available in. - * This method is asynchronous because the service may need to retrieve - * information from the back end in order to determine what formats are - * available for the given data context. + * Creates a FormattedValueDMContext representing the given formatId. * - * @param dmc Context for which to retrieve a IValueDMContext. - * @param formatId Defines format to be supplied from the returned context. + * @param dmc Parent context for the context that is being created + * @param formatId Defines format to be used for the returned context. */ - public FormattedValueDMContext getFormattedValue(IFormattedDataDMContext dmc, String formatId); + public FormattedValueDMContext getFormattedValueContext(IFormattedDataDMContext dmc, String formatId); /** * DMC that represents a value with specific format. The format ID can be From 7286137a7e3db3fe5de219667d7bd5d629161ed1 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 19 Oct 2007 22:15:57 +0000 Subject: [PATCH 168/834] [205132] First step in refactoring IDMContext: - Removed the type parameter from IDMContext - Got rid of the IDMContext.getServiceFilter() method. --- .../org.eclipse.dd.dsf.debug.ui/plugin.xml | 3 - .../debug/ui/actions/DsfTerminateCommand.java | 2 +- .../sourcelookup/MISourceDisplayAdapter.java | 16 +-- .../ui/sourcelookup/SourceLookupResult.java | 8 +- .../detailpanesupport/DetailPane.java | 4 +- .../AbstractExpressionLayoutNode.java | 5 +- .../expression/ExpressionVMProvider.java | 4 +- .../launch/StackFramesLayoutNode.java | 50 ++++++++- .../RegisterBitFieldLayoutCellModifier.java | 2 +- .../register/RegisterBitFieldLayoutNode.java | 11 +- .../register/RegisterGroupLayoutNode.java | 50 ++++++++- .../register/RegisterLayoutNode.java | 13 +-- .../RegisterLayoutValueCellModifier.java | 2 +- .../register/RegisterVMProvider.java | 2 +- .../register/SyncRegisterDataAccess.java | 99 ++++++++++------- .../variable/SyncVariableDataAccess.java | 82 ++++++++------ .../variable/VariableLayoutNode.java | 11 +- .../variable/VariableVMProvider.java | 2 +- .../debug/model/DsfMemoryBlockRetrieval.java | 20 ++-- .../dd/dsf/debug/service/IBreakpoints.java | 6 +- .../dd/dsf/debug/service/IExpressions.java | 6 +- .../dsf/debug/service/IFormattedValues.java | 19 ++-- .../eclipse/dd/dsf/debug/service/IMemory.java | 12 +- .../dd/dsf/debug/service/IModules.java | 12 +- .../dsf/debug/service/INativeProcesses.java | 20 ++-- .../org/eclipse/dd/dsf/debug/service/IOS.java | 10 +- .../dd/dsf/debug/service/IRegisters.java | 20 ++-- .../dd/dsf/debug/service/IRunControl.java | 22 ++-- .../dd/dsf/debug/service/ISourceLookup.java | 7 +- .../eclipse/dd/dsf/debug/service/IStack.java | 14 +-- .../dsf/debug/service/IStepQueueManager.java | 12 +- .../dd/dsf/debug/service/ISymbols.java | 2 +- .../dd/dsf/debug/service/ITargets.java | 4 +- .../dsf/debug/service/command/ICommand.java | 2 +- .../DsfMISourceLookupParticipant.java | 8 +- .../viewmodel/dm/AbstractDMVMLayoutNode.java | 105 +++--------------- .../ui/viewmodel/dm/DMVMRootLayoutNode.java | 10 +- .../dd/dsf/ui/viewmodel/update/VMCache.java | 10 +- .../dd/dsf/datamodel/AbstractDMContext.java | 26 ++--- .../dd/dsf/datamodel/AbstractDMEvent.java | 2 +- .../eclipse/dd/dsf/datamodel/DMContexts.java | 12 +- .../eclipse/dd/dsf/datamodel/IDMContext.java | 15 +-- .../org/eclipse/dd/dsf/datamodel/IDMData.java | 20 +--- .../eclipse/dd/dsf/datamodel/IDMEvent.java | 2 +- .../eclipse/dd/dsf/datamodel/IDMService.java | 6 +- .../dd/dsf/datamodel/ServiceDMContext.java | 6 +- 46 files changed, 387 insertions(+), 389 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml index 7a9f78f174e..6c3f7d75771 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml +++ b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml @@ -117,7 +117,6 @@ .DMVMContext)" need to use the // construct below and suppress warnings. @SuppressWarnings("unchecked") - AbstractDMVMLayoutNode.DMVMContext vmc = (AbstractDMVMLayoutNode.DMVMContext)request.getElements()[0]; + AbstractDMVMLayoutNode.DMVMContext vmc = (AbstractDMVMLayoutNode.DMVMContext)request.getElements()[0]; final IExecutionDMContext dmc = DMContexts.getAncestorOfType(vmc.getDMC(), IExecutionDMContext.class); if (dmc == null) { request.setEnabled(false); diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java index 97db364a8ff..f909be36734 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java @@ -89,13 +89,13 @@ public class MISourceDisplayAdapter implements ISourceDisplay */ class LookupJob extends Job { - private IDMContext fDmc; + private IDMContext fDmc; private IWorkbenchPage fPage; /** * Constructs a new source lookup job. */ - public LookupJob(IDMContext dmc, IWorkbenchPage page) { + public LookupJob(IDMContext dmc, IWorkbenchPage page) { super("DSF Source Lookup"); //$NON-NLS-1$ setPriority(Job.INTERACTIVE); setSystem(true); @@ -103,7 +103,7 @@ public class MISourceDisplayAdapter implements ISourceDisplay fPage = page; } - IDMContext getDmc() { return fDmc; } + IDMContext getDmc() { return fDmc; } /* (non-Javadoc) * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor) @@ -164,7 +164,7 @@ public class MISourceDisplayAdapter implements ISourceDisplay private SourceLookupResult fResult; private IWorkbenchPage fPage; - IDMContext getDmc() { return fResult.getDmc(); } + IDMContext getDmc() { return fResult.getDmc(); } /** * Constructs a new source display job @@ -257,7 +257,7 @@ public class MISourceDisplayAdapter implements ISourceDisplay /** * Positions the text editor for the given stack frame */ - private void positionEditor(ITextEditor editor, final IDMContext dmc) { + private void positionEditor(ITextEditor editor, final IDMContext dmc) { if (!(dmc instanceof IFrameDMContext)) return; final IFrameDMContext frameDmc = (IFrameDMContext)dmc; @@ -387,7 +387,7 @@ public class MISourceDisplayAdapter implements ISourceDisplay private DsfSession fSession; private DsfExecutor fExecutor; private DsfServicesTracker fServicesTracker; - private IDMContext fPrevModelContext; + private IDMContext fPrevModelContext; private SourceLookupResult fPrevResult; private ISourceLookupDirector fSourceLookup; private DsfMISourceLookupParticipant fSourceLookupParticipant; @@ -430,7 +430,7 @@ public class MISourceDisplayAdapter implements ISourceDisplay if (!(context instanceof DMVMContext)) return; // Correct cast: (AbstractDMVMLayoutNode.DMVMContext) breaks the javac compiler @SuppressWarnings("unchecked") - final IDMContext dmc = ((DMVMContext)context).getDMC(); + final IDMContext dmc = ((DMVMContext)context).getDMC(); // Quick test. DMC is checked again in source lookup participant, but // it's much quicker to test here. @@ -455,7 +455,7 @@ public class MISourceDisplayAdapter implements ISourceDisplay } } - private void startLookupJob(final IDMContext dmc, final IWorkbenchPage page) { + private void startLookupJob(final IDMContext dmc, final IWorkbenchPage page) { // If there is a previous lookup job running, cancel it. if (fRunningLookupJob != null) { fRunningLookupJob.cancel(); diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/SourceLookupResult.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/SourceLookupResult.java index fdf90a4eeab..01dd9526711 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/SourceLookupResult.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/SourceLookupResult.java @@ -24,7 +24,7 @@ class SourceLookupResult { /** * Element that source was resolved for. */ - private IDMContext fDmc; + private IDMContext fDmc; /** * Corresponding source element, or null * if unknown. @@ -45,7 +45,7 @@ class SourceLookupResult { * Creates a source lookup result on the given artifact, source element, * editor id, and editor input. */ - public SourceLookupResult(IDMContext dmc, Object sourceElement, String editorId, IEditorInput editorInput) { + public SourceLookupResult(IDMContext dmc, Object sourceElement, String editorId, IEditorInput editorInput) { fDmc = dmc; setSourceElement(sourceElement); setEditorId(editorId); @@ -55,7 +55,7 @@ class SourceLookupResult { /* (non-Javadoc) * @see org.eclipse.debug.ui.sourcelookup.ISourceLookupResult#getArtifact() */ - public IDMContext getDmc() { + public IDMContext getDmc() { return fDmc; } @@ -121,7 +121,7 @@ class SourceLookupResult { * * @param artifact new artifact state */ - public void updateArtifact(IDMContext dmc) { + public void updateArtifact(IDMContext dmc) { if (fDmc.equals(dmc)) { fDmc = dmc; } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPane.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPane.java index 309057757ad..992a98612ce 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPane.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPane.java @@ -321,7 +321,7 @@ public class DetailPane implements IDetailPane, IAdaptable, IPropertyChangeListe */ if ( element instanceof DMVMContext) { IFormattedValues service = null; - IFormattedDataDMContext dmc = null ; + IFormattedDataDMContext dmc = null ; /* * We are specifically looking to support the following Data Model Contexts @@ -384,7 +384,7 @@ public class DetailPane implements IDetailPane, IAdaptable, IPropertyChangeListe * typically be a burden. We should probably consider perhaps doing a * preference where they can select what formats they want to show. */ - final IFormattedDataDMContext finalDmc = dmc; + final IFormattedDataDMContext finalDmc = dmc; final IFormattedValues finalService = service; final DataRequestMonitor getAvailableFormatsDone = diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionLayoutNode.java index 10e75b9a990..94034ddcdf1 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionLayoutNode.java @@ -21,7 +21,6 @@ import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.MultiRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.datamodel.IDMData; import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; @@ -39,11 +38,11 @@ import org.eclipse.jface.viewers.TreePath; * */ @SuppressWarnings("restriction") -public abstract class AbstractExpressionLayoutNode extends AbstractDMVMLayoutNode +public abstract class AbstractExpressionLayoutNode extends AbstractDMVMLayoutNode implements IExpressionLayoutNode { - public AbstractExpressionLayoutNode(AbstractVMProvider provider, DsfSession session, Class> dmcClassType) { + public AbstractExpressionLayoutNode(AbstractVMProvider provider, DsfSession session, Class dmcClassType) { super(provider, session, dmcClassType); } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java index b7e56356f52..33c54a67b97 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java @@ -60,8 +60,8 @@ public class ExpressionVMProvider extends AbstractDebugDMVMProviderWithCache imp /* * Allocate the synchronous data providers. */ - SyncRegisterDataAccess syncRegDataAccess = new SyncRegisterDataAccess(); - SyncVariableDataAccess syncvarDataAccess = new SyncVariableDataAccess() ; + SyncRegisterDataAccess syncRegDataAccess = new SyncRegisterDataAccess(getSession()); + SyncVariableDataAccess syncvarDataAccess = new SyncVariableDataAccess(getSession()) ; /* * Create the top level node which provides the anchor starting point. diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java index cb5a105de49..62bee6a8935 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java @@ -15,7 +15,6 @@ import java.util.List; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.DMContexts; -import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMEvent; import org.eclipse.dd.dsf.debug.service.IRunControl; import org.eclipse.dd.dsf.debug.service.IStack; @@ -28,10 +27,12 @@ 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.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; @@ -41,7 +42,7 @@ import org.eclipse.debug.ui.DebugUITools; import org.eclipse.debug.ui.IDebugUIConstants; @SuppressWarnings("restriction") -public class StackFramesLayoutNode extends AbstractDMVMLayoutNode { +public class StackFramesLayoutNode extends AbstractDMVMLayoutNode { public IVMContext[] fCachedOldFrameVMCs; @@ -143,8 +144,49 @@ public class StackFramesLayoutNode extends AbstractDMVMLayoutNode dmContext, IFrameDMData dmData, String columnId, int idx, - ILabelUpdate update) + protected void updateLabelInSessionThread(ILabelUpdate[] updates) { + for (final ILabelUpdate update : updates) { + final IFrameDMContext dmc = findDmcInPath(update.getElementPath(), IFrameDMContext.class); + if (!checkDmc(dmc, update) || !checkService(IStack.class, null, update)) continue; + + VMCacheManager.getVMCacheManager().getCache(update.getPresentationContext()) + .getModelData(getServicesTracker().getService(IStack.class, null), + dmc, + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + protected void handleCompleted() { + /* + * Check that the request was evaluated and data is still + * valid. The request could fail if the state of the + * service changed during the request, but the view model + * has not been updated yet. + */ + if (!getStatus().isOK()) { + assert getStatus().isOK() || + getStatus().getCode() != IDsfService.INTERNAL_ERROR || + getStatus().getCode() != IDsfService.NOT_SUPPORTED; + handleFailedUpdate(update); + return; + } + + /* + * If columns are configured, call the protected methods to + * fill in column values. + */ + String[] localColumns = update.getPresentationContext().getColumns(); + if (localColumns == null) localColumns = new String[] { null }; + + for (int i = 0; i < localColumns.length; i++) { + fillColumnLabel(dmc, getData(), localColumns[i], i, update); + } + update.done(); + } + }, + getExecutor()); + } + } + + protected void fillColumnLabel(IFrameDMContext dmContext, IFrameDMData dmData, String columnId, int idx, ILabelUpdate update) { if (idx != 0) return; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutCellModifier.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutCellModifier.java index ca6743d766a..c2277e7cf6a 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutCellModifier.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutCellModifier.java @@ -41,7 +41,7 @@ public class RegisterBitFieldLayoutCellModifier extends WatchExpressionCellModif */ private IBitFieldDMContext getBitFieldDMC(Object element) { if (element instanceof AbstractDMVMLayoutNode.DMVMContext) { - IDMContext dmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); + IDMContext dmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); return DMContexts.getAncestorOfType(dmc, IBitFieldDMContext.class); } return null; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java index 5a4cde99f6d..bd52e022401 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java @@ -18,7 +18,6 @@ import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMEvent; -import org.eclipse.dd.dsf.datamodel.IDMService; import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.dd.dsf.debug.service.IRegisters; import org.eclipse.dd.dsf.debug.service.IRunControl; @@ -64,13 +63,13 @@ import org.eclipse.jface.viewers.TreePath; import org.eclipse.swt.widgets.Composite; @SuppressWarnings("restriction") -public class RegisterBitFieldLayoutNode extends AbstractExpressionLayoutNode implements IElementEditor { +public class RegisterBitFieldLayoutNode extends AbstractExpressionLayoutNode implements IElementEditor { protected class BitFieldVMC extends DMVMContext implements IVariable, IFormattedValueVMContext { private IExpression fExpression; - public BitFieldVMC(IDMContext dmc) { + public BitFieldVMC(IDMContext dmc) { super(dmc); } @@ -285,7 +284,7 @@ public class RegisterBitFieldLayoutNode extends AbstractExpressionLayoutNode(getSession().getExecutor(), null) { @Override @@ -296,7 +295,7 @@ public class RegisterBitFieldLayoutNode extends AbstractExpressionLayoutNode dmc) { + protected IVMContext createVMContext(IDMContext dmc) { return new BitFieldVMC(dmc); } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java index 54e50c28698..7d78bcd950d 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java @@ -56,14 +56,14 @@ import org.eclipse.jface.viewers.TreePath; import org.eclipse.swt.widgets.Composite; @SuppressWarnings("restriction") -public class RegisterGroupLayoutNode extends AbstractExpressionLayoutNode +public class RegisterGroupLayoutNode extends AbstractExpressionLayoutNode implements IElementEditor { protected class RegisterGroupVMC extends DMVMContext implements IVariable { private IExpression fExpression; - public RegisterGroupVMC(IDMContext dmc) { + public RegisterGroupVMC(IDMContext dmc) { super(dmc); } @@ -173,13 +173,55 @@ public class RegisterGroupLayoutNode extends AbstractExpressionLayoutNode dmc) { + protected IVMContext createVMContext(IDMContext dmc) { return new RegisterGroupVMC(dmc); } @Override - protected void fillColumnLabel(IDMContext dmContext, IRegisterGroupDMData dmData, + protected void updateLabelInSessionThread(ILabelUpdate[] updates) { + for (final ILabelUpdate update : updates) { + final IRegisterGroupDMContext dmc = findDmcInPath(update.getElementPath(), IRegisterGroupDMContext.class); + if (!checkDmc(dmc, update) || !checkService(IRegisters.class, null, update)) continue; + + VMCacheManager.getVMCacheManager().getCache(update.getPresentationContext()) + .getModelData(getServicesTracker().getService(IRegisters.class, null), + dmc, + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + protected void handleCompleted() { + /* + * Check that the request was evaluated and data is still + * valid. The request could fail if the state of the + * service changed during the request, but the view model + * has not been updated yet. + */ + if (!getStatus().isOK()) { + assert getStatus().isOK() || + getStatus().getCode() != IDsfService.INTERNAL_ERROR || + getStatus().getCode() != IDsfService.NOT_SUPPORTED; + handleFailedUpdate(update); + return; + } + + /* + * If columns are configured, call the protected methods to + * fill in column values. + */ + String[] localColumns = update.getPresentationContext().getColumns(); + if (localColumns == null) localColumns = new String[] { null }; + + for (int i = 0; i < localColumns.length; i++) { + fillColumnLabel(dmc, getData(), localColumns[i], i, update); + } + update.done(); + } + }, + getExecutor()); + } + } + + protected void fillColumnLabel(IRegisterGroupDMContext dmContext, IRegisterGroupDMData dmData, String columnId, int idx, ILabelUpdate update) { if (IDebugVMConstants.COLUMN_ID__NAME.equals(columnId)) { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java index 62a111723a1..09ccc6d68ab 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java @@ -18,7 +18,6 @@ import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMEvent; -import org.eclipse.dd.dsf.datamodel.IDMService; import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.dd.dsf.debug.service.IRegisters; import org.eclipse.dd.dsf.debug.service.IRunControl; @@ -63,14 +62,14 @@ import org.eclipse.jface.viewers.TreePath; import org.eclipse.swt.widgets.Composite; @SuppressWarnings("restriction") -public class RegisterLayoutNode extends AbstractExpressionLayoutNode +public class RegisterLayoutNode extends AbstractExpressionLayoutNode implements IElementEditor { protected class RegisterVMC extends DMVMContext implements IVariable, IFormattedValueVMContext { private IExpression fExpression; - public RegisterVMC(IDMContext dmc) { + public RegisterVMC(IDMContext dmc) { super(dmc); } @@ -282,10 +281,10 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode(getSession().getExecutor(), null) { @Override @@ -296,7 +295,7 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode dmc) { + protected IVMContext createVMContext(IDMContext dmc) { return new RegisterVMC(dmc); } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutValueCellModifier.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutValueCellModifier.java index d0e0f6a7d23..eb699b3f28d 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutValueCellModifier.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutValueCellModifier.java @@ -45,7 +45,7 @@ public class RegisterLayoutValueCellModifier extends WatchExpressionCellModifier */ protected IRegisterDMContext getRegisterDMC(Object element) { if (element instanceof AbstractDMVMLayoutNode.DMVMContext) { - IDMContext dmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); + IDMContext dmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); return DMContexts.getAncestorOfType(dmc, IRegisterDMContext.class); } return null; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java index f2b0b6bf103..35a655e91e7 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java @@ -35,7 +35,7 @@ public class RegisterVMProvider extends AbstractDebugDMVMProviderWithCache /* * Create the register data access routines. */ - SyncRegisterDataAccess regAccess = new SyncRegisterDataAccess() ; + SyncRegisterDataAccess regAccess = new SyncRegisterDataAccess(session) ; /* * Create the top level node to deal with the root selection. diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java index bbcc9cbdafd..60c37dde51b 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java @@ -17,6 +17,7 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.Query; +import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.concurrent.ThreadSafeAndProhibitedFromDsfExecutor; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; @@ -38,45 +39,59 @@ import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; import org.osgi.framework.InvalidSyntaxException; import org.osgi.util.tracker.ServiceTracker; -@ThreadSafeAndProhibitedFromDsfExecutor("") +@ThreadSafeAndProhibitedFromDsfExecutor("fSession#getExecutor") public class SyncRegisterDataAccess { + /** + * The session that this data access operates in. + */ + private final DsfSession fSession; + /** * Need to use the OSGi service tracker here (instead of DsfServiceTracker), * because we're accessing it in non-dispatch thread. DsfServiceTracker is * not thread-safe. */ + @ThreadSafe private ServiceTracker fServiceTracker; - private synchronized IRegisters getService(String filter) { + public SyncRegisterDataAccess(DsfSession session) { + fSession = session; + } + + @ThreadSafe + private synchronized IRegisters getService() { if (fServiceTracker == null) { try { - fServiceTracker = new ServiceTracker(DsfDebugUIPlugin - .getBundleContext(), DsfDebugUIPlugin.getBundleContext() - .createFilter(filter), null); + fServiceTracker = new ServiceTracker( + DsfDebugUIPlugin.getBundleContext(), + DsfDebugUIPlugin.getBundleContext().createFilter(getServiceFilter()), null); fServiceTracker.open(); } catch (InvalidSyntaxException e) { - assert false : "Invalid filter in DMC: " + filter; //$NON-NLS-1$ return null; } - } else { - /* - * All of the DMCs that this cell modifier is invoked for should - * originate from the same service. This assertion checks this - * assumption by comparing the service reference in the tracker to - * the filter string in the DMC. - */ - try { - assert DsfDebugUIPlugin.getBundleContext().createFilter(filter) - .match(fServiceTracker.getServiceReference()); - } catch (InvalidSyntaxException e) { - } } return (IRegisters) fServiceTracker.getService(); } - public void dispose() { + private String getServiceFilter() { + StringBuffer filter = new StringBuffer(); + filter.append("(&"); //$NON-NLS-1$ + filter.append("(OBJECTCLASS="); //$NON-NLS-1$ + filter.append(IRegisters.class.getName()); + filter.append(')'); + filter.append('('); + filter.append(IDsfService.PROP_SESSION_ID); + filter.append('='); + filter.append(fSession.getId()); + filter.append(')'); + filter.append(')'); + return filter.toString(); + } + + @ThreadSafe + public synchronized void dispose() { if ( fServiceTracker != null ) { fServiceTracker.close(); } @@ -105,7 +120,7 @@ public class SyncRegisterDataAccess { return; } - IRegisters service = getService(fDmc.getServiceFilter()); + IRegisters service = getService(); if (service == null) { rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service not available", null)); //$NON-NLS-1$ rm.done(); @@ -140,7 +155,7 @@ public class SyncRegisterDataAccess { public IBitFieldDMContext getBitFieldDMC(Object element) { if (element instanceof AbstractDMVMLayoutNode.DMVMContext) { - IDMContext dmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); + IDMContext dmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); return DMContexts.getAncestorOfType(dmc, IBitFieldDMContext.class); } return null; @@ -207,7 +222,7 @@ public class SyncRegisterDataAccess { /* * Guard against a disposed service */ - IRegisters service = getService(fDmc.getServiceFilter()); + IRegisters service = getService(); if (service == null) { rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ rm.done(); @@ -315,7 +330,7 @@ public class SyncRegisterDataAccess { /* * Guard against a disposed service */ - IRegisters service = getService(fDmc.getServiceFilter()); + IRegisters service = getService(); if (service == null) { rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ rm.done(); @@ -396,7 +411,7 @@ public class SyncRegisterDataAccess { public IRegisterGroupDMContext getRegisterGroupDMC(Object element) { if (element instanceof AbstractDMVMLayoutNode.DMVMContext) { - IDMContext dmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); + IDMContext dmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); return DMContexts.getAncestorOfType(dmc, IRegisterGroupDMContext.class); } return null; @@ -404,15 +419,15 @@ public class SyncRegisterDataAccess { public IRegisterDMContext getRegisterDMC(Object element) { if (element instanceof AbstractDMVMLayoutNode.DMVMContext) { - IDMContext dmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); + IDMContext dmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); return DMContexts.getAncestorOfType(dmc, IRegisterDMContext.class); } return null; } - public IFormattedDataDMContext getFormattedDMC(Object element) { + public IFormattedDataDMContext getFormattedDMC(Object element) { if (element instanceof AbstractDMVMLayoutNode.DMVMContext) { - IDMContext dmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); + IDMContext dmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); IRegisterDMContext regdmc = DMContexts.getAncestorOfType(dmc, IRegisterDMContext.class); return DMContexts.getAncestorOfType(regdmc, IFormattedDataDMContext.class); } @@ -442,7 +457,7 @@ public class SyncRegisterDataAccess { return; } - IRegisters service = getService(fDmc.getServiceFilter()); + IRegisters service = getService(); if (service == null) { rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service not available", null)); //$NON-NLS-1$ rm.done(); @@ -531,7 +546,7 @@ public class SyncRegisterDataAccess { return; } - IRegisters service = getService(fDmc.getServiceFilter()); + IRegisters service = getService(); if (service == null) { rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service not available", null)); //$NON-NLS-1$ rm.done(); @@ -625,7 +640,7 @@ public class SyncRegisterDataAccess { /* * Guard against a disposed service */ - IRegisters service = getService(fDmc.getServiceFilter()); + IRegisters service = getService(); if (service == null) { rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ rm.done(); @@ -712,9 +727,9 @@ public class SyncRegisterDataAccess { public class GetSupportFormatsValueQuery extends Query { - IFormattedDataDMContext fDmc; + IFormattedDataDMContext fDmc; - public GetSupportFormatsValueQuery(IFormattedDataDMContext dmc) { + public GetSupportFormatsValueQuery(IFormattedDataDMContext dmc) { super(); fDmc = dmc; } @@ -734,7 +749,7 @@ public class SyncRegisterDataAccess { /* * Guard against a disposed service */ - IRegisters service = getService(fDmc.getServiceFilter()); + IRegisters service = getService(); if (service == null) { rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ rm.done(); @@ -779,9 +794,9 @@ public class SyncRegisterDataAccess { * Get the DMC and the session. If element is not an register DMC, or * session is stale, then bail out. */ - IFormattedDataDMContext dmc = null; + IFormattedDataDMContext dmc = null; if (element instanceof AbstractDMVMLayoutNode.DMVMContext) { - IDMContext vmcdmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); + IDMContext vmcdmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); IRegisterDMContext regdmc = DMContexts.getAncestorOfType(vmcdmc, IRegisterDMContext.class); dmc = DMContexts.getAncestorOfType(regdmc, IFormattedDataDMContext.class); } @@ -815,10 +830,10 @@ public class SyncRegisterDataAccess { public class GetFormattedValueValueQuery extends Query { - private IFormattedDataDMContext fDmc; + private IFormattedDataDMContext fDmc; private String fFormatId; - public GetFormattedValueValueQuery(IFormattedDataDMContext dmc, String formatId) { + public GetFormattedValueValueQuery(IFormattedDataDMContext dmc, String formatId) { super(); fDmc = dmc; fFormatId = formatId; @@ -839,7 +854,7 @@ public class SyncRegisterDataAccess { /* * Guard against a disposed service */ - IRegisters service = getService(fDmc.getServiceFilter()); + IRegisters service = getService(); if (service == null) { rm .setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ rm.done(); @@ -883,9 +898,9 @@ public class SyncRegisterDataAccess { * Get the DMC and the session. If element is not an register DMC, or * session is stale, then bail out. */ - IFormattedDataDMContext dmc = null; + IFormattedDataDMContext dmc = null; if (element instanceof AbstractDMVMLayoutNode.DMVMContext) { - IDMContext vmcdmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); + IDMContext vmcdmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); IRegisterDMContext regdmc = DMContexts.getAncestorOfType(vmcdmc, IRegisterDMContext.class); dmc = DMContexts.getAncestorOfType(regdmc, IFormattedDataDMContext.class); } @@ -923,9 +938,9 @@ public class SyncRegisterDataAccess { * Get the DMC and the session. If element is not an register DMC, or * session is stale, then bail out. */ - IFormattedDataDMContext dmc = null; + IFormattedDataDMContext dmc = null; if (element instanceof AbstractDMVMLayoutNode.DMVMContext) { - IDMContext vmcdmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); + IDMContext vmcdmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); IBitFieldDMContext bitfielddmc = DMContexts.getAncestorOfType(vmcdmc, IBitFieldDMContext.class); dmc = DMContexts.getAncestorOfType(bitfielddmc, IFormattedDataDMContext.class); } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java index b2ca3cb0107..6c010c9f15a 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java @@ -13,6 +13,7 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.Query; +import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.concurrent.ThreadSafeAndProhibitedFromDsfExecutor; import org.eclipse.dd.dsf.debug.service.IExpressions; import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; @@ -26,45 +27,60 @@ import org.eclipse.dd.dsf.service.IDsfService; import org.osgi.framework.InvalidSyntaxException; import org.osgi.util.tracker.ServiceTracker; -@ThreadSafeAndProhibitedFromDsfExecutor("") +@ThreadSafeAndProhibitedFromDsfExecutor("fSession#getExecutor") public class SyncVariableDataAccess { + /** + * The session that this data access operates in. + */ + private final DsfSession fSession; + /** * Need to use the OSGi service tracker here (instead of DsfServiceTracker), * because we're accessing it in non-dispatch thread. DsfServiceTracker is * not thread-safe. */ + @ThreadSafe private ServiceTracker fServiceTracker; - private synchronized IExpressions getService(String filter) { + + public SyncVariableDataAccess(DsfSession session) { + fSession = session; + } + + @ThreadSafe + private synchronized IExpressions getService() { if (fServiceTracker == null) { try { - fServiceTracker = new ServiceTracker(DsfDebugUIPlugin - .getBundleContext(), DsfDebugUIPlugin.getBundleContext() - .createFilter(filter), null); + fServiceTracker = new ServiceTracker( + DsfDebugUIPlugin.getBundleContext(), + DsfDebugUIPlugin.getBundleContext().createFilter(getServiceFilter()), null); fServiceTracker.open(); } catch (InvalidSyntaxException e) { - assert false : "Invalid filter in DMC: " + filter; //$NON-NLS-1$ return null; } - } else { - /* - * All of the DMCs that this cell modifier is invoked for should - * originate from the same service. This assertion checks this - * assumption by comparing the service reference in the tracker to - * the filter string in the DMC. - */ - try { - assert DsfDebugUIPlugin.getBundleContext().createFilter(filter) - .match(fServiceTracker.getServiceReference()); - } catch (InvalidSyntaxException e) { - } - } + } return (IExpressions) fServiceTracker.getService(); } - - public void dispose() { + + private String getServiceFilter() { + StringBuffer filter = new StringBuffer(); + filter.append("(&"); //$NON-NLS-1$ + filter.append("(OBJECTCLASS="); //$NON-NLS-1$ + filter.append(IExpressions.class.getName()); + filter.append(')'); + filter.append('('); + filter.append(IDsfService.PROP_SESSION_ID); + filter.append('='); + filter.append(fSession.getId()); + filter.append(')'); + filter.append(')'); + return filter.toString(); + } + + @ThreadSafe + public synchronized void dispose() { if (fServiceTracker != null) { fServiceTracker.close(); } @@ -101,7 +117,7 @@ public class SyncVariableDataAccess { return; } - IExpressions service = getService(fDmc.getServiceFilter()); + IExpressions service = getService(); if (service == null) { rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service not available", null)); //$NON-NLS-1$ rm.done(); @@ -202,7 +218,7 @@ public class SyncVariableDataAccess { /* * Guard against a disposed service */ - IExpressions service = getService(fDmc.getServiceFilter()); + IExpressions service = getService(); if (service == null) { rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ rm.done(); @@ -282,18 +298,18 @@ public class SyncVariableDataAccess { } } - public IFormattedDataDMContext getFormattedDMC(Object element) { + public IFormattedDataDMContext getFormattedDMC(Object element) { if (element instanceof IAdaptable) { - return (IFormattedDataDMContext) ((IAdaptable) element).getAdapter(IFormattedDataDMContext.class); + return (IFormattedDataDMContext) ((IAdaptable) element).getAdapter(IFormattedDataDMContext.class); } return null; } public class GetSupportFormatsValueQuery extends Query { - IFormattedDataDMContext fDmc; + IFormattedDataDMContext fDmc; - public GetSupportFormatsValueQuery(IFormattedDataDMContext dmc) { + public GetSupportFormatsValueQuery(IFormattedDataDMContext dmc) { super(); fDmc = dmc; } @@ -313,7 +329,7 @@ public class SyncVariableDataAccess { /* * Guard against a disposed service */ - IExpressions service = getService(fDmc.getServiceFilter()); + IExpressions service = getService(); if (service == null) { rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ rm.done(); @@ -358,7 +374,7 @@ public class SyncVariableDataAccess { * Get the DMC and the session. If element is not an register DMC, or * session is stale, then bail out. */ - IFormattedDataDMContext dmc = getFormattedDMC(element); + IFormattedDataDMContext dmc = getFormattedDMC(element); if (dmc == null) return null; DsfSession session = DsfSession.getSession(dmc.getSessionId()); if (session == null) return null; @@ -388,10 +404,10 @@ public class SyncVariableDataAccess { public class GetFormattedValueValueQuery extends Query { - private IFormattedDataDMContext fDmc; + private IFormattedDataDMContext fDmc; private String fFormatId; - public GetFormattedValueValueQuery(IFormattedDataDMContext dmc, String formatId) { + public GetFormattedValueValueQuery(IFormattedDataDMContext dmc, String formatId) { super(); fDmc = dmc; fFormatId = formatId; @@ -412,7 +428,7 @@ public class SyncVariableDataAccess { /* * Guard against a disposed service */ - IExpressions service = getService(fDmc.getServiceFilter()); + IExpressions service = getService(); if (service == null) { rm .setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ rm.done(); @@ -456,7 +472,7 @@ public class SyncVariableDataAccess { * Get the DMC and the session. If element is not an register DMC, or * session is stale, then bail out. */ - IFormattedDataDMContext dmc = getFormattedDMC(element); + IFormattedDataDMContext dmc = getFormattedDMC(element); if (dmc == null) return null; DsfSession session = DsfSession.getSession(dmc.getSessionId()); if (session == null) return null; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java index 52f36f58a3a..d696d5233b9 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java @@ -19,7 +19,6 @@ import org.eclipse.dd.dsf.concurrent.MultiRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.datamodel.IDMService; import org.eclipse.dd.dsf.debug.service.IExpressions; import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.dd.dsf.debug.service.IRunControl; @@ -63,7 +62,7 @@ import org.eclipse.jface.viewers.TextCellEditor; import org.eclipse.swt.widgets.Composite; @SuppressWarnings({"restriction", "nls"}) -public class VariableLayoutNode extends AbstractExpressionLayoutNode implements IElementEditor { +public class VariableLayoutNode extends AbstractExpressionLayoutNode implements IElementEditor { /** * List of child nodes containing only a reference to this. This is what enables the view model @@ -126,7 +125,7 @@ public class VariableLayoutNode extends AbstractExpressionLayoutNode dmc) { + public VariableExpressionVMC(IDMContext dmc) { super(dmc); } @@ -208,7 +207,7 @@ public class VariableLayoutNode extends AbstractExpressionLayoutNode dmc) { + protected IVMContext createVMContext(IDMContext dmc) { return new VariableExpressionVMC(dmc); } @@ -225,7 +224,7 @@ public class VariableLayoutNode extends AbstractExpressionLayoutNode(getSession().getExecutor(), null) { @Override @@ -234,7 +233,7 @@ public class VariableLayoutNode extends AbstractExpressionLayoutNode fContext; + private IDMContext fContext; private final ServiceTracker fMemoryServiceTracker; private final ServiceTracker fExpressionServiceTracker; @@ -77,7 +77,7 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl * @param dmc * @throws DebugException */ - public DsfMemoryBlockRetrieval(String modelId, IDMContext dmc) throws DebugException { + public DsfMemoryBlockRetrieval(String modelId, IDMContext dmc) throws DebugException { fModelId = modelId; fContext = dmc; @@ -143,7 +143,7 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl return fExecutor; } - public IDMContext getContext() { + public IDMContext getContext() { return fContext; } @@ -254,9 +254,9 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl // In case of failure, simply return 'null' // Drill for the actual DMC - IDMContext dmc = null; + IDMContext dmc = null; if (context instanceof IAdaptable) { - dmc = (IDMContext)((IAdaptable)context).getAdapter(IDMContext.class); + dmc = (IDMContext)((IAdaptable)context).getAdapter(IDMContext.class); } if (dmc == null) { @@ -293,7 +293,7 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl // Helper functions // //////////////////////////////////////////////////////////////////////// - private BigInteger resolveMemoryAddress(final IDMContext idmContext, final String expression) throws DebugException { + private BigInteger resolveMemoryAddress(final IDMContext idmContext, final String expression) throws DebugException { // Use a Query to "synchronise" the downstream calls Query query = new Query() { @@ -312,15 +312,13 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl FormattedValueDMContext valueDmc = expressionService.getFormattedValueContext(expressionDMC, formatId); expressionService.getModelData( valueDmc, - new DataRequestMonitor(getExecutor(), null) { + new DataRequestMonitor(getExecutor(), drm) { @Override protected void handleOK() { // Store the result FormattedValueDMData data = getData(); - if (data.isValid()) { - String value = data.getFormattedValue().substring(2); // Strip the "0x" - drm.setData(new BigInteger(value, 16)); - } + String value = data.getFormattedValue().substring(2); // Strip the "0x" + drm.setData(new BigInteger(value, 16)); drm.done(); } } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java index 5dfef324649..0b2b47cfa0e 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java @@ -28,7 +28,7 @@ public interface IBreakpoints extends IDMService { public enum BreakpointStatus { INSTALLED, FAILED_TO_INSTALL, FILTERED_OUT } - public interface IBreakpointDMContext extends IDMContext {} + public interface IBreakpointDMContext extends IDMContext {} public interface IBreakpointDMData extends IDMData { IBreakpoint getPlatformBreakpoint(); @@ -43,7 +43,7 @@ public interface IBreakpoints extends IDMService { public interface IBreakpointHitEvent extends IBreakpointDMEvent {} - public void getAllBreakpoints(IDMContext execDmc, DataRequestMonitor rm); - public void getBreakpoints(IDMContext execDmc, IBreakpoint platformBp, DataRequestMonitor rm); + public void getAllBreakpoints(IDMContext ctx, DataRequestMonitor rm); + public void getBreakpoints(IDMContext ctx, IBreakpoint platformBp, DataRequestMonitor rm); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java index c959988c262..46171c09738 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java @@ -32,7 +32,7 @@ public interface IExpressions extends IDMService, IFormattedValues { * Expression context. Since some expressions have children, expression contexts can have an * arbitrary number of parents of type IExpressionDMContext. */ - public interface IExpressionDMContext extends IFormattedDataDMContext { + public interface IExpressionDMContext extends IFormattedDataDMContext { /** * Returns a fully qualified expression string represented by this context. This * expression string is the same as the string that is sent to the debug engine to be @@ -149,7 +149,7 @@ public interface IExpressions extends IDMService, IFormattedValues { * @return An expression data model context object that must be passed to getModelData() to obtain the * value of the expression. */ - IExpressionDMContext createExpression(IDMContext ctx, String expression); + IExpressionDMContext createExpression(IDMContext ctx, String expression); /** * Retrieves the sub-expressions of the given expression. Sub-expressions are fields of a struct, union, @@ -208,5 +208,5 @@ public interface IExpressions extends IDMService, IFormattedValues { * * @param rm: Request completion monitor. */ - void writeExpression(IDMContext expressionContext, String exressionValue, String formatId, RequestMonitor rm); + void writeExpression(IDMContext expressionContext, String exressionValue, String formatId, RequestMonitor rm); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java index dbff3af9fed..1e046f79899 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java @@ -20,7 +20,7 @@ import org.eclipse.dd.dsf.datamodel.IDMService; public interface IFormattedValues extends IDMService { /** Marker interface for a DMC that has a formatted value. */ - public interface IFormattedDataDMContext extends IDMContext {} + public interface IFormattedDataDMContext extends IDMContext {} /** * These strings represent the standard known formats for any bit stream @@ -43,7 +43,7 @@ public interface IFormattedValues extends IDMService { * @param dmc Context for which to retrieve available formats. * @param rm Completion monitor returns an array of support formatIds. */ - public void getAvailableFormats(IFormattedDataDMContext dmc, DataRequestMonitor rm); + public void getAvailableFormats(IFormattedDataDMContext dmc, DataRequestMonitor rm); /** * Creates a FormattedValueDMContext representing the given formatId. @@ -51,24 +51,24 @@ public interface IFormattedValues extends IDMService { * @param dmc Parent context for the context that is being created * @param formatId Defines format to be used for the returned context. */ - public FormattedValueDMContext getFormattedValueContext(IFormattedDataDMContext dmc, String formatId); + public FormattedValueDMContext getFormattedValueContext(IFormattedDataDMContext dmc, String formatId); /** * DMC that represents a value with specific format. The format ID can be * persisted and used for comparison. */ - public static class FormattedValueDMContext extends AbstractDMContext + public static class FormattedValueDMContext extends AbstractDMContext { private final String fFormatID; - public FormattedValueDMContext(IDMService service, IDMContext parent, String formatId) { + public FormattedValueDMContext(IDMService service, IDMContext parent, String formatId) { super(service, new IDMContext[] { parent }); fFormatID = formatId; } - public FormattedValueDMContext(String sessionId, String filter, IDMContext parent, String formatId) { - super(sessionId, filter, new IDMContext[] { parent }); + public FormattedValueDMContext(String sessionId, IDMContext parent, String formatId) { + super(sessionId, new IDMContext[] { parent }); fFormatID = formatId; } @@ -103,10 +103,5 @@ public interface IFormattedValues extends IDMService { public String getFormattedValue() { return fValue; } - - public boolean isValid() { - return true; - } - } } \ No newline at end of file diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java index c8abbffe41e..24b1f4de6a7 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java @@ -50,14 +50,14 @@ public interface IMemory extends IDsfService { */ public class MemoryChangedEvent { IAddress[] fAddresses; - IDMContext fContext; + IDMContext fContext; - public MemoryChangedEvent(IDMContext context, IAddress[] addresses) { + public MemoryChangedEvent(IDMContext context, IAddress[] addresses) { fContext = context; fAddresses = addresses; } - public IDMContext getContext() { + public IDMContext getContext() { return fContext; } @@ -86,7 +86,7 @@ public interface IMemory extends IDsfService { * @param count the number of data elements to read * @param drm the asynchronous data request monitor */ - public void getMemory(IDMContext context, IAddress address, long offset, + public void getMemory(IDMContext context, IAddress address, long offset, int word_size, int count, DataRequestMonitor drm); /** @@ -107,7 +107,7 @@ public interface IMemory extends IDsfService { * @param buffer the source buffer * @param rm the asynchronous data request monitor */ - public void setMemory(IDMContext context, IAddress address, long offset, + public void setMemory(IDMContext context, IAddress address, long offset, int word_size, int count, byte[] buffer, RequestMonitor rm); /** @@ -123,7 +123,7 @@ public interface IMemory extends IDsfService { * @param pattern the source buffer * @param rm the asynchronous data request monitor */ - public void fillMemory(IDMContext context, IAddress address, long offset, + public void fillMemory(IDMContext context, IAddress address, long offset, int word_size, int count, byte[] pattern, RequestMonitor rm); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java index 6625ffcf9d2..6592afd98ec 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java @@ -30,12 +30,12 @@ public interface IModules extends IDMService { * 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 ISymbolDMContext extends IDMContext{} + public interface ISymbolDMContext extends IDMContext {} /** * Module context represents a single module that is loaded. */ - public interface IModuleDMContext extends IDMContext {} + public interface IModuleDMContext extends IDMContext {} /** * Event indicating a change in the symbol information for given context. @@ -101,7 +101,7 @@ public interface IModules extends IDMService { } /** Module information. */ - public interface IModuleDMData extends IDMData { + public interface IModuleDMData { String getName(); String getFile(); long getTimeStamp(); @@ -134,16 +134,16 @@ public interface IModules extends IDMService { /** * Retreives the list of modules loaded in given symbol context. */ - void getModules(IDMContext symCtx, DataRequestMonitor rm); + void getModules(IDMContext symCtx, DataRequestMonitor rm); /** * Calculates the line numbers corresponding to the given address. */ - void calcLineInfo(IDMContext symCtx, IAddress address, DataRequestMonitor rm); + void calcLineInfo(IDMContext symCtx, IAddress address, DataRequestMonitor rm); /** * Calculates the addresses corresponding to the given source file location. */ - void calcAddressInfo(IDMContext symCtx, String file, int line, int col, DataRequestMonitor rm); + void calcAddressInfo(IDMContext symCtx, String file, int line, int col, DataRequestMonitor rm); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/INativeProcesses.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/INativeProcesses.java index 9ec6fb99795..b3509de12a1 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/INativeProcesses.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/INativeProcesses.java @@ -26,8 +26,8 @@ import org.eclipse.dd.dsf.datamodel.IDMService; */ public interface INativeProcesses extends IDMService { - public interface IThreadDMContext extends IDMContext {} - public interface IProcessDMContext extends IDMContext {} + public interface IThreadDMContext extends IDMContext {} + public interface IProcessDMContext extends IDMContext {} /** * Interface for thread and process object data. @@ -36,7 +36,7 @@ public interface INativeProcesses extends IDMService { String getName(); String getId(); boolean isDebuggerAttached(); - IDMContext getDebugContext(); + IDMContext getDebugContext(); } /** @@ -46,7 +46,7 @@ public interface INativeProcesses extends IDMService { String getName(); String getId(); boolean isDebuggerAttached(); - IDMContext getDebugContext(); + IDMContext getDebugContext(); } /** @@ -55,11 +55,11 @@ public interface INativeProcesses extends IDMService { public interface IProcessChangedDMEvent extends IDMEvent {} - public interface IProcessStartedEvent extends IDMEvent> { + public interface IProcessStartedEvent extends IDMEvent { IProcessDMContext getProcess(); } - public interface IProcessExitedEvent extends IDMEvent> { + public interface IProcessExitedEvent extends IDMEvent { IProcessDMContext getProcess(); } @@ -69,13 +69,13 @@ public interface INativeProcesses extends IDMService { * @param execCtx * @return */ - public IThreadDMContext getThreadForDebugContext(IDMContext execCtx); + public IThreadDMContext getThreadForDebugContext(IDMContext execCtx); /** * Returns a process context corresponding to the given context. null if no * corresponding process exists. */ - public IProcessDMContext getProcessForDebugContext(IDMContext execCtx); + public IProcessDMContext getProcessForDebugContext(IDMContext execCtx); /** * Retrieves the current list of processes running on target. @@ -114,13 +114,13 @@ public interface INativeProcesses extends IDMService { * @param thread Thread or process to terminate. * @param rm Return token. */ - void canTerminate(IDMContext ctx, DataRequestMonitor rm); + void canTerminate(IDMContext ctx, DataRequestMonitor rm); /** * Terminates the selected process or thread. * @param thread Thread or process to terminate. * @param rm Request completion monitor, indicates success or failure. */ - void terminate(IDMContext ctx, RequestMonitor requestMonitor); + void terminate(IDMContext ctx, RequestMonitor requestMonitor); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IOS.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IOS.java index 165719a2ebd..e399e572a3d 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IOS.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IOS.java @@ -10,8 +10,8 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.service; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMData; import org.eclipse.dd.dsf.datamodel.IDMService; @@ -30,7 +30,7 @@ public interface IOS extends IDMService { * Context object for the whole OS, for debuggers that support * debugging multiple targets/cores simultaneously. */ - public interface IOSDMContext extends IDMContext {} + public interface IOSDMContext extends IDMContext {} /** * Data object describing OS info @@ -44,7 +44,7 @@ public interface IOS extends IDMService { /** * Context for a OS object type, such as process, kernel task, semaphore, etc. */ - public interface IObjectTypeDMContext extends IDMContext {} + public interface IObjectTypeDMContext extends IDMContext {} /** * Description data for a OS object type. @@ -59,7 +59,7 @@ public interface IOS extends IDMService { /** * OS object context. */ - public interface IObjectDMContext extends IDMContext {} + public interface IObjectDMContext extends IDMContext {} /** * Description data for an OS object. @@ -69,7 +69,7 @@ public interface IOS extends IDMService { String getID(); boolean canAttachDebugger(); boolean isDebuggerAttached(); - IDMContext getDebuggingContext(); + IDMContext getDebuggingContext(); } /** diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java index 46812eb93bf..56ce313eedb 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java @@ -25,7 +25,7 @@ public interface IRegisters extends IFormattedValues { public interface IGroupsChangedDMEvent extends IDMEvent {} /** Register group context */ - public interface IRegisterGroupDMContext extends IFormattedDataDMContext { + public interface IRegisterGroupDMContext extends IFormattedDataDMContext { public String getName(); } @@ -45,7 +45,7 @@ public interface IRegisters extends IFormattedValues { } /** Register context */ - public interface IRegisterDMContext extends IFormattedDataDMContext { + public interface IRegisterDMContext extends IFormattedDataDMContext { public String getName(); } @@ -66,7 +66,7 @@ public interface IRegisters extends IFormattedValues { } /** Bit field context */ - public interface IBitFieldDMContext extends IFormattedDataDMContext { + public interface IBitFieldDMContext extends IFormattedDataDMContext { public String getName(); } @@ -109,28 +109,28 @@ public interface IRegisters extends IFormattedValues { * @param ctx Context for the returned data. * @param rm Request completion monitor. */ - void getRegisterGroups(IDMContext ctx, DataRequestMonitor rm); + void getRegisterGroups(IDMContext ctx, DataRequestMonitor rm); /** * Retrieves list of sub-groups of given register group. * @param ctx Context for the returned data. * @param rm Request completion monitor. */ - void getRegisterSubGroups(IDMContext ctx, DataRequestMonitor rm); + void getRegisterSubGroups(IDMContext ctx, DataRequestMonitor rm); /** * Retrieves registers in given register group. * @param ctx Context for the returned data. * @param rm Request completion monitor. */ - void getRegisters(IDMContext ctx, DataRequestMonitor rm); + void getRegisters(IDMContext ctx, DataRequestMonitor rm); /** * Retrieves bit fields for given register * @param ctx Context for the returned data. * @param rm Request completion monitor. */ - void getBitFields(IDMContext ctx, DataRequestMonitor rm); + void getBitFields(IDMContext ctx, DataRequestMonitor rm); /** * Writes a register value for a given register to the target @@ -139,7 +139,7 @@ public interface IRegisters extends IFormattedValues { * @param formatId Format of the value to be written. * @param rm Request completion monitor. */ - void writeRegister(IDMContext regCtx, String regValue, String formatId, RequestMonitor rm); + void writeRegister(IDMContext regCtx, String regValue, String formatId, RequestMonitor rm); /** * Writes a bit field value for a given bit field to the target @@ -148,7 +148,7 @@ public interface IRegisters extends IFormattedValues { * @param formatId Format of the value to be written. * @param rm Request completion monitor. */ - void writeBitField(IDMContext bitFieldCtx, String bitFieldValue, String formatId, RequestMonitor rm); + void writeBitField(IDMContext bitFieldCtx, String bitFieldValue, String formatId, RequestMonitor rm); /** * Writes a bit field value for a given bit field to the target @@ -156,5 +156,5 @@ public interface IRegisters extends IFormattedValues { * @param mnemonic Mnemonic which represents the value to be written. * @param rm Request completion monitor. */ - void writeBitField(IDMContext bitFieldCtx, IMnemonic mnemonic, RequestMonitor rm); + void writeBitField(IDMContext bitFieldCtx, IMnemonic mnemonic, RequestMonitor rm); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java index 54237082d3c..2d5f7dc8ca9 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java @@ -33,7 +33,7 @@ public interface IRunControl extends IDMService * 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 IExecutionDMContext extends IDMContext {} + public interface IExecutionDMContext extends IDMContext {} /** * Context representing a process, kernel, or some other logical container @@ -95,15 +95,15 @@ public interface IRunControl extends IDMService * Run control commands. They all require the IExecutionContext object on * which they perform the operations. */ - boolean canResume(IDMContext context); - boolean canSuspend(IDMContext context); - boolean isSuspended(IDMContext context); - void resume(IDMContext context, RequestMonitor requestMonitor); - void suspend(IDMContext context, RequestMonitor requestMonitor); + boolean canResume(IDMContext context); + boolean canSuspend(IDMContext context); + boolean isSuspended(IDMContext context); + void resume(IDMContext context, RequestMonitor requestMonitor); + void suspend(IDMContext context, RequestMonitor requestMonitor); public enum StepType { STEP_OVER, STEP_INTO, STEP_RETURN }; - boolean isStepping(IDMContext context); - boolean canStep(IDMContext context); - void step(IDMContext context, StepType stepType, RequestMonitor requestMonitor); - boolean canInstructionStep(IDMContext context); - void instructionStep(IDMContext context, StepType stepType, RequestMonitor requestMonitor); + boolean isStepping(IDMContext context); + boolean canStep(IDMContext context); + void step(IDMContext context, StepType stepType, RequestMonitor requestMonitor); + boolean canInstructionStep(IDMContext context); + void instructionStep(IDMContext context, StepType stepType, RequestMonitor requestMonitor); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISourceLookup.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISourceLookup.java index 066f620ae25..a59e4f87acb 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISourceLookup.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISourceLookup.java @@ -12,7 +12,6 @@ package org.eclipse.dd.dsf.debug.service; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; 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.service.IDsfService; @@ -24,17 +23,17 @@ import org.eclipse.dd.dsf.service.IDsfService; */ public interface ISourceLookup extends IDsfService { - public interface ISourceLookupDMContext extends IDMContext {} + public interface ISourceLookupDMContext extends IDMContext {} public interface ISourceLookupChangedDMEvent extends IDMEvent {} /** * Retrieves the host source object for given debugger path string. */ - void getSource(IDMContext ctx, String debuggerPath, DataRequestMonitor rm); + void getSource(IDMContext ctx, String debuggerPath, DataRequestMonitor rm); /** * Retrieves the debugger path string for given host source object. */ - void getDebuggerPath(IDMContext ctx, Object source, DataRequestMonitor rm); + void getDebuggerPath(IDMContext ctx, Object source, DataRequestMonitor rm); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java index 19c07e5a516..b8bd4e6eee8 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java @@ -27,7 +27,7 @@ public interface IStack extends IDMService { * frame data, this context is used by other services that require a stack * frame for evaluation. */ - public interface IFrameDMContext extends IDMContext {} + public interface IFrameDMContext extends IDMContext {} /** * Stack frame information. @@ -46,7 +46,7 @@ public interface IStack extends IDMService { * expression information. For displaying complete information, * Expressions service should be used. */ - public interface IVariableDMContext extends IDMContext {} + public interface IVariableDMContext extends IDMContext {} /** * Stack frame variable information. @@ -59,13 +59,13 @@ public interface IStack extends IDMService { /** * Returns whether the stack frames can be retrieved for given thread. */ - boolean isStackAvailable(IDMContext execContext); + boolean isStackAvailable(IDMContext execContext); /** * Retrieves list of stack frames for the given execution context. Request * will fail if the stack frame data is not available. */ - void getFrames(IDMContext execContext, DataRequestMonitor rm); + void getFrames(IDMContext execContext, DataRequestMonitor rm); /** * Retrieves the top stack frame for the given execution context. @@ -76,17 +76,17 @@ public interface IStack extends IDMService { * @param execContext * @param rm */ - void getTopFrame(IDMContext execContext, DataRequestMonitor rm); + void getTopFrame(IDMContext execContext, DataRequestMonitor rm); /** * Retrieves variables which were arguments to the stack frame's function. */ - void getArguments(IDMContext frameCtx, DataRequestMonitor rm); + void getArguments(IDMContext frameCtx, DataRequestMonitor rm); /** * Retrieves variables local to the stack frame. */ - void getLocals(IDMContext frameCtx, DataRequestMonitor rm); + void getLocals(IDMContext frameCtx, DataRequestMonitor rm); /** * Retrieves the stack depth of the specified stack frame. diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStepQueueManager.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStepQueueManager.java index a37a143b328..19318f2599c 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStepQueueManager.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStepQueueManager.java @@ -46,21 +46,21 @@ public interface IStepQueueManager extends IDsfService { * Returns the number of step commands that are queued for given execution * context. */ - int getPendingStepCount(IDMContext ctx); + int getPendingStepCount(IDMContext ctx); /** * Checks whether a step command can be queued up for given context. */ - boolean canEnqueueStep(IDMContext execCtx); + boolean canEnqueueStep(IDMContext execCtx); - boolean canEnqueueInstructionStep(IDMContext ctx); + boolean canEnqueueInstructionStep(IDMContext ctx); /** * 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(IDMContext ctx, IRunControl.StepType stepType); + void enqueueStep(IDMContext ctx, IRunControl.StepType stepType); /** * Adds an instruction step command to the execution queue for given @@ -68,7 +68,7 @@ public interface IStepQueueManager extends IDsfService { * @param execCtx Execution context that should perform the step. * @param stepType Type of step to execute. */ - void enqueueInstructionStep(IDMContext ctx, IRunControl.StepType stepType); + void enqueueInstructionStep(IDMContext ctx, IRunControl.StepType stepType); - boolean isSteppingTimedOut(IDMContext context); + boolean isSteppingTimedOut(IDMContext context); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISymbols.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISymbols.java index 94da90b32c4..7a8b3ea8f46 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISymbols.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISymbols.java @@ -23,7 +23,7 @@ import org.eclipse.dd.dsf.datamodel.IDMService; * @see IModules */ public interface ISymbols extends IDMService { - public interface ISymbolObjectDMContext extends IDMContext {} + public interface ISymbolObjectDMContext extends IDMContext {} /** * Data about a debug symbol. diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ITargets.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ITargets.java index 8108979fdad..d24c24ecaff 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ITargets.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ITargets.java @@ -22,7 +22,7 @@ import org.eclipse.dd.dsf.datamodel.IDMService; */ public interface ITargets extends IDMService { - public interface ITargetDMContext extends IDMContext {} + public interface ITargetDMContext extends IDMContext {} public interface ITargetDMData extends IDMData { String getName(); @@ -31,7 +31,7 @@ public interface ITargets extends IDMService { public interface ITargetStateChanged extends IDMEvent {} - public interface ICoreDMContext extends IDMContext {} + public interface ICoreDMContext extends IDMContext {} public interface ICoreDMData extends IDMData { String getName(); diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommand.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommand.java index 8c8a53c4b48..b15ccfed442 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommand.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommand.java @@ -39,7 +39,7 @@ public interface ICommand { * Returns the context that this command is to be evaluated in. May be null * if the command does not need to be evaluated in a specific context. */ - public IDMContext getContext(); + public IDMContext getContext(); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java index ed5a6438270..8064a9a6476 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java @@ -176,13 +176,13 @@ public class DsfMISourceLookupParticipant implements ISourceLookupParticipant { * @see org.eclipse.debug.internal.core.sourcelookup.ISourceLookupParticipant#getSourceName(java.lang.Object) */ public String getSourceName(Object object) throws CoreException { - if ( !(object instanceof IDMContext) || - !((IDMContext)object).getSessionId().equals(fSessionId) ) + if ( !(object instanceof IDMContext) || + !((IDMContext)object).getSessionId().equals(fSessionId) ) { throw new CoreException(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, -1, "Invalid object", null)); //$NON-NLS-1$ } - final IDMContext dmc = (IDMContext)object; + final IDMContext dmc = (IDMContext)object; Query query = new Query() { @Override protected void execute(final DataRequestMonitor rm) { @@ -202,7 +202,7 @@ public class DsfMISourceLookupParticipant implements ISourceLookupParticipant { } @ConfinedToDsfExecutor("fExecutor") - private void getSourceNameOnDispatchThread(IDMContext dmc, final DataRequestMonitor rm) { + private void getSourceNameOnDispatchThread(IDMContext dmc, final DataRequestMonitor rm) { if (!(dmc instanceof IStack.IFrameDMContext)) { rm.setStatus(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "No source for this object", null)); //$NON-NLS-1$ rm.done(); diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java index 49ae5506c11..fbd7567ff0a 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java @@ -22,9 +22,7 @@ import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.datamodel.IDMData; import org.eclipse.dd.dsf.datamodel.IDMEvent; -import org.eclipse.dd.dsf.datamodel.IDMService; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; @@ -34,21 +32,16 @@ import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; 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.update.VMCacheManager; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; -import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITreeSelection; import org.eclipse.jface.viewers.TreePath; -import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.graphics.RGB; /** @@ -58,7 +51,7 @@ import org.eclipse.swt.graphics.RGB; * are of the same class type. */ @SuppressWarnings("restriction") -abstract public class AbstractDMVMLayoutNode extends AbstractVMLayoutNode +abstract public class AbstractDMVMLayoutNode extends AbstractVMLayoutNode implements IElementLabelProvider { @@ -67,14 +60,14 @@ abstract public class AbstractDMVMLayoutNode extends Abstract */ @Immutable public class DMVMContext extends AbstractVMContext { - private final IDMContext fDmc; + private final IDMContext fDmc; - public DMVMContext(IDMContext dmc) { + public DMVMContext(IDMContext dmc) { super(getVMProvider().getVMAdapter(), AbstractDMVMLayoutNode.this); fDmc = dmc; } - public IDMContext getDMC() { return fDmc; } + public IDMContext getDMC() { return fDmc; } /** * The IAdaptable implementation. If the adapter is the DM context, @@ -122,7 +115,7 @@ abstract public class AbstractDMVMLayoutNode extends Abstract * this type is erased at runtime, so a concrete class typs of the DMC * is needed for instanceof chacks. */ - private Class> fDMCClassType; + private Class fDMCClassType; /** * Constructor initializes instance data, except for the child nodes. @@ -131,7 +124,7 @@ abstract public class AbstractDMVMLayoutNode extends Abstract * @param dmcClassType * @see #setChildNodes(IVMLayoutNode[]) */ - public AbstractDMVMLayoutNode(AbstractVMProvider provider, DsfSession session, Class> dmcClassType) { + public AbstractDMVMLayoutNode(AbstractVMProvider provider, DsfSession session, Class dmcClassType) { super(provider); fSession = session; fServicesTracker = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), session.getId()); @@ -161,7 +154,7 @@ abstract public class AbstractDMVMLayoutNode extends Abstract Object element = update.getElement(); if (element instanceof AbstractDMVMLayoutNode.DMVMContext) { // If update element is a DMC, check if session is still alive. - IDMContext dmc = ((DMVMContext)element).getDMC(); + IDMContext dmc = ((DMVMContext)element).getDMC(); if (dmc.getSessionId() != getSession().getId() || !DsfSession.isSessionActive(dmc.getSessionId())) { handleFailedUpdate(update); return false; @@ -177,7 +170,7 @@ abstract public class AbstractDMVMLayoutNode extends Abstract * @param update Update to handle in case the DMC is null. * @return true if the DMC is NOT null, indicating that it's OK to proceed. */ - protected boolean checkDmc(IDMContext dmc, IViewerUpdate update) { + protected boolean checkDmc(IDMContext dmc, IViewerUpdate update) { if (dmc == null) { update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "No valid context found.", null)); //$NON-NLS-1$ @@ -306,77 +299,7 @@ abstract public class AbstractDMVMLayoutNode extends Abstract } } - /** - * The default implementation of the retrieve label method. It acquires - * the service, using parameters in the DMC, then it fetches the model - * data from the service, and then it calls the protected method - * fillColumnLabel() for each column. The deriving classes should override - * this method if a different method of computing the label is needed. - * - * @see #fillColumnLabel(IDMData, String, int, String[], ImageDescriptor[], FontData[], RGB[], RGB[]) - */ - protected void updateLabelInSessionThread(ILabelUpdate[] updates) { - for (final ILabelUpdate update : updates) { - final IDMContext dmc = findDmcInPath(update.getElementPath(), fDMCClassType); - if (!checkDmc(dmc, update) || !checkService(null, dmc.getServiceFilter(), update)) continue; - - VMCacheManager.getVMCacheManager().getCache(update.getPresentationContext()) - .getModelData((IDMService)getServicesTracker().getService(null, dmc.getServiceFilter()), - dmc, - new DataRequestMonitor(getSession().getExecutor(), null) { - @Override - protected void handleCompleted() { - /* - * Check that the request was evaluated and data is still - * valid. The request could fail if the state of the - * service changed during the request, but the view model - * has not been updated yet. - */ - if (!getStatus().isOK() || !getData().isValid()) { - assert getStatus().isOK() || - getStatus().getCode() != IDsfService.INTERNAL_ERROR || - getStatus().getCode() != IDsfService.NOT_SUPPORTED; - handleFailedUpdate(update); - return; - } - - /* - * If columns are configured, call the protected methods to - * fill in column values. - */ - String[] localColumns = update.getPresentationContext().getColumns(); - if (localColumns == null) localColumns = new String[] { null }; - - for (int i = 0; i < localColumns.length; i++) { - fillColumnLabel(dmc, getData(), localColumns[i], i, update); - } - update.done(); - } - }, - getExecutor()); - } - } - - /** - * Fills in label information for given column. This method is intended to - * be overriden by deriving classes, to supply label information specific - * to the node.
    - * The implementation should fill in the correct value in each array at the - * given index. - * @param dmContext Data Model Context object for which the label is generated. - * @param dmData Data Model Data object retrieved from the model service. - * for the DM Context supplied to the retrieveLabel() call. - * @param columnId Name of the column to fill in, null if no columns specified. - * @param idx Index to fill in in the label arrays. - * @param update Update object to fill information to - * - * @see IElementLabelProvider - * @see IColumnPresentationFactory - */ - protected void fillColumnLabel(@SuppressWarnings("unused") IDMContext dmContext, @SuppressWarnings("unused") V dmData, - @SuppressWarnings("unused") String columnId, int idx, ILabelUpdate update) { - update.setLabel("", idx); //$NON-NLS-1$ - } + abstract protected void updateLabelInSessionThread(ILabelUpdate[] updates); @Override public int getDeltaFlags(Object e) { @@ -417,7 +340,7 @@ abstract public class AbstractDMVMLayoutNode extends Abstract * will only create a delta node for this one element. */ protected void buildDeltaForDMEvent(final IDMEvent event, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) { - IDMContext dmc = DMContexts.getAncestorOfType(event.getDMContext(), fDMCClassType); + IDMContext dmc = DMContexts.getAncestorOfType(event.getDMContext(), fDMCClassType); if (dmc != null) { // Create the VM context based on the DM context from the DM event. @@ -493,7 +416,7 @@ abstract public class AbstractDMVMLayoutNode extends Abstract * @param dmcs Array of DMC objects to build return array on. * @return Array of IVMContext objects. */ - protected IVMContext[] dmcs2vmcs(IDMContext[] dmcs) { + protected IVMContext[] dmcs2vmcs(IDMContext[] dmcs) { IVMContext[] vmContexts = new IVMContext[dmcs.length]; for (int i = 0; i < dmcs.length; i++) { vmContexts[i] = new DMVMContext(dmcs[i]); @@ -501,7 +424,7 @@ abstract public class AbstractDMVMLayoutNode extends Abstract return vmContexts; } - protected void fillUpdateWithVMCs(IChildrenUpdate update, IDMContext[] dmcs) { + protected void fillUpdateWithVMCs(IChildrenUpdate update, IDMContext[] dmcs) { int startIdx = update.getOffset() != -1 ? update.getOffset() : 0; int endIdx = update.getLength() != -1 ? startIdx + update.getLength() : dmcs.length; // Ted: added bounds limitation of dmcs.length @@ -511,7 +434,7 @@ abstract public class AbstractDMVMLayoutNode extends Abstract } } - protected IVMContext createVMContext(IDMContext dmc) { + protected IVMContext createVMContext(IDMContext dmc) { return new DMVMContext(dmc); } @@ -528,7 +451,7 @@ abstract public class AbstractDMVMLayoutNode extends Abstract T retVal = null; for (int i = path.getSegmentCount() - 1; i >= 0; i--) { if (path.getSegment(i) instanceof AbstractDMVMLayoutNode.DMVMContext) { - IDMContext dmc = ((DMVMContext)path.getSegment(i)).getDMC(); + IDMContext dmc = ((DMVMContext)path.getSegment(i)).getDMC(); if ( dmc.getSessionId().equals(getSession().getId()) ) { retVal = DMContexts.getAncestorOfType(dmc, dmcType); if (retVal != null) break; diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/DMVMRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/DMVMRootLayoutNode.java index b2955c2a6cb..c04df1f6002 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/DMVMRootLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/DMVMRootLayoutNode.java @@ -61,14 +61,14 @@ public class DMVMRootLayoutNode extends VMRootLayoutNode */ @Override public int getDeltaFlags(Object event) { - IDMContext inputDmc = getSelectedDMC(); + IDMContext inputDmc = getSelectedDMC(); if (event instanceof IDMEvent && inputDmc != null) { boolean potentialMatchFound = false; boolean matchFound = false; - IDMContext eventDmc = ((IDMEvent)event).getDMContext(); - for (IDMContext eventDmcAncestor : DMContexts.toList(eventDmc)) { - IDMContext inputDmcAncestor = DMContexts.getAncestorOfType(inputDmc, eventDmcAncestor.getClass()); + IDMContext eventDmc = ((IDMEvent)event).getDMContext(); + for (IDMContext eventDmcAncestor : DMContexts.toList(eventDmc)) { + IDMContext inputDmcAncestor = DMContexts.getAncestorOfType(inputDmc, eventDmcAncestor.getClass()); if (inputDmcAncestor != null) { potentialMatchFound = true; if (inputDmcAncestor.equals(eventDmcAncestor)) { @@ -84,7 +84,7 @@ public class DMVMRootLayoutNode extends VMRootLayoutNode return super.getDeltaFlags(event); } - private IDMContext getSelectedDMC() { + private IDMContext getSelectedDMC() { Object rootObject = getVMProvider().getRootElement(); if (rootObject instanceof DMVMContext) { diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java index de182ab99db..224cde67366 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java @@ -44,9 +44,9 @@ public abstract class VMCache protected HashMap fHasChildren = new HashMap(); - protected HashMap, IDMData> fData = new HashMap, IDMData>(); + protected HashMap fData = new HashMap(); - protected HashMap, IDMData> fDataArchive = fData; + protected HashMap fDataArchive = fData; public HashMap[] getCacheData() { @@ -69,8 +69,8 @@ public abstract class VMCache fHasChildren = (HashMap)oldCacheData[0]; fChildrenCounts = (HashMap)oldCacheData[1]; fChildren = (HashMap>)oldCacheData[2]; - fData = (HashMap, IDMData>)oldCacheData[3]; - fDataArchive = (HashMap, IDMData>)oldCacheData[4]; + fData = (HashMap)oldCacheData[3]; + fDataArchive = (HashMap)oldCacheData[4]; } } @@ -78,7 +78,7 @@ public abstract class VMCache { if(archive) fDataArchive = fData; - fData = new HashMap, IDMData>(); + fData = new HashMap(); fChildrenCounts.clear(); fChildren.clear(); fHasChildren.clear(); diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMContext.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMContext.java index a68690c9277..c5400aa2cbf 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMContext.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMContext.java @@ -29,26 +29,24 @@ import org.eclipse.dd.dsf.service.DsfSession; * @param Data Model data type that this context is for. */ @Immutable -abstract public class AbstractDMContext extends PlatformObject - implements IDMContext +abstract public class AbstractDMContext extends PlatformObject + implements IDMContext { private final String fSessionId; - private final String fServiceFilter; - private final IDMContext[] fParents; + private final IDMContext[] fParents; /** * Main constructor provides all data needed to implement the IModelContext * interface. */ - public AbstractDMContext(String sessionId, String filter, IDMContext[] parents) { + public AbstractDMContext(String sessionId, IDMContext[] parents) { fSessionId = sessionId; - fServiceFilter = filter; fParents = parents; } /** Convenience constructor */ - public AbstractDMContext(IDMService service, IDMContext[] parents) { - this(service.getSession().getId(), service.getServiceFilter(), parents); + public AbstractDMContext(IDMService service, IDMContext[] parents) { + this(service.getSession().getId(), parents); } /** @@ -60,13 +58,12 @@ abstract public class AbstractDMContext extends PlatformObjec protected boolean baseEquals(Object other) { if (other == null) return false; if ( !(other.getClass().equals(getClass()))) return false; - IDMContext otherCtx = (IDMContext)other; + IDMContext otherCtx = (IDMContext)other; return getSessionId().equals(otherCtx.getSessionId()) && - getServiceFilter().equals(otherCtx.getServiceFilter()) && areParentsEqual(otherCtx.getParents()); } - private boolean areParentsEqual(IDMContext[] 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,20 +78,19 @@ abstract public class AbstractDMContext extends PlatformObjec for (Object parent : getParents()) { parentsHash += parent.hashCode(); } - return getSessionId().hashCode() + getServiceFilter().hashCode() + parentsHash; + return getSessionId().hashCode() + parentsHash; } protected String baseToString() { StringBuffer retVal = new StringBuffer(); - for (IDMContext parent : fParents) { + for (IDMContext parent : fParents) { retVal.append(parent); } return retVal.toString(); } public String getSessionId() { return fSessionId; } - public String getServiceFilter() { return fServiceFilter; } - public IDMContext[] getParents() { return fParents; } + public IDMContext[] getParents() { return fParents; } /** * Overrides the standard platform getAdapter to provide session-specific diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMEvent.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMEvent.java index 9ea389977cc..86fcebe1e61 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMEvent.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMEvent.java @@ -17,7 +17,7 @@ import org.eclipse.dd.dsf.concurrent.Immutable; * required DM-Context reference. */ @Immutable -abstract public class AbstractDMEvent> implements IDMEvent { +abstract public class AbstractDMEvent implements IDMEvent { private final V fModelContext; public AbstractDMEvent(V context) { diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/DMContexts.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/DMContexts.java index d0877827bf3..2e093304bce 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/DMContexts.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/DMContexts.java @@ -59,16 +59,16 @@ public class DMContexts { * @return true if a match is found. */ @ThreadSafe - public static boolean isAncestorOf(IDMContext dmc, IDMContext potentialAncestor) { + public static boolean isAncestorOf(IDMContext dmc, IDMContext potentialAncestor) { // Check the direct parents for a match. - for (IDMContext parentDmc : dmc.getParents()) { + for (IDMContext parentDmc : dmc.getParents()) { if (potentialAncestor.equals(parentDmc)) { return true; } } // Recursively check the parents' parents for a match. - for (IDMContext parentDmc : dmc.getParents()) { + for (IDMContext parentDmc : dmc.getParents()) { if (isAncestorOf(parentDmc, potentialAncestor)) { return true; } @@ -83,15 +83,15 @@ public class DMContexts { * into a list. */ @ThreadSafe - public static List> toList(IDMContext dmc) { + public static List toList(IDMContext dmc) { /* * This method is implemented recursively, which is not necessarily * the most efficient way to do this. */ - List> list = new ArrayList>(); + List list = new ArrayList(); list.add(dmc); - for (IDMContext parentDmc : dmc.getParents()) { + for (IDMContext parentDmc : dmc.getParents()) { list.addAll(toList(parentDmc)); } return list; diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMContext.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMContext.java index 0fc319c2f64..e21145817d7 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMContext.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMContext.java @@ -44,7 +44,7 @@ import org.eclipse.dd.dsf.concurrent.Immutable; * @see IDMData */ @Immutable -public interface IDMContext extends IAdaptable +public interface IDMContext extends IAdaptable { /** * Each model context object needs to track the session from which it @@ -55,17 +55,6 @@ public interface IDMContext extends IAdaptable */ public String getSessionId(); - /** - * Returns the service filter object which can be used to uniquely identify - * a service. For most services, it's sufficient to know the service class - * and the session-id to find the service, but some services may have - * multiple instances running in the same session. For those services, this - * filter string can be used to find the correct service instance. - * @see org.osgi.framework.BundleContext#getServiceReferences - * @return - */ - public String getServiceFilter(); - /** * Returns the parent context of this context. ModelContext objects can be * chained this way to allow methods that require context from multiple @@ -73,5 +62,5 @@ public interface IDMContext extends IAdaptable * the client. * @return parent context of this context. */ - public IDMContext[] getParents(); + public IDMContext[] getParents(); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMData.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMData.java index 9533c1476c1..fd45a2c652a 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMData.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMData.java @@ -10,23 +10,13 @@ *******************************************************************************/ package org.eclipse.dd.dsf.datamodel; -import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; +import org.eclipse.dd.dsf.concurrent.Immutable; /** - * Data object containing information regarding a model context. Unlike the - * 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. 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). + * Marker interface for data corresponding to IDMContext, retrieved from a + * service. These data objects are meant to be processed by clients on + * different threads, therefore they should be immutable. */ -@ConfinedToDsfExecutor("") +@Immutable public interface IDMData { - - /** - * Returns true if the data represented by this object is still valid. - * Data may become invalid if, for example the cache object backing this - * data was cleared. - */ - public boolean isValid(); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMEvent.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMEvent.java index 373689b3877..d73dd889864 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMEvent.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMEvent.java @@ -16,6 +16,6 @@ package org.eclipse.dd.dsf.datamodel; * this base class only identifies the DM Context that is affected. * @param Data Model context type that is affected by this event. */ -public interface IDMEvent > { +public interface IDMEvent { V getDMContext(); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMService.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMService.java index 4f494895533..66187bf0184 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMService.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMService.java @@ -20,13 +20,13 @@ import org.eclipse.dd.dsf.service.IDsfService; * and has a method which allows clients to retrieve the DM Context that * represents the service data. */ -public interface IDMService extends IDsfService, IDMData { +public interface IDMService extends IDsfService { /** * 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. */ - IDMContext getServiceContext(); + IDMContext getServiceContext(); /** /** @@ -38,5 +38,5 @@ public interface IDMService extends IDsfService, IDMData { * @param dmc Data Model Context for the data model data object to be retrieved. * @param rm Request completion monitor to be filled in with the Data Model Data. */ - void getModelData(IDMContext dmc, DataRequestMonitor rm); + void getModelData(IDMContext dmc, DataRequestMonitor rm); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/ServiceDMContext.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/ServiceDMContext.java index 89de05e027a..d3a27b76910 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/ServiceDMContext.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/ServiceDMContext.java @@ -16,11 +16,11 @@ package org.eclipse.dd.dsf.datamodel; * {@link IDMService#getServiceContext()} methods. The service DM Context * should be the parent of all contexts originating from the given service. */ -public class ServiceDMContext extends AbstractDMContext { +public class ServiceDMContext extends AbstractDMContext { String fServiceDMID; public ServiceDMContext(IDMService service, String serviceDMID) { - super(service, new IDMContext[0]); + super(service, new IDMContext[0]); fServiceDMID = serviceDMID; } @@ -29,7 +29,7 @@ public class ServiceDMContext extends AbstractDMContext @Override public boolean equals(Object obj) { - return obj instanceof ServiceDMContext && fServiceDMID.equals(((ServiceDMContext)obj).fServiceDMID); + return obj instanceof ServiceDMContext && fServiceDMID.equals(((ServiceDMContext)obj).fServiceDMID); } @Override From ec4694c8b821670cce73dda3a4aed22d6ae92088 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 19 Oct 2007 23:06:31 +0000 Subject: [PATCH 169/834] [205132] Second step in refactoring IDMContext: - Removed the IDMService.getServiceContext() method. --- .../src/org/eclipse/dd/dsf/datamodel/IDMService.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMService.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMService.java index 66187bf0184..6dbc5aa40a9 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMService.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMService.java @@ -21,14 +21,6 @@ import org.eclipse.dd.dsf.service.IDsfService; * represents the service data. */ public interface IDMService extends IDsfService { - /** - * 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. - */ - IDMContext getServiceContext(); - - /** /** * Retrieves model data object for given context. This method makes it * un-necessary for every model service to declare a separate method From 75d779d6b9c9d1deeb7e7c36c8c1457935d83fb9 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 19 Oct 2007 23:52:16 +0000 Subject: [PATCH 170/834] [205132] Third step in refactoring IDMContext: - Marked IDMService.getModelData() as deprecated. - Created public get*Data() method in debug services. --- .../dd/dsf/debug/service/IExpressions.java | 10 ++++++++++ .../dd/dsf/debug/service/IFormattedValues.java | 8 ++++++++ .../eclipse/dd/dsf/debug/service/IRegisters.java | 15 +++++++++++++++ .../eclipse/dd/dsf/debug/service/IRunControl.java | 7 +++++++ .../org/eclipse/dd/dsf/debug/service/IStack.java | 14 ++++++++++++++ .../org/eclipse/dd/dsf/datamodel/IDMService.java | 5 +++++ 6 files changed, 59 insertions(+) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java index 46171c09738..3e6ca7b6a1b 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java @@ -137,6 +137,16 @@ public interface IExpressions extends IDMService, IFormattedValues { */ interface IExpressionChangedDMEvent extends IDMEvent {} + /** + * Retrieves the expression DM data object for the given expression context(dmc). + * + * @param dmc + * The ExpressionDMC for the expression to be evaluated. + * @param rm + * The data request monitor that will contain the requested data + */ + void getExpressionData(IExpressionDMContext dmc, DataRequestMonitor rm); + /** * Returns the data model context object for the specified expression in the context * specified by ctx. diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java index 1e046f79899..3eb94571573 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java @@ -53,6 +53,14 @@ public interface IFormattedValues extends IDMService { */ public FormattedValueDMContext getFormattedValueContext(IFormattedDataDMContext dmc, String formatId); + /** + * Retrieves the DM data associated with given formatted value context. + * @param dmc Context to retrieve the value for. + * @param rm Completion monitor returns the formatted value. + */ + public void getFormattedExpressionValue(FormattedValueDMContext dmc, DataRequestMonitor rm); + + /** * DMC that represents a value with specific format. The format ID can be * persisted and used for comparison. diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java index 56ce313eedb..d704f54f4ab 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java @@ -104,6 +104,21 @@ public interface IRegisters extends IFormattedValues { String getLongName(); } + /** + * Retrieves register group data for given context. + * @param regGroupDmc Context to retrieve data for. + * @param rm Request completion monitor. + */ + void getRegisterGroupData(IRegisterGroupDMContext regGroupDmc, DataRequestMonitor rm); + + /** + * Retrieves register data for given context. + * @param regGroupDmc Context to retrieve data for. + * @param rm Request completion monitor. + */ + void getRegisterData(IRegisterDMContext regDmc , DataRequestMonitor rm); + + /** * Retrieves the list of register groups. * @param ctx Context for the returned data. diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java index 2d5f7dc8ca9..28d4dceb0b8 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java @@ -86,6 +86,13 @@ public interface IRunControl extends IDMService StateChangeReason getStateChangeReason(); } + /** + * Retrieves execution data for given context. + * @param dmc Context to retrieve data for. + * @param rm Request completion monitor. + */ + public void getExecutionData(IExecutionDMContext dmc, DataRequestMonitor rm); + /** * Returns execution contexts belonging to the given container context. */ diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java index b8bd4e6eee8..8a4180ad89c 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java @@ -56,6 +56,20 @@ public interface IStack extends IDMService { String getValue(); } + /** + * Retrieves stack frame data for given context. + * @param frameDmc Context to retrieve data for. + * @param rm Request completion monitor. + */ + public void getFrameData(final IFrameDMContext frameDmc, DataRequestMonitor rm); + + /** + * Retrieves stack frame variable data for given context. + * @param variableDmc Context to retrieve data for. + * @param rm Request completion monitor. + */ + public void getVariableData(IVariableDMContext variableDmc, DataRequestMonitor rm); + /** * Returns whether the stack frames can be retrieved for given thread. */ diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMService.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMService.java index 6dbc5aa40a9..c32b36e5124 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMService.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMService.java @@ -29,6 +29,11 @@ public interface IDMService extends IDsfService { * @param The Data Model Data type that is to be retrieved. * @param dmc Data Model Context for the data model data object to be retrieved. * @param rm Request completion monitor to be filled in with the Data Model Data. + * + * @deprecated + * This method is not deprecated as there is no compile-time linking + * between IDMContext and IDMData objects (see bug 205132) */ + @Deprecated void getModelData(IDMContext dmc, DataRequestMonitor rm); } From f89ea1624ca358f9c9c40629444d088b58b5020d Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Sun, 21 Oct 2007 16:17:34 +0000 Subject: [PATCH 171/834] [205132] Fourth step in refactoring IDMContext: - Migrated debug services not to use IDMService.getModelData(), the only class left using it is the cache in update policy. --- .../ui/sourcelookup/MISourceDisplayAdapter.java | 2 +- .../ui/viewmodel/detailpanesupport/DetailPane.java | 2 +- .../viewmodel/register/SyncRegisterDataAccess.java | 8 ++++---- .../viewmodel/variable/SyncVariableDataAccess.java | 4 ++-- .../dsf/debug/model/DsfMemoryBlockRetrieval.java | 4 ++-- .../dd/dsf/debug/service/INativeProcesses.java | 5 +++++ .../eclipse/dd/dsf/debug/service/IRegisters.java | 14 ++++++++++---- .../sourcelookup/DsfMISourceLookupParticipant.java | 2 +- .../org/eclipse/dd/dsf/datamodel/IDMService.java | 7 +++++-- 9 files changed, 31 insertions(+), 17 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java index f909be36734..2338223bb17 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java @@ -282,7 +282,7 @@ public class MISourceDisplayAdapter implements ISourceDisplay doneException(new CoreException(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, -1, "Stack data not available", null))); //$NON-NLS-1$ return; } - stackService.getModelData( + stackService.getFrameData( frameDmc, new DataRequestMonitor(fExecutor, rm) { @Override diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPane.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPane.java index 992a98612ce..b0484718b11 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPane.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPane.java @@ -403,7 +403,7 @@ public class DetailPane implements IDetailPane, IAdaptable, IPropertyChangeListe * Format has been validated. Get the formatted value. */ final FormattedValueDMContext valueDmc = finalService.getFormattedValueContext(finalDmc, str); - finalService.getModelData( + finalService.getFormattedExpressionValue( valueDmc, new DataRequestMonitor(finalService.getSession().getExecutor(), null) { @Override diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java index 60c37dde51b..ab6985389db 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java @@ -127,7 +127,7 @@ public class SyncRegisterDataAccess { return; } - service.getModelData(fDmc, new DataRequestMonitor(session.getExecutor(), rm) { + service.getBitFieldData(fDmc, new DataRequestMonitor(session.getExecutor(), rm) { @Override protected void handleCompleted() { /* @@ -464,7 +464,7 @@ public class SyncRegisterDataAccess { return; } - service.getModelData(fDmc, new DataRequestMonitor( session.getExecutor(), rm) { + service.getRegisterGroupData(fDmc, new DataRequestMonitor( session.getExecutor(), rm) { @Override protected void handleCompleted() { /* @@ -553,7 +553,7 @@ public class SyncRegisterDataAccess { return; } - service.getModelData(fDmc, new DataRequestMonitor( session.getExecutor(), rm) { + service.getRegisterData(fDmc, new DataRequestMonitor( session.getExecutor(), rm) { @Override protected void handleCompleted() { /* @@ -867,7 +867,7 @@ public class SyncRegisterDataAccess { FormattedValueDMContext formDmc = service.getFormattedValueContext(fDmc, fFormatId); - service.getModelData(formDmc, new DataRequestMonitor( session.getExecutor(), rm) { + service.getFormattedExpressionValue(formDmc, new DataRequestMonitor( session.getExecutor(), rm) { @Override protected void handleCompleted() { /* diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java index 6c010c9f15a..41100d7cc2c 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java @@ -124,7 +124,7 @@ public class SyncVariableDataAccess { return; } - service.getModelData(fDmc, new DataRequestMonitor(session.getExecutor(), rm) { + service.getExpressionData(fDmc, new DataRequestMonitor(session.getExecutor(), rm) { @Override protected void handleCompleted() { /* @@ -441,7 +441,7 @@ public class SyncVariableDataAccess { FormattedValueDMContext formDmc = service.getFormattedValueContext(fDmc, fFormatId); - service.getModelData(formDmc, new DataRequestMonitor(session.getExecutor(), rm) { + service.getFormattedExpressionValue(formDmc, new DataRequestMonitor(session.getExecutor(), rm) { @Override protected void handleCompleted() { /* diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java index db151b1207f..b83c77bc4af 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java @@ -304,13 +304,13 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl if (expressionService != null) { // Create the expression final IExpressionDMContext expressionDMC = expressionService.createExpression(idmContext, expression); - expressionService.getModelData(expressionDMC, new DataRequestMonitor(getExecutor(), drm) { + expressionService.getExpressionData(expressionDMC, new DataRequestMonitor(getExecutor(), drm) { @Override protected void handleOK() { // Evaluate the expression - request HEX since it works in every case String formatId = IFormattedValues.HEX_FORMAT; FormattedValueDMContext valueDmc = expressionService.getFormattedValueContext(expressionDMC, formatId); - expressionService.getModelData( + expressionService.getFormattedExpressionValue( valueDmc, new DataRequestMonitor(getExecutor(), drm) { @Override diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/INativeProcesses.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/INativeProcesses.java index b3509de12a1..e71b08fd5f8 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/INativeProcesses.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/INativeProcesses.java @@ -63,6 +63,11 @@ public interface INativeProcesses extends IDMService { IProcessDMContext getProcess(); } + public void getThreadData(IThreadDMContext dmc, DataRequestMonitor rm); + + public void getProcessData(IProcessDMContext dmc, DataRequestMonitor rm); + + /** * Returns a thread for the corresponding context. null if no corresponding * thread exists. diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java index d704f54f4ab..7c739841b19 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java @@ -106,18 +106,24 @@ public interface IRegisters extends IFormattedValues { /** * Retrieves register group data for given context. - * @param regGroupDmc Context to retrieve data for. + * @param dmc Context to retrieve data for. * @param rm Request completion monitor. */ - void getRegisterGroupData(IRegisterGroupDMContext regGroupDmc, DataRequestMonitor rm); + void getRegisterGroupData(IRegisterGroupDMContext dmc, DataRequestMonitor rm); /** * Retrieves register data for given context. - * @param regGroupDmc Context to retrieve data for. + * @param dmc Context to retrieve data for. * @param rm Request completion monitor. */ - void getRegisterData(IRegisterDMContext regDmc , DataRequestMonitor rm); + void getRegisterData(IRegisterDMContext dmc , DataRequestMonitor rm); + /** + * Retrieves bit field data for given context. + * @param dmc Context to retrieve data for. + * @param rm Request completion monitor. + */ + void getBitFieldData(IBitFieldDMContext dmc , DataRequestMonitor rm); /** * Retrieves the list of register groups. diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java index 8064a9a6476..2b826894e10 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java @@ -217,7 +217,7 @@ public class DsfMISourceLookupParticipant implements ISourceLookupParticipant { return; } - stackService.getModelData( + stackService.getFrameData( frameDmc, new DataRequestMonitor(fExecutor, rm) { @Override public void handleOK() { diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMService.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMService.java index c32b36e5124..fc5d1f21be3 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMService.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMService.java @@ -19,6 +19,10 @@ import org.eclipse.dd.dsf.service.IDsfService; * For completeness this service interface derives from IDMData * and has a method which allows clients to retrieve the DM Context that * represents the service data. + * + * @deprecated Without getModelData method this service has no function. + * There's also no need for it as a marker interface so we may as well + * get rid of it. */ public interface IDMService extends IDsfService { /** @@ -30,8 +34,7 @@ public interface IDMService extends IDsfService { * @param dmc Data Model Context for the data model data object to be retrieved. * @param rm Request completion monitor to be filled in with the Data Model Data. * - * @deprecated - * This method is not deprecated as there is no compile-time linking + * @deprecated This method is not deprecated as there is no compile-time linking * between IDMContext and IDMData objects (see bug 205132) */ @Deprecated From 27bc6ae2b6ecea7e58c350e9c38c5f756e0db11f Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Mon, 22 Oct 2007 14:34:40 +0000 Subject: [PATCH 172/834] Cleanup of class comments --- .../src/org/eclipse/dd/dsf/datamodel/IDMContext.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMContext.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMContext.java index e21145817d7..075dd49fc72 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMContext.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMContext.java @@ -36,12 +36,6 @@ import org.eclipse.dd.dsf.concurrent.Immutable; * This may prevent the service from being garbage collected, possibly keeping * a lot of resources tied up. * - * @param For each context object there is a corresponding data object - * which will contain information about that context. This template argument - * allows the clients to avoid casting the data class when retrieving data - * for a context object. - * - * @see IDMData */ @Immutable public interface IDMContext extends IAdaptable From cfd78eff47fee8eb31079c4d8c81690e797b2f1c Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Mon, 22 Oct 2007 21:47:15 +0000 Subject: [PATCH 173/834] [187888] Initial (stubbed) version of the modules service and the connection to the Modules view. --- .../META-INF/MANIFEST.MF | 1 + .../viewmodel/modules/ModulesLayoutNode.java | 155 ++++++++++++++++++ .../viewmodel/modules/ModulesVMProvider.java | 48 ++++++ .../dd/dsf/debug/service/IModules.java | 56 +------ .../dd/dsf/datamodel/AbstractDMContext.java | 3 +- .../eclipse/dd/dsf/datamodel/DMContexts.java | 5 + 6 files changed, 217 insertions(+), 51 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesLayoutNode.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMProvider.java diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF index 5dcf58db94e..4a6877ee333 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF @@ -28,6 +28,7 @@ Export-Package: org.eclipse.dd.dsf.debug.ui.viewmodel.expression, org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport, org.eclipse.dd.dsf.debug.ui.viewmodel.launch, + org.eclipse.dd.dsf.debug.ui.viewmodel.modules, org.eclipse.dd.dsf.debug.ui.viewmodel.register, org.eclipse.dd.dsf.debug.ui.viewmodel.variable Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesLayoutNode.java new file mode 100644 index 00000000000..49163bd4a44 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesLayoutNode.java @@ -0,0 +1,155 @@ +/******************************************************************************* + * 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.modules; + +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.IDMEvent; +import org.eclipse.dd.dsf.debug.service.IModules; +import org.eclipse.dd.dsf.debug.service.IRegisters; +import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.IModules.IModuleDMContext; +import org.eclipse.dd.dsf.debug.service.IModules.IModuleDMData; +import org.eclipse.dd.dsf.debug.service.IRegisters.IGroupChangedDMEvent; +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.AbstractVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; + +@SuppressWarnings("restriction") +public class ModulesLayoutNode extends AbstractDMVMLayoutNode +{ + public ModulesLayoutNode(AbstractVMProvider provider, DsfSession session) { + super(provider, session, IModuleDMContext.class); + } + + @Override + protected void updateElementsInSessionThread(final IChildrenUpdate update) { + if (!checkService(IRegisters.class, null, update)) return; + + final IExecutionDMContext execDmc = findDmcInPath(update.getElementPath(), IExecutionDMContext.class) ; + + if (execDmc != null) { + getServicesTracker().getService(IModules.class).getModules( + execDmc, + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + public void handleCompleted() { + if (!getStatus().isOK()) { + update.done(); + return; + } + fillUpdateWithVMCs(update, getData()); + update.done(); + }}); + } else { + handleFailedUpdate(update); + } + + } + + @Override + protected void updateLabelInSessionThread(ILabelUpdate[] updates) { + for (final ILabelUpdate update : updates) { + final IModuleDMContext dmc = findDmcInPath(update.getElementPath(), IModuleDMContext.class); + if (!checkDmc(dmc, update) || !checkService(IModules.class, null, update)) continue; + + getServicesTracker().getService(IModules.class, null).getModuleData( + dmc, + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + protected void handleCompleted() { + /* + * The request could fail if the state of the service + * changed during the request, but the view model + * has not been updated yet. + */ + if (!getStatus().isOK()) { + assert getStatus().isOK() || + getStatus().getCode() != IDsfService.INTERNAL_ERROR || + getStatus().getCode() != IDsfService.NOT_SUPPORTED; + handleFailedUpdate(update); + return; + } + + /* + * If columns are configured, call the protected methods to + * fill in column values. + */ + String[] localColumns = update.getPresentationContext().getColumns(); + if (localColumns == null) localColumns = new String[] { null }; + + for (int i = 0; i < localColumns.length; i++) { + fillColumnLabel(dmc, getData(), localColumns[i], i, update); + } + update.done(); + } + }); + } + } + + protected void fillColumnLabel(IModuleDMContext dmContext, IModuleDMData dmData, + String columnId, int idx, ILabelUpdate update) + { + if ( columnId == null ) { + /* + * If the Column ID comes in as "null" then this is the case where the user has decided + * to not have any columns. So we need a default action which makes the most sense and + * is doable. In this case we elect to simply display the name. + */ + update.setLabel(dmData.getName(), idx); + } + } + + @Override + protected int getNodeDeltaFlagsForDMEvent(IDMEvent e) { + if (e instanceof IRunControl.ISuspendedDMEvent) { + return IModelDelta.CONTENT; + } + else if (e instanceof IRegisters.IGroupsChangedDMEvent) { + return IModelDelta.CONTENT; + } + else if (e instanceof IRegisters.IGroupChangedDMEvent) { + return IModelDelta.STATE; + } + return IModelDelta.NO_CHANGE; + } + + @Override + protected void buildDeltaForDMEvent(IDMEvent e, VMDelta parent, int nodeOffset, RequestMonitor rm) { + if (e instanceof IRunControl.ISuspendedDMEvent) { + // Create a delta that indicates all groups have changed + parent.addFlags(IModelDelta.CONTENT); + } + else if (e instanceof IRegisters.IGroupsChangedDMEvent) { + // flush the cache + VMCacheManager.getVMCacheManager().flush(super.getVMProvider().getPresentationContext()); + + // Create a delta that indicates all groups have changed + parent.addFlags(IModelDelta.CONTENT); + } + else if (e instanceof IRegisters.IGroupChangedDMEvent) { + // flush the cache + VMCacheManager.getVMCacheManager().flush(super.getVMProvider().getPresentationContext()); + + // Create a delta that indicates that specific group changed + parent.addNode( createVMContext(((IGroupChangedDMEvent)e).getDMContext()), IModelDelta.STATE ); + } + + super.buildDeltaForDMEvent(e, parent, nodeOffset, rm); + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMProvider.java new file mode 100644 index 00000000000..5faae582ec5 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMProvider.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel.modules; + +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; +import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.dm.DMVMRootLayoutNode; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; + +/** + * + */ +@SuppressWarnings("restriction") +public class ModulesVMProvider extends AbstractDMVMProvider { + /* + * Current default for register formatting. + */ + public ModulesVMProvider(AbstractVMAdapter adapter, IPresentationContext context, DsfSession session) { + super(adapter, context, session); + + /* + * Create the top level node to deal with the root selection. + */ + IVMRootLayoutNode debugViewSelection = new DMVMRootLayoutNode(this); + + /* + * Create the Group nodes next. They represent the first level shown in the view. + */ + IVMLayoutNode modulesNode = new ModulesLayoutNode(this, getSession()); + debugViewSelection.setChildNodes(new IVMLayoutNode[] { modulesNode }); + + /* + * Now set this schema set as the layout set. + */ + setRootLayoutNode(debugViewSelection); + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java index 6592afd98ec..607a8af49af 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java @@ -15,14 +15,13 @@ import java.math.BigInteger; import org.eclipse.cdt.core.IAddress; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.datamodel.IDMData; import org.eclipse.dd.dsf.datamodel.IDMEvent; -import org.eclipse.dd.dsf.datamodel.IDMService; +import org.eclipse.dd.dsf.service.IDsfService; /** * Debugger service representing module handling logic of a debugger. */ -public interface IModules extends IDMService { +public interface IModules extends IDsfService { /** * Symbol context represents the space into which module symbols are loaded. @@ -56,59 +55,14 @@ public interface IModules extends IDMService { IModuleDMContext getUnloadedModuleContext(); } - /** - * Object representing a unuqie location in a symbol context, based on - * a module, section, and address offset within the seciton. - */ - public final class ModuleSectionOffset { - private final IModuleDMContext fModule; - private final Section fSection; - private final BigInteger fOffset; - - public IModuleDMContext getModule() { return fModule; } - public Section getSection() { return fSection; } - public BigInteger getOffset() { return fOffset; } - - public ModuleSectionOffset(IModuleDMContext module, Section section, BigInteger offset) { - this.fModule = module; - this.fSection = section; - this.fOffset = offset; - } - - @Override - public int hashCode() { - return fModule.hashCode() + fSection.hashCode() + fOffset.intValue(); - } - - @Override - public boolean equals(Object o) { - if (!(o instanceof ModuleSectionOffset)) return false; - ModuleSectionOffset mso = (ModuleSectionOffset)o; - return fModule.equals(mso.fModule) && fSection.equals(mso.fSection) && fOffset.equals(mso.fOffset); - } - } - - /** - * Symbol context data includes a mapping between run-time addresses and - * module-section-offset coordinates. - */ - public interface ISymbolDMData extends IDMData { - /** Convert link-time address 'addr' to run-time address */ - public long convertToRT(ModuleSectionOffset mso); - - /** Convert run-time address 'addr' to link-time address */ - public ModuleSectionOffset convertFromRT(IAddress addr); - } - /** Module information. */ public interface IModuleDMData { String getName(); String getFile(); long getTimeStamp(); - Section[] getSections(); } - /** Section information */ + /** i information */ public interface Section { String getName(); IAddress getStartAddress(); @@ -130,7 +84,9 @@ public interface IModules extends IDMService { IAddress getStartAddress(); IAddress getEndAddress(); } - + + void getModuleData(IModuleDMContext dmc, DataRequestMonitor rm); + /** * Retreives the list of modules loaded in given symbol context. */ diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMContext.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMContext.java index c5400aa2cbf..0011c938968 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMContext.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMContext.java @@ -13,6 +13,7 @@ package org.eclipse.dd.dsf.datamodel; import org.eclipse.core.runtime.PlatformObject; import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; /** * Base implementation of the IDMContext interface. There are two pieces of @@ -45,7 +46,7 @@ abstract public class AbstractDMContext extends PlatformObject } /** Convenience constructor */ - public AbstractDMContext(IDMService service, IDMContext[] parents) { + public AbstractDMContext(IDsfService service, IDMContext[] parents) { this(service.getSession().getId(), parents); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/DMContexts.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/DMContexts.java index 2e093304bce..5882848766f 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/DMContexts.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/DMContexts.java @@ -22,6 +22,11 @@ import org.eclipse.dd.dsf.concurrent.ThreadSafe; */ public class DMContexts { + /** + * Convenience constant. + */ + public static final IDMContext[] EMPTY_CONTEXTS_ARRAY = new IDMContext[0]; + /** * Finds a data model context of given type among ancestors of the * specified context. From 60cccc683cdc1f5bb16ba81d0c17d8bd969b8045 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 23 Oct 2007 22:21:40 +0000 Subject: [PATCH 174/834] [207236] Single-click "Add new expression" workflow. --- .../ExpressionManagerLayoutNode.java | 129 +++++++++++++----- .../expression/MessagesForExpressionVM.java | 2 + .../WatchExpressionCellModifier.java | 15 +- .../viewmodel/expression/messages.properties | 1 + 4 files changed, 107 insertions(+), 40 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerLayoutNode.java index ff4d7c6f2f7..170a22ee6a0 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerLayoutNode.java @@ -26,6 +26,7 @@ import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.IExpressionManager; import org.eclipse.debug.core.model.IExpression; +import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementEditor; @@ -36,6 +37,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.ui.DebugUITools; import org.eclipse.debug.ui.IDebugUIConstants; +import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.ICellModifier; import org.eclipse.jface.viewers.TextCellEditor; @@ -94,7 +96,33 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode return fExpression.hashCode(); } } - + + /** + * VMC for a new expression object to be added. When user clicks on this node to + * edit it, he will create a new expression. + */ + public class NewExpressionVMC extends AbstractVMContext { + public NewExpressionVMC() { + super(getVMProvider().getVMAdapter(), ExpressionManagerLayoutNode.this); + } + + @Override + @SuppressWarnings("unchecked") + public Object getAdapter(Class adapter) { + return super.getAdapter(adapter); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof NewExpressionVMC; + } + + @Override + public int hashCode() { + return getClass().hashCode(); + } + } + /** Array of expression nodes which parse the user expressions and handle model events */ private IExpressionLayoutNode[] fExpressionNodes = new IExpressionLayoutNode[0]; @@ -120,7 +148,9 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode } public void updateElementCount(IChildrenCountUpdate update) { - update.setChildCount(fManager.getExpressions().length); + // We assume that the getExpressions() will just read local state data, + // so we don't bother using a job to perform this operation. + update.setChildCount(fManager.getExpressions().length + 1); update.done(); } @@ -140,45 +170,45 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode }; int expressionRmCount = 0; - for (int i = update.getOffset(); i < update.getOffset() + update.getLength() && i < expressions.length; i++) { + for (int i = update.getOffset(); i < update.getOffset() + update.getLength() && i < expressions.length + 1; i++) { - // Check the array boundaries as the expression manager could change asynchronously. - // The expression manager change should lead to a refresh in the view. - if (i > expressions.length) { - continue; - } - - final String expressionText = expressions[i].getExpressionText(); - final int expressionIdx = i; - final IExpression expression = expressions[i]; - IExpressionLayoutNode expressionNode = findNodeForExpression(expressionText); - if (expressionNode == null) { - update.setChild(new InvalidExpressionVMC(expression), i); + // The last element is the "new expression" + if (i == expressions.length) { + update.setChild(new NewExpressionVMC(), i); } else { - expressionRmCount++; - // getElementForExpression() accepts a IElementsUpdate as an argument. - // Construct an instance of VMElementsUpdate which will call a - // the request monitor when it is finished. The request monitor - // will in turn set the element in the update argument in this method. - VMElementsUpdate expressionElementUpdate = new VMElementsUpdate( - update, 0, 1, - new DataRequestMonitor>(getExecutor(), multiRm) { - @Override - protected void handleOK() { - update.setChild(getData().get(0), expressionIdx); - multiRm.done(); - } - - @Override - protected void handleError() { - update.setChild(new InvalidExpressionVMC(expression), expressionIdx); - multiRm.done(); - } - }); - expressionNode.getElementForExpression(expressionElementUpdate, expressionText, expression); + final String expressionText = expressions[i].getExpressionText(); + final int expressionIdx = i; + final IExpression expression = expressions[i]; + IExpressionLayoutNode expressionNode = findNodeForExpression(expressionText); + if (expressionNode == null) { + update.setChild(new InvalidExpressionVMC(expression), i); + } else { + expressionRmCount++; + // getElementForExpression() accepts a IElementsUpdate as an argument. + // Construct an instance of VMElementsUpdate which will call a + // the request monitor when it is finished. The request monitor + // will in turn set the element in the update argument in this method. + VMElementsUpdate expressionElementUpdate = new VMElementsUpdate( + update, 0, 1, + new DataRequestMonitor>(getExecutor(), multiRm) { + @Override + protected void handleOK() { + update.setChild(getData().get(0), expressionIdx); + multiRm.done(); + } + + @Override + protected void handleError() { + update.setChild(new InvalidExpressionVMC(expression), expressionIdx); + multiRm.done(); + } + }); + expressionNode.getElementForExpression(expressionElementUpdate, expressionText, expression); + } } } + // If no expressions were parsed, we're finished. // Set the count to the counting RM. multiRm.setDoneCount(expressionRmCount); } @@ -190,6 +220,8 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode for (ILabelUpdate update : updates) { if (update.getElement() instanceof InvalidExpressionVMC) { updateInvalidExpressionVMCLabel(update, (InvalidExpressionVMC) update.getElement()); + } else if (update.getElement() instanceof NewExpressionVMC) { + updateNewExpressionVMCLabel(update, (NewExpressionVMC) update.getElement()); } else { update.done(); } @@ -215,12 +247,35 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode } else { update.setLabel("", i); //$NON-NLS-1$ } + update.setFontData(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0], i); } update.done(); } - + + + /** + * Updates the label for the NewExpressionVMC. + */ + private void updateNewExpressionVMCLabel(ILabelUpdate update, NewExpressionVMC vmc) { + String[] columnIds = update.getColumnIds() != null ? + update.getColumnIds() : new String[] { IDebugVMConstants.COLUMN_ID__NAME }; + + for (int i = 0; i < columnIds.length; i++) { + if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(columnIds[i])) { + update.setLabel(MessagesForExpressionVM.ExpressionManagerLayoutNode__newExpression_label, i); + update.setFontData(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0], i); + } else { + update.setLabel("", i); //$NON-NLS-1$ + } + } + + + update.done(); + } + + /** * Convenience call that iterates through all the configured expression * layout nodes and finds the first one that can parse the given expression. diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/MessagesForExpressionVM.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/MessagesForExpressionVM.java index 6b943864783..acc8b005c96 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/MessagesForExpressionVM.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/MessagesForExpressionVM.java @@ -14,6 +14,8 @@ public class MessagesForExpressionVM extends NLS { public static String ExpressionManagerLayoutNode__invalidExpression_nameColumn_label; public static String ExpressionManagerLayoutNode__invalidExpression_valueColumn_label; + public static String ExpressionManagerLayoutNode__newExpression_label; + static { // initialize resource bundle NLS.initializeMessages(BUNDLE_NAME, MessagesForExpressionVM.class); diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/WatchExpressionCellModifier.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/WatchExpressionCellModifier.java index a66ccef945f..ab65a47f772 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/WatchExpressionCellModifier.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/WatchExpressionCellModifier.java @@ -13,6 +13,9 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.dd.dsf.concurrent.ThreadSafeAndProhibitedFromDsfExecutor; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; +import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.ExpressionManagerLayoutNode.NewExpressionVMC; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.IExpressionManager; import org.eclipse.debug.core.model.IWatchExpression; import org.eclipse.jface.viewers.ICellModifier; @@ -32,7 +35,8 @@ public class WatchExpressionCellModifier implements ICellModifier { } public boolean canModify(Object element, String property) { - return IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(property) && getWatchExpression(element) != null; + return IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(property) && + (getWatchExpression(element) != null || element instanceof NewExpressionVMC); } public Object getValue(Object element, String property) { @@ -49,11 +53,16 @@ public class WatchExpressionCellModifier implements ICellModifier { public void modify(Object element, String property, Object value) { if (!IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(property)) return; + if (!(value instanceof String)) return; IWatchExpression expression = getWatchExpression(element); - if (expression != null && value instanceof String) { + if (expression != null) { expression.setExpressionText((String)value); - } + } else if (element instanceof NewExpressionVMC && ((String)value).trim().length() != 0) { + IExpressionManager expressionManager = DebugPlugin.getDefault().getExpressionManager(); + IWatchExpression watchExpression = expressionManager.newWatchExpression((String)value); + expressionManager.addExpression(watchExpression); + } } private IWatchExpression getWatchExpression(Object element) { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/messages.properties b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/messages.properties index 9c940b5d501..edf8a7d0a53 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/messages.properties +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/messages.properties @@ -5,3 +5,4 @@ ExpressionColumnPresentation_value=Value ExpressionColumnPresentation_description=Description ExpressionManagerLayoutNode__invalidExpression_nameColumn_label=Invalid expression ExpressionManagerLayoutNode__invalidExpression_valueColumn_label=Invalid expression +ExpressionManagerLayoutNode__newExpression_label=Add new expression From b19bdedd15e3d8b0680a8f5b32f023338a6b3775 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Thu, 25 Oct 2007 18:22:24 +0000 Subject: [PATCH 175/834] Fix for Bug 200896 This is the full support for marking variable objects as USED. Also, the ExpressionService JUnit tests have been extended. --- .../src/org/eclipse/dd/dsf/debug/service/IExpressions.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java index 3e6ca7b6a1b..0112de57190 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java @@ -218,5 +218,5 @@ public interface IExpressions extends IDMService, IFormattedValues { * * @param rm: Request completion monitor. */ - void writeExpression(IDMContext expressionContext, String exressionValue, String formatId, RequestMonitor rm); + void writeExpression(IDMContext expressionContext, String expressionValue, String formatId, RequestMonitor rm); } From 90ee5db87f120666bded563f59c1990113bb2971 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Fri, 2 Nov 2007 15:12:22 +0000 Subject: [PATCH 176/834] IExpressions should provide address and size of an expression --- .../dd/dsf/debug/service/IExpressions.java | 49 ++++++++++--------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java index 0112de57190..6c418069124 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java @@ -7,6 +7,7 @@ * * Contributors: * Wind River Systems - initial API and implementation + * Ericsson - Update for GDB/MI *******************************************************************************/ package org.eclipse.dd.dsf.debug.service; @@ -18,19 +19,17 @@ import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMData; import org.eclipse.dd.dsf.datamodel.IDMEvent; -import org.eclipse.dd.dsf.datamodel.IDMService; /** * Expressions service provides access to the debugger's expression evaluator. This service has - * dependencies on the Modules service, RunControl service, and Stack service, as all may be used to - * provide context for an expression to be evaluated. + * dependencies on the Stack service, as it is be used to provide context for an + * expression to be evaluated. */ @SuppressWarnings("nls") -public interface IExpressions extends IDMService, IFormattedValues { +public interface IExpressions extends IFormattedValues { /** - * Expression context. Since some expressions have children, expression contexts can have an - * arbitrary number of parents of type IExpressionDMContext. + * Expression context. */ public interface IExpressionDMContext extends IFormattedDataDMContext { /** @@ -41,12 +40,19 @@ public interface IExpressions extends IDMService, IFormattedValues { String getExpression(); } + /** + * The address and size of an expression. + */ + public interface IExpressionDMAddress { + IAddress getAddress(); + int getSize(); + } + /** * This is the model data interface that corresponds to IExpressionDMContext. */ interface IExpressionDMData extends IDMData { - // These static fields define the possible return values of method getTypeId(). QUESTION: Why can't - // these have type int? + // These static fields define the possible return values of method getTypeId(). final static String TYPEID_UNKNOWN = "TYPEID_UNKNOWN"; final static String TYPEID_INTEGER = "TYPEID_INTEGER"; @@ -100,24 +106,11 @@ public interface IExpressions extends IDMService, IFormattedValues { */ String getTypeId(); - /** - * @return The number of bits in the value of the expression. For a bit field, this is the number - * of bits in the field. For other types, this is 8 times the number of bytes in the value. - */ - int getBitCount(); - /** * @return A string containing the value of the expression as returned by the debugger backend. */ String getStringValue(); - /** - * @return An IAddress object representing the memory address of the value of the expression (if it - * has one). Non-lvalues do not have memory addresses (e.g., "x + 5"). When the expression - * has no address, this method returns an IAddress object on which isZero() returns true. - */ - IAddress getAddress(); - /** * @return A Map in which the keys are strings that are the names of enumerators in the enumeration * that is the value of this expression and the values are the integer values of the @@ -146,6 +139,18 @@ public interface IExpressions extends IDMService, IFormattedValues { * The data request monitor that will contain the requested data */ void getExpressionData(IExpressionDMContext dmc, DataRequestMonitor rm); + + /** + * Retrieves the address and size of an expression given by the expression context(dmc). + * Non-lvalues do not have an addresses (e.g., "x + 5"). When the expression +- * has no address, the data request monitor will contain null. + * + * @param dmc + * The ExpressionDMC for the expression + * @param rm + * The data request monitor that will contain the requested data + */ + void getExpressionAddressData(IExpressionDMContext dmc, DataRequestMonitor rm); /** * Returns the data model context object for the specified expression in the context @@ -218,5 +223,5 @@ public interface IExpressions extends IDMService, IFormattedValues { * * @param rm: Request completion monitor. */ - void writeExpression(IDMContext expressionContext, String expressionValue, String formatId, RequestMonitor rm); + void writeExpression(IExpressionDMContext expressionContext, String expressionValue, String formatId, RequestMonitor rm); } From cad5eca6bdc5ed7593fb2472ea165da47395d4c7 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Thu, 8 Nov 2007 19:42:02 +0000 Subject: [PATCH 177/834] Updated to use the standard pattern for request monitors --- .../dd/dsf/ui/viewmodel/update/VMCache.java | 33 +++---------------- 1 file changed, 5 insertions(+), 28 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java index 224cde67366..ec6438f0727 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java @@ -16,7 +16,6 @@ import java.util.List; import java.util.Vector; import java.util.concurrent.Executor; -import org.eclipse.core.runtime.IStatus; import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor; @@ -358,36 +357,14 @@ public abstract class VMCache else { service.getModelData(dmc, - new DataRequestMonitor(executor, null) { + new DataRequestMonitor(executor, rm) { @Override - protected void handleCompleted() { - if(getStatus().isOK()) - { - if(isCacheWriteEnabled()) - fData.put(dmc, getData()); - rm.setData(getData()); - } + protected void handleOK() { + if(isCacheWriteEnabled()) + fData.put(dmc, getData()); + rm.setData(getData()); rm.done(); } - - @Override - public synchronized void setCanceled(boolean canceled) { - rm.setCanceled(canceled); - super.setCanceled(canceled); - } - - @Override - public void setMultiStatus(String pluginId, int code, - String message, IStatus subStatus) { - rm.setMultiStatus(pluginId, code, message, subStatus); - super.setMultiStatus(pluginId, code, message, subStatus); - } - - @Override - public synchronized void setStatus(IStatus status) { - rm.setStatus(status); - super.setStatus(status); - } } ); } From 18fd2d6ef61962581c0f8a44056beffcd7294f6e Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Thu, 8 Nov 2007 19:53:21 +0000 Subject: [PATCH 178/834] Updated handleRejectedExecutionException to create its own error status. --- .../dd/dsf/concurrent/RequestMonitor.java | 28 +++++-------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java index 71321a735ab..9a7c0343fbf 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java @@ -156,20 +156,6 @@ public class RequestMonitor { handleRejectedExecutionException(); } } - - /** - * Convenience method for setting the status using a status object of a - * sub-command. - * @param pluginId plugin id of the invoked method - * @param code status code - * @param message message to include - * @param subStatus status object to base the RequestMonitor status on - */ - public void setMultiStatus(String pluginId, int code, String message, final IStatus subStatus) { - MultiStatus status = new MultiStatus(pluginId, code, message, null); - status.merge(subStatus); - fStatus = status; - } @Override public String toString() { @@ -178,7 +164,7 @@ public class RequestMonitor { /** * Default handler for the completion of a request. The implementation - * calls {@link #handleOK()} if the request succeded, and calls + * calls {@link #handleOK()} if the request succeeded, and calls * {@link #handleErrorOrCancel()} or cancel otherwise. *
    * Note: Sub-classes may override this method. @@ -235,7 +221,7 @@ public class RequestMonitor { */ protected void handleError() { if (fParentRequestMonitor != null) { - fParentRequestMonitor.setMultiStatus(DsfPlugin.PLUGIN_ID, getStatus().getCode(), "Failed: " + toString(), getStatus()); //$NON-NLS-1$ + fParentRequestMonitor.setStatus(getStatus()); fParentRequestMonitor.done(); } else { MultiStatus logStatus = new MultiStatus(DsfPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Request for monitor: '" + toString() + "' resulted in an error.", null); //$NON-NLS-1$ //$NON-NLS-2$ @@ -253,23 +239,23 @@ public class RequestMonitor { */ protected void handleCancel() { if (fParentRequestMonitor != null) { - fParentRequestMonitor.setMultiStatus(DsfPlugin.PLUGIN_ID, getStatus().getCode(), "Canceled: " + toString(), getStatus()); //$NON-NLS-1$ + fParentRequestMonitor.setStatus(getStatus()); fParentRequestMonitor.done(); } } /** * Default handler for when the executor supplied in the constructor - * rejects the runnable that is submitted invoke this requrest monitor. + * rejects the runnable that is submitted invoke this request monitor. * This usually happens only when the executor is shutting down. */ protected void handleRejectedExecutionException() { + MultiStatus logStatus = new MultiStatus(DsfPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Request for monitor: '" + toString() + "' resulted in a rejected execution exception.", null); //$NON-NLS-1$ //$NON-NLS-2$ + logStatus.merge(getStatus()); if (fParentRequestMonitor != null) { - fParentRequestMonitor.setMultiStatus(DsfPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Rejected execution exception when trying to complete the request monitor: " + toString(), getStatus()); //$NON-NLS-1$ + fParentRequestMonitor.setStatus(logStatus); fParentRequestMonitor.done(); } else { - MultiStatus logStatus = new MultiStatus(DsfPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Request for monitor: '" + toString() + "' resulted in a rejected execution exception.", null); //$NON-NLS-1$ //$NON-NLS-2$ - logStatus.merge(getStatus()); DsfPlugin.getDefault().getLog().log(logStatus); } } From 1d31b66b194f183741c2294e57f7b5c38196e8f8 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 14 Nov 2007 00:16:00 +0000 Subject: [PATCH 179/834] [205142] Refactored use of DM contexts to make them more flexible. --- .../debug/ui/actions/DsfCommandRunnable.java | 5 - .../debug/ui/actions/DsfTerminateCommand.java | 102 ---- .../debug/model/DsfMemoryBlockRetrieval.java | 10 +- .../dd/dsf/debug/service/IBreakpoints.java | 47 +- .../eclipse/dd/dsf/debug/service/IMemory.java | 2 + .../dsf/debug/service/INativeProcesses.java | 131 ----- .../dd/dsf/debug/service/ISignals.java | 25 + .../eclipse/dd/dsf/debug/service/IStack.java | 8 +- .../debug/service/command/CommandCache.java | 518 ++++++++++++++++++ .../concurrent/CountingRequestMonitor.java | 9 + 10 files changed, 586 insertions(+), 271 deletions(-) delete mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfTerminateCommand.java delete mode 100644 plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/INativeProcesses.java create mode 100644 plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISignals.java create mode 100644 plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java index 3ad8a811f20..3c925b0a819 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java @@ -15,7 +15,6 @@ import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.dsf.datamodel.DMContexts; -import org.eclipse.dd.dsf.debug.service.INativeProcesses; import org.eclipse.dd.dsf.debug.service.IRunControl; import org.eclipse.dd.dsf.debug.service.IStepQueueManager; import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; @@ -40,10 +39,6 @@ public abstract class DsfCommandRunnable extends DsfRunnable { return fTracker.getService(IStepQueueManager.class); } - public INativeProcesses getProcesses() { - return fTracker.getService(INativeProcesses.class); - } - public DsfCommandRunnable(DsfServicesTracker servicesTracker, Object element, IDebugCommandRequest request) { fTracker = servicesTracker; if (element instanceof DMVMContext) { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfTerminateCommand.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfTerminateCommand.java deleted file mode 100644 index 40b954b4d0b..00000000000 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfTerminateCommand.java +++ /dev/null @@ -1,102 +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.ui.actions; - -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.DsfExecutor; -import org.eclipse.dd.dsf.concurrent.DsfRunnable; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.datamodel.DMContexts; -import org.eclipse.dd.dsf.debug.service.INativeProcesses; -import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; -import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; -import org.eclipse.dd.dsf.service.DsfServicesTracker; -import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode.DMVMContext; -import org.eclipse.debug.core.commands.IDebugCommandRequest; -import org.eclipse.debug.core.commands.IEnabledStateRequest; -import org.eclipse.debug.core.commands.ITerminateHandler; - -public class DsfTerminateCommand implements ITerminateHandler { - private final DsfExecutor fExecutor; - private final DsfServicesTracker fTracker; - - public DsfTerminateCommand(DsfSession session) { - fExecutor = session.getExecutor(); - fTracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), session.getId()); - } - - public void dispose() { - fTracker.dispose(); - } - - // Run control may not be avilable after a connection is terminated and shut down. - public void canExecute(final IEnabledStateRequest request) { - if (request.getElements().length != 1 || - !(request.getElements()[0] instanceof DMVMContext) ) - { - request.setEnabled(false); - request.done(); - return; - } - - // Javac doesn't like the cast to "(AbstractDMVMLayoutNode.DMVMContext)" need to use the - // construct below and suppress warnings. - @SuppressWarnings("unchecked") - AbstractDMVMLayoutNode.DMVMContext vmc = (AbstractDMVMLayoutNode.DMVMContext)request.getElements()[0]; - final IExecutionDMContext dmc = DMContexts.getAncestorOfType(vmc.getDMC(), IExecutionDMContext.class); - if (dmc == null) { - request.setEnabled(false); - request.done(); - return; - } - - fExecutor.execute( - new DsfRunnable() { - public void run() { - // Get the processes service and the exec context. - INativeProcesses processes = fTracker.getService(INativeProcesses.class); - if (processes == null || dmc == null) { - // Context or service already invalid. - request.done(); - } else { - // Check the teriminate. - processes.canTerminate( - processes.getProcessForDebugContext(dmc), - new DataRequestMonitor(fExecutor, null) { - @Override - public void handleCompleted() { - request.setEnabled(getData()); - request.done(); - } - }); - } - } - }); - } - - public boolean execute(final IDebugCommandRequest request) { - if (request.getElements().length != 1) { - request.done(); - return false; - } - - fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) { - @Override public void doExecute() { - getProcesses().terminate( - getProcesses().getProcessForDebugContext(getContext()), new RequestMonitor(fExecutor, null)); - } - }); - return false; - } - -} diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java index b83c77bc4af..8b82bd70110 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java @@ -33,6 +33,7 @@ import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMData; import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext; import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData; +import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryDMContext; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.debug.core.DebugException; @@ -66,7 +67,7 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl private final String fModelId; private final DsfSession fSession; private final DsfExecutor fExecutor; - private IDMContext fContext; + private IMemoryDMContext fContext; private final ServiceTracker fMemoryServiceTracker; private final ServiceTracker fExpressionServiceTracker; @@ -77,7 +78,7 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl * @param dmc * @throws DebugException */ - public DsfMemoryBlockRetrieval(String modelId, IDMContext dmc) throws DebugException { + public DsfMemoryBlockRetrieval(String modelId, IMemoryDMContext dmc) throws DebugException { fModelId = modelId; fContext = dmc; @@ -263,11 +264,8 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl return null; } - // Update the DMC - fContext = dmc; - // Resolve the expression - blockAddress = resolveMemoryAddress(fContext, expression); + blockAddress = resolveMemoryAddress(dmc, expression); if (blockAddress == null) { return null; } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java index 0b2b47cfa0e..87114f4d5c2 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java @@ -10,12 +10,9 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.service; -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.datamodel.IDMData; -import org.eclipse.dd.dsf.datamodel.IDMEvent; -import org.eclipse.dd.dsf.datamodel.IDMService; -import org.eclipse.debug.core.model.IBreakpoint; +import org.eclipse.dd.dsf.service.IDsfService; /** * Breakpoint service interface. The breakpoint service tracks platform breakpoint @@ -24,26 +21,28 @@ import org.eclipse.debug.core.model.IBreakpoint; * breakpoint status in more detail and more dynamically than it it possible with * just the marker-based breakpoint object. */ -public interface IBreakpoints extends IDMService { - - public enum BreakpointStatus { INSTALLED, FAILED_TO_INSTALL, FILTERED_OUT } +public interface IBreakpoints extends IDsfService { + + /** + * Marker interface for a context for which breakpoints can be installed. + */ + public interface IBreakpointsDMContext extends IDMContext {}; - public interface IBreakpointDMContext extends IDMContext {} + /** + * Install and begin tracking breakpoints for given context. The service + * will keep installing new breakpoints that appear in the IDE for this + * context until {@link #uninstallBreakpoints(IDMContext)} is called for that + * context. + * @param dmc Context to start tracking breakpoints for. + * @param rm Completion callback. + */ + public void installBreakpoints(IDMContext dmc, RequestMonitor rm); - public interface IBreakpointDMData extends IDMData { - IBreakpoint getPlatformBreakpoint(); - BreakpointStatus getStatus(); - } - - public interface IBreakpointDMEvent extends IDMEvent {} - - public interface IBreakpointInstalledDMEvent extends IBreakpointDMEvent {} - public interface IBreakpointUninstalledDMEvent extends IBreakpointDMEvent {} - public interface IBreakpointInstallFailedDMEvent extends IBreakpointDMEvent {} - - public interface IBreakpointHitEvent extends IBreakpointDMEvent {} - - public void getAllBreakpoints(IDMContext ctx, DataRequestMonitor rm); - public void getBreakpoints(IDMContext ctx, IBreakpoint platformBp, DataRequestMonitor rm); + /** + * Uninstall and stop tracking breakpoints for the given context. + * @param dmc Context to start tracking breakpoints for. + * @param rm Completion callback. + */ + public void uninstallBreakpoints(IDMContext dmc, RequestMonitor rm); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java index 24b1f4de6a7..e54ae738e94 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java @@ -26,6 +26,8 @@ import org.eclipse.debug.core.model.MemoryByte; */ public interface IMemory extends IDsfService { + public interface IMemoryDMContext extends IDMContext {} + /** * Event generated every time a range of bytes is modified. * diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/INativeProcesses.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/INativeProcesses.java deleted file mode 100644 index e71b08fd5f8..00000000000 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/INativeProcesses.java +++ /dev/null @@ -1,131 +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.service; - -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.datamodel.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 - * information, manipulation methods, and debugging methods. - * This service provides a relatively simple interface for - * manipulating processes as compared with a full-blown - * remote target debugger. - */ -public interface INativeProcesses extends IDMService { - - public interface IThreadDMContext extends IDMContext {} - public interface IProcessDMContext extends IDMContext {} - - /** - * Interface for thread and process object data. - */ - public interface IThreadDMData extends IDMData { - String getName(); - String getId(); - boolean isDebuggerAttached(); - IDMContext getDebugContext(); - } - - /** - * Interface for thread and process object data. - */ - public interface IProcessDMData extends IDMData { - String getName(); - String getId(); - boolean isDebuggerAttached(); - IDMContext getDebugContext(); - } - - /** - * Event indicating that process data has changed. - */ - public interface IProcessChangedDMEvent extends IDMEvent {} - - - public interface IProcessStartedEvent extends IDMEvent { - IProcessDMContext getProcess(); - } - - public interface IProcessExitedEvent extends IDMEvent { - IProcessDMContext getProcess(); - } - - public void getThreadData(IThreadDMContext dmc, DataRequestMonitor rm); - - public void getProcessData(IProcessDMContext dmc, DataRequestMonitor rm); - - - /** - * Returns a thread for the corresponding context. null if no corresponding - * thread exists. - * @param execCtx - * @return - */ - public IThreadDMContext getThreadForDebugContext(IDMContext execCtx); - - /** - * Returns a process context corresponding to the given context. null if no - * corresponding process exists. - */ - public IProcessDMContext getProcessForDebugContext(IDMContext execCtx); - - /** - * Retrieves the current list of processes running on target. - * @param rm Request completion monitor, to be filled in with array of process contexts. - */ - void getRunningProcesses(DataRequestMonitor rm); - - /** - * Attaches debugger to the given process. - */ - void attachDebuggerToProcess(IProcessDMContext procCtx, RequestMonitor requestMonitor); - - /** - * Starts a new process. - * @param file Process image to use for the new process. - * @param rm Request completion monitor, to be filled in with the process context. - */ - void runNewProcess(String file, DataRequestMonitor rm); - - /** - * Starts a new process with debugger attached. - * @param file Process image to use for the new process. - * @param rm Request completion monitor, to be willed in with the process context. - */ - void debugNewProcess(String file, DataRequestMonitor rm); - - /** - * Retrieves the list of processes which are currently under - * debugger control. - * @param rm Request completion monitor. - */ - void getProcessesBeingDebugged(DataRequestMonitor rm); - - /** - * Checks whether the given process or thread can be terminated. - * @param thread Thread or process to terminate. - * @param rm Return token. - */ - void canTerminate(IDMContext ctx, DataRequestMonitor rm); - - /** - * Terminates the selected process or thread. - * @param thread Thread or process to terminate. - * @param rm Request completion monitor, indicates success or failure. - */ - void terminate(IDMContext ctx, RequestMonitor requestMonitor); - -} diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISignals.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISignals.java new file mode 100644 index 00000000000..4ae9c3e3910 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISignals.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.service; + +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.service.IDsfService; + +/** + * + */ +public interface ISignals extends IDsfService { + /** + * Marker interface for a context for which signals can be set. + */ + public interface ISignalsDMContext extends IDMContext {}; + +} diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java index 8a4180ad89c..49020ad4c25 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java @@ -104,10 +104,12 @@ public interface IStack extends IDMService { /** * Retrieves the stack depth of the specified stack frame. + * @param dmc Context to retrieve data for. + * @param The maximum depth of stack to calculate. Should be 0 to calculate + * depth with no limit. + * @param rm Callback */ - void getStackDepth(DataRequestMonitor rm); - - void getStackDepth(int maxDepth, DataRequestMonitor rm); + void getStackDepth(IDMContext dmc, int maxDepth, DataRequestMonitor rm); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java new file mode 100644 index 00000000000..5bdd7e9513f --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java @@ -0,0 +1,518 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + * Ericsson - Modified for caching commands corresponding to multiple execution contexts + *******************************************************************************/ + +package org.eclipse.dd.dsf.debug.service.command; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.DsfDebugPlugin; +import org.eclipse.dd.dsf.service.IDsfService; + +/** + * This is a utility class for caching results of MI Commands. Return MIInfo + * data is retrieved from the cache if command was previously executed, and + * it is executed with MICommand service if it was not previously seen. + * + * Resetting the cache has to be performed by the object owning the cache when + * when an event indicates that the data is obsolete (which is specific to the + * types of commands being cached). + */ + +public class CommandCache implements ICommandListener +{ + static enum CommandStyle { COALESCED, NONCOALESCED } + + /** + * Holds cache information for a given command. + * @param Type matches the result type associated with the command. + */ + class CommandInfo { + + /* + * Control variables. + */ + + /** List of the request monitors associated with this command */ + List> fCurrentRequestMonitors ; + + /** Original command. Need for reference from Queue completion notification */ + ICommand fCommand; + + /** Style of this command ( internal coalesced or not) */ + CommandStyle fCmdStyle; + + /** Command being processed for this command */ + CommandInfo fCoalescedCmd; + + /** No longer really used and needs to be deleted */ + int fResetCounterStatus; + + public CommandInfo( CommandStyle cmdstyle, ICommand cmd, DataRequestMonitor rm ) { + + fCmdStyle = cmdstyle; + fCommand = cmd; + fCurrentRequestMonitors = new LinkedList>(); + fCurrentRequestMonitors.add(rm); + fCoalescedCmd = null; + fResetCounterStatus = fResetCounter; + } + + public CommandStyle getCommandstyle() { return fCmdStyle; } + public List> getRequestMonitorList() { return fCurrentRequestMonitors; } + public ICommand getCommand() { return fCommand; } + public CommandInfo getCoalescedCmd() { return fCoalescedCmd; } + public void setCoalescedCmd( CommandInfo cmd ) { fCoalescedCmd = cmd; } + + @Override + public boolean equals(Object other) { + if (!(other instanceof CommandInfo)) return false; + CommandInfo otherCmd = (CommandInfo)other; + + return otherCmd.fCommand.equals(fCommand); + } + + @Override + public int hashCode() { + return (fCommand.hashCode()+ (fResetCounterStatus + 1)); + } + } + + /* + * This class contains 5 significant lists. + * + * Cached Results : + * + * Contains a mapping of commands and their completed results. Until the cached + * results are cleared by the owner of the cache. + * + * Pending Commands Not Queued : + * + * The Control object has not yet indicated that it has recognized the command + * yet. The user is not allowed to interrogate these objects until the Control + * object indicates they have been queued ( commandQueued notification ). + * + * Pending Commands Unsent : + * + * This is the list of commands which have been issued to the Control object but + * have not been actually issued to the backend. These commands represent coalesce + * options. They may be compared against the Queued list being maintained by the + * Control object until told otherwise - commandSent notification ). + * + * Pending Commands Sent : + * + * This is a list of commands which have been issued to the Control object and + * have also been sent to the backend. It is not possible use these objects for + * coalescents. + * + * Coalesced Pending Q : + * + * These represent original commands for which a new coalesced command has been + * created. When the coalesced commands completes the results will be decomposed + * when back into individual results from this command. + */ + + private boolean fIsTargetAvailable = true; + private int fResetCounter = 0; + + private ICommandControl fCommandControl; + + private Map> fCachedContexts = new HashMap>(); + + private ArrayList fPendingQCommandsSent = new ArrayList(); + + private ArrayList fPendingQCommandsNotYetSent = new ArrayList(); + + private ArrayList fPendingQWaitingForCoalescedCompletion = new ArrayList(); + + public CommandCache(ICommandControl control) { + fCommandControl = control; + + /* + * We listen for the notifications that the commands have been sent to the + * backend from the GDB/MI Communications engine. + */ + fCommandControl.addCommandListener(this); + } + + /* + * Constructs a coalesced command if possible. + */ + private CommandInfo getCoalescedCommand(CommandInfo cmd) { + + for ( CommandInfo currentUnsentEntry : new ArrayList(fPendingQCommandsNotYetSent) ) { + /* + * Get the current unsent entry to determine if we can coalesced with it. + */ + ICommand unsentCommand = currentUnsentEntry.getCommand(); + + /* + * Check if we can so construct a new COALESCED command from scratch. + */ + + // For sanity's sake, cast the generic ?'s to concrete types in the cache implementation. + @SuppressWarnings("unchecked") + ICommand coalescedCmd = + (ICommand)unsentCommand.coalesceWith( cmd.getCommand() ); + + if ( coalescedCmd != null ) { + CommandInfo coalescedCmdInfo = new CommandInfo( CommandStyle.COALESCED, coalescedCmd, null) ; + + if ( currentUnsentEntry.getCommandstyle() == CommandStyle.COALESCED ) { + /* + * We matched a command which is itself already a COALESCED command. So + * we need to run through the reference list and point all the current + * command which are referencing the command we just subsumed and change + * them to point to the new super command. + */ + + for ( CommandInfo waitingEntry : new ArrayList(fPendingQWaitingForCoalescedCompletion) ) { + + if ( waitingEntry.getCoalescedCmd() == currentUnsentEntry ) { + /* + * This referenced the old command change it to point to the new one. + */ + waitingEntry.setCoalescedCmd(coalescedCmdInfo); + } + } + } else { + /* + * This currently unsent entry needs to go into the coalescing list. To + * be completed when the coalesced command comes back with a result. + */ + fPendingQWaitingForCoalescedCompletion.add(currentUnsentEntry); + currentUnsentEntry.setCoalescedCmd(coalescedCmdInfo); + } + + /* + * Either way we want to take the command back from the Control object so it + * does not continue to process it. + */ + fPendingQCommandsNotYetSent.remove(currentUnsentEntry); + fCommandControl.removeCommand(unsentCommand); + + return( coalescedCmdInfo ); + } + } + + return null; + } + + /** + * Executes given ICommand, or retrieves the cached result if known. + * @param command Command to execute. + * @param rm Return token, contains the retrieved MIInfo object as + * well as its cache status. + */ + public void execute(ICommand command, DataRequestMonitor rm) { + assert fCommandControl.getExecutor().isInExecutorThread(); + + // Cast the generic ?'s to concrete types in the cache implementation. + @SuppressWarnings("unchecked") + final ICommand genericCommand = (ICommand)command; + @SuppressWarnings("unchecked") + final DataRequestMonitor genericDone = (DataRequestMonitor) rm; + + CommandInfo cachedCmd = new CommandInfo( CommandStyle.NONCOALESCED, genericCommand, genericDone) ; + + final IDMContext context = genericCommand.getContext(); + + /* + * If command is already cached, just return the cached data. + */ + if(fCachedContexts.get(context) != null && fCachedContexts.get(context).containsKey(cachedCmd)){ + // Cast to the erased type of the returned command result. + // To ensure type safety, we are relying on the correct matching + // of command and result in the cached results map. + @SuppressWarnings("unchecked") + V v = (V) fCachedContexts.get(context).get(cachedCmd); + + rm.setData(v); + rm.done(); + return; + } + + /* + * Return an error if the target is available anymore. + */ + if (!fIsTargetAvailable) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Target not available.", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + /* + * If we are waiting for this command to complete ( but the command has + * been sent to the debug engine), add this request monitor to list of waiting monitors. + */ + + for ( CommandInfo sentCommand : fPendingQCommandsSent ) { + if ( sentCommand.equals( cachedCmd )) { + sentCommand.getRequestMonitorList().add(genericDone); + return; + } + } + + /* + * We see if this command can be combined into a coalesced one. The + * coalesce routine will take care of the already enqueued one which + * this command is being coalesced with. + */ + + CommandInfo coalescedCmd = getCoalescedCommand(cachedCmd); + + if ( coalescedCmd != null ) { + /* + * The original command we were handed needs to go into the waiting QUEUE. + * We also need to point it it to the coalesced command. + */ + fPendingQWaitingForCoalescedCompletion.add(cachedCmd); + cachedCmd.setCoalescedCmd(coalescedCmd); + cachedCmd = coalescedCmd; + } + + /* + * Now we have a command to send ( coalesced or not ). Put it in the cannot touch + * it list and give it to the Control object. Our state handlers will move it into + * the proper list as the Control object deals with it. + */ + final CommandInfo finalCachedCmd = cachedCmd; + fPendingQCommandsNotYetSent.add(finalCachedCmd); + + fCommandControl.queueCommand( + finalCachedCmd.getCommand(), + new DataRequestMonitor(fCommandControl.getExecutor(), null) { + @Override + public void handleCompleted() { + + /* + * Match this up with a command set we know about. + */ + if ( ! fPendingQCommandsSent.remove(finalCachedCmd) ) { + /* + * It should not be the case that this is possible. It would mean we + * have mismanaged the queues or completions are lost at the lower + * levels. When the removal and cancellation is completed this code + * will probably not be here. But for now just return. + */ + return ; + } + + if ( finalCachedCmd.getCommandstyle() == CommandStyle.COALESCED ) { + /* + * We matched a command which is itself already a COALESCED command. So + * we need to go throught the list of unsent commands which were not sent + * because the coalesced command represented it. For each match we find + * we create a new result from the coalesced command for it. + */ + ICommandResult result = getData(); + + for ( CommandInfo waitingEntry : new ArrayList(fPendingQWaitingForCoalescedCompletion) ) { + + if ( waitingEntry.getCoalescedCmd() == finalCachedCmd ) { + + /* + * Remove this entry from the list since we can complete it. + */ + fPendingQWaitingForCoalescedCompletion.remove(waitingEntry); + + // Cast the calculated result back to the requested type. + @SuppressWarnings("unchecked") + V newresult = (V)result.getSubsetResult(waitingEntry.getCommand()); + + + if(fCachedContexts.get(context) != null){ + fCachedContexts.get(context).put(waitingEntry, newresult); + } + else{ + HashMap map = new HashMap(); + map.put(waitingEntry, newresult); + fCachedContexts.put(context, map); + } + + if (!getStatus().isOK()) { + + /* + * We had some form of error with the original command. So notify the + * original requestors of the issues. + */ + for (DataRequestMonitor pendingRM : waitingEntry.getRequestMonitorList()) { + pendingRM.setStatus(getStatus()); + pendingRM.done(); + } + } else { + assert newresult != null; + + /* + * Notify the original requestors of the positive results. + */ + for (DataRequestMonitor pendingRM : waitingEntry.getRequestMonitorList()) { + // Cast the pending return token to match the requested type. + @SuppressWarnings("unchecked") + DataRequestMonitor vPendingRM = (DataRequestMonitor) pendingRM; + + vPendingRM.setData(newresult); + vPendingRM.done(); + } + } + } + } + } else { + /* + * This is an original request which completed. Indicate success or + * failure to the original requestors. + */ + + if (!getStatus().isOK()) { + /* + * We had some form of error with the original command. So notify the + * original requestors of the issues. + */ + for (DataRequestMonitor pendingRM : finalCachedCmd.getRequestMonitorList()) { + pendingRM.setStatus(getStatus()); + pendingRM.done(); + } + } else { + // Cast the calculated result back to the requested type. + @SuppressWarnings("unchecked") + V result = (V)getData(); + + if(fCachedContexts.get(context) != null){ + fCachedContexts.get(context).put(finalCachedCmd, result); + } + else{ + HashMap map = new HashMap(); + map.put(finalCachedCmd, result); + fCachedContexts.put(context, map); + } + + for (DataRequestMonitor pendingRM : finalCachedCmd.getRequestMonitorList()) { + // Cast the pending return token to match the requested type. + @SuppressWarnings("unchecked") + DataRequestMonitor vPendingRM = (DataRequestMonitor) pendingRM; + + vPendingRM.setData(result); + vPendingRM.done(); + } + } + } + } + }); + } + + /** + * Sets the cache to a state in which target access is not allowed. + * When target is not available, commands to the target will either + * return data that is found in the cache already, or will return an + * error. This is useful in avoiding sending commands to target when + * they are known to fail or return unreliable results, while still + * providing access to the cached data. + * + * @param isAvailable Flag indicating whether target can be accessed. + */ + public void setTargetAvailable(boolean isAvailable) { + fIsTargetAvailable = isAvailable; + } + + /** + * Retrieves current flag indicating target availability. + * @see #setTargetAvailable(boolean) + */ + public boolean isTargetAvailable() { + return fIsTargetAvailable; + } + + /** + * Clears the cache data. + */ + public void reset() { + fCachedContexts.clear(); + fResetCounter++; + } + + public void commandRemoved(ICommand command) { + /* + * Do nothing. + */ + } + + /* + * (non-Javadoc) + * @see org.eclipse.dd.dsf.mi.service.control.IDebuggerControl.ICommandListener#commandQueued(org.eclipse.dd.dsf.mi.core.command.ICommand) + */ + public void commandQueued(ICommand command) { + /* + * Do nothing. + */ + } + + /* + * (non-Javadoc) + * @see org.eclipse.dd.dsf.mi.service.control.IDebuggerControl.ICommandListener#commandDone(org.eclipse.dd.dsf.mi.core.command.ICommand, org.eclipse.dd.dsf.mi.core.command.ICommandResult) + */ + public void commandDone(ICommand command, ICommandResult result) { + /* + * We handle the done with a runnable where we initiated the command + * so there is nothing to do here. + */ + } + + /* + * Move the command into our internal sent list. This means we can no longer look at + * this command for possible coalescence since it has been given to the debug engine + * and is currently being processed. + * + * (non-Javadoc) + * @see org.eclipse.dd.dsf.mi.service.control.IDebuggerControl.ICommandListener#commandSent(org.eclipse.dd.dsf.mi.core.command.ICommand) + */ + public void commandSent(ICommand command) { + + // Cast the generic ?'s to concrete types in the cache implementation. + @SuppressWarnings("unchecked") + ICommand genericCommand = (ICommand)command; + + CommandInfo cachedCmd = new CommandInfo( CommandStyle.NONCOALESCED, genericCommand, null) ; + + for ( CommandInfo unqueuedCommand : new ArrayList(fPendingQCommandsNotYetSent) ) { + if ( unqueuedCommand.equals( cachedCmd )) { + fPendingQCommandsNotYetSent.remove(unqueuedCommand); + fPendingQCommandsSent.add(unqueuedCommand); + break; + } + } + } + + /** + * Clears the cache entries for given context. Clears the whole cache if + * context parameter is null. + */ + public void reset(IDMContext dmc) { + if (dmc == null) { + fCachedContexts.clear(); + } + for (Iterator itr = fCachedContexts.keySet().iterator(); itr.hasNext();) { + IDMContext keyDmc = itr.next(); + if (keyDmc != null && DMContexts.isAncestorOf(keyDmc, dmc)) { + itr.remove(); + } + } + } +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/CountingRequestMonitor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/CountingRequestMonitor.java index 0fabdafb7da..736dc3cc957 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/CountingRequestMonitor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/CountingRequestMonitor.java @@ -12,6 +12,7 @@ package org.eclipse.dd.dsf.concurrent; import java.util.concurrent.Executor; +import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.dd.dsf.DsfPlugin; @@ -88,4 +89,12 @@ public class CountingRequestMonitor extends RequestMonitor { public String toString() { return "CountingRequestMonitor: " + getStatus().toString(); //$NON-NLS-1$ } + + @Override + public synchronized void setStatus(IStatus status) { + if (!(getStatus() instanceof MultiStatus)) { + super.setStatus(new MultiStatus(DsfPlugin.PLUGIN_ID, 0, "Combined status of multiple asynchronous operations", null)); //$NON-NLS-1$ + } + ((MultiStatus)getStatus()).add(status); + }; } From 6e8c328c016267fe910b0b733bdbee92902606be Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 15 Nov 2007 16:44:56 +0000 Subject: [PATCH 180/834] [205334] Implemented viewer input provider to set the default input in expressions view. Also, added more expression manager event handling. --- .../expression/ExpressionVMProvider.java | 14 +++++++++++--- .../dd/dsf/ui/viewmodel/AbstractVMAdapter.java | 17 +++++++++++++++-- .../dsf/ui/viewmodel/AbstractVMProvider.java | 18 +++++++++++++++++- .../dd/dsf/ui/viewmodel/IVMAdapter.java | 3 ++- .../dd/dsf/ui/viewmodel/IVMProvider.java | 3 ++- 5 files changed, 47 insertions(+), 8 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java index 33c54a67b97..7fb7ed6438b 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java @@ -24,8 +24,8 @@ import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode; import org.eclipse.dd.dsf.ui.viewmodel.dm.DMVMRootLayoutNode; import org.eclipse.debug.core.DebugPlugin; -import org.eclipse.debug.core.IExpressionsListener; import org.eclipse.debug.core.model.IExpression; +import org.eclipse.debug.internal.core.IExpressionsListener2; import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; @@ -33,10 +33,10 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationCont * */ @SuppressWarnings("restriction") -public class ExpressionVMProvider extends AbstractDebugDMVMProviderWithCache implements IExpressionsListener +public class ExpressionVMProvider extends AbstractDebugDMVMProviderWithCache implements IExpressionsListener2 { public static class ExpressionsChangedEvent { - enum Type {ADDED, CHANGED, REMOVED} + enum Type {ADDED, CHANGED, REMOVED, MOVED, INSERTED} public final Type fType; public final IExpression[] fExpressions; public ExpressionsChangedEvent(Type type, IExpression[] expressions) { @@ -162,4 +162,12 @@ public class ExpressionVMProvider extends AbstractDebugDMVMProviderWithCache imp public void expressionsRemoved(IExpression[] expressions) { handleEvent(new ExpressionsChangedEvent(ExpressionsChangedEvent.Type.REMOVED, expressions)); } + + public void expressionsInserted(IExpression[] expressions, int index) { + handleEvent(new ExpressionsChangedEvent(ExpressionsChangedEvent.Type.INSERTED, expressions)); + } + + public void expressionsMoved(IExpression[] expressions, int index) { + handleEvent(new ExpressionsChangedEvent(ExpressionsChangedEvent.Type.MOVED, expressions)); + } } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java index d74c297c78f..12fd985be2e 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java @@ -29,6 +29,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentati import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; /** @@ -110,7 +111,7 @@ abstract public class AbstractVMAdapter implements IVMAdapter public void update(final IChildrenUpdate[] updates) { handleUpdates(updates); } - + private void handleUpdates(final IViewerUpdate[] updates) { try { getExecutor().execute(new DsfRunnable() { @@ -131,6 +132,10 @@ abstract public class AbstractVMAdapter implements IVMAdapter } }); } catch(RejectedExecutionException e) { + for (IViewerUpdate update : updates) { + update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, "VM adapter executor not available", e)); //$NON-NLS-1$ + update.done(); + } } } @@ -190,7 +195,15 @@ abstract public class AbstractVMAdapter implements IVMAdapter } return null; } - + + + public void update(IViewerInputUpdate update) { + final IVMProvider provider = getVMProvider(update.getPresentationContext()); + if (provider != null) { + provider.update(update); + } + } + /** * Creates a new View Model Provider for given presentation context. Returns null * if the presentation context is not supported. diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java index 8bdec75ce00..2ba86fa5b25 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java @@ -38,6 +38,8 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdat import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; import org.eclipse.debug.internal.ui.viewers.provisional.AbstractModelProxy; import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousContentAdapter; @@ -486,7 +488,21 @@ abstract public class AbstractVMProvider implements IVMProvider return null; } - + /** + * Calculates the proxy input object to be used for the given input in the given + * viewer. By default no proxy object is used an the given element is used + * as the input into the view. + *

    + * Sub classes can override this method for view-specific behavior. + * + * @see IViewerInputProvider + */ + public void update(IViewerInputUpdate update) { + update.setViewerInput(update.getElement()); + update.done(); + } + + /** * Convenience method that finds the VMC corresponding to given parent * argument given to isContainer() or retrieveChildren(). diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMAdapter.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMAdapter.java index 6c82f654f10..648981f77fe 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMAdapter.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMAdapter.java @@ -5,6 +5,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentati import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputProvider; /** * The View Model adapter handles the layout of a given data model within a @@ -15,7 +16,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationCont @ThreadSafe @SuppressWarnings("restriction") public interface IVMAdapter - extends IElementContentProvider, IModelProxyFactory, IColumnPresentationFactory + extends IElementContentProvider, IModelProxyFactory, IColumnPresentationFactory, IViewerInputProvider { /** * Returns the View Model Provider that is registered for the given presentation diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java index 66fcaa216a0..60960351190 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java @@ -5,6 +5,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentati import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputProvider; /** * The View Model Provider handles the layout of a given model within a @@ -14,7 +15,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationCont @ThreadSafe @SuppressWarnings("restriction") public interface IVMProvider - extends IElementContentProvider, IModelProxyFactory, IColumnPresentationFactory + extends IElementContentProvider, IModelProxyFactory, IColumnPresentationFactory, IViewerInputProvider { /** * Returns the VM Adapter associated with the provider. From d0e0286a8d674a3b222fbf50fe4ced3f91a2a66e Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Sat, 17 Nov 2007 00:24:49 +0000 Subject: [PATCH 181/834] [205142] Refactored use of execution, frame, and expression contexts in the MI implementation. --- .../sourcelookup/MISourceDisplayAdapter.java | 2 +- .../launch/StackFramesLayoutNode.java | 2 +- .../variable/VariableLayoutNode.java | 18 +++++++-------- .../dd/dsf/debug/service/IExpressions.java | 10 ++++---- .../dd/dsf/debug/service/IRunControl.java | 23 +++++++++++++++++-- .../eclipse/dd/dsf/debug/service/IStack.java | 5 ++-- 6 files changed, 39 insertions(+), 21 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java index 2338223bb17..058126bd9ab 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java @@ -288,7 +288,7 @@ public class MISourceDisplayAdapter implements ISourceDisplay @Override public void handleOK() { FramePositioningData clientData = new FramePositioningData(); - clientData.fLevel = getData().getLevel(); + clientData.fLevel = frameDmc.getLevel(); // Document line numbers are 0-based. While debugger line numbers are 1-based. clientData.fLine = getData().getLine() - 1; rm.setData(clientData); diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java index 62bee6a8935..6738a2f4e10 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java @@ -212,7 +212,7 @@ public class StackFramesLayoutNode extends AbstractDMVMLayoutNode { // Add frame number (if total number of frames in known) if (fCachedOldFrameVMCs != null) { - label.append(fCachedOldFrameVMCs.length - dmData.getLevel()); + label.append(fCachedOldFrameVMCs.length - dmContext.getLevel()); } // Add the function name diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java index d696d5233b9..383e3467689 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java @@ -13,6 +13,8 @@ import java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfExecutor; import org.eclipse.dd.dsf.concurrent.MultiRequestMonitor; @@ -439,19 +441,15 @@ public class VariableLayoutNode extends AbstractExpressionLayoutNode implements @Override protected void getElementForExpressionPart(IChildrenUpdate update, String expressionPartText, DataRequestMonitor rm) { - /* - * Create a valid DMC for this entered expression. - */ final IFrameDMContext frameDmc = findDmcInPath(update.getElementPath(), IFrameDMContext.class); final IExpressions expressionService = getServicesTracker().getService(IExpressions.class); - IExpressionDMContext expressionDMC = expressionService.createExpression(frameDmc, expressionPartText); - - /* - * Now create the valid VMC which wrappers it. - */ - IVMContext vmc = createVMContext(expressionDMC); - rm.setData(vmc); + if (frameDmc != null) { + IExpressionDMContext expressionDMC = expressionService.createExpression(frameDmc, expressionPartText); + rm.setData(createVMContext(expressionDMC)); + } else { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ + } rm.done(); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java index 6c418069124..4158552a8c9 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java @@ -51,7 +51,7 @@ public interface IExpressions extends IFormattedValues { /** * This is the model data interface that corresponds to IExpressionDMContext. */ - interface IExpressionDMData extends IDMData { + public interface IExpressionDMData extends IDMData { // These static fields define the possible return values of method getTypeId(). final static String TYPEID_UNKNOWN = "TYPEID_UNKNOWN"; @@ -128,7 +128,7 @@ public interface IExpressions extends IFormattedValues { * Event indicating that a given expression is changed. If an expression is changed, it's implied that all * the children of that expression are changed too. */ - interface IExpressionChangedDMEvent extends IDMEvent {} + public interface IExpressionChangedDMEvent extends IDMEvent {} /** * Retrieves the expression DM data object for the given expression context(dmc). @@ -154,15 +154,15 @@ public interface IExpressions extends IFormattedValues { /** * Returns the data model context object for the specified expression in the context - * specified by ctx. + * specified by ctx. * * @param ctx: Context in which to evaluate the expression. This context could include the * PC location, stack frame, thread, or just a symbol context. * * @param expression: The expression to evaluate. * - * @return An expression data model context object that must be passed to getModelData() to obtain the - * value of the expression. + * @return An expression data model context object that must be passed to + * getModelData() to obtain the value of the expression. */ IExpressionDMContext createExpression(IDMContext ctx, String expression); diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java index 28d4dceb0b8..3f5567cd8ae 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java @@ -47,22 +47,41 @@ public interface IRunControl extends IDMService public enum StateChangeReason { UNKNOWN, USER_REQUEST, STEP, BREAKPOINT, EXCEPTION, CONTAINER, WATCHPOINT, SIGNAL, SHAREDLIB, ERROR }; /** - * Events signaling a state changes. + * Indicates that the given thread has suspended. */ public interface ISuspendedDMEvent extends IDMEvent { StateChangeReason getReason(); } + /** + * Indicates that the given thread has resumed. + */ public interface IResumedDMEvent extends IDMEvent { StateChangeReason getReason(); } + /** + * Indicates that the given container has suspended. + */ public interface IContainerSuspendedDMEvent extends ISuspendedDMEvent { - IExecutionDMContext getTriggeringContext(); + /** + * Returns the context which triggered the resume, which could be + * null if not known. + */ + IExecutionDMContext getTriggeringContext(); } + /** + * Indicates that the given container has resumed. + */ public interface IContainerResumedDMEvent extends IResumedDMEvent { + /** + * Returns the context which triggered the resume, which could be + * null if not known. + */ + IExecutionDMContext getTriggeringContext(); } + /** * Indicates that a new execution context (thread) was started. The DMC * for the event is the container of the new exec context. diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java index 49020ad4c25..f14d6887bac 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java @@ -27,13 +27,14 @@ public interface IStack extends IDMService { * frame data, this context is used by other services that require a stack * frame for evaluation. */ - public interface IFrameDMContext extends IDMContext {} + public interface IFrameDMContext extends IDMContext { + int getLevel(); + } /** * Stack frame information. */ public interface IFrameDMData extends IDMData { - int getLevel(); IAddress getAddress(); String getFile(); String getFunction(); From 9df59c726e8054bc5b71eecfbe0476524a532185 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 20 Nov 2007 03:49:14 +0000 Subject: [PATCH 182/834] [205142] Standardized use of typed DM Context parameters in DSF Debug interfaces. --- .../viewmodel/modules/ModulesLayoutNode.java | 8 +- .../dd/dsf/debug/model/DsfMemoryBlock.java | 32 ++---- .../debug/model/DsfMemoryBlockRetrieval.java | 2 +- .../dd/dsf/debug/service/IBreakpoints.java | 4 +- .../eclipse/dd/dsf/debug/service/IMemory.java | 71 ++++++-------- .../dd/dsf/debug/service/IModules.java | 6 +- .../org/eclipse/dd/dsf/debug/service/IOS.java | 98 ------------------- .../dd/dsf/debug/service/IRegisters.java | 29 +++--- .../dd/dsf/debug/service/IRunControl.java | 22 ++--- .../dd/dsf/debug/service/ISourceLookup.java | 4 +- .../eclipse/dd/dsf/debug/service/IStack.java | 2 +- .../dsf/debug/service/IStepQueueManager.java | 13 ++- .../dd/dsf/debug/service/ITargets.java | 52 ---------- 13 files changed, 82 insertions(+), 261 deletions(-) delete mode 100644 plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IOS.java delete mode 100644 plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ITargets.java diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesLayoutNode.java index 49163bd4a44..f297e5da654 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesLayoutNode.java @@ -18,8 +18,8 @@ import org.eclipse.dd.dsf.debug.service.IRegisters; import org.eclipse.dd.dsf.debug.service.IRunControl; import org.eclipse.dd.dsf.debug.service.IModules.IModuleDMContext; import org.eclipse.dd.dsf.debug.service.IModules.IModuleDMData; +import org.eclipse.dd.dsf.debug.service.IModules.ISymbolDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IGroupChangedDMEvent; -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.AbstractVMProvider; @@ -41,11 +41,11 @@ public class ModulesLayoutNode extends AbstractDMVMLayoutNode protected void updateElementsInSessionThread(final IChildrenUpdate update) { if (!checkService(IRegisters.class, null, update)) return; - final IExecutionDMContext execDmc = findDmcInPath(update.getElementPath(), IExecutionDMContext.class) ; + final ISymbolDMContext symDmc = findDmcInPath(update.getElementPath(), ISymbolDMContext.class) ; - if (execDmc != null) { + if (symDmc != null) { getServicesTracker().getService(IModules.class).getModules( - execDmc, + symDmc, new DataRequestMonitor(getSession().getExecutor(), null) { @Override public void handleCompleted() { diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java index 7809fb2273c..08d217fee8b 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java @@ -27,12 +27,10 @@ import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.Query; import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.debug.DsfDebugPlugin; import org.eclipse.dd.dsf.debug.service.IMemory; import org.eclipse.dd.dsf.debug.service.IRunControl; -import org.eclipse.dd.dsf.debug.service.IMemory.MemoryChangedEvent; -import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryChangedEvent; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.DebugException; @@ -509,28 +507,14 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens } @DsfServiceEventHandler - public void eventDispatched(MemoryChangedEvent e) { + public void eventDispatched(IMemoryChangedEvent e) { - // Find the container of the event - IContainerDMContext eventContext = DMContexts.getAncestorOfType(e.getContext(), IContainerDMContext.class); - if (eventContext == null) { - return; - } - - // Find the container of the block - IContainerDMContext blockContext = DMContexts.getAncestorOfType(fRetrieval.getContext(), IContainerDMContext.class); - if (blockContext == null) { - return; - } - - // Check if we are in the same address space - if (eventContext != blockContext) { - return; - } - - IAddress[] addresses = e.getAddresses(); - for (int i = 0; i < addresses.length; i++) - handleMemoryChange(addresses[i].getValue()); + // Check if we are in the same address space + if (e.getDMContext().equals(fRetrieval.getContext())) { + IAddress[] addresses = e.getAddresses(); + for (int i = 0; i < addresses.length; i++) + handleMemoryChange(addresses[i].getValue()); + } } /** diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java index 8b82bd70110..c0b5fbb163b 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java @@ -144,7 +144,7 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl return fExecutor; } - public IDMContext getContext() { + public IMemoryDMContext getContext() { return fContext; } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java index 87114f4d5c2..3f8aca9a6e9 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java @@ -36,13 +36,13 @@ public interface IBreakpoints extends IDsfService { * @param dmc Context to start tracking breakpoints for. * @param rm Completion callback. */ - public void installBreakpoints(IDMContext dmc, RequestMonitor rm); + public void installBreakpoints(IBreakpointsDMContext dmc, RequestMonitor rm); /** * Uninstall and stop tracking breakpoints for the given context. * @param dmc Context to start tracking breakpoints for. * @param rm Completion callback. */ - public void uninstallBreakpoints(IDMContext dmc, RequestMonitor rm); + public void uninstallBreakpoints(IBreakpointsDMContext dmc, RequestMonitor rm); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java index e54ae738e94..dc043307c68 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMemory.java @@ -16,6 +16,7 @@ import org.eclipse.cdt.core.IAddress; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.datamodel.IDMEvent; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.debug.core.model.MemoryByte; @@ -27,47 +28,33 @@ import org.eclipse.debug.core.model.MemoryByte; public interface IMemory extends IDsfService { public interface IMemoryDMContext extends IDMContext {} - - /** - * Event generated every time a range of bytes is modified. - * - * A client wishing to receive such events has to register as a service - * event listener and implement the corresponding eventDispatched method. - * - * E.g.: - * - * MyMemoryBlock(MIRunControl fRunControl) - * { - * ... - * fRunControl.getSession().addServiceEventListener(MyMemoryBlock.this, null); - * ... - * } - * - * @DsfServiceEventHandler - * public void eventDispatched(MemoryChangedEvent e) { - * IDMContext context = e.getContext(); - * IAddress[] addresses = e.getAddresses(); - * // do whatever... - * } - */ - public class MemoryChangedEvent { - IAddress[] fAddresses; - IDMContext fContext; - - public MemoryChangedEvent(IDMContext context, IAddress[] addresses) { - fContext = context; - fAddresses = addresses; - } - public IDMContext getContext() { - return fContext; - } - - public IAddress[] getAddresses() { - return fAddresses; - } + /** + * Event generated every time a range of bytes is modified. + * + * A client wishing to receive such events has to register as a service + * event listener and implement the corresponding eventDispatched method. + * + * E.g.: + * + * MyMemoryBlock(MIRunControl fRunControl) + * { + * ... + * fRunControl.getSession().addServiceEventListener(MyMemoryBlock.this, null); + * ... + * } + * + * @DsfServiceEventHandler + * public void eventDispatched(MemoryChangedEvent e) { + * IDMContext context = e.getContext(); + * IAddress[] addresses = e.getAddresses(); + * // do whatever... + * } + */ + public interface IMemoryChangedEvent extends IDMEvent { + IAddress[] getAddresses(); } - + /** * Reads a memory block from the target. * @@ -88,7 +75,7 @@ public interface IMemory extends IDsfService { * @param count the number of data elements to read * @param drm the asynchronous data request monitor */ - public void getMemory(IDMContext context, IAddress address, long offset, + public void getMemory(IMemoryDMContext context, IAddress address, long offset, int word_size, int count, DataRequestMonitor drm); /** @@ -109,7 +96,7 @@ public interface IMemory extends IDsfService { * @param buffer the source buffer * @param rm the asynchronous data request monitor */ - public void setMemory(IDMContext context, IAddress address, long offset, + public void setMemory(IMemoryDMContext context, IAddress address, long offset, int word_size, int count, byte[] buffer, RequestMonitor rm); /** @@ -125,7 +112,7 @@ public interface IMemory extends IDsfService { * @param pattern the source buffer * @param rm the asynchronous data request monitor */ - public void fillMemory(IDMContext context, IAddress address, long offset, + public void fillMemory(IMemoryDMContext context, IAddress address, long offset, int word_size, int count, byte[] pattern, RequestMonitor rm); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java index 607a8af49af..c0049a64ed5 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java @@ -90,16 +90,16 @@ public interface IModules extends IDsfService { /** * Retreives the list of modules loaded in given symbol context. */ - void getModules(IDMContext symCtx, DataRequestMonitor rm); + void getModules(ISymbolDMContext symCtx, DataRequestMonitor rm); /** * Calculates the line numbers corresponding to the given address. */ - void calcLineInfo(IDMContext symCtx, IAddress address, DataRequestMonitor rm); + void calcLineInfo(ISymbolDMContext symCtx, IAddress address, DataRequestMonitor rm); /** * Calculates the addresses corresponding to the given source file location. */ - void calcAddressInfo(IDMContext symCtx, String file, int line, int col, DataRequestMonitor rm); + void calcAddressInfo(ISymbolDMContext symCtx, String file, int line, int col, DataRequestMonitor rm); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IOS.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IOS.java deleted file mode 100644 index e399e572a3d..00000000000 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IOS.java +++ /dev/null @@ -1,98 +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.service; - -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.datamodel.IDMData; -import org.eclipse.dd.dsf.datamodel.IDMService; - -/** - * Provides generic access to operating system objects and methods to - * manipulate those objects. This is a much more extensive interface than - * the NativeProcesses service but for simple debugging, it serves the same - * purpose: to list/create/terminate processes and attach debugger to them. - * - * @see INativeProcesses - */ -public interface IOS extends IDMService { - - /** - * Context object for the whole OS, for debuggers that support - * debugging multiple targets/cores simultaneously. - */ - public interface IOSDMContext extends IDMContext {} - - /** - * Data object describing OS info - */ - public interface IOSDMData extends IDMData { - String getName(); - String getDescription(); - String getVersion(); - } - - /** - * Context for a OS object type, such as process, kernel task, semaphore, etc. - */ - public interface IObjectTypeDMContext extends IDMContext {} - - /** - * Description data for a OS object type. - */ - public interface IObjectTypeDMData extends IDMData { - String getName(); - String getDescription(); - String getSingularName(); - String getPluralName(); - } - - /** - * OS object context. - */ - public interface IObjectDMContext extends IDMContext {} - - /** - * Description data for an OS object. - */ - public interface IObjectDMData extends IDMData { - String getName(); - String getID(); - boolean canAttachDebugger(); - boolean isDebuggerAttached(); - IDMContext getDebuggingContext(); - } - - /** - * Retrieves list of OS object types. - * @param os OS context. - * @param parent Optional parent type. - * @param rm Request completion monitor. - */ - public void getObjectTypes(IOSDMContext os, IObjectTypeDMContext parent, DataRequestMonitor rm); - - /** - * Retrieves list of OS objects for given type. - * @param os OS context. - * @param type The object type. - * @param parent Optional parent of the requested objects. - * @param rm Request completion monitor. - */ - public void getObjects(IOSDMContext os, IObjectTypeDMContext type, IObjectDMContext parent, DataRequestMonitor rm); - - /** - * Attaches the debugger to given OS object context. - * @param objectDmc Data Model Context of the OS object to attach to. - * @param rm Request completion monitor. - */ - public void attachDebuggerToObject(IObjectDMContext objectDmc, RequestMonitor requestMonitor); -} diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java index 7c739841b19..2de1e39d168 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java @@ -21,8 +21,14 @@ import org.eclipse.dd.dsf.datamodel.IDMEvent; */ public interface IRegisters extends IFormattedValues { - /** Event indicating groups have changed. */ - public interface IGroupsChangedDMEvent extends IDMEvent {} + /** + * Event indicating groups have changed. The type of context returned by this + * event is generic, because different implementations of the the register service + * could configure register groups using different contexts. Some implementations + * could configure different register groups for each execution context, other + * services may have a global list of groups. + */ + public interface IGroupsChangedDMEvent extends IDMEvent {} /** Register group context */ public interface IRegisterGroupDMContext extends IFormattedDataDMContext { @@ -133,14 +139,9 @@ public interface IRegisters extends IFormattedValues { void getRegisterGroups(IDMContext ctx, DataRequestMonitor rm); /** - * Retrieves list of sub-groups of given register group. - * @param ctx Context for the returned data. - * @param rm Request completion monitor. - */ - void getRegisterSubGroups(IDMContext ctx, DataRequestMonitor rm); - - /** - * Retrieves registers in given register group. + * Retrieves the list of registers for the given context. The given context could include + * a register group and an execution context or just an execution context, in which case all + * registers for all groups should be returned. * @param ctx Context for the returned data. * @param rm Request completion monitor. */ @@ -151,7 +152,7 @@ public interface IRegisters extends IFormattedValues { * @param ctx Context for the returned data. * @param rm Request completion monitor. */ - void getBitFields(IDMContext ctx, DataRequestMonitor rm); + void getBitFields(IRegisterDMContext ctx, DataRequestMonitor rm); /** * Writes a register value for a given register to the target @@ -160,7 +161,7 @@ public interface IRegisters extends IFormattedValues { * @param formatId Format of the value to be written. * @param rm Request completion monitor. */ - void writeRegister(IDMContext regCtx, String regValue, String formatId, RequestMonitor rm); + void writeRegister(IRegisterDMContext regCtx, String regValue, String formatId, RequestMonitor rm); /** * Writes a bit field value for a given bit field to the target @@ -169,7 +170,7 @@ public interface IRegisters extends IFormattedValues { * @param formatId Format of the value to be written. * @param rm Request completion monitor. */ - void writeBitField(IDMContext bitFieldCtx, String bitFieldValue, String formatId, RequestMonitor rm); + void writeBitField(IBitFieldDMContext bitFieldCtx, String bitFieldValue, String formatId, RequestMonitor rm); /** * Writes a bit field value for a given bit field to the target @@ -177,5 +178,5 @@ public interface IRegisters extends IFormattedValues { * @param mnemonic Mnemonic which represents the value to be written. * @param rm Request completion monitor. */ - void writeBitField(IDMContext bitFieldCtx, IMnemonic mnemonic, RequestMonitor rm); + void writeBitField(IBitFieldDMContext bitFieldCtx, IMnemonic mnemonic, RequestMonitor rm); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java index 3f5567cd8ae..1b1c5e50454 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java @@ -11,8 +11,8 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.service; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMData; import org.eclipse.dd.dsf.datamodel.IDMEvent; @@ -121,15 +121,15 @@ public interface IRunControl extends IDMService * Run control commands. They all require the IExecutionContext object on * which they perform the operations. */ - boolean canResume(IDMContext context); - boolean canSuspend(IDMContext context); - boolean isSuspended(IDMContext context); - void resume(IDMContext context, RequestMonitor requestMonitor); - void suspend(IDMContext context, RequestMonitor requestMonitor); + boolean canResume(IExecutionDMContext context); + boolean canSuspend(IExecutionDMContext context); + boolean isSuspended(IExecutionDMContext context); + void resume(IExecutionDMContext context, RequestMonitor requestMonitor); + void suspend(IExecutionDMContext context, RequestMonitor requestMonitor); public enum StepType { STEP_OVER, STEP_INTO, STEP_RETURN }; - boolean isStepping(IDMContext context); - boolean canStep(IDMContext context); - void step(IDMContext context, StepType stepType, RequestMonitor requestMonitor); - boolean canInstructionStep(IDMContext context); - void instructionStep(IDMContext context, StepType stepType, RequestMonitor requestMonitor); + boolean isStepping(IExecutionDMContext context); + boolean canStep(IExecutionDMContext context); + void step(IExecutionDMContext context, StepType stepType, RequestMonitor requestMonitor); + boolean canInstructionStep(IExecutionDMContext context); + void instructionStep(IExecutionDMContext context, StepType stepType, RequestMonitor requestMonitor); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISourceLookup.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISourceLookup.java index a59e4f87acb..01b862c79ce 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISourceLookup.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ISourceLookup.java @@ -30,10 +30,10 @@ public interface ISourceLookup extends IDsfService { /** * Retrieves the host source object for given debugger path string. */ - void getSource(IDMContext ctx, String debuggerPath, DataRequestMonitor rm); + void getSource(ISourceLookupDMContext ctx, String debuggerPath, DataRequestMonitor rm); /** * Retrieves the debugger path string for given host source object. */ - void getDebuggerPath(IDMContext ctx, Object source, DataRequestMonitor rm); + void getDebuggerPath(ISourceLookupDMContext ctx, Object source, DataRequestMonitor rm); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java index f14d6887bac..3eab34e50e5 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java @@ -104,7 +104,7 @@ public interface IStack extends IDMService { void getLocals(IDMContext frameCtx, DataRequestMonitor rm); /** - * Retrieves the stack depth of the specified stack frame. + * Retrieves the number of stack frames available for the given context.. * @param dmc Context to retrieve data for. * @param The maximum depth of stack to calculate. Should be 0 to calculate * depth with no limit. diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStepQueueManager.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStepQueueManager.java index 19318f2599c..3a654c33e62 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStepQueueManager.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStepQueueManager.java @@ -10,7 +10,6 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.service; -import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMEvent; import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; import org.eclipse.dd.dsf.service.IDsfService; @@ -46,21 +45,21 @@ public interface IStepQueueManager extends IDsfService { * Returns the number of step commands that are queued for given execution * context. */ - int getPendingStepCount(IDMContext ctx); + int getPendingStepCount(IExecutionDMContext ctx); /** * Checks whether a step command can be queued up for given context. */ - boolean canEnqueueStep(IDMContext execCtx); + boolean canEnqueueStep(IExecutionDMContext execCtx); - boolean canEnqueueInstructionStep(IDMContext ctx); + boolean canEnqueueInstructionStep(IExecutionDMContext ctx); /** * 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(IDMContext ctx, IRunControl.StepType stepType); + void enqueueStep(IExecutionDMContext ctx, IRunControl.StepType stepType); /** * Adds an instruction step command to the execution queue for given @@ -68,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(IDMContext ctx, IRunControl.StepType stepType); + void enqueueInstructionStep(IExecutionDMContext ctx, IRunControl.StepType stepType); - boolean isSteppingTimedOut(IDMContext context); + boolean isSteppingTimedOut(IExecutionDMContext context); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ITargets.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ITargets.java deleted file mode 100644 index d24c24ecaff..00000000000 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/ITargets.java +++ /dev/null @@ -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.service; - -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -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 {} - - public interface ITargetDMData extends IDMData { - String getName(); - boolean isConnected(); - } - - public interface ITargetStateChanged extends IDMEvent {} - - public interface ICoreDMContext extends IDMContext {} - - public interface ICoreDMData extends IDMData { - String getName(); - boolean isConnected(); - IOS.IOSDMContext getOSDMContext(); - } - - public interface ICoreStateChangedDMEvent extends IDMEvent {} - - public void getTargets(DataRequestMonitor requestMonitor); - public void getCores(ITargetDMContext target, DataRequestMonitor requestMonitor); - - public void connectTarget(ITargetDMContext targetDmc, RequestMonitor requestMonitor); - public void disconnectTarget(ITargetDMContext targetDmc, RequestMonitor requestMonitor); - public void connectCore(ITargetDMContext targetDmc, RequestMonitor requestMonitor); - public void disconnectCore(ITargetDMContext targetDmc, RequestMonitor requestMonitor); - -} From 816a523659c09ba58ef8d3abcc69b48c53683cb2 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Wed, 21 Nov 2007 18:48:56 +0000 Subject: [PATCH 183/834] Caching the status as well as the result, to allow to cache commands that fail. Bug 208920 --- .../debug/service/command/CommandCache.java | 91 +++++++++++-------- 1 file changed, 53 insertions(+), 38 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java index 5bdd7e9513f..72ea07c381e 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java @@ -96,6 +96,19 @@ public class CommandCache implements ICommandListener } } + class CommandResultInfo { + private final ICommandResult fData; + private final IStatus fStatus; + + public CommandResultInfo(ICommandResult data, IStatus status) { + fData = data; + fStatus = status; + } + + public ICommandResult getData() { return fData; } + public IStatus getStatus() { return fStatus; } + } + /* * This class contains 5 significant lists. * @@ -135,7 +148,7 @@ public class CommandCache implements ICommandListener private ICommandControl fCommandControl; - private Map> fCachedContexts = new HashMap>(); + private Map> fCachedContexts = new HashMap>(); private ArrayList fPendingQCommandsSent = new ArrayList(); @@ -239,13 +252,14 @@ public class CommandCache implements ICommandListener * If command is already cached, just return the cached data. */ if(fCachedContexts.get(context) != null && fCachedContexts.get(context).containsKey(cachedCmd)){ - // Cast to the erased type of the returned command result. - // To ensure type safety, we are relying on the correct matching - // of command and result in the cached results map. - @SuppressWarnings("unchecked") - V v = (V) fCachedContexts.get(context).get(cachedCmd); - - rm.setData(v); + CommandResultInfo result = fCachedContexts.get(context).get(cachedCmd); + if (result.getStatus().isOK()) { + @SuppressWarnings("unchecked") + V v = (V)result.getData(); + rm.setData(v); + } else { + rm.setStatus(result.getStatus()); + } rm.done(); return; } @@ -316,14 +330,16 @@ public class CommandCache implements ICommandListener return ; } + ICommandResult result = getData(); + IStatus status = getStatus(); + if ( finalCachedCmd.getCommandstyle() == CommandStyle.COALESCED ) { /* * We matched a command which is itself already a COALESCED command. So - * we need to go throught the list of unsent commands which were not sent + * we need to go through the list of unsent commands which were not sent * because the coalesced command represented it. For each match we find * we create a new result from the coalesced command for it. */ - ICommandResult result = getData(); for ( CommandInfo waitingEntry : new ArrayList(fPendingQWaitingForCoalescedCompletion) ) { @@ -336,40 +352,39 @@ public class CommandCache implements ICommandListener // Cast the calculated result back to the requested type. @SuppressWarnings("unchecked") - V newresult = (V)result.getSubsetResult(waitingEntry.getCommand()); - + V subResult = (V)result.getSubsetResult(waitingEntry.getCommand()); + CommandResultInfo subResultInfo = new CommandResultInfo(subResult, status); if(fCachedContexts.get(context) != null){ - fCachedContexts.get(context).put(waitingEntry, newresult); - } - else{ - HashMap map = new HashMap(); - map.put(waitingEntry, newresult); + fCachedContexts.get(context).put(waitingEntry, subResultInfo); + } else { + HashMap map = new HashMap(); + map.put(waitingEntry, subResultInfo); fCachedContexts.put(context, map); } - if (!getStatus().isOK()) { + if (!status.isOK()) { /* * We had some form of error with the original command. So notify the - * original requestors of the issues. + * original requesters of the issues. */ for (DataRequestMonitor pendingRM : waitingEntry.getRequestMonitorList()) { - pendingRM.setStatus(getStatus()); + pendingRM.setStatus(status); pendingRM.done(); } } else { - assert newresult != null; + assert subResult != null; /* - * Notify the original requestors of the positive results. + * Notify the original requesters of the positive results. */ for (DataRequestMonitor pendingRM : waitingEntry.getRequestMonitorList()) { // Cast the pending return token to match the requested type. @SuppressWarnings("unchecked") DataRequestMonitor vPendingRM = (DataRequestMonitor) pendingRM; - vPendingRM.setData(newresult); + vPendingRM.setData(subResult); vPendingRM.done(); } } @@ -378,38 +393,38 @@ public class CommandCache implements ICommandListener } else { /* * This is an original request which completed. Indicate success or - * failure to the original requestors. + * failure to the original requesters. */ + CommandResultInfo resultInfo = new CommandResultInfo(result, status); - if (!getStatus().isOK()) { + if (fCachedContexts.get(context) != null){ + fCachedContexts.get(context).put(finalCachedCmd, resultInfo); + } else { + HashMap map = new HashMap(); + map.put(finalCachedCmd, resultInfo); + fCachedContexts.put(context, map); + } + + if (!status.isOK()) { /* * We had some form of error with the original command. So notify the - * original requestors of the issues. + * original requesters of the issues. */ for (DataRequestMonitor pendingRM : finalCachedCmd.getRequestMonitorList()) { - pendingRM.setStatus(getStatus()); + pendingRM.setStatus(status); pendingRM.done(); } } else { // Cast the calculated result back to the requested type. @SuppressWarnings("unchecked") - V result = (V)getData(); + V vResult = (V)result; - if(fCachedContexts.get(context) != null){ - fCachedContexts.get(context).put(finalCachedCmd, result); - } - else{ - HashMap map = new HashMap(); - map.put(finalCachedCmd, result); - fCachedContexts.put(context, map); - } - for (DataRequestMonitor pendingRM : finalCachedCmd.getRequestMonitorList()) { // Cast the pending return token to match the requested type. @SuppressWarnings("unchecked") DataRequestMonitor vPendingRM = (DataRequestMonitor) pendingRM; - vPendingRM.setData(result); + vPendingRM.setData(vResult); vPendingRM.done(); } } From 64a3c6512a330ca4dfacfe7e4d6e132c6f8c9d95 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 21 Nov 2007 19:36:08 +0000 Subject: [PATCH 184/834] [210571] Refactored number format detail pane. --- .../org.eclipse.core.resources.prefs | 4 +-- .../META-INF/MANIFEST.MF | 2 +- .../org.eclipse.dd.dsf.debug.ui/plugin.xml | 15 ++++++--- .../dd/dsf/debug/ui/DsfDebugUIPlugin.java | 2 ++ .../viewmodel/detailpanesupport/Messages.java | 31 ------------------- .../detailpanesupport/messages.properties | 3 -- .../expression/ExpressionVMProvider.java | 2 +- .../AbstractSetFormatStyle.java | 2 +- .../FormattedValuePreferenceStore.java | 2 +- .../IFormattedValuePreferenceStore.java | 2 +- .../IFormattedValueVMContext.java | 2 +- .../SetDefaultFormatBinary.java | 2 +- .../SetDefaultFormatDecimal.java | 2 +- .../SetDefaultFormatHex.java | 2 +- .../SetDefaultFormatNatural.java | 2 +- .../SetDefaultFormatOctal.java | 2 +- .../detail/MessagesForNumberFormatDetail.java | 18 +++++++++++ .../detail/NumberFormatDetailPane.java} | 18 +++++------ .../NumberFormatDetailPaneFactory.java} | 23 ++++++-------- .../detail}/TextViewerAction.java | 2 +- .../numberformat/detail/messages.properties | 2 ++ .../RegisterBitFieldLayoutCellModifier.java | 2 +- .../register/RegisterBitFieldLayoutNode.java | 4 +-- .../register/RegisterLayoutNode.java | 4 +-- .../RegisterLayoutValueCellModifier.java | 2 +- .../register/RegisterVMProvider.java | 2 +- .../variable/VariableLayoutNode.java | 4 +-- .../VariableLayoutValueCellModifier.java | 2 +- .../variable/VariableVMProvider.java | 2 +- 29 files changed, 74 insertions(+), 88 deletions(-) delete mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/Messages.java delete mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/messages.properties rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/{formatsupport => numberformat}/AbstractSetFormatStyle.java (99%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/{formatsupport => numberformat}/FormattedValuePreferenceStore.java (96%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/{formatsupport => numberformat}/IFormattedValuePreferenceStore.java (94%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/{formatsupport => numberformat}/IFormattedValueVMContext.java (92%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/{formatsupport => numberformat}/SetDefaultFormatBinary.java (93%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/{formatsupport => numberformat}/SetDefaultFormatDecimal.java (93%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/{formatsupport => numberformat}/SetDefaultFormatHex.java (92%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/{formatsupport => numberformat}/SetDefaultFormatNatural.java (93%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/{formatsupport => numberformat}/SetDefaultFormatOctal.java (93%) create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/MessagesForNumberFormatDetail.java rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/{detailpanesupport/DetailPane.java => numberformat/detail/NumberFormatDetailPane.java} (98%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/{detailpanesupport/DetailPaneFactory.java => numberformat/detail/NumberFormatDetailPaneFactory.java} (72%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/{detailpanesupport => numberformat/detail}/TextViewerAction.java (97%) create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/messages.properties diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/.settings/org.eclipse.core.resources.prefs b/plugins/org.eclipse.dd.dsf.debug.ui/.settings/org.eclipse.core.resources.prefs index 6f616043918..9517031575f 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/.settings/org.eclipse.core.resources.prefs +++ b/plugins/org.eclipse.dd.dsf.debug.ui/.settings/org.eclipse.core.resources.prefs @@ -1,3 +1,3 @@ -#Fri Jul 27 14:30:56 EDT 2007 +#Tue Nov 20 14:43:47 PST 2007 eclipse.preferences.version=1 -encoding//src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/messages.properties=8859_1 +encoding//src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/messages.properties=8859_1 diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF index 4a6877ee333..148e9de92a5 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF @@ -26,9 +26,9 @@ Export-Package: org.eclipse.dd.dsf.debug.ui.viewmodel, org.eclipse.dd.dsf.debug.ui.viewmodel.dm, org.eclipse.dd.dsf.debug.ui.viewmodel.expression, - org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport, org.eclipse.dd.dsf.debug.ui.viewmodel.launch, org.eclipse.dd.dsf.debug.ui.viewmodel.modules, + org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat, org.eclipse.dd.dsf.debug.ui.viewmodel.register, org.eclipse.dd.dsf.debug.ui.viewmodel.variable Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml index 6c3f7d75771..41f40c788de 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml +++ b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml @@ -211,11 +211,18 @@ - + - + + + + + + + + diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/DsfDebugUIPlugin.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/DsfDebugUIPlugin.java index ccab5fcab18..2facb074854 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/DsfDebugUIPlugin.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/DsfDebugUIPlugin.java @@ -12,6 +12,7 @@ public class DsfDebugUIPlugin extends AbstractUIPlugin { // The plug-in ID public static final String PLUGIN_ID = "org.eclipse.dd.dsf.debug.ui"; //$NON-NLS-1$ + // The shared instance private static DsfDebugUIPlugin plugin; @@ -33,6 +34,7 @@ public class DsfDebugUIPlugin extends AbstractUIPlugin { super.start(context); plugin = this; fgBundleContext = context; + } /* diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/Messages.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/Messages.java deleted file mode 100644 index ba14f79459a..00000000000 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/Messages.java +++ /dev/null @@ -1,31 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Randy Rohrbach (Wind River Systems, Inc.) - initial implementation - *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.detailpanesupport; - -import java.util.MissingResourceException; -import java.util.ResourceBundle; - -public class Messages { - private static final String BUNDLE_NAME = "org.eclipse.dd.dsf.debug.ui.viewmodel.detailpanesupport.messages"; //$NON-NLS-1$ - - private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME); - - private Messages() { - } - - public static String getString(String key) { - try { - return RESOURCE_BUNDLE.getString(key); - } catch (MissingResourceException e) { - return '!' + key + '!'; - } - } -} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/messages.properties b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/messages.properties deleted file mode 100644 index 5d99640c01d..00000000000 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/messages.properties +++ /dev/null @@ -1,3 +0,0 @@ -DetailPaneFactory.0=DSF Default Detail Pane -DetailPaneFactory.1=DSF Default Viewer -DetailPaneFactory.2=This is the default detail pane representation for DSF assisted views diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java index 7fb7ed6438b..0f21b57ad0b 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java @@ -11,7 +11,7 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; import org.eclipse.dd.dsf.debug.ui.viewmodel.dm.AbstractDebugDMVMProviderWithCache; -import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.FormattedValuePreferenceStore; +import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.FormattedValuePreferenceStore; import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterGroupLayoutNode; import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterLayoutNode; import org.eclipse.dd.dsf.debug.ui.viewmodel.register.SyncRegisterDataAccess; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/AbstractSetFormatStyle.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/AbstractSetFormatStyle.java similarity index 99% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/AbstractSetFormatStyle.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/AbstractSetFormatStyle.java index 6c481b6e325..5533710f9ed 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/AbstractSetFormatStyle.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/AbstractSetFormatStyle.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport; +package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.dd.dsf.debug.service.IFormattedValues; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/FormattedValuePreferenceStore.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/FormattedValuePreferenceStore.java similarity index 96% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/FormattedValuePreferenceStore.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/FormattedValuePreferenceStore.java index 0fb2f060a64..b2e5659a6df 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/FormattedValuePreferenceStore.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/FormattedValuePreferenceStore.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport; +package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat; import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/IFormattedValuePreferenceStore.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/IFormattedValuePreferenceStore.java similarity index 94% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/IFormattedValuePreferenceStore.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/IFormattedValuePreferenceStore.java index 14af52bc5e7..bb334ed9e56 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/IFormattedValuePreferenceStore.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/IFormattedValuePreferenceStore.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport; +package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/IFormattedValueVMContext.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/IFormattedValueVMContext.java similarity index 92% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/IFormattedValueVMContext.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/IFormattedValueVMContext.java index fb74d6aeeaa..6993af6f0fb 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/IFormattedValueVMContext.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/IFormattedValueVMContext.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport; +package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatBinary.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/SetDefaultFormatBinary.java similarity index 93% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatBinary.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/SetDefaultFormatBinary.java index d0af577d3f1..cb4e08a1635 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatBinary.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/SetDefaultFormatBinary.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport; +package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat; import org.eclipse.dd.dsf.debug.service.IFormattedValues; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatDecimal.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/SetDefaultFormatDecimal.java similarity index 93% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatDecimal.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/SetDefaultFormatDecimal.java index 8e0baca3c27..0cbe7b570bb 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatDecimal.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/SetDefaultFormatDecimal.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport; +package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat; import org.eclipse.dd.dsf.debug.service.IFormattedValues; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatHex.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/SetDefaultFormatHex.java similarity index 92% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatHex.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/SetDefaultFormatHex.java index 3a34e7b9a92..e728974e16b 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatHex.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/SetDefaultFormatHex.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport; +package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat; import org.eclipse.dd.dsf.debug.service.IFormattedValues; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatNatural.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/SetDefaultFormatNatural.java similarity index 93% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatNatural.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/SetDefaultFormatNatural.java index 6d42e9a7365..d844b93c3df 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatNatural.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/SetDefaultFormatNatural.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport; +package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat; import org.eclipse.dd.dsf.debug.service.IFormattedValues; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatOctal.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/SetDefaultFormatOctal.java similarity index 93% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatOctal.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/SetDefaultFormatOctal.java index 34f0f9b75f8..468cf6a9e42 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatOctal.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/SetDefaultFormatOctal.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport; +package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat; import org.eclipse.dd.dsf.debug.service.IFormattedValues; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/MessagesForNumberFormatDetail.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/MessagesForNumberFormatDetail.java new file mode 100644 index 00000000000..ccdba675d7e --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/MessagesForNumberFormatDetail.java @@ -0,0 +1,18 @@ +package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.detail; + +import org.eclipse.osgi.util.NLS; + +class MessagesForNumberFormatDetail extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.detail.messages"; //$NON-NLS-1$ + + public static String NumberFormatDetailPane_name; + public static String NumberFormatDetailPane_description; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, MessagesForNumberFormatDetail.class); + } + + private MessagesForNumberFormatDetail() { + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPane.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/NumberFormatDetailPane.java similarity index 98% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPane.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/NumberFormatDetailPane.java index b0484718b11..ca16f667b12 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPane.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/NumberFormatDetailPane.java @@ -9,7 +9,7 @@ * IBM Corporation - initial API and implementation * Randy Rohrbach (Wind River Systems, Inc.) - extended implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.detailpanesupport; +package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.detail; import java.text.MessageFormat; import java.util.ArrayList; @@ -110,8 +110,7 @@ import org.eclipse.ui.texteditor.ITextEditorActionConstants; import org.eclipse.ui.texteditor.IUpdate; import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds; -@SuppressWarnings("restriction") -public class DetailPane implements IDetailPane, IAdaptable, IPropertyChangeListener { +public class NumberFormatDetailPane implements IDetailPane, IAdaptable, IPropertyChangeListener { /** * The IWorkbenchPartSite that the details area (and the @@ -258,9 +257,7 @@ public class DetailPane implements IDetailPane, IAdaptable, IPropertyChangeListe * The ID, name and description of this pane are stored in constants so that the class * does not have to be instantiated to access them. */ - public static final String ID = DetailMessages.DefaultDetailPane_0; - public static final String NAME = DetailMessages.DefaultDetailPane_1; - public static final String DESCRIPTION = DetailMessages.DefaultDetailPane_57; + public static final String ID = "NumberFormatPane"; /** * Data structure for the position label value. @@ -304,12 +301,11 @@ public class DetailPane implements IDetailPane, IAdaptable, IPropertyChangeListe /* (non-Javadoc) * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor) */ - @SuppressWarnings("unchecked") @Override protected IStatus run(IProgressMonitor monitor) { String message = null; fMonitor = monitor; - Iterator iterator = fElements.iterator(); + Iterator iterator = fElements.iterator(); while (iterator.hasNext()) { if (monitor.isCanceled()) { break; @@ -821,21 +817,21 @@ public class DetailPane implements IDetailPane, IAdaptable, IPropertyChangeListe * @see org.eclipse.debug.ui.IDetailPane#getDescription() */ public String getDescription() { - return DetailPaneFactory.DSF_DETAIL_PANE_DESC; + return MessagesForNumberFormatDetail.NumberFormatDetailPane_description; } /* (non-Javadoc) * @see org.eclipse.debug.ui.IDetailPane#getID() */ public String getID() { - return DetailPaneFactory.DSF_DETAIL_PANE_ID; + return ID; } /* (non-Javadoc) * @see org.eclipse.debug.ui.IDetailPane#getName() */ public String getName() { - return DetailPaneFactory.DSF_DETAIL_PANE_NAME; + return MessagesForNumberFormatDetail.NumberFormatDetailPane_name; } /* (non-Javadoc) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPaneFactory.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/NumberFormatDetailPaneFactory.java similarity index 72% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPaneFactory.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/NumberFormatDetailPaneFactory.java index caaa13079a4..637bf2cd92e 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/DetailPaneFactory.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/NumberFormatDetailPaneFactory.java @@ -8,7 +8,7 @@ * Contributors: * Randy Rohrbach (Wind River Systems, Inc.) - initial implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.detailpanesupport; +package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.detail; import java.util.HashSet; import java.util.Set; @@ -21,18 +21,13 @@ import org.eclipse.jface.viewers.IStructuredSelection; * This provides a simple Detail Pane Factory for the core debug views for DSF. */ -@SuppressWarnings("restriction") -public class DetailPaneFactory implements IDetailPaneFactory { +public class NumberFormatDetailPaneFactory implements IDetailPaneFactory { - public static final String DSF_DETAIL_PANE_ID = Messages.getString("DetailPaneFactory.0"); //$NON-NLS-1$ - public static final String DSF_DETAIL_PANE_NAME = Messages.getString("DetailPaneFactory.1"); //$NON-NLS-1$ - public static final String DSF_DETAIL_PANE_DESC = Messages.getString("DetailPaneFactory.2"); //$NON-NLS-1$ - /* (non-Javadoc) * @see org.eclipse.debug.internal.ui.views.variables.IDetailsFactory#createDetailsArea(java.lang.String) */ public IDetailPane createDetailPane(String id) { - return new DetailPane(); + return new NumberFormatDetailPane(); } /* (non-Javadoc) @@ -41,7 +36,7 @@ public class DetailPaneFactory implements IDetailPaneFactory { @SuppressWarnings("unchecked") public Set getDetailPaneTypes(IStructuredSelection selection) { Set possibleIDs = new HashSet(1); - possibleIDs.add(DSF_DETAIL_PANE_ID); + possibleIDs.add(NumberFormatDetailPane.ID); return possibleIDs; } @@ -49,15 +44,15 @@ public class DetailPaneFactory implements IDetailPaneFactory { * @see org.eclipse.debug.ui.IDetailPaneFactory#getDefaultDetailPane(java.util.Set, org.eclipse.jface.viewers.IStructuredSelection) */ public String getDefaultDetailPane(IStructuredSelection selection) { - return DSF_DETAIL_PANE_ID; + return NumberFormatDetailPane.ID; } /* (non-Javadoc) * @see org.eclipse.debug.internal.ui.views.variables.IDetailsFactory#getName(java.lang.String) */ public String getDetailPaneName(String id) { - if (id.equals(DSF_DETAIL_PANE_ID)){ - return DSF_DETAIL_PANE_NAME; + if (id.equals(NumberFormatDetailPane.ID)){ + return MessagesForNumberFormatDetail.NumberFormatDetailPane_name; } return null; } @@ -66,8 +61,8 @@ public class DetailPaneFactory implements IDetailPaneFactory { * @see org.eclipse.debug.internal.ui.views.variables.IDetailsFactory#getDescription(java.lang.String) */ public String getDetailPaneDescription(String id) { - if (id.equals(DSF_DETAIL_PANE_ID)){ - return DSF_DETAIL_PANE_DESC; + if (id.equals(NumberFormatDetailPane.ID)){ + return MessagesForNumberFormatDetail.NumberFormatDetailPane_description; } return null; } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/TextViewerAction.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/TextViewerAction.java similarity index 97% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/TextViewerAction.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/TextViewerAction.java index 7cd6bafbc15..df9178b6238 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/detailpanesupport/TextViewerAction.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/TextViewerAction.java @@ -9,7 +9,7 @@ * IBM Corporation - initial API and implementation * Randy Rohrbach (Wind River Systems, Inc.) - extended implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.detailpanesupport; +package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.detail; import org.eclipse.jface.action.Action; import org.eclipse.jface.text.ITextOperationTarget; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/messages.properties b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/messages.properties new file mode 100644 index 00000000000..c7f0c414add --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/messages.properties @@ -0,0 +1,2 @@ +NumberFormatDetailPane_name=Number Formats Viewer +NumberFormatDetailPane_description=Detail viewer showing selected variable in all available formats. diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutCellModifier.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutCellModifier.java index c2277e7cf6a..176843d6dd9 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutCellModifier.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutCellModifier.java @@ -14,7 +14,7 @@ import org.eclipse.dd.dsf.debug.service.IRegisters.IBitFieldDMData; import org.eclipse.dd.dsf.debug.service.IRegisters.IMnemonic; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionCellModifier; -import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePreferenceStore; +import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValuePreferenceStore; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java index bd52e022401..d3d8bed1cda 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java @@ -33,8 +33,8 @@ import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent; import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.AbstractExpressionLayoutNode; -import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePreferenceStore; -import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValueVMContext; +import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValuePreferenceStore; +import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValueVMContext; import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterBitFieldLayoutCellModifier.BitFieldEditorStyle; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java index 09ccc6d68ab..94bf4046788 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java @@ -30,8 +30,8 @@ import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext; import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.AbstractExpressionLayoutNode; -import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePreferenceStore; -import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValueVMContext; +import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValuePreferenceStore; +import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValueVMContext; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutValueCellModifier.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutValueCellModifier.java index eb699b3f28d..808f2c293a8 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutValueCellModifier.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutValueCellModifier.java @@ -17,7 +17,7 @@ import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMData; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionCellModifier; -import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePreferenceStore; +import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValuePreferenceStore; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java index 35a655e91e7..7e6c8207990 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java @@ -11,7 +11,7 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.register; import org.eclipse.dd.dsf.debug.ui.viewmodel.dm.AbstractDebugDMVMProviderWithCache; -import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.FormattedValuePreferenceStore; +import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.FormattedValuePreferenceStore; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java index 383e3467689..196a0e9503a 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java @@ -35,8 +35,8 @@ import org.eclipse.dd.dsf.debug.service.IStack.IVariableDMData; import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.AbstractExpressionLayoutNode; -import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePreferenceStore; -import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValueVMContext; +import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValuePreferenceStore; +import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValueVMContext; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutValueCellModifier.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutValueCellModifier.java index f78ff1dd2f5..bce3f7cc0bc 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutValueCellModifier.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutValueCellModifier.java @@ -11,7 +11,7 @@ import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionCellModifier; -import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePreferenceStore; +import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValuePreferenceStore; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java index 15900ea9f0c..5cd0380962c 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java @@ -9,7 +9,7 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.variable; import org.eclipse.dd.dsf.debug.ui.viewmodel.dm.AbstractDebugDMVMProviderWithCache; -import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.FormattedValuePreferenceStore; +import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.FormattedValuePreferenceStore; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; From d9ee930837828f52f102014df370e4aab817eaf1 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 21 Nov 2007 23:47:55 +0000 Subject: [PATCH 185/834] [205132] Got rid of the no-longer used service context object. --- .../dd/dsf/datamodel/ServiceDMContext.java | 40 ------------------- 1 file changed, 40 deletions(-) delete mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/ServiceDMContext.java diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/ServiceDMContext.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/ServiceDMContext.java deleted file mode 100644 index d3a27b76910..00000000000 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/ServiceDMContext.java +++ /dev/null @@ -1,40 +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.datamodel; - - -/** - * The Data Model Context representing the owner service, which is returned by - * {@link IDMService#getServiceContext()} methods. The service DM Context - * should be the parent of all contexts originating from the given service. - */ -public class ServiceDMContext extends AbstractDMContext { - String fServiceDMID; - - public ServiceDMContext(IDMService service, String serviceDMID) { - super(service, new IDMContext[0]); - fServiceDMID = serviceDMID; - } - - @Override - public String toString() { return baseToString() + fServiceDMID; } - - @Override - public boolean equals(Object obj) { - return obj instanceof ServiceDMContext && fServiceDMID.equals(((ServiceDMContext)obj).fServiceDMID); - } - - @Override - public int hashCode() { - return fServiceDMID.hashCode(); - } - -} From 976a665a68865df3ce21c51f14bf28b2d2c9f156 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 21 Nov 2007 23:58:19 +0000 Subject: [PATCH 186/834] [205142] Changed IStack.getArguments() and IStack.getVariables() to accept strong-typed IFrameDMContext. --- .../src/org/eclipse/dd/dsf/debug/service/IStack.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java index 3eab34e50e5..9b88df3a679 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java @@ -96,12 +96,12 @@ public interface IStack extends IDMService { /** * Retrieves variables which were arguments to the stack frame's function. */ - void getArguments(IDMContext frameCtx, DataRequestMonitor rm); + void getArguments(IFrameDMContext frameCtx, DataRequestMonitor rm); /** * Retrieves variables local to the stack frame. */ - void getLocals(IDMContext frameCtx, DataRequestMonitor rm); + void getLocals(IFrameDMContext frameCtx, DataRequestMonitor rm); /** * Retrieves the number of stack frames available for the given context.. From a3649d568b486dbcd2d063cb8328c4470bbe2229 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Mon, 26 Nov 2007 21:42:51 +0000 Subject: [PATCH 187/834] [206832] Added use of CompositeDMContext. --- .../register/RegisterGroupLayoutNode.java | 32 ++--- .../register/RegisterLayoutNode.java | 10 +- .../variable/VariableLayoutNode.java | 15 +-- .../ui/viewmodel/dm/CompositeDMContext.java | 126 ++++++++++++++++++ 4 files changed, 147 insertions(+), 36 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/CompositeDMContext.java diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java index 7d78bcd950d..3d588681ed2 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java @@ -23,7 +23,6 @@ import org.eclipse.dd.dsf.debug.service.IRunControl; import org.eclipse.dd.dsf.debug.service.IRegisters.IGroupChangedDMEvent; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMData; -import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.AbstractExpressionLayoutNode; @@ -34,6 +33,7 @@ import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.dm.CompositeDMContext; import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.ILaunch; @@ -151,25 +151,19 @@ public class RegisterGroupLayoutNode extends AbstractExpressionLayoutNode protected void updateElementsInSessionThread(final IChildrenUpdate update) { if (!checkService(IRegisters.class, null, update)) return; - final IExecutionDMContext execDmc = findDmcInPath(update.getElementPath(), IExecutionDMContext.class) ; - - if (execDmc != null) { - getServicesTracker().getService(IRegisters.class).getRegisterGroups( - execDmc, - new DataRequestMonitor(getSession().getExecutor(), null) { - @Override - public void handleCompleted() { - if (!getStatus().isOK()) { - update.done(); - return; - } - fillUpdateWithVMCs(update, getData()); + CompositeDMContext compositeDmc = new CompositeDMContext(getVMProvider().getRootElement(), update.getElementPath()); + getServicesTracker().getService(IRegisters.class).getRegisterGroups( + compositeDmc, + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + public void handleCompleted() { + if (!getStatus().isOK()) { update.done(); - }}); - } else { - handleFailedUpdate(update); - } - + return; + } + fillUpdateWithVMCs(update, getData()); + update.done(); + }}); } @Override diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java index 94bf4046788..a94cedf4c20 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java @@ -38,6 +38,7 @@ import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.dm.CompositeDMContext; import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.ILaunch; @@ -370,15 +371,10 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode @Override protected void updateElementsInSessionThread(final IChildrenUpdate update) { - final IRegisterGroupDMContext execDmc = findDmcInPath(update.getElementPath(), IRegisterGroupDMContext.class); - - if (execDmc == null) { - handleFailedUpdate(update); - return; - } + CompositeDMContext compositeDmc = new CompositeDMContext(getVMProvider().getRootElement(), update.getElementPath()); getServicesTracker().getService(IRegisters.class).getRegisters( - execDmc, + compositeDmc, new DataRequestMonitor(getSession().getExecutor(), null) { @Override public void handleCompleted() { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java index 196a0e9503a..4b993173fde 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java @@ -13,8 +13,6 @@ import java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfExecutor; import org.eclipse.dd.dsf.concurrent.MultiRequestMonitor; @@ -43,6 +41,7 @@ import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; 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.dm.CompositeDMContext; import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.ILaunch; @@ -441,15 +440,11 @@ public class VariableLayoutNode extends AbstractExpressionLayoutNode implements @Override protected void getElementForExpressionPart(IChildrenUpdate update, String expressionPartText, DataRequestMonitor rm) { - final IFrameDMContext frameDmc = findDmcInPath(update.getElementPath(), IFrameDMContext.class); - final IExpressions expressionService = getServicesTracker().getService(IExpressions.class); + CompositeDMContext compositeDmc = new CompositeDMContext(getVMProvider().getRootElement(), update.getElementPath()); - if (frameDmc != null) { - IExpressionDMContext expressionDMC = expressionService.createExpression(frameDmc, expressionPartText); - rm.setData(createVMContext(expressionDMC)); - } else { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ - } + final IExpressions expressionService = getServicesTracker().getService(IExpressions.class); + IExpressionDMContext expressionDMC = expressionService.createExpression(compositeDmc, expressionPartText); + rm.setData(createVMContext(expressionDMC)); rm.done(); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/CompositeDMContext.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/CompositeDMContext.java new file mode 100644 index 00000000000..0c2234465b9 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/CompositeDMContext.java @@ -0,0 +1,126 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel.dm; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode.DMVMContext; +import org.eclipse.jface.viewers.TreePath; + +/** + * Object used to combine several DM Contexts found in a tree path of a viewer + * update. This object allows the view model to pass complete data model context + * information found in the view to the services. + */ +public class CompositeDMContext implements IDMContext { + + /** + * The input object to the view. This object is not included in the tree + * path. + */ + private final Object fViewerInputObject; + + /** + * The tree path for which the context is created. + */ + private final TreePath fTreePath; + + /** + * The list of parent contexts derived from the input object and + * the path. It is calculated on demand. + */ + private IDMContext[] fParents; + + /** + * Main constructor provides all data needed to implement the IModelContext + * interface. + */ + public CompositeDMContext(Object viewerInputObject, TreePath treePath) { + fViewerInputObject = viewerInputObject; + fTreePath = treePath; + } + + /** + * Returns the session ID of the last DMVMContext element found in the tree + * path of this composite context. May return an empty string if no DMVMContext + * is found in path. + *

    + * Note: The session ID is primarily used by UI components to get access to the + * correct session and executor for the given context. The composite context is + * intended to be created by UI clients which already know the session ID so + * the fact that this method may not return a reliable result is acceptable. + *

    + */ + public String getSessionId() { + return getElement().getDMC().getSessionId(); + } + + public IDMContext[] getParents() { + if (fParents == null) { + List parentsList = new ArrayList(fTreePath.getSegmentCount() + 1); + for (int i = fTreePath.getSegmentCount() - 1; i >=0 ; i--) { + if (fTreePath.getSegment(i) instanceof DMVMContext) { + parentsList.add( ((DMVMContext)fTreePath.getSegment(i)).getDMC() ); + } + } + if (fViewerInputObject instanceof DMVMContext) { + parentsList.add( ((DMVMContext)fViewerInputObject).getDMC() ); + } + + fParents = parentsList.toArray(new IDMContext[parentsList.size()]); + } + return fParents; + } + + /** + * Returns the given adapter of the last DMVMContext element found in the tree + * path of this composite context. Will return null if no DMVMContext is found + * in path. + * @see #getSessionId() + */ + @SuppressWarnings("unchecked") + public Object getAdapter(Class adapterType) { + return getElement().getAdapter(adapterType); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof CompositeDMContext && + ((CompositeDMContext)obj).fTreePath.equals(fTreePath) && + ((CompositeDMContext)obj).fViewerInputObject.equals(fViewerInputObject); + } + + @Override + public int hashCode() { + return fTreePath.hashCode() + fViewerInputObject.hashCode(); + } + + /** + * Returns the principal element that this composite context is based on. + * It is used for calculating the session ID and the adapters of this + * context. May return null if no DMVMContext is found in + * path. + */ + private DMVMContext getElement() { + for (int i = fTreePath.getSegmentCount() - 1; i >= 0; i--) { + if (fTreePath.getSegment(i) instanceof DMVMContext) { + return (DMVMContext)fTreePath.getSegment(i); + } + } + if (fViewerInputObject instanceof DMVMContext) { + return (DMVMContext)fViewerInputObject; + } + + return null; + } +} From 0c476c0d38aba700853ddf07c7d4a03fa457133b Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 30 Nov 2007 01:16:29 +0000 Subject: [PATCH 188/834] [211523] Added an ImmediateExecutor implementation. --- .../dd/dsf/concurrent/ImmediateExecutor.java | 31 +++++++++++++++++++ .../org/eclipse/dd/dsf/concurrent/Query.java | 9 +----- .../dd/dsf/concurrent/RequestMonitor.java | 2 +- 3 files changed, 33 insertions(+), 9 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ImmediateExecutor.java diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ImmediateExecutor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ImmediateExecutor.java new file mode 100644 index 00000000000..4e955b70867 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ImmediateExecutor.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.concurrent; + +import java.util.concurrent.Executor; + +/** + * Executor that executes a runnable immediately as it is submitted. This + * executor is useful for clients that need to create RequestMonitor + * objects, but which do not have their own executor. + * @see RequestMonitor + */ +public class ImmediateExecutor implements Executor { + private static ImmediateExecutor fInstance = new ImmediateExecutor(); + + public static Executor getInstance() { + return fInstance; + } + + public void execute(Runnable command) { + command.run(); + } +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Query.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Query.java index ee1bec45ded..a490ab2df4f 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Query.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Query.java @@ -12,7 +12,6 @@ package org.eclipse.dd.dsf.concurrent; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; -import java.util.concurrent.Executor; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -112,13 +111,7 @@ abstract public class Query extends DsfRunnable * shut down. In that case, the DSF executor may throw a * RejectedExecutionException which would have to be handled by the query. */ - Executor rmExecutor = new Executor() { - public void execute(Runnable command) { - command.run(); - } - }; - - execute(new DataRequestMonitor(rmExecutor, null) { + execute(new DataRequestMonitor(ImmediateExecutor.getInstance(), null) { @Override public void handleCompleted() { if (getStatus().isOK()) fSync.doSet(getData()); diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java index 9a7c0343fbf..4a6aa955515 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java @@ -159,7 +159,7 @@ public class RequestMonitor { @Override public String toString() { - return "RequestMonitor: " + getStatus().toString(); //$NON-NLS-1$ + return "RequestMonitor (" + super.toString() + "): " + getStatus().toString(); //$NON-NLS-1$ //$NON-NLS-2$ } /** From ad27060ba1d207d67d04c4d041e074e719a72380 Mon Sep 17 00:00:00 2001 From: Francois Chouinard Date: Fri, 30 Nov 2007 16:14:54 +0000 Subject: [PATCH 189/834] Second shot at the breakpoint service. Fix for the shutdown sequence where a missing rm.done() in the MIBreakpoints shutdown() method was missing. --- .../dd/dsf/debug/service/IBreakpoints.java | 117 +++++++++++++++--- .../debug/service/IBreakpointsManager.java | 43 +++++++ 2 files changed, 143 insertions(+), 17 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpointsManager.java diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java index 3f8aca9a6e9..a7add59e418 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java @@ -7,9 +7,13 @@ * * Contributors: * Wind River Systems - initial API and implementation + * Ericsson - Revisited the API *******************************************************************************/ package org.eclipse.dd.dsf.debug.service; +import java.util.Map; + +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.service.IDsfService; @@ -17,32 +21,111 @@ import org.eclipse.dd.dsf.service.IDsfService; /** * Breakpoint service interface. The breakpoint service tracks platform breakpoint * objects, and based on those, it manages breakpoints in the debugger back end. - * The purpose of the service model interface is to allow UI clients to display - * breakpoint status in more detail and more dynamically than it it possible with - * just the marker-based breakpoint object. */ public interface IBreakpoints extends IDsfService { /** - * Marker interface for a context for which breakpoints can be installed. + * Marker interface for a context for which breakpoints can be installed */ - public interface IBreakpointsDMContext extends IDMContext {}; + public interface IBreakpointsTargetDMContext extends IDMContext {}; /** - * Install and begin tracking breakpoints for given context. The service - * will keep installing new breakpoints that appear in the IDE for this - * context until {@link #uninstallBreakpoints(IDMContext)} is called for that - * context. - * @param dmc Context to start tracking breakpoints for. - * @param rm Completion callback. + * Specific breakpoint context */ - public void installBreakpoints(IBreakpointsDMContext dmc, RequestMonitor rm); + public interface IDsfBreakpointDMContext extends IDMContext {}; /** - * Uninstall and stop tracking breakpoints for the given context. - * @param dmc Context to start tracking breakpoints for. - * @param rm Completion callback. + * Breakpoint structure. + * Properties are stored in a map. */ - public void uninstallBreakpoints(IBreakpointsDMContext dmc, RequestMonitor rm); -} + public interface IDsfBreakpoint { + // Minimal breakpoint properties + public static final String DSFBREAKPOINT = "org.eclipse.dd.dsf.debug.service.breakpoint"; //$NON-NLS-1$ + public static final String FILE_NAME = DSFBREAKPOINT + ".fileName"; //$NON-NLS-1$ + public static final String LINE_NUMBER = DSFBREAKPOINT + ".lineNumber"; //$NON-NLS-1$ + public static final String FUNCTION = DSFBREAKPOINT + ".function"; //$NON-NLS-1$ + public static final String CONDITION = DSFBREAKPOINT + ".condition"; //$NON-NLS-1$ + public static final String IGNORE_COUNT = DSFBREAKPOINT + ".ignoreCount"; //$NON-NLS-1$ + public static final String IS_ENABLED = DSFBREAKPOINT + ".isEnabled"; //$NON-NLS-1$ + + public Object getReference(); + + public Map getProperties(); + public Object getProperty(String key, Object defaultValue); + + public Object setProperty(String key, Object value); +// public void setProperties(Map properties); + }; + + /** + * Refreshes the list of breakpoints from the [context] and returns the list + * of references. + * + * Use getBreakpoint() to retrieve individual breakpoints. + * + * @param context the execution context of the breakpoint + * @param drm the list of breakpoints in the execution context + */ + public void getBreakpointList(IBreakpointsTargetDMContext context, + DataRequestMonitor drm); + + /** + * Retrieves a specific breakpoint from the service. + * + * @param context the execution context of the breakpoint + * @param dmc the breakpoint reference + * @return IDsfBreakpoint + */ + public IDsfBreakpoint getBreakpoint(IBreakpointsTargetDMContext context, + IDsfBreakpointDMContext dmc); + + /** + * Adds a breakpoint on the target. + * + * The breakpoint reference is returned in the DRM. The actual breakpoint + * object can be later be retrieved using getBreakpoint(reference). + * + * E.g.: + * IDsfBreakpointDMContext ref = addBreakpoint(...); + * IDsfBreakpoint bp = getBreakpoint(ref); + * + * If the breakpoint is a duplicate (already set previously), then it is up to + * the back-end to decide if it is an error or not. + * + * @param context the execution context of the breakpoint + * @param breakpoint the breakpoint to insert + * @param drm the DRM returning the breakpoint reference + */ + public void addBreakpoint(IBreakpointsTargetDMContext context, IDsfBreakpoint breakpoint, + DataRequestMonitor drm); + + /** + * Removes the breakpoint on the target. + * + * If the breakpoint doesn't exist, silently ignore it. + * + * @param context the execution context of the breakpoint + * @param dmc the reference of breakpoint to remove + * @param rm the asynchronous request monitor + */ + public void removeBreakpoint(IBreakpointsTargetDMContext context, + IDsfBreakpointDMContext dmc, RequestMonitor rm); + + /** + * Updates the breakpoint properties on the target. + * + * To add/update/remove a property, simply create a map with + * the desired value(s) for the given key(s). + * + * A null value is used for removal of a property e.g.: + * properties.set(FUNCTION, null); + * + * @param context the execution context of the breakpoint + * @param dmc the reference of breakpoint to remove + * @param rm the asynchronous request monitor + */ + public void updateBreakpoint(IBreakpointsTargetDMContext context, + IDsfBreakpointDMContext dmc, Map properties, + DataRequestMonitor drm); +} diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpointsManager.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpointsManager.java new file mode 100644 index 00000000000..79063e39a6c --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpointsManager.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * 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.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; +import org.eclipse.dd.dsf.service.IDsfService; + +/** + * Breakpoint service interface. The breakpoint service tracks platform breakpoint + * objects, and based on those, it manages breakpoints in the debugger back end. + * The purpose of the service model interface is to allow UI clients to display + * breakpoint status in more detail and more dynamically than it it possible with + * just the marker-based breakpoint object. + */ +public interface IBreakpointsManager extends IDsfService { + + /** + * Install and begin tracking breakpoints for given context. The service + * will keep installing new breakpoints that appear in the IDE for this + * context until {@link #uninstallBreakpoints(IDMContext)} is called for that + * context. + * @param dmc Context to start tracking breakpoints for. + * @param rm Completion callback. + */ + public void startTrackingBreakpoints(IBreakpointsTargetDMContext dmc, RequestMonitor rm); + + /** + * Uninstall and stop tracking breakpoints for the given context. + * @param dmc Context to start tracking breakpoints for. + * @param rm Completion callback. + */ + public void stopTrackingBreakpoints(IBreakpointsTargetDMContext dmc, RequestMonitor rm); +} From 3fef8680c95abc5cfc9b7f898ed8d64f75b57410 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 30 Nov 2007 17:50:44 +0000 Subject: [PATCH 190/834] [211616] Fixed Query.get(timeout) implementation. --- .../src/org/eclipse/dd/dsf/concurrent/Query.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Query.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Query.java index a490ab2df4f..58ba79d0769 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Query.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Query.java @@ -74,7 +74,7 @@ abstract public class Query extends DsfRunnable public V get() throws InterruptedException, ExecutionException { return fSync.doGet(); } public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { - return fSync.doGet(); + return fSync.doGet(unit.toNanos(timeout)); } /** From 4e224fce0a780dabad96806631441935334430b5 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 30 Nov 2007 17:54:01 +0000 Subject: [PATCH 191/834] [211534] Changed the constructor of the singleton class to private. --- .../src/org/eclipse/dd/dsf/concurrent/ImmediateExecutor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ImmediateExecutor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ImmediateExecutor.java index 4e955b70867..9b97db6b81a 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ImmediateExecutor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ImmediateExecutor.java @@ -21,7 +21,7 @@ import java.util.concurrent.Executor; public class ImmediateExecutor implements Executor { private static ImmediateExecutor fInstance = new ImmediateExecutor(); - public static Executor getInstance() { + private static Executor getInstance() { return fInstance; } From 84e4230f3155b8e33333022aef12968341390f3a Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 30 Nov 2007 17:57:36 +0000 Subject: [PATCH 192/834] [211534] Changed the constructor of the singleton class to private (try #2). --- .../eclipse/dd/dsf/concurrent/ImmediateExecutor.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ImmediateExecutor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ImmediateExecutor.java index 9b97db6b81a..64316554eff 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ImmediateExecutor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ImmediateExecutor.java @@ -19,9 +19,19 @@ import java.util.concurrent.Executor; * @see RequestMonitor */ public class ImmediateExecutor implements Executor { + private static ImmediateExecutor fInstance = new ImmediateExecutor(); - private static Executor getInstance() { + /** + * The default constructor is hidden. {@link #getInstance()} should be + * used instead. + */ + private ImmediateExecutor() {} + + /** + * Returns the singleton instance of ImmediateExecutor. + */ + public static Executor getInstance() { return fInstance; } From 72fd69e4f11fc71a7fb2e916c670b7a292daa916 Mon Sep 17 00:00:00 2001 From: Francois Chouinard Date: Mon, 3 Dec 2007 23:07:40 +0000 Subject: [PATCH 193/834] - First implementation of watchpoints - Improved JUnit suite - Fixed a couple of glitches in the previous delivery --- .../dd/dsf/debug/service/IBreakpoints.java | 42 ++++++++++++++++--- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java index a7add59e418..9a6e4dc4727 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java @@ -40,6 +40,9 @@ public interface IBreakpoints extends IDsfService { */ public interface IDsfBreakpoint { + // Breakpoint types + public static enum IDsfBreakpointNature { BREAKPOINT, WATCHPOINT, CATCHPOINT, TRACEPOINT }; + // Minimal breakpoint properties public static final String DSFBREAKPOINT = "org.eclipse.dd.dsf.debug.service.breakpoint"; //$NON-NLS-1$ public static final String FILE_NAME = DSFBREAKPOINT + ".fileName"; //$NON-NLS-1$ @@ -49,13 +52,18 @@ public interface IBreakpoints extends IDsfService { public static final String IGNORE_COUNT = DSFBREAKPOINT + ".ignoreCount"; //$NON-NLS-1$ public static final String IS_ENABLED = DSFBREAKPOINT + ".isEnabled"; //$NON-NLS-1$ + // Minimal watchpoint properties + public static final String EXPRESSION = DSFBREAKPOINT + ".expression"; //$NON-NLS-1$ + public static final String READ = DSFBREAKPOINT + ".read"; //$NON-NLS-1$ + public static final String WRITE = DSFBREAKPOINT + ".write"; //$NON-NLS-1$ + public Object getReference(); + public IDsfBreakpointNature getNature(); public Map getProperties(); public Object getProperty(String key, Object defaultValue); public Object setProperty(String key, Object value); -// public void setProperties(Map properties); }; /** @@ -97,11 +105,12 @@ public interface IBreakpoints extends IDsfService { * @param breakpoint the breakpoint to insert * @param drm the DRM returning the breakpoint reference */ - public void addBreakpoint(IBreakpointsTargetDMContext context, IDsfBreakpoint breakpoint, + public void addBreakpoint(IBreakpointsTargetDMContext context, + IDsfBreakpoint breakpoint, DataRequestMonitor drm); /** - * Removes the breakpoint on the target. + * Removes the breakpoint or watchpoint on the target. * * If the breakpoint doesn't exist, silently ignore it. * @@ -113,19 +122,42 @@ public interface IBreakpoints extends IDsfService { IDsfBreakpointDMContext dmc, RequestMonitor rm); /** - * Updates the breakpoint properties on the target. + * Updates the breakpoint or watchpoint properties on the target. * * To add/update/remove a property, simply create a map with * the desired value(s) for the given key(s). * + * Properties that affect the breakpoint nature or location + * should not be updated. Instead, the breakpoint should be + * removed then re-inserted. + * * A null value is used for removal of a property e.g.: * properties.set(FUNCTION, null); * * @param context the execution context of the breakpoint - * @param dmc the reference of breakpoint to remove + * @param dmc the reference of breakpoint to modify * @param rm the asynchronous request monitor */ public void updateBreakpoint(IBreakpointsTargetDMContext context, IDsfBreakpointDMContext dmc, Map properties, DataRequestMonitor drm); + + /** + * Adds a watchpoint on the target. + * + * The watchpoint reference is returned in the DRM. The actual watchpoint + * object can be later be retrieved using getBreakpoint(reference). + * + * E.g.: + * IDsfBreakpointDMContext ref = addWatchpoint(...); + * IDsfBreakpoint bp = getBreakpoint(ref); + * + * @param context the execution context of the watchpoint + * @param watchpoint the watchpoint to insert + * @param rm the asynchronous request monitor + */ + public void addWatchpoint(IBreakpointsTargetDMContext context, + IDsfBreakpoint watchpoint, + DataRequestMonitor drm); + } From 0f3f42167bdd6bab5d9ba7c53c27db052e46cbac Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Mon, 10 Dec 2007 03:22:21 +0000 Subject: [PATCH 194/834] [212369] org.eclipse.dd.dsf.mi.ui build errors cause nightly build failure --- features/org.eclipse.dd.dsf.sdk-feature/feature.xml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/features/org.eclipse.dd.dsf.sdk-feature/feature.xml b/features/org.eclipse.dd.dsf.sdk-feature/feature.xml index dcf8eb7c355..b62d68de3fe 100644 --- a/features/org.eclipse.dd.dsf.sdk-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.sdk-feature/feature.xml @@ -66,11 +66,4 @@ Core SDK version="0.0.0" unpack="false"/> - - From 4463f50fc6e2758e68603dbd749089b9133a8cc0 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Mon, 10 Dec 2007 20:55:32 +0000 Subject: [PATCH 195/834] [206832] Created a non-UI CompositeDMContext. --- .../register/RegisterGroupLayoutNode.java | 4 +- .../register/RegisterLayoutNode.java | 4 +- .../variable/VariableLayoutNode.java | 4 +- .../ui/viewmodel/dm/CompositeDMContext.java | 126 ------------------ .../ui/viewmodel/dm/CompositeDMVMContext.java | 62 +++++++++ .../dd/dsf/datamodel/CompositeDMContext.java | 92 +++++++++++++ 6 files changed, 160 insertions(+), 132 deletions(-) delete mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/CompositeDMContext.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/CompositeDMVMContext.java create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/CompositeDMContext.java diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java index 3d588681ed2..79cfdcec889 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java @@ -33,7 +33,7 @@ import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; -import org.eclipse.dd.dsf.ui.viewmodel.dm.CompositeDMContext; +import org.eclipse.dd.dsf.ui.viewmodel.dm.CompositeDMVMContext; import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.ILaunch; @@ -151,7 +151,7 @@ public class RegisterGroupLayoutNode extends AbstractExpressionLayoutNode protected void updateElementsInSessionThread(final IChildrenUpdate update) { if (!checkService(IRegisters.class, null, update)) return; - CompositeDMContext compositeDmc = new CompositeDMContext(getVMProvider().getRootElement(), update.getElementPath()); + CompositeDMVMContext compositeDmc = new CompositeDMVMContext(getVMProvider().getRootElement(), update.getElementPath()); getServicesTracker().getService(IRegisters.class).getRegisterGroups( compositeDmc, new DataRequestMonitor(getSession().getExecutor(), null) { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java index a94cedf4c20..43afcdf3e95 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java @@ -38,7 +38,7 @@ import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; -import org.eclipse.dd.dsf.ui.viewmodel.dm.CompositeDMContext; +import org.eclipse.dd.dsf.ui.viewmodel.dm.CompositeDMVMContext; import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.ILaunch; @@ -371,7 +371,7 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode @Override protected void updateElementsInSessionThread(final IChildrenUpdate update) { - CompositeDMContext compositeDmc = new CompositeDMContext(getVMProvider().getRootElement(), update.getElementPath()); + CompositeDMVMContext compositeDmc = new CompositeDMVMContext(getVMProvider().getRootElement(), update.getElementPath()); getServicesTracker().getService(IRegisters.class).getRegisters( compositeDmc, diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java index 4b993173fde..1a4107a0ba2 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java @@ -41,7 +41,7 @@ import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; 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.dm.CompositeDMContext; +import org.eclipse.dd.dsf.ui.viewmodel.dm.CompositeDMVMContext; import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.ILaunch; @@ -440,7 +440,7 @@ public class VariableLayoutNode extends AbstractExpressionLayoutNode implements @Override protected void getElementForExpressionPart(IChildrenUpdate update, String expressionPartText, DataRequestMonitor rm) { - CompositeDMContext compositeDmc = new CompositeDMContext(getVMProvider().getRootElement(), update.getElementPath()); + CompositeDMVMContext compositeDmc = new CompositeDMVMContext(getVMProvider().getRootElement(), update.getElementPath()); final IExpressions expressionService = getServicesTracker().getService(IExpressions.class); IExpressionDMContext expressionDMC = expressionService.createExpression(compositeDmc, expressionPartText); diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/CompositeDMContext.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/CompositeDMContext.java deleted file mode 100644 index 0c2234465b9..00000000000 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/CompositeDMContext.java +++ /dev/null @@ -1,126 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.dsf.ui.viewmodel.dm; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode.DMVMContext; -import org.eclipse.jface.viewers.TreePath; - -/** - * Object used to combine several DM Contexts found in a tree path of a viewer - * update. This object allows the view model to pass complete data model context - * information found in the view to the services. - */ -public class CompositeDMContext implements IDMContext { - - /** - * The input object to the view. This object is not included in the tree - * path. - */ - private final Object fViewerInputObject; - - /** - * The tree path for which the context is created. - */ - private final TreePath fTreePath; - - /** - * The list of parent contexts derived from the input object and - * the path. It is calculated on demand. - */ - private IDMContext[] fParents; - - /** - * Main constructor provides all data needed to implement the IModelContext - * interface. - */ - public CompositeDMContext(Object viewerInputObject, TreePath treePath) { - fViewerInputObject = viewerInputObject; - fTreePath = treePath; - } - - /** - * Returns the session ID of the last DMVMContext element found in the tree - * path of this composite context. May return an empty string if no DMVMContext - * is found in path. - *

    - * Note: The session ID is primarily used by UI components to get access to the - * correct session and executor for the given context. The composite context is - * intended to be created by UI clients which already know the session ID so - * the fact that this method may not return a reliable result is acceptable. - *

    - */ - public String getSessionId() { - return getElement().getDMC().getSessionId(); - } - - public IDMContext[] getParents() { - if (fParents == null) { - List parentsList = new ArrayList(fTreePath.getSegmentCount() + 1); - for (int i = fTreePath.getSegmentCount() - 1; i >=0 ; i--) { - if (fTreePath.getSegment(i) instanceof DMVMContext) { - parentsList.add( ((DMVMContext)fTreePath.getSegment(i)).getDMC() ); - } - } - if (fViewerInputObject instanceof DMVMContext) { - parentsList.add( ((DMVMContext)fViewerInputObject).getDMC() ); - } - - fParents = parentsList.toArray(new IDMContext[parentsList.size()]); - } - return fParents; - } - - /** - * Returns the given adapter of the last DMVMContext element found in the tree - * path of this composite context. Will return null if no DMVMContext is found - * in path. - * @see #getSessionId() - */ - @SuppressWarnings("unchecked") - public Object getAdapter(Class adapterType) { - return getElement().getAdapter(adapterType); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof CompositeDMContext && - ((CompositeDMContext)obj).fTreePath.equals(fTreePath) && - ((CompositeDMContext)obj).fViewerInputObject.equals(fViewerInputObject); - } - - @Override - public int hashCode() { - return fTreePath.hashCode() + fViewerInputObject.hashCode(); - } - - /** - * Returns the principal element that this composite context is based on. - * It is used for calculating the session ID and the adapters of this - * context. May return null if no DMVMContext is found in - * path. - */ - private DMVMContext getElement() { - for (int i = fTreePath.getSegmentCount() - 1; i >= 0; i--) { - if (fTreePath.getSegment(i) instanceof DMVMContext) { - return (DMVMContext)fTreePath.getSegment(i); - } - } - if (fViewerInputObject instanceof DMVMContext) { - return (DMVMContext)fViewerInputObject; - } - - return null; - } -} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/CompositeDMVMContext.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/CompositeDMVMContext.java new file mode 100644 index 00000000000..dce32ee6f0a --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/CompositeDMVMContext.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel.dm; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.datamodel.CompositeDMContext; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode.DMVMContext; +import org.eclipse.jface.viewers.TreePath; + +/** + * Object used to combine several DM Contexts found in a tree path of a viewer + * update. This object allows the view model to pass complete data model context + * information found in the view to the services. + */ +public class CompositeDMVMContext extends CompositeDMContext { + + /** + * Have to pass in an empty array of contexts to parent constructor + * in order to be able to calculate the + */ + private static IDMContext[] EMPTY_CONTEXTS_ARRAY = new IDMContext[0]; + + /** + * The list of parent contexts derived from the input object and + * the path. It is calculated on demand. + */ + private IDMContext[] fParents; + + /** + * Creates a composite context based on view model + */ + public CompositeDMVMContext(Object viewerInputObject, TreePath treePath) { + super(EMPTY_CONTEXTS_ARRAY); + List parentsList = new ArrayList(treePath.getSegmentCount() + 1); + for (int i = treePath.getSegmentCount() - 1; i >=0 ; i--) { + if (treePath.getSegment(i) instanceof DMVMContext) { + parentsList.add( ((DMVMContext)treePath.getSegment(i)).getDMC() ); + } + } + if (viewerInputObject instanceof DMVMContext) { + parentsList.add( ((DMVMContext)viewerInputObject).getDMC() ); + } + + fParents = parentsList.toArray(new IDMContext[parentsList.size()]); +} + + @Override + public IDMContext[] getParents() { + return fParents; + } +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/CompositeDMContext.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/CompositeDMContext.java new file mode 100644 index 00000000000..5cc65fc88ca --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/CompositeDMContext.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.datamodel; + +import java.util.Arrays; + +/** + * Generic DM context used to combine several DM Contexts. This object allows + * clients and other services to combine several contexts into one in order to + * pass them as an argument to a method which takes a generic context as an + * argument. + */ +public class CompositeDMContext implements IDMContext { + + public static String INVALID_SESSION_ID = ""; //$NON-NLS-1$ + + /** + * The list of parent contexts that this composite context is made up of. + */ + private final IDMContext[] fParents; + + /** + * Main constructor provides all data needed to implement the IModelContext + * interface. + * @param parents Array of parent contexts that this composite context is + * made up of. It can be an empty array, but it cannot be null. + */ + public CompositeDMContext(IDMContext[] parents) { + fParents = parents; + } + + /** + * Returns the session ID of the first element in the array of parents of this + * context. May return an empty string if the parents array has no elements. + *

    + * Note: The session ID is primarily used by UI components to get access to the + * correct session and executor for the given context. The composite context is + * intended to be created by clients which already know the session ID so + * the fact that this method may not return a reliable result is acceptable. + *

    + */ + public String getSessionId() { + IDMContext[] parents = getParents(); + if (parents.length > 0) { + return parents[0].getSessionId(); + } else { + return INVALID_SESSION_ID; + } + } + + /** + * Returns the list of parents that this composite context is based on. Subclasses + * may override this method to calculate their own set of parents. + */ + public IDMContext[] getParents() { + return fParents; + } + + /** + * Returns the given adapter of the last DMVMContext element found in the tree + * path of this composite context. Will return null if no DMVMContext is found + * in path. + * @see #getSessionId() + */ + @SuppressWarnings("unchecked") + public Object getAdapter(Class adapterType) { + IDMContext[] parents = getParents(); + if (parents.length > 0) { + return parents[0].getAdapter(adapterType); + } else { + return null; + } + } + + @Override + public boolean equals(Object obj) { + return obj instanceof CompositeDMContext && Arrays.equals(((CompositeDMContext)obj).getParents(), getParents()); + } + + @Override + public int hashCode() { + return Arrays.hashCode(getParents()); + } +} From cd887eb0e383d99fe654532f1983315364548aa2 Mon Sep 17 00:00:00 2001 From: Francois Chouinard Date: Mon, 10 Dec 2007 22:12:01 +0000 Subject: [PATCH 196/834] First part of re-factoring of the Breakpoint service. --- .../dd/dsf/debug/service/IBreakpoints.java | 92 +++++++------------ 1 file changed, 33 insertions(+), 59 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java index 9a6e4dc4727..a4f7639e608 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java @@ -19,8 +19,7 @@ import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.service.IDsfService; /** - * Breakpoint service interface. The breakpoint service tracks platform breakpoint - * objects, and based on those, it manages breakpoints in the debugger back end. + * Breakpoint service interface */ public interface IBreakpoints extends IDsfService { @@ -30,40 +29,36 @@ public interface IBreakpoints extends IDsfService { public interface IBreakpointsTargetDMContext extends IDMContext {}; /** - * Specific breakpoint context + * Specific breakpoint context */ - public interface IDsfBreakpointDMContext extends IDMContext {}; + public interface IDsfBreakpointDMContext extends IDMContext { + + // Get the execution context + IBreakpointsTargetDMContext getTargetContext(); + + // Get the breakpoint reference + Object getReference(); + }; /** - * Breakpoint structure. - * Properties are stored in a map. + * Breakpoint structure */ public interface IDsfBreakpoint { // Breakpoint types public static enum IDsfBreakpointNature { BREAKPOINT, WATCHPOINT, CATCHPOINT, TRACEPOINT }; - // Minimal breakpoint properties - public static final String DSFBREAKPOINT = "org.eclipse.dd.dsf.debug.service.breakpoint"; //$NON-NLS-1$ - public static final String FILE_NAME = DSFBREAKPOINT + ".fileName"; //$NON-NLS-1$ - public static final String LINE_NUMBER = DSFBREAKPOINT + ".lineNumber"; //$NON-NLS-1$ - public static final String FUNCTION = DSFBREAKPOINT + ".function"; //$NON-NLS-1$ - public static final String CONDITION = DSFBREAKPOINT + ".condition"; //$NON-NLS-1$ - public static final String IGNORE_COUNT = DSFBREAKPOINT + ".ignoreCount"; //$NON-NLS-1$ - public static final String IS_ENABLED = DSFBREAKPOINT + ".isEnabled"; //$NON-NLS-1$ - - // Minimal watchpoint properties - public static final String EXPRESSION = DSFBREAKPOINT + ".expression"; //$NON-NLS-1$ - public static final String READ = DSFBREAKPOINT + ".read"; //$NON-NLS-1$ - public static final String WRITE = DSFBREAKPOINT + ".write"; //$NON-NLS-1$ - - public Object getReference(); + // Retrieve the breakpoint nature public IDsfBreakpointNature getNature(); + // Retrieve the breakpoint set of properties public Map getProperties(); + + // Retrieve a single breakpoint property public Object getProperty(String key, Object defaultValue); - public Object setProperty(String key, Object value); + // Update a single breakpoint property + public void setProperty(String key, Object value); }; /** @@ -75,18 +70,17 @@ public interface IBreakpoints extends IDsfService { * @param context the execution context of the breakpoint * @param drm the list of breakpoints in the execution context */ - public void getBreakpointList(IBreakpointsTargetDMContext context, + public void getBreakpoints(IBreakpointsTargetDMContext context, DataRequestMonitor drm); /** * Retrieves a specific breakpoint from the service. * - * @param context the execution context of the breakpoint * @param dmc the breakpoint reference - * @return IDsfBreakpoint + * @param drm the DRM returning the breakpoint data */ - public IDsfBreakpoint getBreakpoint(IBreakpointsTargetDMContext context, - IDsfBreakpointDMContext dmc); + public void getBreakpointDMData(IDsfBreakpointDMContext dmc, + DataRequestMonitor drm); /** * Adds a breakpoint on the target. @@ -102,27 +96,26 @@ public interface IBreakpoints extends IDsfService { * the back-end to decide if it is an error or not. * * @param context the execution context of the breakpoint - * @param breakpoint the breakpoint to insert + * @param breakpoint the breakpoint * @param drm the DRM returning the breakpoint reference */ - public void addBreakpoint(IBreakpointsTargetDMContext context, + public void insertBreakpoint(IBreakpointsTargetDMContext context, IDsfBreakpoint breakpoint, DataRequestMonitor drm); /** - * Removes the breakpoint or watchpoint on the target. + * Removes the breakpoint on the target. * * If the breakpoint doesn't exist, silently ignore it. * - * @param context the execution context of the breakpoint - * @param dmc the reference of breakpoint to remove + * @param dmc the context of the breakpoints to remove * @param rm the asynchronous request monitor */ - public void removeBreakpoint(IBreakpointsTargetDMContext context, - IDsfBreakpointDMContext dmc, RequestMonitor rm); + public void removeBreakpoint(IDsfBreakpointDMContext dmc, + RequestMonitor rm); /** - * Updates the breakpoint or watchpoint properties on the target. + * Updates the breakpoint properties on the target. * * To add/update/remove a property, simply create a map with * the desired value(s) for the given key(s). @@ -132,32 +125,13 @@ public interface IBreakpoints extends IDsfService { * removed then re-inserted. * * A null value is used for removal of a property e.g.: - * properties.set(FUNCTION, null); + * properties.set(some_key, null); * - * @param context the execution context of the breakpoint - * @param dmc the reference of breakpoint to modify + * @param delta the delta properties + * @param dmc the context of the breakpoints to modify * @param rm the asynchronous request monitor */ - public void updateBreakpoint(IBreakpointsTargetDMContext context, - IDsfBreakpointDMContext dmc, Map properties, - DataRequestMonitor drm); - - /** - * Adds a watchpoint on the target. - * - * The watchpoint reference is returned in the DRM. The actual watchpoint - * object can be later be retrieved using getBreakpoint(reference). - * - * E.g.: - * IDsfBreakpointDMContext ref = addWatchpoint(...); - * IDsfBreakpoint bp = getBreakpoint(ref); - * - * @param context the execution context of the watchpoint - * @param watchpoint the watchpoint to insert - * @param rm the asynchronous request monitor - */ - public void addWatchpoint(IBreakpointsTargetDMContext context, - IDsfBreakpoint watchpoint, - DataRequestMonitor drm); + public void updateBreakpoint(IDsfBreakpointDMContext dmc, + Map delta, RequestMonitor drm); } From 34a2e60a29247b36f06d83f602f6c746a5f0a857 Mon Sep 17 00:00:00 2001 From: Veenu Khanna Date: Tue, 11 Dec 2007 10:32:11 +0000 Subject: [PATCH 197/834] IModuleDMData changed --- .../src/org/eclipse/dd/dsf/debug/service/IModules.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java index c0049a64ed5..a1b7e8fd770 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java @@ -60,6 +60,10 @@ public interface IModules extends IDsfService { String getName(); String getFile(); long getTimeStamp(); + String getBaseAddress(); + String getToAddress(); + boolean isSymbolsLoaded(); + long getSize(); } /** i information */ From 945c0892f34defa624033ec0d0acd0b6a216765a Mon Sep 17 00:00:00 2001 From: Veenu Khanna Date: Tue, 11 Dec 2007 15:24:04 +0000 Subject: [PATCH 198/834] Image files for modules view --- .../icons/library_obj.gif | Bin 0 -> 338 bytes .../icons/library_syms_obj.gif | Bin 0 -> 570 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/icons/library_obj.gif create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/icons/library_syms_obj.gif diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/icons/library_obj.gif b/plugins/org.eclipse.dd.dsf.debug.ui/icons/library_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..dd994fdbe69d4c704ff8fedbf725b448ab8a1ea4 GIT binary patch literal 338 zcmZ?wbhEHb6krfwxXQpF?q0)?y2Gqyoqoe+jpm&a-A4ubPq9wD%-Z0gH#MPRN6m*5 z8XpcQyx5`e;ef`A4H6F)2t1e}aAShNg${um9Re2`1Wr^4e7LdWLWRJUF7L}--nSMO z?#(bcSY*E~LS>_;$OaFQ4W1(Z|Nm#84N&~a!pOj&#GnH*9^@wmwtR<)1s*z5-Qp*n zX0+%ioJnF`B*VtS>~yezqhnIv2>}Pa$*rPoEi*E9-wi$))DdvwJ=c-cOAB}e8yXvx zM0rJ>WIMaMWrHQWWuzxfo-89S#xJHMCplMYo}`qV(u`S(%jFeTDJra7A~q{<)8;L% HjttfSGihP1 literal 0 HcmV?d00001 diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/icons/library_syms_obj.gif b/plugins/org.eclipse.dd.dsf.debug.ui/icons/library_syms_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..7da17d4194e5f428e2342a58520a60e2a511c6b9 GIT binary patch literal 570 zcmZ?wbhEHb6krfwc*ejW?q0KK>uHA69cDG_^cyy7H1Cw?J}S_EigoH`spN8L|3EQU zNBwXQ)&>t%H}lzNw&_hxSbcT>oD&0)p=YP1d<4TwJv1i9O?aeSbSY*E~ zLS>_;$OaFQ4W1(Rw=Mkt|3AY}28usf7#SEG7<53M0L2Ld`}78frsftSb)%Nf7Ij7S zu6{lB_GTt#7FITP4km{-70qUbMT;32n+%k+S_Iat5#$kEuc6h^#4E8wT%1pwpHEv^ zr=M++qljKy>cd#~oV`65;Eg~-^ qd(+Ut?x&5dt^ElxSu>T6gAW276}TqZ20ckwxTu*=nTeBy!5RQO4xtbL literal 0 HcmV?d00001 From c8f72adff3c88ee11ae917c3c93c7751d5063b44 Mon Sep 17 00:00:00 2001 From: Veenu Khanna Date: Tue, 11 Dec 2007 15:24:36 +0000 Subject: [PATCH 199/834] Image for modules view incorporated --- .../dsf/debug/ui/viewmodel/modules/ModulesLayoutNode.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesLayoutNode.java index f297e5da654..c162266923c 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesLayoutNode.java @@ -20,6 +20,8 @@ import org.eclipse.dd.dsf.debug.service.IModules.IModuleDMContext; import org.eclipse.dd.dsf.debug.service.IModules.IModuleDMData; import org.eclipse.dd.dsf.debug.service.IModules.ISymbolDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IGroupChangedDMEvent; +import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.debug.ui.IDsfDebugUIConstants; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; @@ -67,7 +69,9 @@ public class ModulesLayoutNode extends AbstractDMVMLayoutNode for (final ILabelUpdate update : updates) { final IModuleDMContext dmc = findDmcInPath(update.getElementPath(), IModuleDMContext.class); if (!checkDmc(dmc, update) || !checkService(IModules.class, null, update)) continue; - + // Use different image for loaded and unloaded symbols when event to report loading of symbols is implemented. + update.setImageDescriptor(DsfDebugUIPlugin.getImageDescriptor(IDsfDebugUIConstants.IMG_OBJS_SHARED_LIBRARY_SYMBOLS_LOADED), 0); + getServicesTracker().getService(IModules.class, null).getModuleData( dmc, new DataRequestMonitor(getSession().getExecutor(), null) { From eff94247473005fdcf8ca564793141fa9f19628c Mon Sep 17 00:00:00 2001 From: Veenu Khanna Date: Tue, 11 Dec 2007 15:24:53 +0000 Subject: [PATCH 200/834] DetailsPane view for modules --- .../viewmodel/modules/ModuleDetailPane.java | 557 ++++++++++++++++++ .../modules/ModuleDetailPaneFactory.java | 40 ++ 2 files changed, 597 insertions(+) create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPane.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPaneFactory.java diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPane.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPane.java new file mode 100644 index 00000000000..2bac45e2e28 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPane.java @@ -0,0 +1,557 @@ +/******************************************************************************* + * Copyright (c) 2006, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * QNX Software Systems - Mikhail Khodjaiants - Registers View (Bug 53640) + * Wind River Systems - adopted to use with Modules view + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel.modules; + + +import java.util.concurrent.ExecutionException; + +import org.eclipse.cdt.debug.internal.ui.views.modules.ModulesMessages; +import org.eclipse.cdt.debug.ui.ICDebugUIConstants; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.Query; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.IModules; +import org.eclipse.dd.dsf.debug.service.IModules.IModuleDMContext; +import org.eclipse.dd.dsf.debug.service.IModules.IModuleDMData; +import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.detail.TextViewerAction; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; +import org.eclipse.debug.core.model.IDebugElement; +import org.eclipse.debug.internal.ui.DebugUIPlugin; +import org.eclipse.debug.internal.ui.IDebugHelpContextIds; +import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; +import org.eclipse.debug.internal.ui.preferences.IDebugPreferenceConstants; +import org.eclipse.debug.internal.ui.views.variables.details.AbstractDetailPane; +import org.eclipse.debug.internal.ui.views.variables.details.DetailMessages; +import org.eclipse.debug.ui.IDebugView; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.text.Document; +import org.eclipse.jface.text.DocumentEvent; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IDocumentListener; +import org.eclipse.jface.text.ITextOperationTarget; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.source.SourceViewer; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.FocusAdapter; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.actions.ActionFactory; +import org.eclipse.ui.progress.WorkbenchJob; +import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds; + + +/** + * + */ +public class ModuleDetailPane extends AbstractDetailPane implements IAdaptable, IPropertyChangeListener { + + /** + * These are the IDs for the actions in the context menu + */ + protected static final String DETAIL_COPY_ACTION = ActionFactory.COPY.getId() + ".SourceDetailPane"; //$NON-NLS-1$ + protected static final String DETAIL_SELECT_ALL_ACTION = IDebugView.SELECT_ALL_ACTION + ".SourceDetailPane"; //$NON-NLS-1$ + + /** + * The ID, name and description of this pane are stored in constants so that the class + * does not have to be instantiated to access them. + */ + public static final String ID = "ModuleDetailPane"; //$NON-NLS-1$ + public static final String NAME = "Module Viewer"; //$NON-NLS-1$ + public static final String DESCRIPTION = "A detail pane that is based on a source viewer. Displays as text and has actions for assigning values, content assist and text modifications."; //$NON-NLS-1$ + + + /** + * The source viewer in which the computed string detail + * of selected modules will be displayed. + */ + private SourceViewer fSourceViewer; + public Control createControl(Composite parent) { + createSourceViewer(parent); + + if (isInView()){ + createViewSpecificComponents(); + createActions(); + DebugUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this); + JFaceResources.getFontRegistry().addListener(this); + } + return fSourceViewer.getControl(); + } + + private DetailJob fDetailJob = null; + public void display(IStructuredSelection selection) { + if (selection == null){ + clearSourceViewer(); + return; + } + + if (isInView()){ + fSourceViewer.setEditable(true); + } + + if (selection.isEmpty()){ + clearSourceViewer(); + return; + } + + Object firstElement = selection.getFirstElement(); + if (firstElement != null && firstElement instanceof IDebugElement) { + String modelID = ((IDebugElement)firstElement).getModelIdentifier(); + } + + synchronized (this) { + if (fDetailJob != null) { + fDetailJob.cancel(); + } + fDetailJob = new DetailJob(selection.getFirstElement()); + fDetailJob.schedule(); + } + + } + + /** + * Clears the source viewer, removes all text. + */ + protected void clearSourceViewer(){ + if (fDetailJob != null) { + fDetailJob.cancel(); + } + fDetailDocument.set(""); + fSourceViewer.setEditable(false); + } + + public void dispose() { + super.dispose(); + if (fDetailJob != null) fDetailJob.cancel(); + if (fSourceViewer != null && fSourceViewer.getControl() != null) fSourceViewer.getControl().dispose(); + + if (isInView()){ + DebugUIPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this); + JFaceResources.getFontRegistry().removeListener(this); + } + + } + public String getDescription() { + return DESCRIPTION; + } + public String getID() { + return ID; + } + public String getName() { + return NAME; + } + + public boolean setFocus() { + if (fSourceViewer != null){ + fSourceViewer.getTextWidget().setFocus(); + return true; + } + return false; + } + public Object getAdapter(Class adapter) { + if (ITextViewer.class.equals(adapter)) { + return fSourceViewer; + } + return null; + } + + public void propertyChange(PropertyChangeEvent event) { + String propertyName= event.getProperty(); + if (propertyName.equals(IInternalDebugUIConstants.DETAIL_PANE_FONT)) { + fSourceViewer.getTextWidget().setFont(JFaceResources.getFont(IInternalDebugUIConstants.DETAIL_PANE_FONT)); + } + } + + + /** + * Creates the source viewer in the given parent composite + * + * @param parent Parent composite to create the source viewer in + */ + private void createSourceViewer(Composite parent) { + + // Create & configure a SourceViewer + fSourceViewer = new SourceViewer(parent, null, SWT.V_SCROLL | SWT.H_SCROLL); + fSourceViewer.setDocument(getDetailDocument()); + fSourceViewer.getTextWidget().setFont(JFaceResources.getFont(IInternalDebugUIConstants.DETAIL_PANE_FONT)); + fSourceViewer.getTextWidget().setWordWrap(DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IDebugPreferenceConstants.PREF_DETAIL_PANE_WORD_WRAP)); + fSourceViewer.setEditable(false); + PlatformUI.getWorkbench().getHelpSystem().setHelp(fSourceViewer.getTextWidget(), IDebugHelpContextIds.DETAIL_PANE); + Control control = fSourceViewer.getControl(); + GridData gd = new GridData(GridData.FILL_BOTH); + control.setLayoutData(gd); + } + + /** + * Variables used to create the detailed information for a selection + */ + private IDocument fDetailDocument; + + /** + * Lazily instantiate and return a Document for the detail pane text viewer. + */ + protected IDocument getDetailDocument() { + if (fDetailDocument == null) { + fDetailDocument = new Document(); + } + return fDetailDocument; + } + + /** + * Creates listeners and other components that should only be added to the + * source viewer when this detail pane is inside a view. + */ + private void createViewSpecificComponents(){ + + // Add a document listener so actions get updated when the document changes + getDetailDocument().addDocumentListener(new IDocumentListener() { + public void documentAboutToBeChanged(DocumentEvent event) {} + public void documentChanged(DocumentEvent event) { + updateSelectionDependentActions(); + } + }); + + // Add the selection listener so selection dependent actions get updated. + fSourceViewer.getSelectionProvider().addSelectionChangedListener(new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent event) { + updateSelectionDependentActions(); + } + }); + + // Add a focus listener to update actions when details area gains focus + fSourceViewer.getControl().addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent e) { + + getViewSite().setSelectionProvider(fSourceViewer.getSelectionProvider()); + + setGlobalAction(IDebugView.SELECT_ALL_ACTION, getAction(DETAIL_SELECT_ALL_ACTION)); + setGlobalAction(IDebugView.COPY_ACTION, getAction(DETAIL_COPY_ACTION)); + + getViewSite().getActionBars().updateActionBars(); + } + + public void focusLost(FocusEvent e) { + + getViewSite().setSelectionProvider(null); + + setGlobalAction(IDebugView.SELECT_ALL_ACTION, null); + setGlobalAction(IDebugView.COPY_ACTION, null); + getViewSite().getActionBars().updateActionBars(); + + } + }); + + // Add a context menu to the detail area + createDetailContextMenu(fSourceViewer.getTextWidget()); + } + + /** + * Create the context menu particular to the detail pane. Note that anyone + * wishing to contribute an action to this menu must use + * ICDebugUIConstants.MODULES_VIEW_DETAIL_ID as the + * targetID in the extension XML. + */ + protected void createDetailContextMenu(Control menuControl) { + MenuManager menuMgr= new MenuManager(); + menuMgr.setRemoveAllWhenShown(true); + menuMgr.addMenuListener(new IMenuListener() { + public void menuAboutToShow(IMenuManager mgr) { + fillDetailContextMenu(mgr); + } + }); + Menu menu= menuMgr.createContextMenu(menuControl); + menuControl.setMenu(menu); + + getViewSite().registerContextMenu(ICDebugUIConstants.MODULES_VIEW_DETAIL_ID, menuMgr, fSourceViewer.getSelectionProvider()); + + } + /** + * Adds items to the detail pane's context menu including any extension defined + * actions. + * + * @param menu The menu to add the item to. + */ + protected void fillDetailContextMenu(IMenuManager menu) { + + menu.add(new Separator(ICDebugUIConstants.MODULES_GROUP)); + menu.add(new Separator()); + menu.add(getAction(DETAIL_COPY_ACTION)); + menu.add(getAction(DETAIL_SELECT_ALL_ACTION)); + menu.add(new Separator()); + menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); + + } + /** + * Creates the actions to add to the context menu + */ + private void createActions() { + TextViewerAction textAction= new TextViewerAction(fSourceViewer, ITextOperationTarget.SELECT_ALL); + textAction.configureAction(DetailMessages.DefaultDetailPane_Select__All_5, "", ""); //$NON-NLS-1$ //$NON-NLS-2$ + textAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.SELECT_ALL); + PlatformUI.getWorkbench().getHelpSystem().setHelp(textAction, IDebugHelpContextIds.DETAIL_PANE_SELECT_ALL_ACTION); + setAction(DETAIL_SELECT_ALL_ACTION, textAction); + + textAction= new TextViewerAction(fSourceViewer, ITextOperationTarget.COPY); + textAction.configureAction(DetailMessages.DefaultDetailPane__Copy_8, "", ""); //$NON-NLS-1$ //$NON-NLS-2$ + textAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.COPY); + PlatformUI.getWorkbench().getHelpSystem().setHelp(textAction, IDebugHelpContextIds.DETAIL_PANE_COPY_ACTION); + setAction(DETAIL_COPY_ACTION, textAction); + + setSelectionDependantAction(DETAIL_COPY_ACTION); + + updateSelectionDependentActions(); + } + + + /** + * Job to compute the details for a selection + */ + class DetailJob extends Job { + + private Object fElement; + // whether a result was collected + private IProgressMonitor fMonitor; + + public DetailJob(Object element) { + super("compute module details"); //$NON-NLS-1$ + setSystem(true); + fElement = element; + } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + protected IStatus run(IProgressMonitor monitor) { + fMonitor = monitor; + /* + * Make sure this is an element we want to deal with. + */ +// if ( fElement instanceof DMVMContext) { +// IModules service = null; +// IModuleDMContext dmc = null ; +// +// IModuleDMContext modDmc = DMContexts.getAncestorOfType(((DMVMContext) fElement).getDMC(), IModuleDMContext.class); +// DsfServicesTracker tracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), ((DMVMContext) fElement).getDMC().getSessionId()); +// +// if ( modDmc != null ) { +// dmc = modDmc ; +// service = tracker.getService(IModules.class); +// } +// +// /* +// * If the desired Data Model Context is null then we are not going to +// * process this data. +// */ +// if ( dmc == null ) return Status.OK_STATUS; +// +// final DataRequestMonitor modData = +// new DataRequestMonitor(service.getSession().getExecutor(), null) { +// @Override +// protected void handleOK() { +// detailComputed(getModuleDetail(getData())); +// } +// }; +// service.getModuleData(modDmc, modData); +// } + IModuleDMContext dmc = null; + if (fElement instanceof AbstractDMVMLayoutNode.DMVMContext) { + IDMContext vmcdmc = ((AbstractDMVMLayoutNode.DMVMContext)fElement).getDMC(); + dmc = DMContexts.getAncestorOfType(vmcdmc, IModuleDMContext.class); + } + + if (dmc == null) return null; + DsfSession session = DsfSession.getSession(dmc.getSessionId()); + if (session == null) return null; + + /* + * Create the query to write the value to the service. Note: no need to + * guard agains RejectedExecutionException, because + * DsfSession.getSession() above would only return an active session. + */ + GetModuleDetailsQuery query = new GetModuleDetailsQuery(dmc); + session.getExecutor().execute(query); + + /* + * Now we have the data, go and get it. Since the call is completed now + * the ".get()" will not suspend it will immediately return with the + * data. + */ + try { + detailComputed(getModuleDetail((IModuleDMData) query.get())); + } catch (InterruptedException e) { + assert false; + return null; + } catch (ExecutionException e) { + return null; + } + return Status.OK_STATUS; + } + + /** + * Set the module details in the detail pane view + * @param result + */ + private void detailComputed(final String result) { + if (!fMonitor.isCanceled()) { + WorkbenchJob setDetail = new WorkbenchJob("set details") { //$NON-NLS-1$ + @Override + public IStatus runInUIThread(IProgressMonitor monitor) { + if (!fMonitor.isCanceled()) { + getDetailDocument().set(result); + } + return Status.OK_STATUS; + } + }; + setDetail.setSystem(true); + setDetail.schedule(); + } + } + + } + + /** + * To get the details of the given module selected in Modules View + * @param module + * @return + */ + private String getModuleDetail( IModuleDMData module ) { + StringBuffer sb = new StringBuffer(); + + // Type + String type = null; +// switch( module.getType() ) { +// case ICModule.EXECUTABLE: +// type = ModulesMessages.getString( "ModulesView.1" ); //$NON-NLS-1$ +// break; +// case ICModule.SHARED_LIBRARY: +// type = ModulesMessages.getString( "ModulesView.2" ); //$NON-NLS-1$ +// break; +// } + type = ModulesMessages.getString( "ModulesView.2" ); //$NON-NLS-1$ + if ( type != null ) { + sb.append( ModulesMessages.getString( "ModulesView.3" ) ); //$NON-NLS-1$ + sb.append( type ); + sb.append( '\n' ); + } + + // Symbols flag + sb.append( ModulesMessages.getString( "ModulesView.4" ) ); //$NON-NLS-1$ + sb.append( ( module.isSymbolsLoaded()) ? ModulesMessages.getString( "ModulesView.5" ) : ModulesMessages.getString( "ModulesView.6" ) ); //$NON-NLS-1$ //$NON-NLS-2$ + sb.append( '\n' ); + + // Symbols file + sb.append( ModulesMessages.getString( "ModulesView.7" ) ); //$NON-NLS-1$ + sb.append( module.getFile()); + sb.append( '\n' ); + // Base address + String baseAddress = module.getBaseAddress(); + sb.append( ModulesMessages.getString( "ModulesView.9" ) ); //$NON-NLS-1$ + sb.append( baseAddress ); +// sb.append( baseAddress.toHexAddressString() ); + sb.append( '\n' ); +// } +// + // Size + long size = module.getSize(); + if ( size > 0 ) { + sb.append( ModulesMessages.getString( "ModulesView.10" ) ); //$NON-NLS-1$ + sb.append( size ); + sb.append( '\n' ); + } + + return sb.toString(); + } + + + public class GetModuleDetailsQuery extends Query { + + private IModuleDMContext fDmc; + + public GetModuleDetailsQuery(IModuleDMContext dmc) { + super(); + fDmc = dmc; + } + + @Override + protected void execute(final DataRequestMonitor rm) { + /* + * We're in another dispatch, so we must guard against executor + * shutdown again. + */ + final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); + if (session == null) { + cancel(false); + return; + } + + /* + * Guard against a disposed service + */ + DsfServicesTracker tracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), fDmc.getSessionId()); + IModules service = tracker.getService(IModules.class); + if (service == null) { + rm .setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + service.getModuleData(fDmc, new DataRequestMonitor( session.getExecutor(), rm) { + @Override + protected void handleCompleted() { + /* + * We're in another dispatch, so we must guard against executor shutdown again. + */ + if (!DsfSession.isSessionActive(session.getId())) { + GetModuleDetailsQuery.this.cancel(false); + return; + } + super.handleCompleted(); + } + + @Override + protected void handleOK() { + /* + * All good set return value. + */ + rm.setData(getData()); + rm.done(); + } + }); + } + } +} + diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPaneFactory.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPaneFactory.java new file mode 100644 index 00000000000..311d9c858bc --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPaneFactory.java @@ -0,0 +1,40 @@ +package org.eclipse.dd.dsf.debug.ui.viewmodel.modules; + +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.debug.ui.IDetailPane; +import org.eclipse.debug.ui.IDetailPaneFactory; +import org.eclipse.jface.viewers.IStructuredSelection; + +public class ModuleDetailPaneFactory implements IDetailPaneFactory { + public static final String MODULE_DETAIL_PANE_ID = ModuleDetailPane.ID; + public IDetailPane createDetailPane(String paneID) { + return new ModuleDetailPane(); + } + + public String getDefaultDetailPane(IStructuredSelection selection) { + return null; + } + + public String getDetailPaneDescription(String paneID) { + if (paneID.equals(ModuleDetailPane.ID)){ + return ModuleDetailPane.DESCRIPTION; + } + return null; + } + + public String getDetailPaneName(String paneID) { + if (paneID.equals(ModuleDetailPane.ID)){ + return ModuleDetailPane.NAME; + } + return null; + } + + public Set getDetailPaneTypes(IStructuredSelection selection) { + Set possibleIDs = new HashSet(1); + possibleIDs.add(ModuleDetailPane.ID); + return possibleIDs; + } + +} From b3f8c7c9dabac449ee261b7992b7ee13af2d6272 Mon Sep 17 00:00:00 2001 From: Veenu Khanna Date: Tue, 11 Dec 2007 15:27:09 +0000 Subject: [PATCH 201/834] Comments updated --- .../debug/ui/viewmodel/modules/ModuleDetailPane.java | 3 ++- .../ui/viewmodel/modules/ModuleDetailPaneFactory.java | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPane.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPane.java index 2bac45e2e28..2ce7ff77992 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPane.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPane.java @@ -8,7 +8,8 @@ * Contributors: * IBM Corporation - initial API and implementation * QNX Software Systems - Mikhail Khodjaiants - Registers View (Bug 53640) - * Wind River Systems - adopted to use with Modules view + * Wind River Systems - adopted to use with Modules view + * Ericsson AB - Modules view for DSF implementation *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.viewmodel.modules; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPaneFactory.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPaneFactory.java index 311d9c858bc..dc9c6077369 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPaneFactory.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPaneFactory.java @@ -1,3 +1,13 @@ +/******************************************************************************* + * Copyright (c) 2006, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ericsson AB - Modules view for DSF implementation + *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.viewmodel.modules; import java.util.HashSet; From 11792cc9d562cf2621a92811cd2658875adddc4f Mon Sep 17 00:00:00 2001 From: Veenu Khanna Date: Tue, 11 Dec 2007 15:27:35 +0000 Subject: [PATCH 202/834] Modules detail pane incorporated --- plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml index 41f40c788de..11007565a2e 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml +++ b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml @@ -223,6 +223,10 @@ + + From 0488406d1c8546f05451f035738c0340b1edb574 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Tue, 11 Dec 2007 19:30:59 +0000 Subject: [PATCH 203/834] FBefore setting the expression, we first check if it is a top-level expression, in which case, we use the full expression string. --- .../debug/ui/viewmodel/variable/VariableLayoutNode.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java index 1a4107a0ba2..d1c0fc135b5 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java @@ -290,7 +290,13 @@ public class VariableLayoutNode extends AbstractExpressionLayoutNode implements } else if (IDebugVMConstants.COLUMN_ID__DESCRIPTION.equals(localColumns[idx])) { update.setLabel("", idx); } else if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(localColumns[idx])) { - update.setLabel(getData().getName(), idx); + IVMContext vmc = (IVMContext)update.getElement(); + IExpression expression = (IExpression)vmc.getAdapter(IExpression.class); + if (expression != null) { + update.setLabel(expression.getExpressionText(), idx); + } else { + update.setLabel(getData().getName(), idx); + } } } From d5f269f61a2fb84597d37a87d42bf2f002010aa7 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 11 Dec 2007 19:59:57 +0000 Subject: [PATCH 204/834] [209045] Fixed a couple of compile bugs in the last checkin. --- plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF | 3 ++- .../dd/dsf/debug/ui/viewmodel/modules/ModulesLayoutNode.java | 4 +--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF index 148e9de92a5..e692605a411 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF @@ -17,7 +17,8 @@ Require-Bundle: org.eclipse.ui, org.eclipse.dd.dsf, org.eclipse.dd.dsf.ui, org.eclipse.dd.dsf.debug, - org.eclipse.cdt.core + org.eclipse.cdt.core, + org.eclipse.cdt.debug.ui Eclipse-LazyStart: true Export-Package: org.eclipse.dd.dsf.debug.ui, diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesLayoutNode.java index c162266923c..32dc582ec32 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesLayoutNode.java @@ -20,8 +20,6 @@ import org.eclipse.dd.dsf.debug.service.IModules.IModuleDMContext; import org.eclipse.dd.dsf.debug.service.IModules.IModuleDMData; import org.eclipse.dd.dsf.debug.service.IModules.ISymbolDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IGroupChangedDMEvent; -import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; -import org.eclipse.dd.dsf.debug.ui.IDsfDebugUIConstants; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; @@ -70,7 +68,7 @@ public class ModulesLayoutNode extends AbstractDMVMLayoutNode final IModuleDMContext dmc = findDmcInPath(update.getElementPath(), IModuleDMContext.class); if (!checkDmc(dmc, update) || !checkService(IModules.class, null, update)) continue; // Use different image for loaded and unloaded symbols when event to report loading of symbols is implemented. - update.setImageDescriptor(DsfDebugUIPlugin.getImageDescriptor(IDsfDebugUIConstants.IMG_OBJS_SHARED_LIBRARY_SYMBOLS_LOADED), 0); + //update.setImageDescriptor(DsfDebugUIPlugin.getImageDescriptor(IDsfDebugUIConstants.IMG_OBJS_SHARED_LIBRARY_SYMBOLS_LOADED), 0); getServicesTracker().getService(IModules.class, null).getModuleData( dmc, From ad73d6a16148b2a92cfc8c1042339f714ee23a8d Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 11 Dec 2007 20:05:07 +0000 Subject: [PATCH 205/834] [209045] Added IDsfDebugUIConstants and a reference to it. --- .../dd/dsf/debug/ui/IDsfDebugUIConstants.java | 16 ++++++++++++++++ .../ui/viewmodel/modules/ModulesLayoutNode.java | 4 +++- 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/IDsfDebugUIConstants.java diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/IDsfDebugUIConstants.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/IDsfDebugUIConstants.java new file mode 100644 index 00000000000..1eab9afc835 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/IDsfDebugUIConstants.java @@ -0,0 +1,16 @@ +package org.eclipse.dd.dsf.debug.ui; + +public interface IDsfDebugUIConstants { + + /** + * Debug UI plug-in identifier (value "org.eclipse.debug.ui"). + */ + public static final String PLUGIN_ID = "org.eclipse.dd.dsf.debug.ui"; //$NON-NLS-1$; + + /** Loaded shared library symbols image identifier. */ + public static final String IMG_OBJS_SHARED_LIBRARY_SYMBOLS_LOADED= "icons/library_syms_obj.gif"; //$NON-NLS-1$ + + /** Unloaded Shared library symbols image identifier. */ + public static final String IMG_OBJS_SHARED_LIBRARY_SYMBOLS_UNLOADED= "icons/library_obj.gif"; //$NON-NLS-1$ + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesLayoutNode.java index 32dc582ec32..c162266923c 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesLayoutNode.java @@ -20,6 +20,8 @@ import org.eclipse.dd.dsf.debug.service.IModules.IModuleDMContext; import org.eclipse.dd.dsf.debug.service.IModules.IModuleDMData; import org.eclipse.dd.dsf.debug.service.IModules.ISymbolDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IGroupChangedDMEvent; +import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.debug.ui.IDsfDebugUIConstants; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; @@ -68,7 +70,7 @@ public class ModulesLayoutNode extends AbstractDMVMLayoutNode final IModuleDMContext dmc = findDmcInPath(update.getElementPath(), IModuleDMContext.class); if (!checkDmc(dmc, update) || !checkService(IModules.class, null, update)) continue; // Use different image for loaded and unloaded symbols when event to report loading of symbols is implemented. - //update.setImageDescriptor(DsfDebugUIPlugin.getImageDescriptor(IDsfDebugUIConstants.IMG_OBJS_SHARED_LIBRARY_SYMBOLS_LOADED), 0); + update.setImageDescriptor(DsfDebugUIPlugin.getImageDescriptor(IDsfDebugUIConstants.IMG_OBJS_SHARED_LIBRARY_SYMBOLS_LOADED), 0); getServicesTracker().getService(IModules.class, null).getModuleData( dmc, From 4346cb12c7bf82d66f89893b4fa549ca471f41c0 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 12 Dec 2007 22:39:39 +0000 Subject: [PATCH 206/834] Initial revision. --- tests/SanityTest/.cproject | 933 ++++++++++++++++++++++++++++++++ tests/SanityTest/.project | 82 +++ tests/SanityTest/SanityTest.cpp | 135 +++++ 3 files changed, 1150 insertions(+) create mode 100644 tests/SanityTest/.cproject create mode 100644 tests/SanityTest/.project create mode 100644 tests/SanityTest/SanityTest.cpp diff --git a/tests/SanityTest/.cproject b/tests/SanityTest/.cproject new file mode 100644 index 00000000000..da4a10e720f --- /dev/null +++ b/tests/SanityTest/.cproject @@ -0,0 +1,933 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/SanityTest/.project b/tests/SanityTest/.project new file mode 100644 index 00000000000..df72c78c2ab --- /dev/null +++ b/tests/SanityTest/.project @@ -0,0 +1,82 @@ + + + SanityTest + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + ?name? + + + + org.eclipse.cdt.make.core.append_environment + true + + + org.eclipse.cdt.make.core.autoBuildTarget + all + + + org.eclipse.cdt.make.core.buildArguments + + + + org.eclipse.cdt.make.core.buildCommand + make + + + org.eclipse.cdt.make.core.buildLocation + ${workspace_loc:/SanityTest/Debug} + + + org.eclipse.cdt.make.core.cleanBuildTarget + clean + + + org.eclipse.cdt.make.core.contents + org.eclipse.cdt.make.core.activeConfigSettings + + + org.eclipse.cdt.make.core.enableAutoBuild + false + + + org.eclipse.cdt.make.core.enableCleanBuild + true + + + org.eclipse.cdt.make.core.enableFullBuild + true + + + org.eclipse.cdt.make.core.fullBuildTarget + all + + + org.eclipse.cdt.make.core.stopOnError + true + + + org.eclipse.cdt.make.core.useDefaultBuildCmd + true + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.core.ccnature + + diff --git a/tests/SanityTest/SanityTest.cpp b/tests/SanityTest/SanityTest.cpp new file mode 100644 index 00000000000..df1c81aa3e4 --- /dev/null +++ b/tests/SanityTest/SanityTest.cpp @@ -0,0 +1,135 @@ +//============================================================================ +// Name : HelloCDT.cpp +// Author : Francois Chouinard +// Version : +// Copyright : Ericsson Research Canada +// Description : Hello World in C++, Ansi-style +//============================================================================ + +#include +#include +using namespace std; + +int i = 0; +char c = 'a'; +char* s = "abcdef"; + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +void print_values(char* ptr) +{ + char* header = ptr; + printf("%s\n", header); + printf("&i = 0x%x, i = %d\n", (int) &i, ++i); + printf("&c = 0x%x, c = %c\n", (int) &c, c++); + printf("&s = 0x%x, s = %s\n\n", (int) &s, s); +} + +void *thread_print(void *ptr) +{ + char* cptr = (char *) ptr; + print_values(cptr); + return NULL; +} + +void test_threads(void) +{ + pthread_t thread1, thread2; + char *message1 = "Thread 2"; + char *message2 = "Thread 3"; + int iret1, iret2; + + // Create independent threads each of which will execute function + iret1 = pthread_create( &thread1, NULL, thread_print, (void*) message1); + iret2 = pthread_create( &thread2, NULL, thread_print, (void*) message2); + + /* Wait till threads are complete before main continues. Unless we */ + /* wait we run the risk of executing an exit which will terminate */ + /* the process and all threads before the threads have completed. */ + + pthread_join(thread1, NULL); + printf("Thread 1 returns: %d\n", iret1); + + pthread_join(thread2, NULL); + printf("Thread 2 returns: %d\n", iret2); +} + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +void test_stack2(int* k) +{ + bool j = true; + int* l = k; + *k += 10; + + // Modifying memory updates the monitors + // but not the Variables view :-( + printf("%d\n", *k); +} + +void test_stack(void) +{ + // Add a memory monitor for 'j' + int j = 5; + // Step into + test_stack2(&j); +} + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +void countdown(int m) +{ + int x = m; + if (x == 0) { + printf("We have a lift-off!\n"); + return; + } + printf("%d, ", x); + countdown(--x); +} + +void test_recursion(void) +{ + // Add a monitor on l + int l = 3; + countdown(l); +} + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +void test_overlap2(void) +{ + int a = 2; +} + +void test_overlap3(void) +{ + int b = 3; +} + +void test_overlap(void) +{ + test_overlap2(); + test_overlap3(); +} + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + // If we don't step this instruction then the initial content of cptr will + // be cached and the Variables view will display the wrong value. + char* cptr = "Thread 1"; + + // char* interpreted as C-string in Variables view + char* cp = (char*) malloc(1); + *cp = 'a'; + + test_stack(); + test_threads(); + test_recursion(); + test_overlap(); + + return 0; +} From 0f9a2839a8b4918ddd282078bc421f97ca6ac39c Mon Sep 17 00:00:00 2001 From: Francois Chouinard Date: Sat, 15 Dec 2007 14:04:31 +0000 Subject: [PATCH 207/834] *** empty log message *** --- .../dd/dsf/debug/service/IBreakpoints.java | 120 ++++++++++++------ .../dd/dsf/datamodel/AbstractDMContext.java | 3 + 2 files changed, 82 insertions(+), 41 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java index a4f7639e608..759d44d1537 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java @@ -13,9 +13,12 @@ package org.eclipse.dd.dsf.debug.service; import java.util.Map; +import org.eclipse.cdt.core.IAddress; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.datamodel.IDMEvent; import org.eclipse.dd.dsf.service.IDsfService; /** @@ -23,55 +26,90 @@ import org.eclipse.dd.dsf.service.IDsfService; */ public interface IBreakpoints extends IDsfService { + /** + * Breakpoint attributes markers used in the map parameters of insert/updateBreakpoint(). + * All are optional with the possible exception of TYPE. It is the responsibility of the + * service to ensure that the set of attributes provided is sufficient to create/update + * a valid breakpoint on the back-end. + */ + // General markers + public static final String DSFBREAKPOINT = "org.eclipse.dd.dsf.debug.breakpoint"; //$NON-NLS-1$ + public static final String BREAKPOINT_TYPE = DSFBREAKPOINT + ".type"; //$NON-NLS-1$ + public static final String BREAKPOINT = "breakpoint"; //$NON-NLS-1$ + public static final String WATCHPOINT = "watchpoint"; //$NON-NLS-1$ + public static final String CATCHPOINT = "catchpoint"; //$NON-NLS-1$ + + // Basic set of breakpoint attribute markers + public static final String FILE_NAME = DSFBREAKPOINT + ".fileName"; //$NON-NLS-1$ + public static final String LINE_NUMBER = DSFBREAKPOINT + ".lineNumber"; //$NON-NLS-1$ + public static final String FUNCTION = DSFBREAKPOINT + ".function"; //$NON-NLS-1$ + public static final String ADDRESS = DSFBREAKPOINT + ".address"; //$NON-NLS-1$ + public static final String CONDITION = DSFBREAKPOINT + ".condition"; //$NON-NLS-1$ + public static final String IGNORE_COUNT = DSFBREAKPOINT + ".ignoreCount"; //$NON-NLS-1$ + public static final String IS_ENABLED = DSFBREAKPOINT + ".isEnabled"; //$NON-NLS-1$ + + // Basic set of watchpoint attribute markers + public static final String EXPRESSION = DSFBREAKPOINT + ".expression"; //$NON-NLS-1$ + public static final String READ = DSFBREAKPOINT + ".read"; //$NON-NLS-1$ + public static final String WRITE = DSFBREAKPOINT + ".write"; //$NON-NLS-1$ + /** * Marker interface for a context for which breakpoints can be installed */ - public interface IBreakpointsTargetDMContext extends IDMContext {}; + public interface IBreakpointsTargetDMContext extends IDMContext {} /** * Specific breakpoint context */ - public interface IDsfBreakpointDMContext extends IDMContext { + @Immutable + public interface IBreakpointDMContext extends IDMContext { - // Get the execution context - IBreakpointsTargetDMContext getTargetContext(); - - // Get the breakpoint reference - Object getReference(); - }; + public IBreakpointsTargetDMContext getTargetContext(); + } /** - * Breakpoint structure + * Breakpoint events + */ + public interface IBreakpointsChangedEvent extends IDMEvent {} + + public interface IBreakpointAddedEvent extends IBreakpointsChangedEvent { + public IBreakpointDMContext getAddedBreakpoint(); + } + + public interface IBreakpointUpdatedEvent extends IBreakpointsChangedEvent { + public IBreakpointDMContext getUpdatedBreakpoint(); + } + + public interface IBreakpointRemovedEvent extends IBreakpointsChangedEvent { + public IBreakpointDMContext getRemovedBreakpoint(); + } + + /** + * Effective breakpoint data as held by the back-end. */ - public interface IDsfBreakpoint { + public interface IBreakpointDMData { - // Breakpoint types - public static enum IDsfBreakpointNature { BREAKPOINT, WATCHPOINT, CATCHPOINT, TRACEPOINT }; - - // Retrieve the breakpoint nature - public IDsfBreakpointNature getNature(); - - // Retrieve the breakpoint set of properties - public Map getProperties(); - - // Retrieve a single breakpoint property - public Object getProperty(String key, Object defaultValue); - - // Update a single breakpoint property - public void setProperty(String key, Object value); - }; + public String getBreakpointType(); + public String getFileName(); + public int getLineNumber(); + public String getFunctionName(); + public IAddress[] getAddresses(); + public String getCondition(); + public int getIgnoreCount(); + public boolean isEnabled(); + public String getExpression(); + } /** - * Refreshes the list of breakpoints from the [context] and returns the list - * of references. + * Retrieves the list of breakpoints installed in the context. * - * Use getBreakpoint() to retrieve individual breakpoints. + * Use getBreakpointDMData() to retrieve individual breakpoints. * * @param context the execution context of the breakpoint * @param drm the list of breakpoints in the execution context */ public void getBreakpoints(IBreakpointsTargetDMContext context, - DataRequestMonitor drm); + DataRequestMonitor drm); /** * Retrieves a specific breakpoint from the service. @@ -79,29 +117,29 @@ public interface IBreakpoints extends IDsfService { * @param dmc the breakpoint reference * @param drm the DRM returning the breakpoint data */ - public void getBreakpointDMData(IDsfBreakpointDMContext dmc, - DataRequestMonitor drm); + public void getBreakpointDMData(IBreakpointDMContext dmc, + DataRequestMonitor drm); /** * Adds a breakpoint on the target. * - * The breakpoint reference is returned in the DRM. The actual breakpoint - * object can be later be retrieved using getBreakpoint(reference). + * The breakpoint context is returned in the DRM. The actual breakpoint + * object can be later be retrieved using getBreakpoint(bp_context). * * E.g.: - * IDsfBreakpointDMContext ref = addBreakpoint(...); - * IDsfBreakpoint bp = getBreakpoint(ref); + * IBreakpointDMContext ref = insertBreakpoint(...); + * IBreakpointDMData bp = getBreakpointDMData(ref); * * If the breakpoint is a duplicate (already set previously), then it is up to * the back-end to decide if it is an error or not. * * @param context the execution context of the breakpoint - * @param breakpoint the breakpoint + * @param attributes the breakpoint attributes * @param drm the DRM returning the breakpoint reference */ public void insertBreakpoint(IBreakpointsTargetDMContext context, - IDsfBreakpoint breakpoint, - DataRequestMonitor drm); + Map attributes, + DataRequestMonitor drm); /** * Removes the breakpoint on the target. @@ -111,7 +149,7 @@ public interface IBreakpoints extends IDsfService { * @param dmc the context of the breakpoints to remove * @param rm the asynchronous request monitor */ - public void removeBreakpoint(IDsfBreakpointDMContext dmc, + public void removeBreakpoint(IBreakpointDMContext dmc, RequestMonitor rm); /** @@ -125,13 +163,13 @@ public interface IBreakpoints extends IDsfService { * removed then re-inserted. * * A null value is used for removal of a property e.g.: - * properties.set(some_key, null); + * delta.set(some_key, null); * * @param delta the delta properties * @param dmc the context of the breakpoints to modify * @param rm the asynchronous request monitor */ - public void updateBreakpoint(IDsfBreakpointDMContext dmc, + public void updateBreakpoint(IBreakpointDMContext dmc, Map delta, RequestMonitor drm); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMContext.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMContext.java index 0011c938968..835e2bce30c 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMContext.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/AbstractDMContext.java @@ -43,6 +43,9 @@ abstract public class AbstractDMContext extends PlatformObject public AbstractDMContext(String sessionId, IDMContext[] parents) { fSessionId = sessionId; fParents = parents; + for (IDMContext parent : parents) { + assert(parent != null); + } } /** Convenience constructor */ From 210443c47a7585186481d0766d407b7d6f32a3b0 Mon Sep 17 00:00:00 2001 From: Francois Chouinard Date: Tue, 18 Dec 2007 19:15:09 +0000 Subject: [PATCH 208/834] Removed an extraneous back-end call to resolve the memory address. --- .../debug/model/DsfMemoryBlockRetrieval.java | 41 ++++++++----------- 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java index c0b5fbb163b..345c8734d6a 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java @@ -30,7 +30,6 @@ import org.eclipse.dd.dsf.debug.service.IExpressions; import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.dd.dsf.debug.service.IMemory; import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; -import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMData; import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext; import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData; import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryDMContext; @@ -293,7 +292,7 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl private BigInteger resolveMemoryAddress(final IDMContext idmContext, final String expression) throws DebugException { - // Use a Query to "synchronise" the downstream calls + // Use a Query to "synchronize" the downstream calls Query query = new Query() { @Override protected void execute(final DataRequestMonitor drm) { @@ -302,32 +301,26 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl if (expressionService != null) { // Create the expression final IExpressionDMContext expressionDMC = expressionService.createExpression(idmContext, expression); - expressionService.getExpressionData(expressionDMC, new DataRequestMonitor(getExecutor(), drm) { - @Override - protected void handleOK() { - // Evaluate the expression - request HEX since it works in every case - String formatId = IFormattedValues.HEX_FORMAT; - FormattedValueDMContext valueDmc = expressionService.getFormattedValueContext(expressionDMC, formatId); - expressionService.getFormattedExpressionValue( - valueDmc, - new DataRequestMonitor(getExecutor(), drm) { - @Override - protected void handleOK() { - // Store the result - FormattedValueDMData data = getData(); - String value = data.getFormattedValue().substring(2); // Strip the "0x" - drm.setData(new BigInteger(value, 16)); - drm.done(); - } - } - ); - } - }); + String formatId = IFormattedValues.HEX_FORMAT; + FormattedValueDMContext valueDmc = expressionService.getFormattedValueContext(expressionDMC, formatId); + expressionService.getFormattedExpressionValue( + valueDmc, + new DataRequestMonitor(getExecutor(), drm) { + @Override + protected void handleOK() { + // Store the result + FormattedValueDMData data = getData(); + String value = data.getFormattedValue().substring(2); // Strip the "0x" + drm.setData(new BigInteger(value, 16)); + drm.done(); + } + } + ); } - } }; fExecutor.execute(query); + try { // The happy case return query.get(); From a9ca46d10061b15f8ac973f20fdd287083935896 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 19 Dec 2007 19:45:04 +0000 Subject: [PATCH 209/834] [212938] Fix for NPE as a result of a detail pane job returning null status. --- .../dsf/debug/ui/viewmodel/modules/ModuleDetailPane.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPane.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPane.java index 2ce7ff77992..ce0a8a91172 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPane.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPane.java @@ -394,9 +394,9 @@ public class ModuleDetailPane extends AbstractDetailPane implements IAdaptable, dmc = DMContexts.getAncestorOfType(vmcdmc, IModuleDMContext.class); } - if (dmc == null) return null; + if (dmc == null) return Status.OK_STATUS; DsfSession session = DsfSession.getSession(dmc.getSessionId()); - if (session == null) return null; + if (session == null) return Status.OK_STATUS; /* * Create the query to write the value to the service. Note: no need to @@ -415,9 +415,9 @@ public class ModuleDetailPane extends AbstractDetailPane implements IAdaptable, detailComputed(getModuleDetail((IModuleDMData) query.get())); } catch (InterruptedException e) { assert false; - return null; + return Status.OK_STATUS; } catch (ExecutionException e) { - return null; + return Status.OK_STATUS; } return Status.OK_STATUS; } From 2b3d31bb3155513f069cefdc95f5ac85955ba747 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 19 Dec 2007 23:53:11 +0000 Subject: [PATCH 210/834] [204587][204588] Added the IElementPropertiesProvider and PropertyBasedLabelProvider. --- .../META-INF/MANIFEST.MF | 1 + .../IElementPropertiesProvider.java | 27 ++ .../ILabelAttributeChangedListener.java | 19 ++ .../properties/IPropertiesUpdate.java | 21 ++ .../viewmodel/properties/LabelAttribute.java | 109 +++++++ .../ui/viewmodel/properties/LabelColor.java | 71 +++++ .../viewmodel/properties/LabelColumnInfo.java | 158 +++++++++++ .../ui/viewmodel/properties/LabelFont.java | 57 ++++ .../ui/viewmodel/properties/LabelImage.java | 53 ++++ .../ui/viewmodel/properties/LabelText.java | 86 ++++++ .../PropertyBasedLabelProvider.java | 265 ++++++++++++++++++ 11 files changed, 867 insertions(+) create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/IElementPropertiesProvider.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/ILabelAttributeChangedListener.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/IPropertiesUpdate.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelAttribute.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelColor.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelColumnInfo.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelFont.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelImage.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelText.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/PropertyBasedLabelProvider.java diff --git a/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF index 6cc41f28e37..2ffed4637d8 100644 --- a/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF @@ -14,6 +14,7 @@ Eclipse-LazyStart: true Export-Package: org.eclipse.dd.dsf.ui.concurrent, org.eclipse.dd.dsf.ui.viewmodel, org.eclipse.dd.dsf.ui.viewmodel.dm, + org.eclipse.dd.dsf.ui.viewmodel.properties, org.eclipse.dd.dsf.ui.viewmodel.update, org.eclipse.dd.dsf.ui.viewmodel.update.actions Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/IElementPropertiesProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/IElementPropertiesProvider.java new file mode 100644 index 00000000000..139bd3408cd --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/IElementPropertiesProvider.java @@ -0,0 +1,27 @@ +package org.eclipse.dd.dsf.ui.viewmodel.properties; + + +/** + * Provides context-sensitive properties. Can be registered as an adapter for + * an element or implemented directly + */ +public interface IElementPropertiesProvider { + + /** + * Updates the specified property sets. + * + * @param updates each update specifies the element and context for which + * a set of properties is requested and stores them + */ + public void update(IPropertiesUpdate[] updates); + + /** + * Returns a user-presentable name for the given property. + */ + public String getPropertyName(String property); + + /** + * Returns a description for the given property. + */ + public String getPropertyDescription(String property); +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/ILabelAttributeChangedListener.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/ILabelAttributeChangedListener.java new file mode 100644 index 00000000000..6f60b2c33d0 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/ILabelAttributeChangedListener.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel.properties; + +/** + * + */ +public interface ILabelAttributeChangedListener { + + public void attributesChanged(); +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/IPropertiesUpdate.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/IPropertiesUpdate.java new file mode 100644 index 00000000000..c81586edba4 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/IPropertiesUpdate.java @@ -0,0 +1,21 @@ +package org.eclipse.dd.dsf.ui.viewmodel.properties; + +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; + +/** + * Context sensitive properties update request for an element. + */ +public interface IPropertiesUpdate extends IViewerUpdate { + /** + * Returns the list of element properties that the provider should set. + * If null, all available properties should be set. + */ + public String[] getProperties(); + + /** + * Sets the given property to update. + * @param property Property ID. + * @param value Property value. + */ + public void setProperty(String property, Object value); +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelAttribute.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelAttribute.java new file mode 100644 index 00000000000..e615c0ce5f4 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelAttribute.java @@ -0,0 +1,109 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel.properties; + +import java.util.Map; + +import org.eclipse.core.runtime.ListenerList; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; + +/** + * This is a base class for a label attribute used in generating label + * information based on properties of an element. There are currently + * four types of attributes: text, image, font, and color, and a given + * attribute can be either enabled or disabled based on the element + * properties. + *

    + * Clients are intended to override this class and its extensions to + * implement the {@link LabelAttribute#isEnabled(Map)} and + * {@link LabelAttribute#getPropertyNames()} methods as needed. Clients can + * also override how the attribute settings are stored, for example in + * order to use a preference. + * + * @see PropertyBasedLabelProvider + * @see LabelColumnInfo + */ +@SuppressWarnings("restriction") +abstract public class LabelAttribute { + public static final String[] EMPTY_PROPERTY_NAMES_ARRAY = new String[0]; + + /** + * Listeners for when this attribute is modified. + */ + private ListenerList fListeners = new ListenerList(); + + public LabelAttribute() { + } + + /** + * Disposes this attribute. + */ + public void dispose() { + } + + /** + * Registers the given listener for changes in this attribute. A change in + * the attributes of a label should cause a view to repaint. + * @param listener Listener to register. + */ + public void addChangedListener(ILabelAttributeChangedListener listener) { + fListeners.add(listener); + } + + /** + * Unregisters the given listener. + * @param listener Listener to unregister. + */ + public void removeChangedListener(ILabelAttributeChangedListener listener) { + fListeners.remove(listener); + } + + /** + * Calls the listeners to notify them that this attribute has changed. + */ + protected void fireAttributeChanged() { + Object[] listeners = fListeners.getListeners(); + for (Object listener : listeners) { + ((ILabelAttributeChangedListener)listener).attributesChanged(); + } + } + + /** + * Returns the propertis that are needed by this attribute in order to + * determine whether this attribute is enabled and/or for the actual + * attribute itself. + * @return Array of names of properties for the element properties provider. + */ + public String[] getPropertyNames() { + return EMPTY_PROPERTY_NAMES_ARRAY; + } + + /** + * Returns whether this attribute is enabled for an element which has + * the given properties. + * @param properties Map or element properties. The client should ensure + * that all properties specified by {@link #getPropertyNames()} are + * supplied in this map. + * @return true if this attribute is enabled. + */ + public boolean isEnabled(Map properties) { + return true; + } + + /** + * Updates the label with this attribute. + * + * @param update Label update object to write to. + * @param columnIndex Colum index to write at. + * @param properties Element properties to use. + */ + abstract public void updateAttribute(ILabelUpdate update, int columnIndex, Map properties); +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelColor.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelColor.java new file mode 100644 index 00000000000..a4582b17f41 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelColor.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel.properties; + +import java.util.Map; + +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.swt.graphics.RGB; + +/** + * The color attribute of a label. It determines what foreground and + * background color to use for the given label. + * + * @see LabelAttribute + * @see LabelColumnInfo + * @see PropertyBasedLabelProvider + */ + +@SuppressWarnings("restriction") +public class LabelColor extends LabelAttribute { + private RGB fForeground; + private RGB fBackground; + + public LabelColor() { + this(null, null); + } + + public LabelColor(RGB foreground, RGB background) { + fForeground = foreground; + fBackground = background; + } + + public RGB getForeground() { + return fForeground; + } + + public RGB getBackground() { + return fBackground; + } + + public void setForeground(RGB foreground) { + fForeground = foreground; + fireAttributeChanged(); + } + + public void setBackground(RGB background) { + fBackground = background; + fireAttributeChanged(); + } + + @Override + public void updateAttribute(ILabelUpdate update, int columnIndex, Map properties) { + RGB foreground = getForeground(); + if (foreground != null) { + update.setForeground(foreground, columnIndex); + } + + RGB background = getBackground(); + if (background != null) { + update.setBackground(background, columnIndex); + } + } +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelColumnInfo.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelColumnInfo.java new file mode 100644 index 00000000000..c22d5e5a6ee --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelColumnInfo.java @@ -0,0 +1,158 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel.properties; + +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.ListenerList; +import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; + +/** + * Class used by the PropertyBasedLabelProvider to generate store + * label attributes related to a single column. Each column info is + * configured with an array of attributes (there are currently four + * types of attributes: text, image, font, and color), which are + * evaluated in order to generate the label. + *

    + * Clients are not intended to extend this class. + * + * @see PropertyBasedLabelProvider + */ +@SuppressWarnings("restriction") +@ThreadSafe +public class LabelColumnInfo implements ILabelAttributeChangedListener { + + private static final LabelAttribute[] EMPTY_ATTRIBUTES_ARRAY = new LabelAttribute[0]; + + /** + * Calculated list of property names that need to be retrieved to + * generate the label for this column. + */ + private String[] fPropertyNames; + + /** + * Array of label attribute objects. + */ + private LabelAttribute[] fLabelAttributes; + + /** + * Listeners for when column attributes are modified. + */ + private ListenerList fListeners = new ListenerList(); + + /** + * Creates the column info object with given array of attributes. + * @param attributeInfos Attributes for the label. + */ + public LabelColumnInfo(LabelAttribute[] attributes) + { + fLabelAttributes = attributes; + + List names = new LinkedList(); + for (LabelAttribute attr : attributes) { + attr.addChangedListener(this); + for (String name : attr.getPropertyNames()) { + names.add(name); + } + } + + fPropertyNames = names.toArray(new String[names.size()]); + } + + /** + * Disposes this column info object and the attribute objects + * within it. + */ + public void dispose() { + for (LabelAttribute attr : fLabelAttributes) { + attr.dispose(); + attr.removeChangedListener(this); + } + fLabelAttributes = EMPTY_ATTRIBUTES_ARRAY; + fPropertyNames = null; + } + + /** + * Returns the property names that need to be retrieved in order + * to generate the label for this column. + */ + public String[] getPropertyNames() { return fPropertyNames; } + + /** + * Returns the list of configured label attributes for this column. + */ + public LabelAttribute[] getLabelAttributes() { return fLabelAttributes; } + + /** + * Registers the given listener for changes in the attributes of this + * column. A change in the attributes of a label should cause + * a view to repaint. + * @param listener Listener to register. + */ + public void addChangedListener(ILabelAttributeChangedListener listener) { + fListeners.add(listener); + } + + /** + * Unregisters the given listener. + * @param listener Listener to unregister. + */ + public void removeChangedListener(ILabelAttributeChangedListener listener) { + fListeners.remove(listener); + } + + /** + * Listener method called by the attribute objects. + * @see ILabelAttributeChangedListener + */ + public void attributesChanged() { + Object[] listeners = fListeners.getListeners(); + for (Object listener : listeners) { + ((ILabelAttributeChangedListener)listener).attributesChanged(); + } + } + + /** + * Updates the label parameters for this column based on the provided + * properties. The label information is written to the givne label + * update under the given column index. + * @param update Update to write to. + * @param columnIndex Column to write label information under. + * @param properties Map of properties to use to generate the label. + */ + public void updateColumn(ILabelUpdate update, int columnIndex, Map properties) { + boolean textSet = false; + boolean imageSet = false; + boolean fontSet = false; + boolean colorSet = false; + + LabelAttribute[] labelAttributes = getLabelAttributes(); + for (LabelAttribute info : labelAttributes) { + + if (!(info instanceof LabelText && textSet) && + !(info instanceof LabelImage && imageSet) && + !(info instanceof LabelFont && fontSet) && + !(info instanceof LabelColor && colorSet) && + info.isEnabled(properties)) + { + info.updateAttribute(update, columnIndex, properties); + + textSet = textSet || info instanceof LabelText; + imageSet = imageSet || info instanceof LabelImage; + fontSet = fontSet || info instanceof LabelFont; + colorSet = colorSet || info instanceof LabelColor; + } + } + } +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelFont.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelFont.java new file mode 100644 index 00000000000..303a6f48fda --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelFont.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel.properties; + +import java.util.Map; + +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.swt.graphics.FontData; + +/** + * The font attribute of a label. + * + * @see LabelAttribute + * @see LabelColumnInfo + * @see PropertyBasedLabelProvider + */ +@SuppressWarnings("restriction") +public class LabelFont extends LabelAttribute { + private static final FontData DEFAULT_FONT = JFaceResources.getDefaultFontDescriptor().getFontData()[0]; + + /** + * The font data of this attribute. + */ + private FontData fFontData; + + public LabelFont() { + this(DEFAULT_FONT); + } + + public LabelFont(FontData fontData) { + fFontData = fontData; + } + + public FontData getFontData() { + return fFontData; + } + + public void setFontData(FontData fontData) { + fFontData = fontData; + fireAttributeChanged(); + } + + @Override + public void updateAttribute(ILabelUpdate update, int columnIndex, Map properties) { + update.setFontData(getFontData(), columnIndex); + } + +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelImage.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelImage.java new file mode 100644 index 00000000000..143ad406582 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelImage.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel.properties; + +import java.util.Map; + +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.jface.resource.ImageDescriptor; + +/** + * The image attribute of a label. + * + * @see LabelAttribute + * @see LabelColumnInfo + * @see PropertyBasedLabelProvider + */ +@SuppressWarnings("restriction") +public class LabelImage extends LabelAttribute { + private ImageDescriptor fImageDescriptor; + + public LabelImage() { + this(null); + } + + public LabelImage(ImageDescriptor image) { + fImageDescriptor = image; + } + + public ImageDescriptor getImageDescriptor() { + return fImageDescriptor; + } + + public void setImageDescriptor(ImageDescriptor image) { + fImageDescriptor = image; + fireAttributeChanged(); + } + + @Override + public void updateAttribute(ILabelUpdate update, int columnIndex, Map properties) { + ImageDescriptor descriptor = getImageDescriptor(); + if (descriptor != null) { + update.setImageDescriptor(descriptor, columnIndex); + } + } +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelText.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelText.java new file mode 100644 index 00000000000..298eec8d851 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelText.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel.properties; + +import java.text.MessageFormat; +import java.util.Map; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.ui.DsfUIPlugin; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; + +/** + * The text attribute of a label. It uses a message format string in order to + * compose the text string. The parameter names determine the array of objects + * given to the message format. + * + * @see MessageFormat#format(Object[], StringBuffer, java.text.FieldPosition) + * @see LabelAttribute + * @see LabelColumnInfo + * @see PropertyBasedLabelProvider + */ +@SuppressWarnings("restriction") +public class LabelText extends LabelAttribute { + + public static final MessageFormat DEFAULT_MESSAGE = new MessageFormat(""); + + /** + * Message format used to generate the label text. + * + */ + private MessageFormat fMessageFormat; + + /** + * The property names needed for the message format. The property values + * corresponding to these names are given the the {@link MessageFormat#format(Object[], StringBuffer, java.text.FieldPosition)} + * method. + */ + private String[] fPropertyNames; + + public LabelText() { + this(DEFAULT_MESSAGE, EMPTY_PROPERTY_NAMES_ARRAY); + } + + public LabelText(MessageFormat format, String[] propertyNames) { + fMessageFormat = format; + fPropertyNames = propertyNames; + } + + @Override + public String[] getPropertyNames() { + return fPropertyNames; + } + + public MessageFormat getMessageFormat() { + return fMessageFormat; + } + + public void setMessageFormat(MessageFormat messageFormat) { + fMessageFormat = messageFormat; + fireAttributeChanged(); + } + + @Override + public void updateAttribute(ILabelUpdate update, int columnIndex, Map properties) { + String[] propertyNames = getPropertyNames(); + Object[] propertyValues = new Object[propertyNames.length]; + for (int i = 0; i < propertyNames.length; i++) { + propertyValues[i] = properties.get(propertyNames[i]); + } + + try { + update.setLabel(getMessageFormat().format(propertyValues, new StringBuffer(), null).toString(), columnIndex); + } catch (IllegalArgumentException e) { + update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, 0, "Failed formatting a message for column " + columnIndex + ", for update " + update, e)); //$NON-NLS-1$ //$NON-NLS-2$ + } + } +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/PropertyBasedLabelProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/PropertyBasedLabelProvider.java new file mode 100644 index 00000000000..f13ccd36c18 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/PropertyBasedLabelProvider.java @@ -0,0 +1,265 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel.properties; + +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.ListenerList; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; +import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.dsf.ui.DsfUIPlugin; +import org.eclipse.dd.dsf.ui.viewmodel.VMViewerUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; + +/** + * A configurable label provider which uses element's property label provider + * to set element's label attributes. + *

    + * When this provider is registered for an element it calculates the properties + * that need to be retrieved based on view's active columns, and then it calls the + * element's property provider to retrieve those properties. After the property + * values are retrieved, they are processed in order to produce correct label text, + * images, fonts, and colors, for the given element. + */ +@SuppressWarnings("restriction") +@ThreadSafe +public class PropertyBasedLabelProvider + implements IElementLabelProvider, ILabelAttributeChangedListener +{ + private static final String[] EMPTY_PROPERTY_NAMES_ARRAY = new String[0]; + + /** + * Properties update used as to collect property data from the provider. + */ + private class PropertiesUpdate extends VMViewerUpdate implements IPropertiesUpdate { + + private final String[] fProperties; + private final Map fValues; + + public PropertiesUpdate(String[] properties, ILabelUpdate labelUpdate, DataRequestMonitor> rm) { + super(labelUpdate, rm); + fProperties = properties; + fValues = fProperties != null + ? new HashMap(properties.length * 4 / 3, 0.75f) + : new HashMap(); + } + + public String[] getProperties() { + return fProperties; + } + + public void setProperty(String property, Object value) { + fValues.put(property, value); + } + + /** + * Overrides the standard done in order to store the retrieved values + * in the client's request monitor. + */ + @Override + public void done() { + @SuppressWarnings("unchecked") + DataRequestMonitor> rm = (DataRequestMonitor>)fRequestMonitor; + if (fProperties == null || fValues.size() >= fProperties.length) { + rm.setData(fValues); + } else { + rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, "Incomplete properties updated", null)); //$NON-NLS-1$ + } + super.done(); + } + } + + /** + * Attribute information for each column by column ID. + */ + private Map fColumnInfos = Collections.synchronizedMap(new HashMap()); + + private ListenerList fListeners = new ListenerList(); + + /** + * Standard constructor. A property based label constructor does not + * initialize column attribute information {@link #setColumnInfo(String, LabelColumnInfo)} + * must be called to configure each column. + */ + public PropertyBasedLabelProvider() { + } + + /** + * Disposes this label provider and its configured column info objects. + */ + public void dispose() { + LabelColumnInfo[] infos = null; + synchronized (fColumnInfos) { + infos = fColumnInfos.values().toArray(new LabelColumnInfo[fColumnInfos.size()]); + fColumnInfos.clear(); + } + for (LabelColumnInfo info : infos) { + info.dispose(); + } + } + + /** + * Sets the given column info object for the given column ID. This column + * info will be used to generate the label when the given column is visibile. + * @param columnId Column ID that the given column info is being registered for. + * @param info Column 'info' object containing column attributes. + * @return The previous column info object configured for this ID. + */ + public LabelColumnInfo setColumnInfo(String columnId, LabelColumnInfo info) { + LabelColumnInfo oldInfo = fColumnInfos.put(columnId, info); + info.addChangedListener(this); + if (oldInfo != null) { + info.removeChangedListener(this); + } + return oldInfo; + } + + /** + * Returns the given column info object for the given column ID. + * @param columnId Column ID to retrieve the column info for. + * @@return Column 'info' object containing column attributes. + */ + public LabelColumnInfo getColumnInfo(String column) { + return fColumnInfos.get(column); + } + + /** + * Registers the given listener for changes in the attributes of this + * label provider. A change in the attributes of a label should cause + * a view to repaint. + * @param listener Listener to register. + */ + public void addChangedListener(ILabelAttributeChangedListener listener) { + fListeners.add(listener); + } + + /** + * Unregisters the given listener. + * @param listener Listener to unregister. + */ + public void removeChangedListener(ILabelAttributeChangedListener listener) { + fListeners.remove(listener); + } + + /** + * Listener method called by label provider's column info objects. + * @see ILabelAttributeChangedListener + */ + public void attributesChanged() { + Object[] listeners = fListeners.getListeners(); + for (Object listener : listeners) { + ((ILabelAttributeChangedListener)listener).attributesChanged(); + } + } + + public void update(ILabelUpdate[] labelUpdates) { + IElementPropertiesProvider propertiesProvider = getElementPropertiesProvider(labelUpdates[0].getElement()); + if (propertiesProvider == null) { + for (ILabelUpdate update : labelUpdates) { + update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, "Properties-based label provider " + this + " failed to generate a label, no properties provider registered for element: " + labelUpdates[0].getElement())); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + + String[] columnIds = labelUpdates[0].getColumnIds(); + String[] propertyNames = calcPropertyNamesForColumns(columnIds); + + // Call the properties provider. Create a request monitor for each label update. + // We can use an immediate executor for the request monitor because the label provider + // is thread safe. + IPropertiesUpdate[] propertiesUpdates = new IPropertiesUpdate[labelUpdates.length]; + for (int i = 0; i < labelUpdates.length; i++) { + final ILabelUpdate labelUpdate = labelUpdates[i]; + propertiesUpdates[i] = new PropertiesUpdate( + propertyNames, labelUpdates[i], + new DataRequestMonitor>(ImmediateExecutor.getInstance(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + updateLabel(labelUpdate, getData()); + } + labelUpdate.done(); + } + }); + } + propertiesProvider.update(propertiesUpdates); + } + + /** + * Calculates the names of properties that have to be retrieved from the property + * provider to generate the labels for given columns. + * @param columnIds Column IDs to check. + * @return Array of property names. + */ + private String[] calcPropertyNamesForColumns(String[] columnIds) { + if (columnIds == null) { + LabelColumnInfo columnInfo = getColumnInfo(null); + if (columnInfo != null) { + return columnInfo.getPropertyNames(); + } else { + return EMPTY_PROPERTY_NAMES_ARRAY; + } + } else { + List properties = new LinkedList(); + for (String columnId : columnIds) { + LabelColumnInfo info = getColumnInfo(columnId); + if (info != null) { + String[] infoPropertyNames = info.getPropertyNames(); + for (int i = 0; i < infoPropertyNames.length; i++) { + properties.add(infoPropertyNames[i]); + } + } + } + return properties.toArray(new String[properties.size()]); + } + } + + /** + * Updates the label information based on given map of properties. + * @param update Label update to write to. + * @param properties Properties retrieved from the element properties provider. + */ + protected void updateLabel(ILabelUpdate update, Map properties) { + if (update.getColumnIds() == null) { + LabelColumnInfo info = getColumnInfo(null); + if (info != null) { + info.updateColumn(update, 0, properties); + } + } else { + String[] columnIds = update.getColumnIds(); + + for (int i = 0; i < columnIds.length; i++) { + LabelColumnInfo info = getColumnInfo(columnIds[i]); + if (info != null) { + info.updateColumn(update, i, properties); + } + } + } + + update.done(); + } + + private IElementPropertiesProvider getElementPropertiesProvider(Object element) { + if (element instanceof IAdaptable) { + return (IElementPropertiesProvider)((IAdaptable)element).getAdapter(IElementPropertiesProvider.class); + } + return null; + } +} From 0ce3cca4dafbc6e4f75190d3353ab3bd5bd37439 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 20 Dec 2007 19:20:09 +0000 Subject: [PATCH 211/834] [213635] Added name to DSF executor. --- .../dsf/ui/concurrent/DisplayDsfExecutor.java | 232 ++++++++++++++++++ .../ui/concurrent/SWTDispatchDsfExecutor.java | 138 ----------- plugins/org.eclipse.dd.dsf/.options | 1 + .../dd/dsf/concurrent/DefaultDsfExecutor.java | 38 ++- 4 files changed, 267 insertions(+), 142 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/DisplayDsfExecutor.java delete mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/SWTDispatchDsfExecutor.java diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/DisplayDsfExecutor.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/DisplayDsfExecutor.java new file mode 100644 index 00000000000..7a5dfe600b1 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/DisplayDsfExecutor.java @@ -0,0 +1,232 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.dsf.ui.concurrent; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Callable; +import java.util.concurrent.Future; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.widgets.Display; + +public class DisplayDsfExecutor extends DefaultDsfExecutor +{ + /** + * Internal mapping of display objects to executors. + */ + private static Map fExecutors = Collections.synchronizedMap( new HashMap() ); + + /** + * Factory method for display executors. + * @param display Display to create an executor for. + * @return The new (or re-used) executor. + */ + public static DsfExecutor getDisplayDsfExecutor(Display display) { + synchronized (fExecutors) { + DisplayDsfExecutor executor = fExecutors.get(display); + if (executor == null) { + executor = new DisplayDsfExecutor(display); + fExecutors.put(display, executor); + } + return executor; + } + } + + /** + * The display class used by this executor to execute the submitted runnables. + */ + private final Display fDisplay; + + + private DisplayDsfExecutor(Display display) { + super("Display DSF Executor"); //$NON-NLS-1$ + fDisplay = display; + } + + /** + * Creates a callable wrapper, which delegates to the display to perform the + * operation. The callable blocks the executor thread while each call + * is executed in the display thred. + * @param Type used in the callable. + * @param callable Callable to wrap. + * @return Wrapper callable. + */ + private Callable createSWTDispatchCallable(final Callable callable) { + return new Callable() { + @SuppressWarnings("unchecked") + public V call() throws Exception { + final Object[] v = new Object[1]; + final Throwable[] e = new Throwable[1]; + + try { + fDisplay.syncExec(new Runnable() { + public void run() { + try { + v[0] = callable.call(); + } catch(Throwable exception) { + e[0] = exception; + } + } + }); + } catch (SWTException swtException) { + if (swtException.code == SWT.ERROR_DEVICE_DISPOSED) { + DisplayDsfExecutor.super.shutdown(); + } + } + + if(e[0] instanceof RuntimeException) + throw (RuntimeException) e[0]; + else if(e[0] instanceof Exception) + throw (Exception) e[0]; + + return (V) v[0]; + } + }; + } + + /** + * Creates a runnable wrapper, which delegates to the display to perform the + * operation. The runnable blocks the executor thread while each call + * is executed in the display thred. + * @param runnable Runnable to wrap. + * @return Wrapper runnable. + */ + private Runnable createSWTDispatchRunnable(final Runnable runnable) { + return new Runnable() { + public void run() { + final Throwable[] e = new Throwable[1]; + try { + fDisplay.syncExec(new Runnable() { + public void run() { + try { + runnable.run(); + } catch(Throwable exception) { + e[0] = exception; + } + } + }); + } catch (SWTException swtException) { + if (swtException.code == SWT.ERROR_DEVICE_DISPOSED) { + DisplayDsfExecutor.super.shutdown(); + } + } + if(e[0] instanceof RuntimeException) + throw (RuntimeException) e[0]; + } + }; + } + + @Override + public ScheduledFuture schedule(final Callable callable, long delay, TimeUnit unit) { + if (fDisplay.isDisposed()) { + if (!super.isShutdown()) super.shutdown(); + throw new RejectedExecutionException("Display " + fDisplay + " is disposed."); //$NON-NLS-1$ //$NON-NLS-2$ + } + return super.schedule(createSWTDispatchCallable(callable), delay, unit); + } + + @Override + public ScheduledFuture schedule(Runnable command, long delay, TimeUnit unit) { + if (fDisplay.isDisposed()) { + if (!super.isShutdown()) super.shutdown(); + throw new RejectedExecutionException("Display " + fDisplay + " is disposed."); //$NON-NLS-1$ //$NON-NLS-2$ + } + return super.schedule(createSWTDispatchRunnable(command), delay, unit); + } + + @Override + public ScheduledFuture scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) { + if (fDisplay.isDisposed()) { + if (!super.isShutdown()) super.shutdown(); + throw new RejectedExecutionException("Display " + fDisplay + " is disposed."); //$NON-NLS-1$ //$NON-NLS-2$ + } + return super.scheduleAtFixedRate(createSWTDispatchRunnable(command), initialDelay, period, unit); + } + + @Override + public ScheduledFuture scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) { + if (fDisplay.isDisposed()) { + if (!super.isShutdown()) super.shutdown(); + throw new RejectedExecutionException("Display " + fDisplay + " is disposed."); //$NON-NLS-1$ //$NON-NLS-2$ + } + return super.scheduleWithFixedDelay(createSWTDispatchRunnable(command), initialDelay, delay, unit); + } + + @Override + public void execute(Runnable command) { + if (fDisplay.isDisposed()) { + if (!super.isShutdown()) super.shutdown(); + throw new RejectedExecutionException("Display " + fDisplay + " is disposed."); //$NON-NLS-1$ //$NON-NLS-2$ + } + super.execute(createSWTDispatchRunnable(command)); + } + + @Override + public Future submit(Callable callable) { + if (fDisplay.isDisposed()) { + if (!super.isShutdown()) super.shutdown(); + throw new RejectedExecutionException("Display " + fDisplay + " is disposed."); //$NON-NLS-1$ //$NON-NLS-2$ + } + return super.submit(createSWTDispatchCallable(callable)); + } + + @Override + public Future submit(Runnable command, T result) { + if (fDisplay.isDisposed()) { + if (!super.isShutdown()) super.shutdown(); + throw new RejectedExecutionException("Display " + fDisplay + " is disposed."); //$NON-NLS-1$ //$NON-NLS-2$ + } + return super.submit(createSWTDispatchRunnable(command), result); + } + + @Override + public Future submit(Runnable command) { + if (fDisplay.isDisposed()) { + if (!super.isShutdown()) super.shutdown(); + throw new RejectedExecutionException("Display " + fDisplay + " is disposed."); //$NON-NLS-1$ //$NON-NLS-2$ + } + return super.submit(createSWTDispatchRunnable(command)); + } + + /** + * Override to prevent clients from shutting down. The executor will be + * shut down when the underlying display is discovered to be shut down. + */ + @Override + public void shutdown() { + } + + /** + * Override to prevent clients from shutting down. The executor will be + * shut down when the underlying display is discovered to be shut down. + */ + @SuppressWarnings({ "cast", "unchecked" }) + @Override + public List shutdownNow() { + return (List)Collections.EMPTY_LIST; + } + + @Override + public boolean isShutdown() { + // TODO Auto-generated method stub + return super.isShutdown(); + } +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/SWTDispatchDsfExecutor.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/SWTDispatchDsfExecutor.java deleted file mode 100644 index 3f1e61ec5c6..00000000000 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/SWTDispatchDsfExecutor.java +++ /dev/null @@ -1,138 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ - -package org.eclipse.dd.dsf.ui.concurrent; - -import java.util.concurrent.Callable; -import java.util.concurrent.Future; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; - -import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor; -import org.eclipse.swt.widgets.Display; - -public class SWTDispatchDsfExecutor extends DefaultDsfExecutor -{ - - public SWTDispatchDsfExecutor() - { - super(); - } - - private Callable createSWTDispatchCallable(final Callable callable) - { - return new Callable() - { - @SuppressWarnings("unchecked") - public V call() throws Exception - { - final Object[] v = new Object[1]; - final Throwable[] e = new Throwable[1]; - - Display.getDefault().syncExec(new Runnable() - { - public void run() - { - try - { - v[0] = callable.call(); - } - catch(Throwable exception) - { - e[0] = exception; - } - } - }); - - if(e[0] instanceof RuntimeException) - throw (RuntimeException) e[0]; - else if(e[0] instanceof Exception) - throw (Exception) e[0]; - - return (V) v[0]; - } - }; - } - - private Runnable createSWTDispatchRunnable(final Runnable runnable) - { - return new Runnable() - { - public void run() - { - final Throwable[] e = new Throwable[1]; - - Display.getDefault().syncExec(new Runnable() - { - public void run() - { - try - { - runnable.run(); - } - catch(Throwable exception) - { - e[0] = exception; - } - } - }); - - if(e[0] instanceof RuntimeException) - throw (RuntimeException) e[0]; - } - }; - } - - @Override - public ScheduledFuture schedule(final Callable callable, long delay, - TimeUnit unit) { - return super.schedule(createSWTDispatchCallable(callable), delay, unit); - } - - @Override - public ScheduledFuture schedule(Runnable command, long delay, - TimeUnit unit) { - return super.schedule(createSWTDispatchRunnable(command), delay, unit); - } - - @Override - public ScheduledFuture scheduleAtFixedRate(Runnable command, - long initialDelay, long period, TimeUnit unit) { - return super.scheduleAtFixedRate(createSWTDispatchRunnable(command), initialDelay, period, unit); - } - - @Override - public ScheduledFuture scheduleWithFixedDelay(Runnable command, - long initialDelay, long delay, TimeUnit unit) { - return super.scheduleWithFixedDelay(createSWTDispatchRunnable(command), initialDelay, delay, unit); - } - - @Override - public void execute(Runnable command) { - super.execute(createSWTDispatchRunnable(command)); - } - - @Override - public Future submit(Callable callable) { - return super.submit(createSWTDispatchCallable(callable)); - } - - @Override - public Future submit(Runnable command, T result) { - return super.submit(createSWTDispatchRunnable(command), result); - } - - @Override - public Future submit(Runnable command) { - return super.submit(createSWTDispatchRunnable(command)); - } - -} diff --git a/plugins/org.eclipse.dd.dsf/.options b/plugins/org.eclipse.dd.dsf/.options index 54b07bac112..46b81df7dd3 100644 --- a/plugins/org.eclipse.dd.dsf/.options +++ b/plugins/org.eclipse.dd.dsf/.options @@ -1,2 +1,3 @@ org.eclipse.dd.dsf/debug = false org.eclipse.dd.dsf/debug/executor = false +org.eclipse.dd.dsf/debug/executorName = diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java index 9860699b246..6bd0a31ba33 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java @@ -36,18 +36,43 @@ import org.eclipse.dd.dsf.DsfPlugin; public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor implements DsfExecutor { + /** + * Instance counter for DSF executors. Used in the executor's thread name. + */ + private static int fgInstanceCounter = 0; + + /** + * Name of the executor, used in the executor's thread name. + */ + private String fName; + /** Thread factory that creates the single thread to be used for this executor */ static class DsfThreadFactory implements ThreadFactory { + private String fThreadName; + DsfThreadFactory(String name) { + fThreadName = name; + } + Thread fThread; public Thread newThread(Runnable r) { assert fThread == null; // Should be called only once. - fThread = new Thread(new ThreadGroup("DSF Thread Group"), r, "DSF Dispatch Thread", 0); //$NON-NLS-1$//$NON-NLS-2$ + fThread = new Thread(new ThreadGroup(fThreadName), r, fThreadName, 0); return fThread; } } public DefaultDsfExecutor() { - super(1, new DsfThreadFactory()); + this("DSF Executor"); //$NON-NLS-1$ + } + + /** + * Creates a new DSF Executor with the given name. + * @param name Name used to create executor's thread. + */ + public DefaultDsfExecutor(String name) { + super(1, new DsfThreadFactory(name + " - " + fgInstanceCounter++)); //$NON-NLS-1$ + fName = name; + if(DEBUG_EXECUTOR || ASSERTIONS_ENABLED) { // If tracing, pre-start the dispatch thread, and add it to the map. prestartAllCoreThreads(); @@ -84,10 +109,13 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor // Utilities used for tracing. // static boolean DEBUG_EXECUTOR = false; + static String DEBUG_EXECUTOR_NAME = ""; static boolean ASSERTIONS_ENABLED = false; static { DEBUG_EXECUTOR = DsfPlugin.DEBUG && "true".equals( //$NON-NLS-1$ Platform.getDebugOption("org.eclipse.dd.dsf/debug/executor")); //$NON-NLS-1$ + DEBUG_EXECUTOR_NAME = DsfPlugin.DEBUG + ? Platform.getDebugOption("org.eclipse.dd.dsf/debug/executorName") : ""; //$NON-NLS-1$ assert (ASSERTIONS_ENABLED = true) == true; } @@ -141,7 +169,7 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor fCurrentlyExecuting = this; // Write to console only if tracing is enabled (as opposed to tracing or assertions). - if (DEBUG_EXECUTOR) { + if (DEBUG_EXECUTOR && ("".equals(DEBUG_EXECUTOR_NAME) || fName.equals(DEBUG_EXECUTOR_NAME))) { //$NON-NLS-1$ StringBuilder traceBuilder = new StringBuilder(); // Record the time @@ -212,7 +240,9 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor fRunnable = runnable; // Check if executable wasn't executed already. - if (DEBUG_EXECUTOR && fRunnable instanceof DsfExecutable) { + if (fRunnable instanceof DsfExecutable && + DEBUG_EXECUTOR && ("".equals(DEBUG_EXECUTOR_NAME) || fName.equals(DEBUG_EXECUTOR_NAME))) //$NON-NLS-1$ + { assert !((DsfExecutable)fRunnable).getSubmitted() : "Executable was previously executed."; //$NON-NLS-1$ ((DsfExecutable)fRunnable).setSubmitted(); } From a4c2cc234f0aec0767931ba27ccc4db558ab6cc1 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 20 Dec 2007 19:32:29 +0000 Subject: [PATCH 212/834] [213635] Added name to DSF executor. --- .../dd/dsf/concurrent/DefaultDsfExecutor.java | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java index 6bd0a31ba33..e72be2757c3 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java @@ -46,6 +46,11 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor */ private String fName; + /** + * Instance number of this executor, used with the executor name. + */ + private int fInstanceNumber; + /** Thread factory that creates the single thread to be used for this executor */ static class DsfThreadFactory implements ThreadFactory { private String fThreadName; @@ -70,8 +75,9 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor * @param name Name used to create executor's thread. */ public DefaultDsfExecutor(String name) { - super(1, new DsfThreadFactory(name + " - " + fgInstanceCounter++)); //$NON-NLS-1$ + super(1, new DsfThreadFactory(name + " - " + fgInstanceCounter)); //$NON-NLS-1$ fName = name; + fInstanceNumber = fgInstanceCounter++; if(DEBUG_EXECUTOR || ASSERTIONS_ENABLED) { // If tracing, pre-start the dispatch thread, and add it to the map. @@ -179,8 +185,15 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor // Record the executor # traceBuilder.append('#'); traceBuilder.append(fSequenceNumber); + + // Record the executor name + traceBuilder.append('('); + traceBuilder.append(fName); + traceBuilder.append(" - "); //$NON-NLS-1$ + traceBuilder.append(fInstanceNumber); + traceBuilder.append(')'); traceBuilder.append(' '); - + // Append executable class name traceBuilder.append(getExecutable().getClass().getName()); From e2aa815c7c02246cd5f7a019ac32eaad1af4ace0 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 4 Jan 2008 03:46:52 +0000 Subject: [PATCH 213/834] [212841] Changed the IViewerUpdate interface implementations to work with platform 3.4 M4 milestone. --- .../eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java | 7 +------ .../eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java | 2 +- .../org/eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java | 1 + 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java index 0542927d929..92dc16e0d3f 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java @@ -444,12 +444,7 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode { fTreePath = path; } - public Object getElement(TreePath path) { - // If not asking for root, just return the last segment in path. - if (path.getSegmentCount() > 0) { - return path.getLastSegment(); - } - // Calculate the root of the viewer. + public Object getViewerInput() { return getVMProvider().getRootElement(); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java index 2ba86fa5b25..0359bb59e1f 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java @@ -498,7 +498,7 @@ abstract public class AbstractVMProvider implements IVMProvider * @see IViewerInputProvider */ public void update(IViewerInputUpdate update) { - update.setViewerInput(update.getElement()); + update.setInputElement(update.getElement()); update.done(); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java index 2da11734ebc..0ed79ad8e06 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java @@ -35,6 +35,7 @@ public class VMViewerUpdate implements IViewerUpdate { fClientUpdate = clientUpdate; } + public Object getViewerInput() { return fClientUpdate.getViewerInput(); } public Object getElement() { return fClientUpdate.getElement(); } public TreePath getElementPath() { return fClientUpdate.getElementPath(); } public IPresentationContext getPresentationContext() { return fClientUpdate.getPresentationContext(); } From a09c42806c565c71c653a891e640bdf9a7cd041f Mon Sep 17 00:00:00 2001 From: Francois Chouinard Date: Mon, 7 Jan 2008 22:02:31 +0000 Subject: [PATCH 214/834] Fix for bug215545 --- .../org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java index 345c8734d6a..51ec8716f60 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java @@ -216,7 +216,6 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl * @see org.eclipse.debug.core.model.IMemoryBlockRetrievalExtension#getExtendedMemoryBlock(java.lang.String, * java.lang.Object) */ - @SuppressWarnings("unchecked") public IMemoryBlockExtension getExtendedMemoryBlock(String expression, Object context) throws DebugException { // The block start address (supports 64-bit processors) From 7cfa3745842ec3e620b46592c371ca68d55b2134 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Wed, 9 Jan 2008 20:12:24 +0000 Subject: [PATCH 215/834] Fixed the import of StatusLineContributionItem. It moved in platform 3.4M4. --- .../viewmodel/numberformat/detail/NumberFormatDetailPane.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/NumberFormatDetailPane.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/NumberFormatDetailPane.java index ca16f667b12..eafe79f19d3 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/NumberFormatDetailPane.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/NumberFormatDetailPane.java @@ -53,7 +53,6 @@ import org.eclipse.debug.internal.ui.actions.variables.details.DetailPaneMaxLeng import org.eclipse.debug.internal.ui.actions.variables.details.DetailPaneWordWrapAction; import org.eclipse.debug.internal.ui.preferences.IDebugPreferenceConstants; import org.eclipse.debug.internal.ui.views.variables.IndexedValuePartition; -import org.eclipse.debug.internal.ui.views.variables.StatusLineContributionItem; import org.eclipse.debug.internal.ui.views.variables.details.DetailMessages; import org.eclipse.debug.ui.IDebugModelPresentation; import org.eclipse.debug.ui.IDebugUIConstants; @@ -66,6 +65,7 @@ import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.IStatusLineManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.Separator; +import org.eclipse.jface.action.StatusLineContributionItem; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.Document; From 7d83b3a7dd63fb33870280ae667f96b987a9bd69 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Sat, 19 Jan 2008 00:34:30 +0000 Subject: [PATCH 216/834] [192019] View Model framework refactoring. --- .../META-INF/MANIFEST.MF | 1 - .../build.properties | 1 + .../org.eclipse.dd.dsf.debug.ui/plugin.xml | 123 +-- .../debug/ui/actions/DsfCommandRunnable.java | 13 +- .../sourcelookup/MISourceDisplayAdapter.java | 9 +- .../AbstractVMProviderActionDelegate.java | 104 +++ .../AbstractDebugDMVMProviderWithCache.java | 44 - .../AbstractExpressionLayoutNode.java | 305 ------- .../expression/AbstractExpressionVMNode.java | 119 +++ ...Node.java => ExpressionManagerVMNode.java} | 243 +++--- .../expression/ExpressionVMProvider.java | 271 ++++-- .../ExpressionVMProviderContentStragegy.java | 87 ++ ...xpressionVMProviderModelProxyStrategy.java | 134 +++ .../expression/IExpressionLayoutNode.java | 55 -- .../expression/IExpressionUpdate.java | 34 + .../expression/IExpressionVMNode.java | 60 ++ .../expression/VMExpressionUpdate.java | 79 ++ .../WatchExpressionCellModifier.java | 3 +- ...tLayoutNode.java => LaunchRootVMNode.java} | 93 +- ...LayoutNode.java => StackFramesVMNode.java} | 131 +-- ...utNode.java => StandardProcessVMNode.java} | 94 ++- .../viewmodel/modules/ModuleDetailPane.java | 6 +- .../modules/ModuleDetailPaneFactory.java | 4 +- ...ulesLayoutNode.java => ModulesVMNode.java} | 68 +- .../viewmodel/modules/ModulesVMProvider.java | 14 +- .../numberformat/AbstractSetFormatStyle.java | 28 +- .../detail/NumberFormatDetailPane.java | 14 +- ...java => RegisterBitFieldCellModifier.java} | 22 +- ...tNode.java => RegisterBitFieldVMNode.java} | 209 +++-- ...odifier.java => RegisterCellModifier.java} | 21 +- ...youtNode.java => RegisterGroupVMNode.java} | 121 +-- ...terLayoutNode.java => RegisterVMNode.java} | 350 ++++---- .../register/RegisterVMProvider.java | 50 +- .../register/SyncRegisterDataAccess.java | 30 +- .../update/BreakpointHitUpdatePolicy.java | 45 + .../update/VMCacheRefreshAlways.java | 36 - .../update/VMCacheRefreshManual.java | 32 - .../update/VMCacheRefreshOnBreak.java | 42 - .../update/actions/RefreshActionDelegate.java | 142 +--- .../actions/RefreshAlwaysActionDelegate.java | 35 - .../actions/RefreshManualActionDelegate.java | 35 - .../actions/RefreshOnBreakActionDelegate.java | 35 - .../actions/SelectUpdatePolicyAction.java | 128 +++ ...odifier.java => VariableCellModifier.java} | 16 +- ...bleLayoutNode.java => VariableVMNode.java} | 224 +++-- .../variable/VariableVMProvider.java | 52 +- .../org.eclipse.dd.dsf.debug/build.properties | 1 + .../META-INF/MANIFEST.MF | 3 +- .../org.eclipse.dd.dsf.ui/build.properties | 1 + .../dsf/ui/concurrent/DisplayDsfExecutor.java | 33 +- .../ViewerCountingRequestMonitor.java | 55 ++ .../concurrent/ViewerDataRequestMonitor.java | 53 ++ .../dsf/ui/viewmodel/AbstractVMAdapter.java | 147 ++-- .../dsf/ui/viewmodel/AbstractVMContext.java | 57 ++ .../ui/viewmodel/AbstractVMLayoutNode.java | 517 ------------ .../dd/dsf/ui/viewmodel/AbstractVMNode.java | 93 ++ .../dsf/ui/viewmodel/AbstractVMProvider.java | 798 ++++++++---------- .../DefaultVMContentProviderStrategy.java | 370 ++++++++ .../DefaultVMModelProxyStrategy.java | 615 ++++++++++++++ .../dd/dsf/ui/viewmodel/IRootVMNode.java | 46 + .../dd/dsf/ui/viewmodel/IVMContext.java | 9 +- .../dd/dsf/ui/viewmodel/IVMModelProxy.java | 31 + .../{IVMLayoutNode.java => IVMNode.java} | 102 +-- .../dd/dsf/ui/viewmodel/IVMProvider.java | 60 +- .../dsf/ui/viewmodel/IVMRootLayoutNode.java | 32 - .../dd/dsf/ui/viewmodel/RootVMNode.java | 69 ++ ...Update.java => VMChildrenCountUpdate.java} | 23 +- ...mentsUpdate.java => VMChildrenUpdate.java} | 69 +- .../eclipse/dd/dsf/ui/viewmodel/VMDelta.java | 330 -------- ...tsUpdate.java => VMHasChildrenUpdate.java} | 24 +- .../dd/dsf/ui/viewmodel/VMRootLayoutNode.java | 107 --- .../dd/dsf/ui/viewmodel/VMViewerUpdate.java | 140 ++- .../viewmodel/dm/AbstractDMVMLayoutNode.java | 481 ----------- .../dsf/ui/viewmodel/dm/AbstractDMVMNode.java | 334 ++++++++ .../ui/viewmodel/dm/AbstractDMVMProvider.java | 31 +- .../dm/AbstractDMVMProviderWithCache.java | 74 -- .../ui/viewmodel/dm/CompositeDMVMContext.java | 22 +- .../dd/dsf/ui/viewmodel/dm/IDMVMContext.java} | 14 +- ...MRootLayoutNode.java => RootDMVMNode.java} | 64 +- .../properties/IPropertiesUpdate.java | 1 + .../ui/viewmodel/properties/LabelText.java | 2 +- .../properties/MessagesForProperties.java | 17 + .../PropertyBasedLabelProvider.java | 2 +- .../viewmodel/properties/messages.properties | 1 + .../update/AbstractCachingVMProvider.java | 761 +++++++++++++++++ .../update/AutomaticUpdatePolicy.java | 45 + .../viewmodel/update/ICachingVMProvider.java | 44 + .../update/IElementUpdateTester.java | 41 + .../ui/viewmodel/update/IVMUpdatePolicy.java | 53 ++ .../viewmodel/update/ManualUpdatePolicy.java | 89 ++ .../ui/viewmodel/update/UserEditEvent.java | 37 + .../dd/dsf/ui/viewmodel/update/VMCache.java | 384 --------- .../ui/viewmodel/update/VMCacheManager.java | 112 --- .../AbstractRefreshActionDelegate.java | 40 - plugins/org.eclipse.dd.dsf/build.properties | 1 + .../dd/dsf/concurrent/DefaultDsfExecutor.java | 16 +- .../dd/dsf/concurrent/DsfExecutable.java | 6 +- .../dd/dsf/concurrent/ImmediateExecutor.java | 18 + 98 files changed, 5705 insertions(+), 4532 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/actions/AbstractVMProviderActionDelegate.java delete mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/dm/AbstractDebugDMVMProviderWithCache.java delete mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionLayoutNode.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionVMNode.java rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/{ExpressionManagerLayoutNode.java => ExpressionManagerVMNode.java} (60%) create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderContentStragegy.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderModelProxyStrategy.java delete mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionLayoutNode.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionUpdate.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionVMNode.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/VMExpressionUpdate.java rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/{StandardLaunchRootLayoutNode.java => LaunchRootVMNode.java} (53%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/{StackFramesLayoutNode.java => StackFramesVMNode.java} (79%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/{StandardProcessLayoutNode.java => StandardProcessVMNode.java} (74%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/{ModulesLayoutNode.java => ModulesVMNode.java} (75%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/{RegisterBitFieldLayoutCellModifier.java => RegisterBitFieldCellModifier.java} (87%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/{RegisterBitFieldLayoutNode.java => RegisterBitFieldVMNode.java} (78%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/{RegisterLayoutValueCellModifier.java => RegisterCellModifier.java} (86%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/{RegisterGroupLayoutNode.java => RegisterGroupVMNode.java} (80%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/{RegisterLayoutNode.java => RegisterVMNode.java} (62%) create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/BreakpointHitUpdatePolicy.java delete mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshAlways.java delete mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshManual.java delete mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshOnBreak.java delete mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshAlwaysActionDelegate.java delete mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshManualActionDelegate.java delete mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshOnBreakActionDelegate.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/SelectUpdatePolicyAction.java rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/{VariableLayoutValueCellModifier.java => VariableCellModifier.java} (85%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/{VariableLayoutNode.java => VariableVMNode.java} (80%) create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/ViewerCountingRequestMonitor.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/ViewerDataRequestMonitor.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMContext.java delete mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMNode.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMContentProviderStrategy.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMModelProxyStrategy.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IRootVMNode.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMModelProxy.java rename plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/{IVMLayoutNode.java => IVMNode.java} (55%) delete mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMRootLayoutNode.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/RootVMNode.java rename plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/{VMElementsCountUpdate.java => VMChildrenCountUpdate.java} (62%) rename plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/{VMElementsUpdate.java => VMChildrenUpdate.java} (51%) delete mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java rename plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/{VMHasElementsUpdate.java => VMHasChildrenUpdate.java} (57%) delete mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMRootLayoutNode.java delete mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMNode.java delete mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProviderWithCache.java rename plugins/{org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionVMContext.java => org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/IDMVMContext.java} (59%) rename plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/{DMVMRootLayoutNode.java => RootDMVMNode.java} (59%) create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/MessagesForProperties.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/messages.properties create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AutomaticUpdatePolicy.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/ICachingVMProvider.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/IElementUpdateTester.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/IVMUpdatePolicy.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/ManualUpdatePolicy.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/UserEditEvent.java delete mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java delete mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCacheManager.java delete mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/actions/AbstractRefreshActionDelegate.java diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF index e692605a411..ec919b9fc41 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF @@ -25,7 +25,6 @@ Export-Package: org.eclipse.dd.dsf.debug.ui.actions, org.eclipse.dd.dsf.debug.ui.sourcelookup, org.eclipse.dd.dsf.debug.ui.viewmodel, - org.eclipse.dd.dsf.debug.ui.viewmodel.dm, org.eclipse.dd.dsf.debug.ui.viewmodel.expression, org.eclipse.dd.dsf.debug.ui.viewmodel.launch, org.eclipse.dd.dsf.debug.ui.viewmodel.modules, diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/build.properties b/plugins/org.eclipse.dd.dsf.debug.ui/build.properties index 65c7e05604b..485a5d61a61 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/build.properties +++ b/plugins/org.eclipse.dd.dsf.debug.ui/build.properties @@ -2,6 +2,7 @@ source.. = src/ output.. = bin/ bin.includes = META-INF/,\ plugin.xml,\ + plugin.properties,\ about.html,\ .,\ icons/ diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml index 11007565a2e..242376a0803 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml +++ b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml @@ -86,126 +86,23 @@ -

    - - - - - - - - - + class="org.eclipse.dd.dsf.debug.ui.viewmodel.update.actions.SelectUpdatePolicyAction" + id="org.eclipse.dd.dsf.debug.ui.update.selectUpdatePolicy" + label="Update Policy" + menubarPath="additions"> - - - - - - - - - - - - - - - - - - - - - - - - + class="org.eclipse.dd.dsf.debug.ui.viewmodel.update.actions.SelectUpdatePolicyAction" + id="org.eclipse.dd.dsf.debug.ui.update.selectUpdatePolicy" + label="Update Policy" + menubarPath="additions"> diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java index 3c925b0a819..42f870b9f1d 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java @@ -20,11 +20,9 @@ import org.eclipse.dd.dsf.debug.service.IStepQueueManager; import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.service.DsfServicesTracker; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode.DMVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; import org.eclipse.debug.core.commands.IDebugCommandRequest; -@SuppressWarnings("restriction") @Immutable public abstract class DsfCommandRunnable extends DsfRunnable { private final IExecutionDMContext fContext; @@ -41,12 +39,9 @@ public abstract class DsfCommandRunnable extends DsfRunnable { public DsfCommandRunnable(DsfServicesTracker servicesTracker, Object element, IDebugCommandRequest request) { fTracker = servicesTracker; - if (element instanceof DMVMContext) { - // Javac doesn't like the cast to "(AbstractDMVMLayoutNode.DMVMContext)" need to use the - // construct below and suppress warnings. - @SuppressWarnings("unchecked") - AbstractDMVMLayoutNode.DMVMContext vmc = (AbstractDMVMLayoutNode.DMVMContext)element; - fContext = DMContexts.getAncestorOfType(vmc.getDMC(), IExecutionDMContext.class); + if (element instanceof IDMVMContext) { + IDMVMContext vmc = (IDMVMContext)element; + fContext = DMContexts.getAncestorOfType(vmc.getDMContext(), IExecutionDMContext.class); } else { fContext = null; } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java index 058126bd9ab..18eb513a053 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java @@ -40,7 +40,7 @@ import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode.DMVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector; import org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant; import org.eclipse.debug.ui.IDebugUIConstants; @@ -81,7 +81,6 @@ import org.eclipse.ui.texteditor.ITextEditor; * dispatch thread to synchronize access to the state data of the running jobs. */ @ThreadSafe -@SuppressWarnings("restriction") public class MISourceDisplayAdapter implements ISourceDisplay { /** @@ -427,10 +426,8 @@ public class MISourceDisplayAdapter implements ISourceDisplay * @see org.eclipse.debug.ui.contexts.ISourceDisplayAdapter#displaySource(java.lang.Object, org.eclipse.ui.IWorkbenchPage, boolean) */ public void displaySource(Object context, final IWorkbenchPage page, final boolean force) { - if (!(context instanceof DMVMContext)) return; - // Correct cast: (AbstractDMVMLayoutNode.DMVMContext) breaks the javac compiler - @SuppressWarnings("unchecked") - final IDMContext dmc = ((DMVMContext)context).getDMC(); + if (!(context instanceof IDMVMContext)) return; + final IDMContext dmc = ((IDMVMContext)context).getDMContext(); // Quick test. DMC is checked again in source lookup participant, but // it's much quicker to test here. diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/actions/AbstractVMProviderActionDelegate.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/actions/AbstractVMProviderActionDelegate.java new file mode 100644 index 00000000000..5e262b409f4 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/actions/AbstractVMProviderActionDelegate.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + *******************************************************************************/ + +package org.eclipse.dd.dsf.debug.ui.viewmodel.actions; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.dd.dsf.ui.viewmodel.IVMAdapter; +import org.eclipse.dd.dsf.ui.viewmodel.IVMProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer; +import org.eclipse.debug.ui.AbstractDebugView; +import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.debug.ui.contexts.DebugContextEvent; +import org.eclipse.debug.ui.contexts.IDebugContextListener; +import org.eclipse.debug.ui.contexts.IDebugContextService; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.widgets.Event; +import org.eclipse.ui.IActionDelegate2; +import org.eclipse.ui.IViewActionDelegate; +import org.eclipse.ui.IViewPart; + +@SuppressWarnings("restriction") +abstract public class AbstractVMProviderActionDelegate implements IViewActionDelegate, IDebugContextListener, IActionDelegate2 { + + private IViewPart fView = null; + private IAction fAction = null; + private ISelection fDebugContext; + + public void init(IViewPart view) { + fView = view; + + // Get the current selection from the DebugView so we can determine if we want this menu action to be live or not. + IDebugContextService debugContextService = DebugUITools.getDebugContextManager().getContextService(view.getSite().getWorkbenchWindow()); + debugContextService.addPostDebugContextListener(this); + fDebugContext = debugContextService.getActiveContext(); + } + + public void selectionChanged(IAction action, ISelection selection) { + if (fAction != action) { + fAction = action; + } + } + + public void runWithEvent(IAction action, Event event) { + run(action); + } + + public void init(IAction action) { + fAction = action; + } + + public void dispose() { + DebugUITools.getDebugContextManager().getContextService(getView().getSite().getWorkbenchWindow()).removePostDebugContextListener(this); + } + + public void debugContextChanged(DebugContextEvent event) { + fDebugContext = event.getContext(); + } + + protected IViewPart getView() { return fView; } + + protected IAction getAction() { return fAction; } + + protected Object getViewerInput() { + if (fDebugContext instanceof IStructuredSelection) { + return ((IStructuredSelection)fDebugContext).getFirstElement(); + } + return null; + } + + protected IVMProvider getVMProvider() { + Object viewerInput = getViewerInput(); + IPresentationContext presentationContext = getPresentationContext(); + + if (viewerInput instanceof IAdaptable && presentationContext != null) { + IVMAdapter adapter = (IVMAdapter) ((IAdaptable)viewerInput).getAdapter(IVMAdapter.class); + + if ( adapter != null ) { + return adapter.getVMProvider(presentationContext); + } + } + + return null; + } + + protected IPresentationContext getPresentationContext() { + if (fView instanceof AbstractDebugView && + ((AbstractDebugView) fView).getViewer() instanceof TreeModelViewer) + { + return ((TreeModelViewer) ((AbstractDebugView) fView).getViewer()).getPresentationContext(); + } + return null; + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/dm/AbstractDebugDMVMProviderWithCache.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/dm/AbstractDebugDMVMProviderWithCache.java deleted file mode 100644 index c0557044656..00000000000 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/dm/AbstractDebugDMVMProviderWithCache.java +++ /dev/null @@ -1,44 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Ted R Williams (Wind River Systems, Inc.) - initial implementation - *******************************************************************************/ - -package org.eclipse.dd.dsf.debug.ui.viewmodel.dm; - -import org.eclipse.dd.dsf.debug.ui.viewmodel.update.VMCacheRefreshAlways; -import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProviderWithCache; -import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; - - - -/* - * The purpose of this class is to satisfy package structure requirements while enabling VM update modes. - * The non-debug centric VMCacheManager and VMCache live under org.eclipse.dd.dsf.*. The debug data view - * caches (VMCacheRefreshAlways/Manual/OnBreak) live under org.eclipse.dd.dsf.debug.* because of their - * awareness of debug specific events. There is a need to instantiate a default (always) cache on view - * startup. AbstractDMVMProviderWithCache would be a good place to accomplish this task, but like the - * VMCacheManager, this class cannot access the *dsf.debug* VMCacheRefreshAlways. AbstractDebugDMVMProviderWithCache - * is meant to solve this problem. - */ - -@SuppressWarnings("restriction") -public class AbstractDebugDMVMProviderWithCache extends - AbstractDMVMProviderWithCache -{ - - public AbstractDebugDMVMProviderWithCache(AbstractVMAdapter adapter, IPresentationContext presentationContext, DsfSession session) { - super(adapter, presentationContext, session); - - VMCacheManager.getVMCacheManager().registerCache(presentationContext, new VMCacheRefreshAlways()); - } - -} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionLayoutNode.java deleted file mode 100644 index 94034ddcdf1..00000000000 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionLayoutNode.java +++ /dev/null @@ -1,305 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; - -import java.util.List; -import java.util.Map; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; -import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor; -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.MultiRequestMonitor; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; -import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; -import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; -import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; -import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; -import org.eclipse.dd.dsf.ui.viewmodel.VMElementsUpdate; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; -import org.eclipse.debug.core.model.IExpression; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; -import org.eclipse.jface.viewers.TreePath; - -/** - * - */ -@SuppressWarnings("restriction") -public abstract class AbstractExpressionLayoutNode extends AbstractDMVMLayoutNode - implements IExpressionLayoutNode -{ - - public AbstractExpressionLayoutNode(AbstractVMProvider provider, DsfSession session, Class dmcClassType) { - super(provider, session, dmcClassType); - } - - public void getElementForExpression(final IChildrenUpdate update, final String expressionText, final IExpression expression) { - final int exprLength = getExpressionLength(expressionText); - if (exprLength < 0) { - update.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Invalid expression", null)); //$NON-NLS-1$ - update.done(); - return; - } - - final String nodeExpressionText = exprLength > 0 ? expressionText.substring(0, exprLength) : expressionText; - - getElementForExpressionPart( - update, nodeExpressionText, - new DataRequestMonitor(getExecutor(), null) { - @Override - protected void handleOK() { - /** - * If the current expression is the whole expression from the argument, - * return the VMC. Otherwise, call the child nodes to continue evaluating - * the expression. - */ - if (exprLength == expressionText.length()) { - Object element = getData(); - associateExpression(element, expression); - update.setChild(element, 0); - update.done(); - } else { - getVMContextForExpressionFromChildNodes( - update, getData(), expressionText.substring(exprLength), expression); - } - } - - @Override - protected void handleErrorOrCancel() { - update.setStatus(getStatus()); - update.done(); - } - }); - } - - protected void getElementForExpressionPart(final IChildrenUpdate update, final String expressionPartText, final DataRequestMonitor rm) { - updateElements(new VMElementsUpdate( - update, -1, -1, - new DataRequestMonitor>(getExecutor(), rm) { - @Override - protected void handleOK() { - if (getData().size() == 0) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "No contexts", null)); //$NON-NLS-1$ - rm.done(); - } else { - final List elements = getData(); - - final MultiRequestMonitor> multiRm = new MultiRequestMonitor>(getExecutor(), rm) { - @Override - protected void handleOK() { - boolean foundMatchingContext = false; - for (int i = 0; i < getRequestMonitors().size(); i++) { - if (getRequestMonitors().get(i).getData()) { - rm.setData(elements.get(i)); - foundMatchingContext = true; - break; - } - } - if (!foundMatchingContext) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Context not found", null)); //$NON-NLS-1$ - } - rm.done(); - } - }; - - for (Object element : elements) { - testContextForExpression( - element, expressionPartText, - multiRm.add( - new DataRequestMonitor(getExecutor(), null) { - @Override - protected void handleCompleted() { - multiRm.requestMonitorDone(this); - } - })); - } - } - } - - @Override - protected void handleErrorOrCancel() { - update.setStatus(getStatus()); - update.done(); - } - }) - ); - } - - - @ConfinedToDsfExecutor("#getSession#getExecutor") - protected abstract void testContextForExpression(Object element, final String expression, final DataRequestMonitor rm); - protected abstract void associateExpression(Object element, IExpression expression); - - protected void getVMContextForExpressionFromChildNodes(final IChildrenUpdate update, Object parentElement, String childExpression, IExpression expression) { - IChildrenUpdate childUpdate = new ChildExpressionElementUpdate( - update, update.getElementPath().createChildPath(parentElement), - new DataRequestMonitor>(getExecutor(), null) { - @Override - protected void handleOK() { - update.setChild(getData().get(0), 0); - update.done(); - } - @Override - protected void handleErrorOrCancel() { - update.setStatus(getStatus()); - update.done(); - } - }); - - - for (int i = 0; i < getChildLayoutNodes().length; i++) { - if (getChildLayoutNodes()[i] instanceof IExpressionLayoutNode) { - IExpressionLayoutNode childNode = (IExpressionLayoutNode)getChildLayoutNodes()[i]; - if (childNode.getExpressionLength(childExpression) > 0) { - // The child node will call update.done(); - childNode.getElementForExpression(childUpdate, childExpression, expression); - return; - } - } - } - - // If we didn't find a matching child node in the for loop above, return an error. - update.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Invalid expression", null)); //$NON-NLS-1$ - update.done(); - - } - - public int getDeltaFlagsForExpression(String expressionText, Object event) { - int exprLength = getExpressionLength(expressionText); - if (exprLength >= 0) { - if (exprLength == expressionText.length()) { - return getDeltaFlags(event); - } else { - int retVal = getDeltaFlagsForExpressionPart(event); - String childExpression = expressionText.substring(exprLength); - for (int i = 0; i < getChildLayoutNodes().length; i++) { - if (getChildLayoutNodes()[i] instanceof IExpressionLayoutNode) { - IExpressionLayoutNode exprNode = (IExpressionLayoutNode)getChildLayoutNodes()[i]; - if (exprNode.getExpressionLength(childExpression) > 0) { - // The child node will call update.done(); - retVal |= exprNode.getDeltaFlagsForExpression(childExpression, event); - } - } - } - return retVal; - } - } - - return IModelDelta.NO_CHANGE; - } - - protected abstract int getDeltaFlagsForExpressionPart(Object event); - - public void buildDeltaForExpression(final IExpression expression, final int elementIdx, final String expressionText, final Object event, final VMDelta parentDelta, final TreePath path, final RequestMonitor rm) - { - // Find the expression part that belong to this node. If expression - // is not recognized, do nothing. - final int exprLength = getExpressionLength(expressionText); - if (exprLength < 0) { - rm.done(); - return; - } - - final String nodeExpressionText = exprLength > 0 ? expressionText.substring(0, exprLength) : expressionText; - - getElementForExpressionPart( - new ElementsUpdate(new DataRequestMonitor>(getExecutor(), null), path), - nodeExpressionText, - new DataRequestMonitor(getExecutor(), null) { - @Override - protected void handleOK() { - if (exprLength == expressionText.length()) { - associateExpression(getData(), expression); - buildDeltaForExpressionElement(getData(), elementIdx, event, parentDelta, rm); - } else { - TreePath newPath = path.createChildPath(getData()); - callChildExpressionNodesToBuildDelta( - expression, elementIdx, expressionText.substring(exprLength), event, parentDelta, newPath, rm); - } - } - - @Override - protected void handleErrorOrCancel() { - // There is no matching element for given expression. That's OK, it just - // means that the expression is invalid. - rm.done(); - } - }); - } - - protected void buildDeltaForExpressionElement(Object element, int elementIdx, Object event, VMDelta parentDelta, final RequestMonitor rm) - { - // Find the child nodes that have deltas for the given event. - final Map childNodesWithDeltaFlags = getChildNodesWithDeltaFlags(event); - - // If no child layout nodes have deltas we can stop here. - if (childNodesWithDeltaFlags.size() == 0) { - rm.done(); - return; - } - - callChildNodesToBuildDelta( - childNodesWithDeltaFlags, parentDelta.addNode(element, elementIdx, IModelDelta.NO_CHANGE), event, rm); - } - - protected void callChildExpressionNodesToBuildDelta(IExpression expression, int elementIdx, String expressionRemainder, Object event, VMDelta parentDelta, TreePath path, final RequestMonitor rm) - { - final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), null) { - @Override - protected void handleCompleted() { - rm.done(); - } - }; - - int childRmCount = 0; - - for (int i = 0; i < getChildLayoutNodes().length; i++) { - if (getChildLayoutNodes()[i] instanceof IExpressionLayoutNode) { - IExpressionLayoutNode childNode = (IExpressionLayoutNode)getChildLayoutNodes()[i]; - if (childNode.getExpressionLength(expressionRemainder) > 0 && - childNode.getDeltaFlagsForExpression(expressionRemainder, event) != IModelDelta.NO_CHANGE) - { - childNode.buildDeltaForExpression( - expression, elementIdx, expressionRemainder, event, parentDelta, path, countingRm); - childRmCount++; - // The child node will call update.done(); - } - } - } - - countingRm.setDoneCount(childRmCount); - } - - - class ChildExpressionElementUpdate extends VMElementsUpdate { - private final TreePath fPath; - - ChildExpressionElementUpdate(IChildrenUpdate clientUpdate, TreePath path, DataRequestMonitor> rm) { - super(clientUpdate, 0, 1, rm); - fPath = path; - } - - @Override - public Object getElement() { - return fPath.getLastSegment(); - } - - @Override - public TreePath getElementPath() { - return fPath; - } - } -} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionVMNode.java new file mode 100644 index 00000000000..c5fbf8165d3 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionVMNode.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; + +import java.util.List; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.MultiRequestMonitor; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.dsf.ui.concurrent.ViewerDataRequestMonitor; +import org.eclipse.dd.dsf.ui.viewmodel.VMChildrenUpdate; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; +import org.eclipse.debug.core.model.IExpression; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; + +/** + * + */ +@SuppressWarnings("restriction") +public abstract class AbstractExpressionVMNode extends AbstractDMVMNode + implements IExpressionVMNode +{ + + public AbstractExpressionVMNode(AbstractDMVMProvider provider, DsfSession session, Class dmcClassType) { + super(provider, session, dmcClassType); + } + + public void update(final IExpressionUpdate update) { + if (!canParseExpression(update.getExpression())) { + update.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Invalid expression", null)); //$NON-NLS-1$ + update.done(); + return; + } + + update(new IChildrenUpdate[] { new VMChildrenUpdate( + update, -1, -1, + new ViewerDataRequestMonitor>(getExecutor(), update) { + @Override + protected void handleOK() { + if (getData().size() == 0) { + update.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "No contexts", null)); //$NON-NLS-1$ + update.done(); + } else { + final List elements = getData(); + + final MultiRequestMonitor> multiRm = new MultiRequestMonitor>(getExecutor(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + boolean foundMatchingContext = false; + for (int i = 0; i < getRequestMonitors().size(); i++) { + if (getRequestMonitors().get(i).getData()) { + Object element = elements.get(i); + associateExpression(element, update.getExpression()); + update.setExpressionElement(element); + foundMatchingContext = true; + break; + } + } + if (!foundMatchingContext) { + update.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Context not found", null)); //$NON-NLS-1$ + } + } else { + update.setStatus(getStatus()); + } + update.done(); + } + }; + + for (Object element : elements) { + testElementForExpression( + element, update.getExpression(), + multiRm.add( + new DataRequestMonitor(getExecutor(), null) { + @Override + protected void handleCompleted() { + multiRm.requestMonitorDone(this); + } + })); + } + } + } + + @Override + protected void handleErrorOrCancel() { + update.setStatus(getStatus()); + update.done(); + } + })} + ); + + } + + + @ConfinedToDsfExecutor("#getSession#getExecutor") + protected void testElementForExpression(Object element, IExpression expression, final DataRequestMonitor rm) { + rm.setData(false); + rm.done(); + } + + protected void associateExpression(Object element, IExpression expression) { + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerVMNode.java similarity index 60% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerLayoutNode.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerVMNode.java index 170a22ee6a0..e39d2c5b485 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerVMNode.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; +import java.util.LinkedList; import java.util.List; import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor; @@ -17,12 +18,10 @@ import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.ExpressionVMProvider.ExpressionsChangedEvent; -import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMLayoutNode; -import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; -import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; -import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; -import org.eclipse.dd.dsf.ui.viewmodel.VMElementsUpdate; -import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager; +import org.eclipse.dd.dsf.ui.concurrent.ViewerCountingRequestMonitor; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.IVMNode; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.IExpressionManager; import org.eclipse.debug.core.model.IExpression; @@ -35,30 +34,32 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdat import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; import org.eclipse.debug.ui.DebugUITools; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.ICellModifier; import org.eclipse.jface.viewers.TextCellEditor; +import org.eclipse.jface.viewers.TreePath; import org.eclipse.swt.widgets.Composite; /** - * This is the top-level layout node in the expressions view. Its job is to: + * This is the top-level view model node in the expressions view. Its job is to: *
  • *
      retrieve the {@link IExpression} objects from the global {@link IExpressionManager},
    *
      retrieve the expression string from the IExpression object,
    *
      then to call the configured expression nodes to parse the expression string.
    *
  • *

    - * This node is not intended to have any standard child layout nodes, therefore - * the implementation of {@link #setChildNodes(IVMLayoutNode[])} throws an exception. - * Instead users should call {@link #setExpressionLayoutNodes(IExpressionLayoutNode[])} - * to configure layout nodes that this node will delegate to when processing expressions. + * This node is not intended to have any standard child nodes, therefore + * the implementation of {@link #setChildNodes(IVMNode[])} throws an exception. + * Instead users should call {@link #setExpressionNodes(IExpressionVMNode[])} + * to configure the nodes that this node will delegate to when processing expressions. *

    */ @SuppressWarnings("restriction") -public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode +public class ExpressionManagerVMNode extends AbstractVMNode implements IElementLabelProvider, IElementEditor { @@ -68,11 +69,11 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode * error message in the view, and to allow the user to edit the * expression. */ - private class InvalidExpressionVMC extends AbstractVMContext { - final IExpression fExpression; + static class InvalidExpressionVMContext extends AbstractVMContext { + final private IExpression fExpression; - public InvalidExpressionVMC(IExpression expression) { - super(getVMProvider().getVMAdapter(), ExpressionManagerLayoutNode.this); + public InvalidExpressionVMContext(ExpressionManagerVMNode node, IExpression expression) { + super(node.getVMProvider().getVMAdapter(), node); fExpression = expression; } @@ -86,9 +87,13 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode } } + public IExpression getExpression() { + return fExpression; + } + @Override public boolean equals(Object obj) { - return obj instanceof InvalidExpressionVMC && ((InvalidExpressionVMC)obj).fExpression.equals(fExpression); + return obj instanceof InvalidExpressionVMContext && ((InvalidExpressionVMContext)obj).fExpression.equals(fExpression); } @Override @@ -96,14 +101,14 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode return fExpression.hashCode(); } } - + /** * VMC for a new expression object to be added. When user clicks on this node to * edit it, he will create a new expression. */ - public class NewExpressionVMC extends AbstractVMContext { + class NewExpressionVMC extends AbstractVMContext { public NewExpressionVMC() { - super(getVMProvider().getVMAdapter(), ExpressionManagerLayoutNode.this); + super(getVMProvider().getVMAdapter(), ExpressionManagerVMNode.this); } @Override @@ -123,20 +128,21 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode } } - /** Array of expression nodes which parse the user expressions and handle model events */ - private IExpressionLayoutNode[] fExpressionNodes = new IExpressionLayoutNode[0]; - /** Local reference to the global expression manager */ private IExpressionManager fManager = DebugPlugin.getDefault().getExpressionManager(); /** Cached reference to a cell modifier for editing expression strings of invalid expressions */ private WatchExpressionCellModifier fWatchExpressionCellModifier = new WatchExpressionCellModifier(); - public ExpressionManagerLayoutNode(AbstractVMProvider provider) { + public ExpressionManagerVMNode(ExpressionVMProvider provider) { super(provider); } - public void updateHasElements(IHasChildrenUpdate[] updates) { + private ExpressionVMProvider getExpressionVMProvider() { + return (ExpressionVMProvider)getVMProvider(); + } + + public void update(IHasChildrenUpdate[] updates) { // Test availability of children based on whether there are any expressions // in the manager. We assume that the getExpressions() will just read // local state data, so we don't bother using a job to perform this @@ -147,70 +153,70 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode } } - public void updateElementCount(IChildrenCountUpdate update) { - // We assume that the getExpressions() will just read local state data, - // so we don't bother using a job to perform this operation. - update.setChildCount(fManager.getExpressions().length + 1); - update.done(); + public void update(IChildrenCountUpdate[] updates) { + for (IChildrenCountUpdate update : updates) { + if (!checkUpdate(update)) continue; + + // We assume that the getExpressions() will just read local state data, + // so we don't bother using a job to perform this operation. + update.setChildCount(fManager.getExpressions().length + 1); + update.done(); + } } - public void updateElements(final IChildrenUpdate update) { + public void update(final IChildrenUpdate[] updates) { + for (IChildrenUpdate update : updates) { + doUpdateChildren(update); + } + } + + public void doUpdateChildren(final IChildrenUpdate update) { final IExpression[] expressions = fManager.getExpressions(); - + // For each (expression) element in update, find the layout node that can // parse it. And for each expression that has a corresponding layout node, // call IExpressionLayoutNode#getElementForExpression to generate a VMC. // Since the last is an async call, we need to create a multi-RM to wait // for all the calls to complete. - final CountingRequestMonitor multiRm = new CountingRequestMonitor(getExecutor(), null) { - @Override - protected void handleCompleted() { - update.done(); - } - }; + final CountingRequestMonitor multiRm = new ViewerCountingRequestMonitor(getVMProvider().getExecutor(), update); + int multiRmCount = 0; - int expressionRmCount = 0; for (int i = update.getOffset(); i < update.getOffset() + update.getLength() && i < expressions.length + 1; i++) { - - // The last element is the "new expression" - if (i == expressions.length) { - update.setChild(new NewExpressionVMC(), i); - } else { - final String expressionText = expressions[i].getExpressionText(); - final int expressionIdx = i; + if (i < expressions.length) { + multiRmCount++; + final int childIndex = i; final IExpression expression = expressions[i]; - IExpressionLayoutNode expressionNode = findNodeForExpression(expressionText); - if (expressionNode == null) { - update.setChild(new InvalidExpressionVMC(expression), i); - } else { - expressionRmCount++; - // getElementForExpression() accepts a IElementsUpdate as an argument. - // Construct an instance of VMElementsUpdate which will call a - // the request monitor when it is finished. The request monitor - // will in turn set the element in the update argument in this method. - VMElementsUpdate expressionElementUpdate = new VMElementsUpdate( - update, 0, 1, - new DataRequestMonitor>(getExecutor(), multiRm) { + // getElementForExpression() accepts a IElementsUpdate as an argument. + // Construct an instance of VMElementsUpdate which will call a + // the request monitor when it is finished. The request monitor + // will in turn set the element in the update argument in this method. + ((ExpressionVMProvider)getVMProvider()).update( + new VMExpressionUpdate( + update, expression, + new DataRequestMonitor(getVMProvider().getExecutor(), multiRm) { @Override protected void handleOK() { - update.setChild(getData().get(0), expressionIdx); + update.setChild(getData(), childIndex); multiRm.done(); } @Override protected void handleError() { - update.setChild(new InvalidExpressionVMC(expression), expressionIdx); + update.setChild(new InvalidExpressionVMContext(ExpressionManagerVMNode.this, expression), childIndex); multiRm.done(); } - }); - expressionNode.getElementForExpression(expressionElementUpdate, expressionText, expression); - } + }) + ); + } else { + // Last element in the list of expressions is the "add new expression" + // dummy entry. + update.setChild(new NewExpressionVMC(), i); } } - + // If no expressions were parsed, we're finished. // Set the count to the counting RM. - multiRm.setDoneCount(expressionRmCount); + multiRm.setDoneCount(multiRmCount); } public void update(ILabelUpdate[] updates) { @@ -218,8 +224,8 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode // The expression layout nodes are responsible for supplying label providers // for their VMCs. for (ILabelUpdate update : updates) { - if (update.getElement() instanceof InvalidExpressionVMC) { - updateInvalidExpressionVMCLabel(update, (InvalidExpressionVMC) update.getElement()); + if (update.getElement() instanceof InvalidExpressionVMContext) { + updateInvalidExpressionVMCLabel(update, (InvalidExpressionVMContext) update.getElement()); } else if (update.getElement() instanceof NewExpressionVMC) { updateNewExpressionVMCLabel(update, (NewExpressionVMC) update.getElement()); } else { @@ -231,16 +237,16 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode /** * Updates the label for the InvalidExpressionVMC. */ - private void updateInvalidExpressionVMCLabel(ILabelUpdate update, InvalidExpressionVMC vmc) { + private void updateInvalidExpressionVMCLabel(ILabelUpdate update, InvalidExpressionVMContext vmc) { String[] columnIds = update.getColumnIds() != null ? update.getColumnIds() : new String[] { IDebugVMConstants.COLUMN_ID__NAME }; for (int i = 0; i < columnIds.length; i++) { if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(columnIds[i])) { - update.setLabel(vmc.fExpression.getExpressionText(), i); + update.setLabel(vmc.getExpression().getExpressionText(), i); update.setImageDescriptor(DebugUITools.getImageDescriptor( IDebugUIConstants.IMG_OBJS_EXPRESSION ), i); } else if (IDebugVMConstants.COLUMN_ID__NAME.equals(columnIds[i])) { - update.setLabel(vmc.fExpression.getExpressionText(), i); + update.setLabel(vmc.getExpression().getExpressionText(), i); update.setImageDescriptor(DebugUITools.getImageDescriptor( IDebugUIConstants.IMG_OBJS_EXPRESSION ), i); } else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(columnIds[i])) { update.setLabel(MessagesForExpressionVM.ExpressionManagerLayoutNode__invalidExpression_valueColumn_label, i); @@ -275,54 +281,6 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode update.done(); } - - /** - * Convenience call that iterates through all the configured expression - * layout nodes and finds the first one that can parse the given expression. - */ - private IExpressionLayoutNode findNodeForExpression(String expressionText) { - for (IExpressionLayoutNode node : fExpressionNodes) { - if (node.getExpressionLength(expressionText) > 0) { - return node; - } - } - return null; - } - - /** - * ExpressionManagerLayoutNode does not support child layout nodes. - * @see #setExpressionLayoutNodes(IExpressionLayoutNode[]) - */ - @Override - public void setChildNodes(IVMLayoutNode[] childNodes) { - throw new UnsupportedOperationException("This node does not support children."); //$NON-NLS-1$ - } - - /** - * Configures the set of expression layout nodes that the expression manager layout - * node will use to parse the expressions. - *

    - * Note: The nodes specified in the array will be called to parse expressions, - * in the order as they are in the array. Therefore if one node is a "greedy" - * parser, and will accept any expression string, it should appear last in the list - * of the nodes. - *

    - * @param nodes Array of expression layout nodes to configure with the manager. - */ - public void setExpressionLayoutNodes(IExpressionLayoutNode[] nodes) { - fExpressionNodes = nodes; - } - - @Override - public void dispose() { - - for (IExpressionLayoutNode exprNode : fExpressionNodes) { - exprNode.dispose(); - } - super.dispose(); - } - - @Override public int getDeltaFlags(Object event) { int retVal = 0; @@ -331,52 +289,53 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode retVal |= IModelDelta.CONTENT; } - // If any of the expressions nodes have delta flags, that means that this - // node probably needs to generate a delta as well. Ideally, we would call - // IExpressionLayoutNode.getDeltaFlagsForExpression() here, but getDeltaFlags() - // is an optimization call anyway, and it's OK if it generates some false - // positives. We will call getDeltaFlagsForExpression in buildDelta() instead.. - for (IExpressionLayoutNode node : fExpressionNodes) { - retVal |= node.getDeltaFlags(event); + for (IExpression expression : fManager.getExpressions()) { + retVal |= getExpressionVMProvider().getDeltaFlagsForExpression(expression, event); } return retVal; } - @Override - public void buildDelta(final Object event, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) { + public void buildDelta(final Object event, final ModelDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) { // Add a flag if the list of expressions has changed. if (event instanceof ExpressionsChangedEvent) { - VMCacheManager.getVMCacheManager().flush(super.getVMProvider().getPresentationContext()); - parentDelta.addFlags(IModelDelta.CONTENT); + parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); } - // Once again, for each expression, find its corresponding layout node and ask that + // Once again, for each expression, find its corresponding node and ask that // layout node for its delta flags for given event. If there are delta flags to be // generated, call the asynchronous method to do so. - CountingRequestMonitor multiRm = new CountingRequestMonitor(getExecutor(), requestMonitor); + CountingRequestMonitor multiRm = new CountingRequestMonitor(getExecutor(), requestMonitor); + int buildDeltaForExpressionCallCount = 0; IExpression[] expressions = fManager.getExpressions(); for (int i = 0; i < expressions.length; i++ ) { - String expressionText = expressions[i].getExpressionText(); - IExpressionLayoutNode node = findNodeForExpression(expressionText); - if (node == null) continue; - - int flags = node.getDeltaFlagsForExpression(expressionText, event); - - // If the given node has no delta flags, skip it. + int flags = getExpressionVMProvider().getDeltaFlagsForExpression(expressions[i], event); + // If the given expression has no delta flags, skip it. if (flags == IModelDelta.NO_CHANGE) continue; - - node.buildDeltaForExpression(expressions[i], i + nodeOffset, expressionText, event, parentDelta, - getTreePathFromDelta(parentDelta), - new RequestMonitor(getExecutor(), multiRm)); + + int elementOffset = nodeOffset >= 0 ? nodeOffset + i : -1; + getExpressionVMProvider().buildDeltaForExpression( + expressions[i], elementOffset, event, parentDelta, getTreePathFromDelta(parentDelta), + new RequestMonitor(getExecutor(), multiRm)); buildDeltaForExpressionCallCount++; } multiRm.setDoneCount(buildDeltaForExpressionCallCount); } + private TreePath getTreePathFromDelta(IModelDelta delta) { + List elementList = new LinkedList(); + IModelDelta listDelta = delta; + elementList.add(0, listDelta.getElement()); + while (listDelta.getParentDelta() != null) { + elementList.add(0, listDelta.getElement()); + listDelta = listDelta.getParentDelta(); + } + return new TreePath(elementList.toArray()); + } + public CellEditor getCellEditor(IPresentationContext context, String columnId, Object element, Composite parent) { if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(columnId)) { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java index 0f21b57ad0b..c3d4ffac01e 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java @@ -10,51 +10,175 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; -import org.eclipse.dd.dsf.debug.ui.viewmodel.dm.AbstractDebugDMVMProviderWithCache; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.FormattedValuePreferenceStore; -import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterGroupLayoutNode; -import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterLayoutNode; +import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterGroupVMNode; +import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterVMNode; import org.eclipse.dd.dsf.debug.ui.viewmodel.register.SyncRegisterDataAccess; +import org.eclipse.dd.dsf.debug.ui.viewmodel.update.BreakpointHitUpdatePolicy; import org.eclipse.dd.dsf.debug.ui.viewmodel.variable.SyncVariableDataAccess; -import org.eclipse.dd.dsf.debug.ui.viewmodel.variable.VariableLayoutNode; +import org.eclipse.dd.dsf.debug.ui.viewmodel.variable.VariableVMNode; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; -import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; -import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; -import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode; -import org.eclipse.dd.dsf.ui.viewmodel.dm.DMVMRootLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.IRootVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.IVMModelProxy; +import org.eclipse.dd.dsf.ui.viewmodel.IVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.DefaultVMContentProviderStrategy; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.dm.RootDMVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.update.AutomaticUpdatePolicy; +import org.eclipse.dd.dsf.ui.viewmodel.update.IVMUpdatePolicy; +import org.eclipse.dd.dsf.ui.viewmodel.update.ManualUpdatePolicy; +import org.eclipse.dd.dsf.ui.viewmodel.update.UserEditEvent; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.model.IExpression; import org.eclipse.debug.internal.core.IExpressionsListener2; import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.TreePath; /** - * - */ + * The expression provider is used to populate the contents of the expressions + * view. The node hierarchy in this view is a little different than in a typical + * provider: the expression manager node should be registered as the single child + * of the root node and no nodes should be registered as children of expression node. + * Instead the top level expression nodes should be registered with a call to + * {@link #setExpressionNodes(IExpressionVMNode[])}. And each expression node can + * have its own sub-hierarchy of elements as needed. However all nodes configured + * with this provider (with the exception of the root and the expression manager) + * should implement {@link IExpressionVMNode}. + */ @SuppressWarnings("restriction") -public class ExpressionVMProvider extends AbstractDebugDMVMProviderWithCache implements IExpressionsListener2 +public class ExpressionVMProvider extends AbstractDMVMProvider + implements IPropertyChangeListener, IExpressionsListener2 { - public static class ExpressionsChangedEvent { + /** + * Object representing a change in configured expressions. This event is + * object is used when generating a model delta. + */ + public static class ExpressionsChangedEvent extends UserEditEvent { enum Type {ADDED, CHANGED, REMOVED, MOVED, INSERTED} public final Type fType; - public final IExpression[] fExpressions; - public ExpressionsChangedEvent(Type type, IExpression[] expressions) { + public ExpressionsChangedEvent(Type type, Set elements) { + super(elements); fType = type; - fExpressions = expressions; } } + + private IExpressionVMNode[] fExpressionNodes; public ExpressionVMProvider(AbstractVMAdapter adapter, IPresentationContext context, DsfSession session) { super(adapter, context, session); + context.addPropertyChangeListener(this); + // The VM provider has to handle all events that result in model deltas. // Add the provider as listener to expression changes events. DebugPlugin.getDefault().getExpressionManager().addExpressionListener(this); - + configureLayout(); } + + @Override + protected DefaultVMContentProviderStrategy createContentStrategy() { + return new ExpressionVMProviderContentStragegy(this); + } + @Override + protected IVMModelProxy createModelProxyStrategy(Object rootElement) { + return new ExpressionVMProviderModelProxyStrategy(this, rootElement); + } + + /** + * Updates the given expression element. This method is used by the + * expression manager node to obtain a view model element based on the + * {@link IExpression} retrieved from the expression manager. The + * implementation of this method (which is in the content strategy), + * checks the configured expression nodes to see which one can + * process the given expression, when it finds it it delegates + * to that expression node's {@link IExpressionVMNode#update(IExpressionUpdate)} + * method. + * @param update Expression update to process. + */ + public void update(IExpressionUpdate update) { + ((ExpressionVMProviderContentStragegy)getContentStrategy()).update(update); + } + + /** + * Retrieves the delta flags that can be generated for the given expression + * and the given event. This method is used by the + * expression manager node to obtain the delta flags based on the + * {@link IExpression} retrieved from the expression manager. The + * implementation of this method (which is in the model proxy strategy), + * checks the configured expression nodes to see which one can + * process the given expression, when it finds it it delegates + * to that expression node's {@link IExpressionVMNode#getDeltaFlagsForExpression(IExpression, Object)} + * method. + */ + public int getDeltaFlagsForExpression(IExpression expression, Object event) { + // Workaround: find the first active proxy and use it. + if (!getActiveModelProxies().isEmpty()) { + return ((ExpressionVMProviderModelProxyStrategy)getActiveModelProxies().get(0)).getDeltaFlagsForExpression(expression, event); + } + return 0; + } + + /** + * Builds the model delta based on the given expression + * and the given event. This method is used by the + * expression manager to build the delta based on the + * {@link IExpression} retrieved from the expression manager. The + * implementation of this method (which is in the model proxy strategy), + * checks the configured expression nodes to see which one can + * process the given expression, when it finds it it delegates + * to that expression node's {@link IExpressionVMNode#buildDeltaForExpression(IExpression, int, Object, ModelDelta, TreePath, RequestMonitor)} + * and {@link IExpressionVMNode#buildDeltaForExpressionElement(Object, int, Object, ModelDelta, RequestMonitor) + * methods. + */ + public void buildDeltaForExpression(final IExpression expression, final int expressionElementIdx, final Object event, + final ModelDelta parentDelta, final TreePath path, final RequestMonitor rm) + { + // Workaround: find the first active proxy and use it. + if (!getActiveModelProxies().isEmpty()) { + ((ExpressionVMProviderModelProxyStrategy)getActiveModelProxies().get(0)).buildDeltaForExpression( + expression, expressionElementIdx, event, parentDelta, path, rm); + } else { + rm.done(); + } + } + + /** + * Configures the given nodes as the top-level expression nodes. + */ + protected void setExpressionNodes(IExpressionVMNode[] nodes) { + fExpressionNodes = nodes; + + // Call the base class to make sure that the nodes are also + // returned by the getAllNodes method. + for (IExpressionVMNode node : nodes) { + addNode(node); + } + } + + /** + * Returns the list of configured top-level expression nodes. + * @return + */ + public IExpressionVMNode[] getExpressionNodes() { + return fExpressionNodes; + } + + /** + * Configures the nodes of this provider. This method may be overriden by + * sub classes to create an alternate configuration in this provider. + */ protected void configureLayout() { /* @@ -66,29 +190,30 @@ public class ExpressionVMProvider extends AbstractDebugDMVMProviderWithCache imp /* * Create the top level node which provides the anchor starting point. */ - IVMRootLayoutNode debugViewSelectionNode = new DMVMRootLayoutNode(this); + IRootVMNode rootNode = new RootDMVMNode(this); /* * Now the Overarching management node. */ - ExpressionManagerLayoutNode expressionManagerNode = new ExpressionManagerLayoutNode(this); - debugViewSelectionNode.setChildNodes(new IVMLayoutNode[] {expressionManagerNode}); + ExpressionManagerVMNode expressionManagerNode = new ExpressionManagerVMNode(this); + addChildNodes(rootNode, new IVMNode[] {expressionManagerNode}); /* * The expression view wants to support fully all of the components of the register view. */ - IExpressionLayoutNode registerGroupNode = new RegisterGroupLayoutNode(this, getSession(), syncRegDataAccess); - IVMLayoutNode registerNode = new RegisterLayoutNode(FormattedValuePreferenceStore.getDefault(), this, getSession(), syncRegDataAccess); - registerGroupNode.setChildNodes(new IVMLayoutNode[] { registerNode }); + IExpressionVMNode registerGroupNode = new RegisterGroupVMNode(this, getSession(), syncRegDataAccess); + + IExpressionVMNode registerNode = new RegisterVMNode(FormattedValuePreferenceStore.getDefault(), this, getSession(), syncRegDataAccess); + addChildNodes(registerGroupNode, new IExpressionVMNode[] {registerNode}); /* * Create the support for the SubExpressions. Anything which is brought into the expressions * view comes in as a fully qualified expression so we go directly to the SubExpression layout * node. */ - IExpressionLayoutNode subExpressioNode = - - new VariableLayoutNode(FormattedValuePreferenceStore.getDefault(), this, getSession(), syncvarDataAccess); + IExpressionVMNode variableNode = + new VariableVMNode(FormattedValuePreferenceStore.getDefault(), this, getSession(), syncvarDataAccess); + addChildNodes(variableNode, new IExpressionVMNode[] {variableNode}); /* * Tell the expression node which subnodes it will directly support. It is very important @@ -101,17 +226,54 @@ public class ExpressionVMProvider extends AbstractDebugDMVMProviderWithCache imp * assume what it was passed was for it and the real node which wants to handle it would be * left out in the cold. */ - expressionManagerNode.setExpressionLayoutNodes(new IExpressionLayoutNode[] { registerGroupNode, subExpressioNode }); + setExpressionNodes(new IExpressionVMNode[] {registerGroupNode, variableNode}); /* * Let the work know which is the top level node. */ - setRootLayoutNode(debugViewSelectionNode); + setRootNode(rootNode); } + + /** + * Finds the expression node which can parse the given expression. This + * method is used by the expression content and model proxy strategies. + * + * @param parentNode The parent of the nodes to search. If null, + * then the top level expressions will be searched. + * @param expression The expression object. + * @return The matching expression node. + */ + public IExpressionVMNode findNodeToParseExpression(IExpressionVMNode parentNode, IExpression expression) { + IVMNode[] childNOdes; + if (parentNode == null) { + childNOdes = getExpressionNodes(); + } else { + childNOdes = getChildVMNodes(parentNode); + } + for (IVMNode childNode : childNOdes) { + if (childNode instanceof IExpressionVMNode) { + IExpressionVMNode childExpressionNode = (IExpressionVMNode)childNode; + if (childExpressionNode.canParseExpression(expression)) { + return childExpressionNode; + } else if (!childExpressionNode.equals(parentNode)) { + // The above check is to make sure that child isn't the same as + // parent to avoid recursive loops. + IExpressionVMNode matchingNode = + findNodeToParseExpression(childExpressionNode, expression); + if (matchingNode != null) { + return matchingNode; + } + } + } + } + return null; + } + @Override public void dispose() { DebugPlugin.getDefault().getExpressionManager().removeExpressionListener(this); + getPresentationContext().removePropertyChangeListener(this); super.dispose(); } @@ -125,49 +287,42 @@ public class ExpressionVMProvider extends AbstractDebugDMVMProviderWithCache imp return ExpressionColumnPresentation.ID; } - /** - * Override this operation to avoid the standard test of isOurLayoutNode(), - * which does not take into account {@link ExpressionManagerLayoutNode.setExpressionLayoutNodes} - * nodes. - */ @Override - protected IVMLayoutNode getLayoutNodeForElement(Object element) { - /* - * First check to see if the parent object is the root object of the - * hierarchy. If that's the case, then retrieve the correcponding - * root VMC from the root node, and pass this root vmc to the root's - * child layout nodes. - */ - IVMRootLayoutNode rootLayoutNode = getRootLayoutNode(); - if (rootLayoutNode == null) { - return null; - } - else if (element.equals(getRootElement())) { - return rootLayoutNode; - } - else if (element instanceof IVMContext){ - return ((IVMContext)element).getLayoutNode(); - } - return null; + protected IVMUpdatePolicy[] createUpdateModes() { + return new IVMUpdatePolicy[] { new AutomaticUpdatePolicy(), new ManualUpdatePolicy(), new BreakpointHitUpdatePolicy() }; + } + + public void propertyChange(PropertyChangeEvent event) { + handleEvent(event); } public void expressionsAdded(IExpression[] expressions) { - handleEvent(new ExpressionsChangedEvent(ExpressionsChangedEvent.Type.ADDED, expressions)); - } - - public void expressionsChanged(IExpression[] expressions) { - handleEvent(new ExpressionsChangedEvent(ExpressionsChangedEvent.Type.CHANGED, expressions)); + expressionsListChanged(ExpressionsChangedEvent.Type.ADDED); } public void expressionsRemoved(IExpression[] expressions) { - handleEvent(new ExpressionsChangedEvent(ExpressionsChangedEvent.Type.REMOVED, expressions)); + expressionsListChanged(ExpressionsChangedEvent.Type.REMOVED); } public void expressionsInserted(IExpression[] expressions, int index) { - handleEvent(new ExpressionsChangedEvent(ExpressionsChangedEvent.Type.INSERTED, expressions)); + expressionsListChanged(ExpressionsChangedEvent.Type.INSERTED); } public void expressionsMoved(IExpression[] expressions, int index) { - handleEvent(new ExpressionsChangedEvent(ExpressionsChangedEvent.Type.MOVED, expressions)); + expressionsListChanged(ExpressionsChangedEvent.Type.MOVED); + } + + public void expressionsChanged(IExpression[] expressions) { + Set expressionsSet = new HashSet(); + expressionsSet.addAll(Arrays.asList(expressions)); + handleEvent(new ExpressionsChangedEvent(ExpressionsChangedEvent.Type.CHANGED, expressionsSet)); + } + + private void expressionsListChanged(ExpressionsChangedEvent.Type type) { + Set rootElements = new HashSet(); + for (IVMModelProxy proxy : getActiveModelProxies()) { + rootElements.add(proxy.getRootElement()); + } + handleEvent(new ExpressionsChangedEvent(type, rootElements)); } } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderContentStragegy.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderContentStragegy.java new file mode 100644 index 00000000000..68fe43293aa --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderContentStragegy.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.dsf.ui.concurrent.ViewerDataRequestMonitor; +import org.eclipse.dd.dsf.ui.viewmodel.DefaultVMContentProviderStrategy; + +/** + * The IElementContentProvider implementation to be used with an expression + * view model provider. + * + * @see ExpressionVMProvider + */ +@SuppressWarnings("restriction") +public class ExpressionVMProviderContentStragegy extends DefaultVMContentProviderStrategy { + public ExpressionVMProviderContentStragegy(ExpressionVMProvider provider) { + super(provider); + } + + private ExpressionVMProvider getExpressionVMProvider() { + return (ExpressionVMProvider)getVMProvider(); + } + + public void update(final IExpressionUpdate update) { + final IExpressionVMNode matchingNode = + getExpressionVMProvider().findNodeToParseExpression(null, update.getExpression()); + + if (matchingNode != null) { + updateExpressionWithNode(matchingNode, update); + } else { + update.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, "Cannot parse expression", null)); //$NON-NLS-1$ + update.done(); + } + } + + private void updateExpressionWithNode(final IExpressionVMNode node, final IExpressionUpdate update) { + // Call the expression node to parse the expression and fill in the value. + node.update( + new VMExpressionUpdate( + update, update.getExpression(), + new ViewerDataRequestMonitor(getVMProvider().getExecutor(), update) { + @Override + protected void handleOK() { + // Check if the evaluated node has child expression nodes. + // If it does, check if any of those nodes can evaluate the given + // expression further. If they can, call the child node to further + // process the expression. Otherwise we found our element and + // we're done. + final IExpressionVMNode matchingNode = getExpressionVMProvider(). + findNodeToParseExpression(node, update.getExpression()); + + if (matchingNode != null && !matchingNode.equals(node)) { + updateExpressionWithNode( + matchingNode, + new VMExpressionUpdate( + update.getElementPath().createChildPath(getData()), update.getViewerInput(), + update.getPresentationContext(), update.getExpression(), + new ViewerDataRequestMonitor(getVMProvider().getExecutor(), update) { + + @Override + protected void handleOK() { + update.setExpressionElement(getData()); + update.done(); + } + }) + ); + } else { + update.setExpressionElement(getData()); + update.done(); + } + } + }) + ); + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderModelProxyStrategy.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderModelProxyStrategy.java new file mode 100644 index 00000000000..f17aabc25a2 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderModelProxyStrategy.java @@ -0,0 +1,134 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; + +import java.util.Map; + +import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.ui.viewmodel.IVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.DefaultVMModelProxyStrategy; +import org.eclipse.debug.core.model.IExpression; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; +import org.eclipse.jface.viewers.TreePath; + +/** + * The IModelProxy implementation to be used with an expression + * view model provider. + * + * @see ExpressionVMProvider + */ +@SuppressWarnings("restriction") +public class ExpressionVMProviderModelProxyStrategy extends DefaultVMModelProxyStrategy { + + public ExpressionVMProviderModelProxyStrategy(ExpressionVMProvider provider, Object rootElement) { + super(provider, rootElement); + } + + private ExpressionVMProvider getExpressionVMProvider() { + return (ExpressionVMProvider)getVMProvider(); + } + + public int getDeltaFlagsForExpression(IExpression expression, Object event) { + final IExpressionVMNode matchingNode = getExpressionVMProvider().findNodeToParseExpression(null, expression); + + if (matchingNode != null) { + return getNodeDeltaFlagsForExpression(matchingNode, expression, event); + } + return IModelDelta.NO_CHANGE; + } + + private int getNodeDeltaFlagsForExpression(IExpressionVMNode node, IExpression expression, Object event) { + int flags = node.getDeltaFlagsForExpression(expression, event); + + IExpressionVMNode matchingNode = getExpressionVMProvider().findNodeToParseExpression(node, expression); + if (matchingNode != null && !matchingNode.equals(node)) { + flags = flags | getNodeDeltaFlagsForExpression(matchingNode, expression, event); + } + return flags; + } + + public void buildDeltaForExpression(IExpression expression, int expressionElementIdx, Object event, + ModelDelta parentDelta, TreePath path, RequestMonitor rm) + { + final IExpressionVMNode matchingNode = getExpressionVMProvider().findNodeToParseExpression(null, expression); + + if (matchingNode != null) { + buildNodeDeltaForExpression(matchingNode, expression, expressionElementIdx, event, + parentDelta, path, rm); + } else { + rm.done(); + } + } + + private void buildNodeDeltaForExpression(final IExpressionVMNode node, final IExpression expression, + final int expressionElementIdx, final Object event, final ModelDelta parentDelta, final TreePath path, + final RequestMonitor rm) + { + node.buildDeltaForExpression( + expression, expressionElementIdx, event, parentDelta, path, + new RequestMonitor(getVMProvider().getExecutor(), rm) { + @Override + protected void handleOK() { + final IExpressionVMNode matchingNode = + getExpressionVMProvider().findNodeToParseExpression(node, expression); + if (matchingNode != null && !matchingNode.equals(node)) { + buildNodeDeltaForExpression( + matchingNode, expression, expressionElementIdx, event, parentDelta, path, rm); + } else { + getExpressionVMProvider().update(new VMExpressionUpdate( + parentDelta, getVMProvider().getPresentationContext(), expression, + new DataRequestMonitor(getVMProvider().getExecutor(), rm) { + @Override + protected void handleOK() { + buildDeltaForExpressionElement( + node, getData(), expressionElementIdx, event, parentDelta, path, rm); + } + + @Override + protected void handleError() { + // Avoid propagating the error to avoid processing the delta by + // all nodes. + rm.done(); + } + })); + } + } + }); + } + + private void buildDeltaForExpressionElement(final IExpressionVMNode node, Object expressionElement, + final int expressionElementIdx, final Object event, final ModelDelta parentDelta, final TreePath path, + final RequestMonitor rm) + { + CountingRequestMonitor multiRm = new CountingRequestMonitor(getVMProvider().getExecutor(), rm); + int multiRmCount = 0; + + node.buildDeltaForExpressionElement(expressionElement, expressionElementIdx, event, parentDelta, multiRm); + multiRmCount++; + + // Find the child nodes that have deltas for the given event. + Map childNodesWithDeltaFlags = getChildNodesWithDeltaFlags(node, parentDelta, event); + + // If no child layout nodes have deltas we can stop here. + if (childNodesWithDeltaFlags.size() != 0) { + callChildNodesToBuildDelta( + node, childNodesWithDeltaFlags, + parentDelta.addNode(expressionElement, expressionElementIdx, IModelDelta.NO_CHANGE), + event, multiRm); + multiRmCount++; + } + + multiRm.setDoneCount(multiRmCount); + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionLayoutNode.java deleted file mode 100644 index 782ba7784a0..00000000000 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionLayoutNode.java +++ /dev/null @@ -1,55 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; - -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; -import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; -import org.eclipse.debug.core.model.IExpression; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; -import org.eclipse.jface.viewers.TreePath; - -/** - * Interface for layout nodes that can be used within the expression view. - * The methods of this interface allow the {@link ExpressionManagerLayoutNode} - * to use this layout node to delegate expression parsing to this node, and to - * generate deltas for expressions that are owned by this node. - */ -@SuppressWarnings("restriction") -public interface IExpressionLayoutNode extends IVMLayoutNode { - - /** - * Returns the length of the portion of the expression that can be parsed - * by this node. - * @param expression String to parse - * @return length of the expression recognized by this node. Length of less than 1 - * indicates that this node cannot parse this expression. - */ - int getExpressionLength(String expression); - - /** - * Retrieves the element for the given expression. The node implementing - * this method should parse the expression and set a valid view model - * context (VMC) element in the update provided as an argument. - * @param update to fill in with the element. The tree path in this update - * object may contain elements which are not actually displayed in the viewer. - * These element may have been added to the original path by other expression - * layout nodes that have parsed preceding parts of the expression. - * @param expressionText expression string to parse - * @param expression expression object that the returned element should contain - */ - void getElementForExpression(IChildrenUpdate update, String expressionText, IExpression expression); - - int getDeltaFlagsForExpression(String expressionText, Object event); - - void buildDeltaForExpression(IExpression expression, int elementIdx, String expressionText, Object event, - VMDelta parentDelta, TreePath path, RequestMonitor rm); -} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionUpdate.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionUpdate.java new file mode 100644 index 00000000000..822a4ec0cc2 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionUpdate.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; + +import org.eclipse.debug.core.model.IExpression; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; + +/** + * An update for an element based on the given expression. The provider processing + * this update needs to create an expression element based on the tree path and the + * expression object in this update. + */ +@SuppressWarnings("restriction") +public interface IExpressionUpdate extends IViewerUpdate { + + /** + * Returns the expression object for this update. + */ + public IExpression getExpression(); + + /** + * Sets the element to the update. The element is to be calculated by the provider + * handling the update. + */ + public void setExpressionElement(Object element); +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionVMNode.java new file mode 100644 index 00000000000..56ef08b816a --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionVMNode.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; + +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.ui.viewmodel.IVMNode; +import org.eclipse.debug.core.model.IExpression; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; +import org.eclipse.jface.viewers.TreePath; + +/** + * Interface for view model nodes that can be used within the expression view. + * The methods of this interface allow the {@link ExpressionManagerVMNode} + * to use this node to delegate expression parsing to this node, and to + * generate deltas for expressions that are owned by this node. + */ +@SuppressWarnings("restriction") +public interface IExpressionVMNode extends IVMNode { + + /** + * Returns whether the given expression node recognizes and can parse the given + * expression. + * @param expression Expression that needs to be parsed. + * @return true if expression can be parsed + */ + public boolean canParseExpression(IExpression expression); + + /** + * Asynchronously fills in the given expression update. + * @param update Update to complete. + */ + public void update(IExpressionUpdate update); + + /** + * Returns the flags that this node can generate for the given expression and + * event. + */ + public int getDeltaFlagsForExpression(IExpression expression, Object event); + + /** + * Adds delta flags to the given parent delta based on the expression object + * given. + */ + public void buildDeltaForExpression(IExpression expression, int elementIdx, Object event, ModelDelta parentDelta, + TreePath path, RequestMonitor rm); + + /** + * Adds delta to the given parent delta based on the given element which was created base on + * an expression parsed by this node. + */ + public void buildDeltaForExpressionElement(Object element, int elementIdx, Object event, ModelDelta parentDelta, final RequestMonitor rm); +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/VMExpressionUpdate.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/VMExpressionUpdate.java new file mode 100644 index 00000000000..3c74a22fc17 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/VMExpressionUpdate.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.dsf.ui.DsfUIPlugin; +import org.eclipse.dd.dsf.ui.viewmodel.VMViewerUpdate; +import org.eclipse.debug.core.model.IExpression; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; +import org.eclipse.jface.viewers.TreePath; + +/** + * + */ +@SuppressWarnings("restriction") +class VMExpressionUpdate extends VMViewerUpdate implements IExpressionUpdate { + + private final IExpression fExpression; + private Object fExpressionElement; + + public VMExpressionUpdate(IViewerUpdate clientUpdate, IExpression expression, DataRequestMonitor rm) + { + super(clientUpdate, rm); + fExpression = expression; + } + + public VMExpressionUpdate(IModelDelta delta, IPresentationContext presentationContext, IExpression expression, DataRequestMonitor rm) + { + super(delta, presentationContext, rm); + fExpression = expression; + } + + public VMExpressionUpdate(TreePath elementPath, Object viewerInput, IPresentationContext presentationContext, IExpression expression, DataRequestMonitor rm) + { + super(elementPath, viewerInput, presentationContext, rm); + fExpression = expression; + } + + + public IExpression getExpression() { + return fExpression; + } + + + public void setExpressionElement(Object element) { + fExpressionElement = element; + } + + @Override + public String toString() { + return "VMExpressionUpdate for elements under parent = " + getElement() + ", in for expression " + getExpression().getExpressionText(); //$NON-NLS-1$ //$NON-NLS-2$ + } + + @Override + public void done() { + @SuppressWarnings("unchecked") + + DataRequestMonitor rm = (DataRequestMonitor)getRequestMonitor(); + if (fExpressionElement != null) { + rm.setData(fExpressionElement); + } else if (rm.getStatus().isOK()) { + rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, "Incomplete elements of updates", null)); //$NON-NLS-1$ + } + super.done(); + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/WatchExpressionCellModifier.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/WatchExpressionCellModifier.java index ab65a47f772..c1fde17b8af 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/WatchExpressionCellModifier.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/WatchExpressionCellModifier.java @@ -13,7 +13,7 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.dd.dsf.concurrent.ThreadSafeAndProhibitedFromDsfExecutor; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; -import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.ExpressionManagerLayoutNode.NewExpressionVMC; +import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.ExpressionManagerVMNode.NewExpressionVMC; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.IExpressionManager; import org.eclipse.debug.core.model.IWatchExpression; @@ -22,7 +22,6 @@ import org.eclipse.jface.viewers.ICellModifier; /** * */ -@SuppressWarnings("restriction") @ThreadSafeAndProhibitedFromDsfExecutor("") public class WatchExpressionCellModifier implements ICellModifier { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/LaunchRootVMNode.java similarity index 53% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/LaunchRootVMNode.java index 7b3516ced4d..bedac741b08 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardLaunchRootLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/LaunchRootVMNode.java @@ -12,15 +12,15 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.launch; import java.util.Arrays; import java.util.List; -import java.util.Map; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; -import org.eclipse.dd.dsf.ui.viewmodel.VMRootLayoutNode; -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.dd.dsf.ui.viewmodel.IRootVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.RootVMNode; import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; @@ -28,6 +28,7 @@ import org.eclipse.debug.core.ILaunchManager; import org.eclipse.debug.core.model.IDebugElement; import org.eclipse.debug.core.model.IProcess; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; /** * Layout node for the standard ILaunch object. This node can only be used at @@ -35,8 +36,8 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; * functionality, so the default adapters should be used to retrieve the label. */ @SuppressWarnings("restriction") -public class StandardLaunchRootLayoutNode extends VMRootLayoutNode - implements IVMRootLayoutNode +public class LaunchRootVMNode extends RootVMNode + implements IRootVMNode { public static class LaunchesEvent { public enum Type { ADDED, REMOVED, CHANGED, TERMINATED } @@ -49,92 +50,76 @@ public class StandardLaunchRootLayoutNode extends VMRootLayoutNode } } - final private ILaunch fLaunch; - public StandardLaunchRootLayoutNode(AbstractVMProvider provider, ILaunch launch) { + public LaunchRootVMNode(AbstractVMProvider provider) { super(provider); - fLaunch = launch; } @Override - public int getDeltaFlags(Object e) { + public boolean isDeltaEvent(Object rootObject, Object e) { if (e instanceof DebugEvent) { DebugEvent de = (DebugEvent)e; if (de.getSource() instanceof IProcess && - !((IProcess)de.getSource()).getLaunch().equals(fLaunch) ) + !((IProcess)de.getSource()).getLaunch().equals(rootObject) ) { - return IModelDelta.NO_CHANGE; + return false; } else if (de.getSource() instanceof IDebugElement && - !fLaunch.equals(((IDebugElement)de.getSource()).getLaunch())) + !rootObject.equals(((IDebugElement)de.getSource()).getLaunch())) { - return IModelDelta.NO_CHANGE; + return false; } } + return true; + } + + @Override + public int getDeltaFlags(Object e) { int flags = 0; if (e instanceof LaunchesEvent) { LaunchesEvent le = (LaunchesEvent)e; - for (ILaunch launch : le.fLaunches) { - if (fLaunch == launch) { - if (le.fType == LaunchesEvent.Type.CHANGED) { - flags = IModelDelta.STATE | IModelDelta.CONTENT; - } else if (le.fType == LaunchesEvent.Type.TERMINATED) { - flags = IModelDelta.STATE | IModelDelta.CONTENT; - } - } + if (le.fType == LaunchesEvent.Type.CHANGED || le.fType == LaunchesEvent.Type.TERMINATED) { + flags = IModelDelta.STATE | IModelDelta.CONTENT; } } - return flags | super.getDeltaFlags(e); + return flags; } @Override - public void createDelta(Object event, final DataRequestMonitor rm) { + public void createRootDelta(Object rootObject, Object event, final DataRequestMonitor rm) { + if (!(rootObject instanceof ILaunch)) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Invalid root element configured with launch root node.", null)); //$NON-NLS-1$ + return; + } + + ILaunch rootLaunch = (ILaunch)rootObject; + /* * 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. + * root of the view, create the delta with the path to the launch. */ ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager(); List launchList = Arrays.asList(manager.getLaunches()); - final VMDelta viewRootDelta = new VMDelta(manager, 0, IModelDelta.NO_CHANGE, launchList.size()); - final VMDelta rootDelta = viewRootDelta.addNode(getRootObject(), launchList.indexOf(fLaunch), IModelDelta.NO_CHANGE); + final ModelDelta viewRootDelta = new ModelDelta(manager, 0, IModelDelta.NO_CHANGE, launchList.size()); + final ModelDelta rootDelta = viewRootDelta.addNode(rootLaunch, launchList.indexOf(rootLaunch), IModelDelta.NO_CHANGE); // Generate delta for launch node. if (event instanceof LaunchesEvent) { LaunchesEvent le = (LaunchesEvent)event; for (ILaunch launch : le.fLaunches) { - if (fLaunch == launch) { + if (rootLaunch == launch) { if (le.fType == LaunchesEvent.Type.CHANGED) { - rootDelta.addFlags(IModelDelta.STATE | IModelDelta.CONTENT); + rootDelta.setFlags(rootDelta.getFlags() | IModelDelta.STATE | IModelDelta.CONTENT); } else if (le.fType == LaunchesEvent.Type.TERMINATED) { - rootDelta.addFlags(IModelDelta.STATE | IModelDelta.CONTENT); + rootDelta.setFlags(rootDelta.getFlags() | IModelDelta.STATE | IModelDelta.CONTENT); } } } } - // Call the child nodes to generate their delta. - Map childNodeDeltas = getChildNodesWithDeltaFlags(event); - if (childNodeDeltas.size() != 0) { - callChildNodesToBuildDelta( - childNodeDeltas, rootDelta, event, - new RequestMonitor(getExecutor(), rm) { - @Override - public void handleOK() { - if (isDisposed()) return; - rm.setData(viewRootDelta); - rm.done(); - } - }); - } else { - rm.setData(viewRootDelta); - rm.done(); - } + rm.setData(rootDelta); + rm.done(); } - @Override - public Object getRootObject() { - return fLaunch; - } } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java similarity index 79% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java index 6738a2f4e10..3a913d371cb 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java @@ -11,11 +11,12 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.launch; import java.util.List; +import java.util.concurrent.RejectedExecutionException; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.DMContexts; -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; @@ -28,50 +29,51 @@ import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMData; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; -import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; -import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; -import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager; +import org.eclipse.dd.dsf.ui.viewmodel.VMChildrenUpdate; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; import org.eclipse.debug.ui.DebugUITools; import org.eclipse.debug.ui.IDebugUIConstants; @SuppressWarnings("restriction") -public class StackFramesLayoutNode extends AbstractDMVMLayoutNode { +public class StackFramesVMNode extends AbstractDMVMNode + implements IElementLabelProvider +{ public IVMContext[] fCachedOldFrameVMCs; - public StackFramesLayoutNode(AbstractVMProvider provider, DsfSession session) { + public StackFramesVMNode(AbstractDMVMProvider provider, DsfSession session) { super(provider, session, IStack.IFrameDMContext.class); } @Override - protected void updateHasElementsInSessionThread(IHasChildrenUpdate[] updates) { + protected void updateHasElementsInSessionThread(IHasChildrenUpdate update) { + if (!checkService(IStack.class, null, update)) return; - for (IHasChildrenUpdate update : updates) { - if (!checkService(IStack.class, null, update)) return; - - IExecutionDMContext execDmc = findDmcInPath(update.getElementPath(), IExecutionDMContext.class); - if (execDmc == null) { - handleFailedUpdate(update); - return; - } - - update.setHasChilren(getServicesTracker().getService(IStack.class).isStackAvailable(execDmc)); - update.done(); - } + IExecutionDMContext execDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IExecutionDMContext.class); + if (execDmc == null) { + handleFailedUpdate(update); + return; + } + + update.setHasChilren(getServicesTracker().getService(IStack.class).isStackAvailable(execDmc)); + update.done(); } @Override protected void updateElementsInSessionThread(final IChildrenUpdate update) { if (!checkService(IStack.class, null, update)) return; - final IExecutionDMContext execDmc = findDmcInPath(update.getElementPath(), IExecutionDMContext.class); + final IExecutionDMContext execDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IExecutionDMContext.class); if (execDmc == null) { handleFailedUpdate(update); return; @@ -110,7 +112,7 @@ public class StackFramesLayoutNode extends AbstractDMVMLayoutNode { * @see #getElements(IVMContext, DataRequestMonitor) */ private void getElementsTopStackFrameOnly(final IChildrenUpdate update) { - final IExecutionDMContext execDmc = findDmcInPath(update.getElementPath(), IExecutionDMContext.class); + final IExecutionDMContext execDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IExecutionDMContext.class); if (execDmc == null) { handleFailedUpdate(update); return; @@ -118,7 +120,7 @@ public class StackFramesLayoutNode extends AbstractDMVMLayoutNode { getServicesTracker().getService(IStack.class).getTopFrame( execDmc, - new DataRequestMonitor(getSession().getExecutor(), null) { + new DataRequestMonitor(getExecutor(), null) { @Override public void handleCompleted() { if (!getStatus().isOK()) { @@ -126,7 +128,7 @@ public class StackFramesLayoutNode extends AbstractDMVMLayoutNode { return; } - IVMContext topFrameVmc = new DMVMContext(getData()); + IVMContext topFrameVmc = createVMContext(getData()); update.setChild(topFrameVmc, 0); // If there are old frames cached, use them and only substitute the top frame object. Otherwise, create @@ -143,14 +145,29 @@ public class StackFramesLayoutNode extends AbstractDMVMLayoutNode { }); } - @Override + + public void update(final ILabelUpdate[] updates) { + try { + getSession().getExecutor().execute(new DsfRunnable() { + public void run() { + updateLabelInSessionThread(updates); + }}); + } catch (RejectedExecutionException e) { + for (ILabelUpdate update : updates) { + handleFailedUpdate(update); + } + } + } + + protected void updateLabelInSessionThread(ILabelUpdate[] updates) { for (final ILabelUpdate update : updates) { - final IFrameDMContext dmc = findDmcInPath(update.getElementPath(), IFrameDMContext.class); + final IFrameDMContext dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IFrameDMContext.class); if (!checkDmc(dmc, update) || !checkService(IStack.class, null, update)) continue; - VMCacheManager.getVMCacheManager().getCache(update.getPresentationContext()) - .getModelData(getServicesTracker().getService(IStack.class, null), + getDMVMProvider().getModelData( + this, update, + getServicesTracker().getService(IStack.class, null), dmc, new DataRequestMonitor(getSession().getExecutor(), null) { @Override @@ -190,7 +207,7 @@ public class StackFramesLayoutNode extends AbstractDMVMLayoutNode { { if (idx != 0) return; - final IExecutionDMContext execDmc = findDmcInPath(update.getElementPath(), IExecutionDMContext.class); + final IExecutionDMContext execDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IExecutionDMContext.class); IRunControl runControlService = getServicesTracker().getService(IRunControl.class); IStepQueueManager stepQueueMgrService = getServicesTracker().getService(IStepQueueManager.class); if (execDmc == null || runControlService == null || stepQueueMgrService == null) return; @@ -253,8 +270,7 @@ public class StackFramesLayoutNode extends AbstractDMVMLayoutNode { } - @Override - protected int getNodeDeltaFlagsForDMEvent(org.eclipse.dd.dsf.datamodel.IDMEvent e) { + public int getDeltaFlags(Object e) { // This node generates delta if the timers have changed, or if the // label has changed. if (e instanceof ISuspendedDMEvent) { @@ -268,15 +284,14 @@ public class StackFramesLayoutNode extends AbstractDMVMLayoutNode { } else if (e instanceof IStepQueueManager.ISteppingTimedOutEvent) { return IModelDelta.CONTENT; } - return 0; + return IModelDelta.NO_CHANGE; } - @Override - protected void buildDeltaForDMEvent(final IDMEvent e, final VMDelta parent, final int nodeOffset, final RequestMonitor rm) { + public void buildDelta(final Object e, final ModelDelta parent, final int nodeOffset, final RequestMonitor rm) { if (e instanceof IContainerSuspendedDMEvent) { IExecutionDMContext threadDmc = null; - if (parent.getElement() instanceof AbstractDMVMLayoutNode.DMVMContext) { - threadDmc = DMContexts.getAncestorOfType( ((DMVMContext)parent.getElement()).getDMC(), IExecutionDMContext.class); + if (parent.getElement() instanceof IDMVMContext) { + threadDmc = DMContexts.getAncestorOfType( ((IDMVMContext)parent.getElement()).getDMContext(), IExecutionDMContext.class); } buildDeltaForSuspendedEvent((ISuspendedDMEvent)e, threadDmc, ((IContainerSuspendedDMEvent)e).getTriggeringContext(), parent, nodeOffset, rm); } else if (e instanceof ISuspendedDMEvent) { @@ -287,17 +302,16 @@ public class StackFramesLayoutNode extends AbstractDMVMLayoutNode { } else if (e instanceof IStepQueueManager.ISteppingTimedOutEvent) { buildDeltaForSteppingTimedOutEvent((IStepQueueManager.ISteppingTimedOutEvent)e, parent, nodeOffset, rm); } else { - // Call super-class to build sub-node delta's. - super.buildDeltaForDMEvent(e, parent, nodeOffset, rm); + rm.done(); } } - private void buildDeltaForSuspendedEvent(final ISuspendedDMEvent e, final IExecutionDMContext executionCtx, final IExecutionDMContext triggeringCtx, final VMDelta parent, final int nodeOffset, final RequestMonitor rm) { + private void buildDeltaForSuspendedEvent(final ISuspendedDMEvent e, final IExecutionDMContext executionCtx, final IExecutionDMContext triggeringCtx, final ModelDelta parentDelta, final int nodeOffset, final RequestMonitor rm) { IRunControl runControlService = getServicesTracker().getService(IRunControl.class); IStack stackService = getServicesTracker().getService(IStack.class); if (stackService == null || runControlService == null) { // Required services have not initialized yet. Ignore the event. - super.buildDeltaForDMEvent(e, parent, nodeOffset, rm); + rm.done(); return; } @@ -305,46 +319,45 @@ public class StackFramesLayoutNode extends AbstractDMVMLayoutNode { // 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 (!runControlService.isStepping(triggeringCtx)) { - parent.addFlags(IModelDelta.CONTENT); + parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); } // Check if we are building a delta for the thread that triggered the event. // Only then expand the stack frames and select the top one. if (executionCtx.equals(triggeringCtx)) { // Always expand the thread node to show the stack frames. - parent.addFlags(IModelDelta.EXPAND); + parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.EXPAND); // Retrieve the list of stack frames, and mark the top frame to be selected. getElementsTopStackFrameOnly( - new ElementsUpdate( - new DataRequestMonitor>(getSession().getExecutor(), null) { + new VMChildrenUpdate( + parentDelta, getVMProvider().getPresentationContext(), -1, -1, + new DataRequestMonitor>(getExecutor(), null) { @Override public void handleCompleted() { if (getStatus().isOK() && getData().size() != 0) { - parent.addNode( getData().get(0), IModelDelta.SELECT | IModelDelta.STATE); + parentDelta.addNode( getData().get(0), 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().size() >= 2) { - parent.addNode( getData().get(1), IModelDelta.STATE); + parentDelta.addNode( getData().get(1), 1, IModelDelta.STATE); } } - // Even in case of errors, call super-class to complete building of the delta. - StackFramesLayoutNode.super.buildDeltaForDMEvent(e, parent, nodeOffset, rm); + // Even in case of errors, complete the request monitor. + rm.done(); } - }, - parent) + }) ); } else { - // Don't forget to call the super class to complete building the delta (and call child nodes.) - StackFramesLayoutNode.super.buildDeltaForDMEvent(e, parent, nodeOffset, rm); + rm.done(); } } - private void buildDeltaForResumedEvent(final IResumedDMEvent e, final VMDelta parent, final int nodeOffset, final RequestMonitor rm) { + private void buildDeltaForResumedEvent(final IResumedDMEvent e, final ModelDelta parentDelta, final int nodeOffset, final RequestMonitor rm) { IStack stackService = getServicesTracker().getService(IStack.class); if (stackService == null) { // Required services have not initialized yet. Ignore the event. - super.buildDeltaForDMEvent(e, parent, nodeOffset, rm); + rm.done(); return; } @@ -352,15 +365,15 @@ public class StackFramesLayoutNode extends AbstractDMVMLayoutNode { if (resumedEvent.getReason() != StateChangeReason.STEP) { // 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); + parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); fCachedOldFrameVMCs = null; } - super.buildDeltaForDMEvent(e, parent, nodeOffset, rm); + rm.done(); } - private void buildDeltaForSteppingTimedOutEvent(final IStepQueueManager.ISteppingTimedOutEvent e, final VMDelta parent, final int nodeOffset, final RequestMonitor rm) { + private void buildDeltaForSteppingTimedOutEvent(final IStepQueueManager.ISteppingTimedOutEvent e, final ModelDelta parentDelta, final int nodeOffset, final RequestMonitor rm) { // Repaint the stack frame images to have the running symbol. - parent.addFlags(IModelDelta.CONTENT); - super.buildDeltaForDMEvent(e, parent, nodeOffset, rm); + parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); + rm.done(); } } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessVMNode.java similarity index 74% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessLayoutNode.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessVMNode.java index a8ba47cbeee..751dfc99553 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessVMNode.java @@ -11,11 +11,11 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.launch; import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMNode; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; 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.IVMNode; import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.ILaunch; @@ -25,6 +25,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpd import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; import org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor; import org.eclipse.jface.viewers.TreePath; @@ -35,7 +36,7 @@ import org.eclipse.jface.viewers.TreePath; * adapters should be used to retrieve the label. */ @SuppressWarnings("restriction") -public class StandardProcessLayoutNode extends AbstractVMLayoutNode { +public class StandardProcessVMNode extends AbstractVMNode { /** * VMC element implementation, it is a proxy for the IProcess class, to @@ -47,12 +48,12 @@ public class StandardProcessLayoutNode extends AbstractVMLayoutNode { private final IProcess fProcess; VMC(IProcess process) { - super(getVMProvider().getVMAdapter(), StandardProcessLayoutNode.this); + super(getVMProvider().getVMAdapter(), StandardProcessVMNode.this); fProcess = process; } @Override - public IVMLayoutNode getLayoutNode() { return StandardProcessLayoutNode.this; } + public IVMNode getVMNode() { return StandardProcessVMNode.this; } @Override @SuppressWarnings("unchecked") public Object getAdapter(Class adapter) { @@ -83,46 +84,51 @@ public class StandardProcessLayoutNode extends AbstractVMLayoutNode { public int hashCode() { return fProcess.hashCode(); } } - public StandardProcessLayoutNode(AbstractVMProvider provider) { + public StandardProcessVMNode(AbstractVMProvider provider) { super(provider); } - public void updateElements(IChildrenUpdate update) { - ILaunch launch = findLaunch(update.getElementPath()); - if (launch == null) { - // There is no launch in the parent of this node. This means that the - // layout is misconfigured. - assert false; + public void update(IChildrenUpdate[] updates) { + for (IChildrenUpdate update : updates) { + ILaunch launch = findLaunch(update.getElementPath()); + if (launch == null) { + // There is no launch in the parent of this node. This means that the + // layout is misconfigured. + assert false; + update.done(); + continue; + } + + /* + * Assume that the process objects are stored within the launch, and + * retrieve them on dispatch thread. + */ + IProcess[] processes = launch.getProcesses(); + for (int i = 0; i < processes.length; i++) { + update.setChild(new VMC(processes[i]), i); + } update.done(); - return; } - - /* - * Assume that the process objects are stored within the launch, and - * retrieve them on dispatch thread. - */ - IProcess[] processes = launch.getProcesses(); - for (int i = 0; i < processes.length; i++) { - update.setChild(new VMC(processes[i]), i); - } - update.done(); } - public void updateElementCount(IChildrenCountUpdate update) { - ILaunch launch = findLaunch(update.getElementPath()); - if (launch == null) { - assert false; - update.setChildCount(0); + public void update(final IChildrenCountUpdate[] updates) { + for (IChildrenCountUpdate update : updates) { + if (!checkUpdate(update)) continue; + ILaunch launch = findLaunch(update.getElementPath()); + if (launch == null) { + assert false; + update.setChildCount(0); + update.done(); + return; + } + + update.setChildCount(launch.getProcesses().length); update.done(); - return; } - - update.setChildCount(launch.getProcesses().length); - update.done(); } // @see org.eclipse.dd.dsf.ui.viewmodel.IViewModelLayoutNode#hasElements(org.eclipse.dd.dsf.ui.viewmodel.IVMContext, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) - public void updateHasElements(IHasChildrenUpdate[] updates) { + public void update(IHasChildrenUpdate[] updates) { for (IHasChildrenUpdate update : updates) { ILaunch launch = findLaunch(update.getElementPath()); if (launch == null) { @@ -138,7 +144,7 @@ public class StandardProcessLayoutNode extends AbstractVMLayoutNode { } // @see org.eclipse.dd.dsf.ui.viewmodel.IViewModelLayoutNode#retrieveLabel(org.eclipse.dd.dsf.ui.viewmodel.IVMContext, org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor) - public void updateLabel(@SuppressWarnings("unused")IVMContext vmc, ILabelRequestMonitor result, @SuppressWarnings("unused") String[] columns) { + public void updateLabel(IVMContext vmc, ILabelRequestMonitor result, String[] columns) { /* * The implementation of IAdapterFactory that uses this node should not @@ -163,7 +169,6 @@ public class StandardProcessLayoutNode extends AbstractVMLayoutNode { return null; } - @Override public int getDeltaFlags(Object e) { int myFlags = 0; if (e instanceof DebugEvent) { @@ -176,11 +181,10 @@ public class StandardProcessLayoutNode extends AbstractVMLayoutNode { myFlags = IModelDelta.STATE; } } - return myFlags | super.getDeltaFlags(e); + return myFlags; } - @Override - public void buildDelta(Object e, VMDelta parent, int nodeOffset, RequestMonitor requestMonitor) { + public void buildDelta(Object e, ModelDelta parent, int nodeOffset, RequestMonitor requestMonitor) { if (e instanceof DebugEvent && ((DebugEvent)e).getSource() instanceof IProcess) { DebugEvent de = (DebugEvent)e; if (de.getKind() == DebugEvent.CHANGE) { @@ -194,21 +198,19 @@ public class StandardProcessLayoutNode extends AbstractVMLayoutNode { * No other node should need to process events related to process. * Therefore, just invoke the request monitor without calling super.buildDelta(). */ - requestMonitor.done(); - } else { - super.buildDelta(e, parent, nodeOffset, requestMonitor); - } + } + requestMonitor.done(); } - protected void handleChange(DebugEvent event, VMDelta parent) { + protected void handleChange(DebugEvent event, ModelDelta parent) { parent.addNode(new VMC((IProcess)event.getSource()), IModelDelta.STATE); } - protected void handleCreate(@SuppressWarnings("unused") DebugEvent event, @SuppressWarnings("unused") VMDelta parent) { + protected void handleCreate(DebugEvent event, ModelDelta parent) { // do nothing - Launch change notification handles this } - protected void handleTerminate(DebugEvent event, VMDelta parent) { + protected void handleTerminate(DebugEvent event, ModelDelta parent) { handleChange(event, parent); } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPane.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPane.java index ce0a8a91172..311de5557bc 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPane.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPane.java @@ -35,7 +35,7 @@ import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.detail.TextViewerActio import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; import org.eclipse.debug.core.model.IDebugElement; import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.internal.ui.IDebugHelpContextIds; @@ -389,8 +389,8 @@ public class ModuleDetailPane extends AbstractDetailPane implements IAdaptable, // service.getModuleData(modDmc, modData); // } IModuleDMContext dmc = null; - if (fElement instanceof AbstractDMVMLayoutNode.DMVMContext) { - IDMContext vmcdmc = ((AbstractDMVMLayoutNode.DMVMContext)fElement).getDMC(); + if (fElement instanceof IDMVMContext) { + IDMContext vmcdmc = ((IDMVMContext)fElement).getDMContext(); dmc = DMContexts.getAncestorOfType(vmcdmc, IModuleDMContext.class); } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPaneFactory.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPaneFactory.java index dc9c6077369..745cf413e35 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPaneFactory.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPaneFactory.java @@ -41,8 +41,8 @@ public class ModuleDetailPaneFactory implements IDetailPaneFactory { return null; } - public Set getDetailPaneTypes(IStructuredSelection selection) { - Set possibleIDs = new HashSet(1); + public Set getDetailPaneTypes(IStructuredSelection selection) { + Set possibleIDs = new HashSet(1); possibleIDs.add(ModuleDetailPane.ID); return possibleIDs; } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMNode.java similarity index 75% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesLayoutNode.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMNode.java index c162266923c..78155c4191d 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMNode.java @@ -10,32 +10,34 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.viewmodel.modules; +import java.util.concurrent.RejectedExecutionException; + import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.datamodel.IDMEvent; import org.eclipse.dd.dsf.debug.service.IModules; import org.eclipse.dd.dsf.debug.service.IRegisters; import org.eclipse.dd.dsf.debug.service.IRunControl; import org.eclipse.dd.dsf.debug.service.IModules.IModuleDMContext; import org.eclipse.dd.dsf.debug.service.IModules.IModuleDMData; import org.eclipse.dd.dsf.debug.service.IModules.ISymbolDMContext; -import org.eclipse.dd.dsf.debug.service.IRegisters.IGroupChangedDMEvent; import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.ui.IDsfDebugUIConstants; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; -import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; -import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; -import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; @SuppressWarnings("restriction") -public class ModulesLayoutNode extends AbstractDMVMLayoutNode +public class ModulesVMNode extends AbstractDMVMNode + implements IElementLabelProvider { - public ModulesLayoutNode(AbstractVMProvider provider, DsfSession session) { + public ModulesVMNode(AbstractDMVMProvider provider, DsfSession session) { super(provider, session, IModuleDMContext.class); } @@ -43,7 +45,7 @@ public class ModulesLayoutNode extends AbstractDMVMLayoutNode protected void updateElementsInSessionThread(final IChildrenUpdate update) { if (!checkService(IRegisters.class, null, update)) return; - final ISymbolDMContext symDmc = findDmcInPath(update.getElementPath(), ISymbolDMContext.class) ; + final ISymbolDMContext symDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), ISymbolDMContext.class) ; if (symDmc != null) { getServicesTracker().getService(IModules.class).getModules( @@ -64,10 +66,24 @@ public class ModulesLayoutNode extends AbstractDMVMLayoutNode } - @Override + + public void update(final ILabelUpdate[] updates) { + try { + getSession().getExecutor().execute(new DsfRunnable() { + public void run() { + updateLabelInSessionThread(updates); + }}); + } catch (RejectedExecutionException e) { + for (ILabelUpdate update : updates) { + handleFailedUpdate(update); + } + } + } + + protected void updateLabelInSessionThread(ILabelUpdate[] updates) { for (final ILabelUpdate update : updates) { - final IModuleDMContext dmc = findDmcInPath(update.getElementPath(), IModuleDMContext.class); + final IModuleDMContext dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IModuleDMContext.class); if (!checkDmc(dmc, update) || !checkService(IModules.class, null, update)) continue; // Use different image for loaded and unloaded symbols when event to report loading of symbols is implemented. update.setImageDescriptor(DsfDebugUIPlugin.getImageDescriptor(IDsfDebugUIConstants.IMG_OBJS_SHARED_LIBRARY_SYMBOLS_LOADED), 0); @@ -119,41 +135,19 @@ public class ModulesLayoutNode extends AbstractDMVMLayoutNode } } - @Override - protected int getNodeDeltaFlagsForDMEvent(IDMEvent e) { + public int getDeltaFlags(Object e) { if (e instanceof IRunControl.ISuspendedDMEvent) { return IModelDelta.CONTENT; } - else if (e instanceof IRegisters.IGroupsChangedDMEvent) { - return IModelDelta.CONTENT; - } - else if (e instanceof IRegisters.IGroupChangedDMEvent) { - return IModelDelta.STATE; - } return IModelDelta.NO_CHANGE; } - @Override - protected void buildDeltaForDMEvent(IDMEvent e, VMDelta parent, int nodeOffset, RequestMonitor rm) { + public void buildDelta(Object e, ModelDelta parentDelta, int nodeOffset, RequestMonitor rm) { if (e instanceof IRunControl.ISuspendedDMEvent) { // Create a delta that indicates all groups have changed - parent.addFlags(IModelDelta.CONTENT); + parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); } - else if (e instanceof IRegisters.IGroupsChangedDMEvent) { - // flush the cache - VMCacheManager.getVMCacheManager().flush(super.getVMProvider().getPresentationContext()); - - // Create a delta that indicates all groups have changed - parent.addFlags(IModelDelta.CONTENT); - } - else if (e instanceof IRegisters.IGroupChangedDMEvent) { - // flush the cache - VMCacheManager.getVMCacheManager().flush(super.getVMProvider().getPresentationContext()); - - // Create a delta that indicates that specific group changed - parent.addNode( createVMContext(((IGroupChangedDMEvent)e).getDMContext()), IModelDelta.STATE ); - } - super.buildDeltaForDMEvent(e, parent, nodeOffset, rm); + rm.done(); } } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMProvider.java index 5faae582ec5..436e4d8dd91 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMProvider.java @@ -12,10 +12,10 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.modules; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; -import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; -import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.IVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.IRootVMNode; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; -import org.eclipse.dd.dsf.ui.viewmodel.dm.DMVMRootLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.dm.RootDMVMNode; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; /** @@ -32,17 +32,17 @@ public class ModulesVMProvider extends AbstractDMVMProvider { /* * Create the top level node to deal with the root selection. */ - IVMRootLayoutNode debugViewSelection = new DMVMRootLayoutNode(this); + IRootVMNode rootNode = new RootDMVMNode(this); /* * Create the Group nodes next. They represent the first level shown in the view. */ - IVMLayoutNode modulesNode = new ModulesLayoutNode(this, getSession()); - debugViewSelection.setChildNodes(new IVMLayoutNode[] { modulesNode }); + IVMNode modulesNode = new ModulesVMNode(this, getSession()); + addChildNodes(rootNode, new IVMNode[] { modulesNode }); /* * Now set this schema set as the layout set. */ - setRootLayoutNode(debugViewSelection); + setRootNode(rootNode); } } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/AbstractSetFormatStyle.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/AbstractSetFormatStyle.java index 5533710f9ed..9347d4f8da9 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/AbstractSetFormatStyle.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/AbstractSetFormatStyle.java @@ -10,12 +10,9 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat; -import org.eclipse.core.runtime.IAdaptable; import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; -import org.eclipse.dd.dsf.ui.viewmodel.IVMAdapter; -import org.eclipse.dd.dsf.ui.viewmodel.IVMProvider; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode.DMVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; import org.eclipse.debug.core.model.IDebugElement; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer; @@ -126,25 +123,6 @@ public class AbstractSetFormatStyle implements IViewActionDelegate, IDebugContex * Store the new style. So it will be picked up by the view when the view changes. */ context.setProperty( IDebugVMConstants.CURRENT_FORMAT_STORAGE, getFormatStyle() ); - - /* - * Now go tell the view to update. We do so by finding the VM provider for this view - * and telling it to redraw the entire view. - */ - if (fViewInput instanceof IAdaptable) { - IVMAdapter adapter = (IVMAdapter) ((IAdaptable)fViewInput).getAdapter(IVMAdapter.class); - - if ( adapter != null ) { - IVMProvider provider = adapter.getVMProvider(context); - - if ( provider != null ) { - /* - * "null" means redraw the entire view. - */ - provider.refresh( null ); - } - } - } } } } @@ -169,7 +147,7 @@ public class AbstractSetFormatStyle implements IViewActionDelegate, IDebugContex Object element = ( (IStructuredSelection) selection ).getFirstElement(); - if ( element instanceof DMVMContext ) { fViewInput = element; } + if (element instanceof IDMVMContext ) { fViewInput = element; } else { /* * We deliberately do nothing here. A valid structured selection has already been @@ -202,7 +180,7 @@ public class AbstractSetFormatStyle implements IViewActionDelegate, IDebugContex { fAction.setEnabled(true); } - else if ( fViewInput instanceof DMVMContext ) + else if ( fViewInput instanceof IDMVMContext ) { fAction.setEnabled(true); } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/NumberFormatDetailPane.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/NumberFormatDetailPane.java index eafe79f19d3..4f31826ed11 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/NumberFormatDetailPane.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/NumberFormatDetailPane.java @@ -38,7 +38,7 @@ import org.eclipse.dd.dsf.debug.service.IRegisters.IBitFieldDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext; import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.service.DsfServicesTracker; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode.DMVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.model.IDebugElement; import org.eclipse.debug.core.model.IExpression; @@ -53,6 +53,7 @@ import org.eclipse.debug.internal.ui.actions.variables.details.DetailPaneMaxLeng import org.eclipse.debug.internal.ui.actions.variables.details.DetailPaneWordWrapAction; import org.eclipse.debug.internal.ui.preferences.IDebugPreferenceConstants; import org.eclipse.debug.internal.ui.views.variables.IndexedValuePartition; +import org.eclipse.debug.internal.ui.views.variables.StatusLineContributionItem; import org.eclipse.debug.internal.ui.views.variables.details.DetailMessages; import org.eclipse.debug.ui.IDebugModelPresentation; import org.eclipse.debug.ui.IDebugUIConstants; @@ -65,7 +66,6 @@ import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.IStatusLineManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.Separator; -import org.eclipse.jface.action.StatusLineContributionItem; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.Document; @@ -315,7 +315,7 @@ public class NumberFormatDetailPane implements IDetailPane, IAdaptable, IPropert /* * Make sure this is an element we want to deal with. */ - if ( element instanceof DMVMContext) { + if (element instanceof IDMVMContext) { IFormattedValues service = null; IFormattedDataDMContext dmc = null ; @@ -341,23 +341,23 @@ public class NumberFormatDetailPane implements IDetailPane, IAdaptable, IPropert * register not the bit field. */ - DsfServicesTracker tracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), ((DMVMContext) element).getDMC().getSessionId()); + DsfServicesTracker tracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), ((IDMVMContext) element).getDMContext().getSessionId()); - IBitFieldDMContext bitfieldDmc = DMContexts.getAncestorOfType(((DMVMContext) element).getDMC(), IBitFieldDMContext.class); + IBitFieldDMContext bitfieldDmc = DMContexts.getAncestorOfType(((IDMVMContext) element).getDMContext(), IBitFieldDMContext.class); if ( bitfieldDmc != null ) { dmc = bitfieldDmc ; service = tracker.getService(IRegisters.class); } else { - IRegisterDMContext regDmc = DMContexts.getAncestorOfType(((DMVMContext) element).getDMC(), IRegisterDMContext.class); + IRegisterDMContext regDmc = DMContexts.getAncestorOfType(((IDMVMContext) element).getDMContext(), IRegisterDMContext.class); if ( regDmc != null ) { dmc = regDmc ; service = tracker.getService(IRegisters.class); } else { - IExpressionDMContext exprDmc = DMContexts.getAncestorOfType(((DMVMContext) element).getDMC(), IExpressionDMContext.class); + IExpressionDMContext exprDmc = DMContexts.getAncestorOfType(((IDMVMContext) element).getDMContext(), IExpressionDMContext.class); if ( exprDmc != null ) { dmc = exprDmc ; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutCellModifier.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldCellModifier.java similarity index 87% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutCellModifier.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldCellModifier.java index 176843d6dd9..50e510ed53f 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutCellModifier.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldCellModifier.java @@ -16,21 +16,27 @@ import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionCellModifier; import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValuePreferenceStore; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.update.AbstractCachingVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.update.UserEditEvent; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; @SuppressWarnings("restriction") -public class RegisterBitFieldLayoutCellModifier extends WatchExpressionCellModifier { +public class RegisterBitFieldCellModifier extends WatchExpressionCellModifier { public static enum BitFieldEditorStyle { NOTHING, BITFIELDCOMBO, BITFIELDTEXT } + private AbstractCachingVMProvider fProvider; private BitFieldEditorStyle fStyle; private IBitFieldDMData fBitFieldData = null; private Object fElement = null; private SyncRegisterDataAccess fDataAccess = null; private IFormattedValuePreferenceStore fFormatPrefStore; - public RegisterBitFieldLayoutCellModifier( IFormattedValuePreferenceStore formatPrefStore, BitFieldEditorStyle style, SyncRegisterDataAccess access ) { + public RegisterBitFieldCellModifier(AbstractCachingVMProvider provider, + IFormattedValuePreferenceStore formatPrefStore, BitFieldEditorStyle style, SyncRegisterDataAccess access ) + { + fProvider = provider; fStyle = style; fDataAccess = access; fFormatPrefStore = formatPrefStore; @@ -40,8 +46,8 @@ public class RegisterBitFieldLayoutCellModifier extends WatchExpressionCellModif * Used to make sure we are dealing with a valid register. */ private IBitFieldDMContext getBitFieldDMC(Object element) { - if (element instanceof AbstractDMVMLayoutNode.DMVMContext) { - IDMContext dmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); + if (element instanceof IDMVMContext) { + IDMContext dmc = ((IDMVMContext)element).getDMContext(); return DMContexts.getAncestorOfType(dmc, IBitFieldDMContext.class); } return null; @@ -98,7 +104,7 @@ public class RegisterBitFieldLayoutCellModifier extends WatchExpressionCellModif * Find the presentation context and then use it to get the current desired format. */ IVMContext ctx = (IVMContext) element; - IPresentationContext presCtx = ctx.getLayoutNode().getVMProvider().getPresentationContext(); + IPresentationContext presCtx = ctx.getVMNode().getVMProvider().getPresentationContext(); formatId = fFormatPrefStore.getCurrentNumericFormat(presCtx); } @@ -156,7 +162,7 @@ public class RegisterBitFieldLayoutCellModifier extends WatchExpressionCellModif * Find the presentation context and then use it to get the current desired format. */ IVMContext ctx = (IVMContext) element; - IPresentationContext presCtx = ctx.getLayoutNode().getVMProvider().getPresentationContext(); + IPresentationContext presCtx = ctx.getVMNode().getVMProvider().getPresentationContext(); formatId = fFormatPrefStore.getCurrentNumericFormat(presCtx); } @@ -164,6 +170,7 @@ public class RegisterBitFieldLayoutCellModifier extends WatchExpressionCellModif formatId = IFormattedValues.NATURAL_FORMAT; } fDataAccess.writeBitField(element, (String) value, formatId); + fProvider.handleEvent(new UserEditEvent(element)); } } else { @@ -177,6 +184,7 @@ public class RegisterBitFieldLayoutCellModifier extends WatchExpressionCellModif * Write the bit field using the selected mnemonic. */ fDataAccess.writeBitField(element, fBitFieldData.getMnemonics()[val.intValue()]); + fProvider.handleEvent(new UserEditEvent(element)); } } } else { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java similarity index 78% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java index d3d8bed1cda..2a48579faa4 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java @@ -10,14 +10,16 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.viewmodel.register; +import java.util.concurrent.RejectedExecutionException; + import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.datamodel.IDMEvent; import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.dd.dsf.debug.service.IRegisters; import org.eclipse.dd.dsf.debug.service.IRunControl; @@ -32,17 +34,15 @@ import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext; import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent; import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; -import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.AbstractExpressionLayoutNode; +import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.AbstractExpressionVMNode; import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValuePreferenceStore; import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValueVMContext; -import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterBitFieldLayoutCellModifier.BitFieldEditorStyle; +import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterBitFieldCellModifier.BitFieldEditorStyle; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; -import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; -import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; -import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.model.IDebugTarget; @@ -51,10 +51,13 @@ import org.eclipse.debug.core.model.IValue; import org.eclipse.debug.core.model.IVariable; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementEditor; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapterExtension; +import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.ComboBoxCellEditor; import org.eclipse.jface.viewers.ICellModifier; @@ -63,7 +66,9 @@ import org.eclipse.jface.viewers.TreePath; import org.eclipse.swt.widgets.Composite; @SuppressWarnings("restriction") -public class RegisterBitFieldLayoutNode extends AbstractExpressionLayoutNode implements IElementEditor { +public class RegisterBitFieldVMNode extends AbstractExpressionVMNode + implements IElementEditor, IElementLabelProvider +{ protected class BitFieldVMC extends DMVMContext implements IVariable, IFormattedValueVMContext @@ -133,7 +138,7 @@ public class RegisterBitFieldLayoutNode extends AbstractExpressionLayoutNode imp StringBuffer exprBuf = new StringBuffer(); IRegisterGroupDMContext groupDmc = - DMContexts.getAncestorOfType(bitFieldVmc.getDMC(), IRegisterGroupDMContext.class); + DMContexts.getAncestorOfType(bitFieldVmc.getDMContext(), IRegisterGroupDMContext.class); if (groupDmc != null) { exprBuf.append("$$\""); //$NON-NLS-1$ exprBuf.append(groupDmc.getName()); @@ -141,14 +146,14 @@ public class RegisterBitFieldLayoutNode extends AbstractExpressionLayoutNode imp } IRegisterDMContext registerDmc = - DMContexts.getAncestorOfType(bitFieldVmc.getDMC(), IRegisterDMContext.class); + DMContexts.getAncestorOfType(bitFieldVmc.getDMContext(), IRegisterDMContext.class); if (registerDmc != null) { exprBuf.append('$'); exprBuf.append(registerDmc.getName()); } IBitFieldDMContext bitFieldDmc = - DMContexts.getAncestorOfType(bitFieldVmc.getDMC(), IBitFieldDMContext.class); + DMContexts.getAncestorOfType(bitFieldVmc.getDMContext(), IBitFieldDMContext.class); if (bitFieldDmc != null) { exprBuf.append('.'); exprBuf.append(bitFieldDmc.getName()); @@ -162,7 +167,7 @@ public class RegisterBitFieldLayoutNode extends AbstractExpressionLayoutNode imp final protected BitFieldExpressionFactory fBitFieldExpressionFactory = new BitFieldExpressionFactory(); private final IFormattedValuePreferenceStore fFormattedPrefStore; - public RegisterBitFieldLayoutNode(IFormattedValuePreferenceStore prefStore, AbstractVMProvider provider, DsfSession session, SyncRegisterDataAccess access) { + public RegisterBitFieldVMNode(IFormattedValuePreferenceStore prefStore, AbstractDMVMProvider provider, DsfSession session, SyncRegisterDataAccess access) { super(provider, session, IRegisters.IBitFieldDMContext.class); fDataAccess = access; fFormattedPrefStore = prefStore; @@ -237,9 +242,8 @@ public class RegisterBitFieldLayoutNode extends AbstractExpressionLayoutNode imp */ FormattedValueDMContext valueDmc = regService.getFormattedValueContext(dmc, finalFormatId); - VMCacheManager.getVMCacheManager().getCache(update.getPresentationContext()) - .getModelData(regService, - valueDmc, + getDMVMProvider().getModelData( + RegisterBitFieldVMNode.this, update, regService, valueDmc, new DataRequestMonitor(getSession().getExecutor(), null) { @Override public void handleCompleted() { @@ -269,22 +273,29 @@ public class RegisterBitFieldLayoutNode extends AbstractExpressionLayoutNode imp ); } - /* - * We override the Abstract method because we now need to perform an extra level of data fetch - * to get the formatted value represenatation of the register. Before we obtained the data from - * the IDMData returned for the Register DMC. Now basically the level of information returned - * is attribute information and the formatted value requires a separate transaction. - * - * @see org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode#updateLabelInSessionThread(org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate[]) - */ - @Override + + public void update(final ILabelUpdate[] updates) { + try { + getSession().getExecutor().execute(new DsfRunnable() { + public void run() { + updateLabelInSessionThread(updates); + }}); + } catch (RejectedExecutionException e) { + for (ILabelUpdate update : updates) { + handleFailedUpdate(update); + } + } + } + + protected void updateLabelInSessionThread(ILabelUpdate[] updates) { for (final ILabelUpdate update : updates) { - final IBitFieldDMContext dmc = findDmcInPath(update.getElementPath(), IRegisters.IBitFieldDMContext.class); + final IBitFieldDMContext dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IRegisters.IBitFieldDMContext.class); - VMCacheManager.getVMCacheManager().getCache(update.getPresentationContext()) - .getModelData(getServicesTracker().getService(IRegisters.class), + getDMVMProvider().getModelData( + this, update, + getServicesTracker().getService(IRegisters.class), dmc, new DataRequestMonitor(getSession().getExecutor(), null) { @Override @@ -367,7 +378,7 @@ public class RegisterBitFieldLayoutNode extends AbstractExpressionLayoutNode imp @Override protected void updateElementsInSessionThread(final IChildrenUpdate update) { - final IRegisterDMContext regDmc = findDmcInPath(update.getElementPath(), IRegisterDMContext.class); + final IRegisterDMContext regDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IRegisterDMContext.class); if (regDmc == null) { handleFailedUpdate(update); @@ -391,61 +402,49 @@ public class RegisterBitFieldLayoutNode extends AbstractExpressionLayoutNode imp } @Override - protected IVMContext createVMContext(IDMContext dmc) { + protected IDMVMContext createVMContext(IDMContext dmc) { return new BitFieldVMC(dmc); } - @Override - protected int getNodeDeltaFlagsForDMEvent(IDMEvent e) { - // In theory we want each node to act independently in terms of events. It might be - // the case that we would only have elements of this type at the root level. It is - // the case that the current layout model always starts with the GROUPS followed by - // REGISTERS followed by BITFIELDS. But if we do this when a run-control event has - // occured we generate a DELTA for every element, which can create a massive list - // of entries all of which say update the entire view. So for now we will just have - // the GROUP LAYOUT node do this. Later we need to revisit the logic and make sure - // there is a way for the nodes to operate independently and efficiently. - // - //if (e instanceof IRunControl.ISuspendedDMEvent) { - // return IModelDelta.CONTENT; - //} + public int getDeltaFlags(Object e) { + if (e instanceof IRunControl.ISuspendedDMEvent) { + return IModelDelta.CONTENT; + } if (e instanceof IRegisters.IBitFieldChangedDMEvent) { return IModelDelta.STATE; } + + if (e instanceof PropertyChangeEvent && + ((PropertyChangeEvent)e).getProperty() == IDebugVMConstants.CURRENT_FORMAT_STORAGE) + { + return IModelDelta.CONTENT; + } return IModelDelta.NO_CHANGE; } - @Override - protected void buildDeltaForDMEvent(IDMEvent e, VMDelta parent, int nodeOffset, RequestMonitor rm) { - // In theory we want each node to act independently in terms of events. It might be - // the case that we would only have elements of this type at the root level. It is - // the case that the current layout model always starts with the GROUPS followed by - // REGISTERS followed by BITFIELDS. But if we do this when a run-control event has - // occured we generate a DELTA for every element, which can create a massive list - // of entries all of which say update the entire view. So for now we will just have - // the GROUP LAYOUT node do this. Later we need to revisit the logic and make sure - // there is a way for the nodes to operate independently and efficiently. - // - // if (e instanceof IRunControl.ISuspendedDMEvent) { - // // Create a delta that the whole register group has changed. - // parent.addFlags(IModelDelta.CONTENT); - // } - + public void buildDelta(Object e, ModelDelta parentDelta, int nodeOffset, RequestMonitor rm) { + if (e instanceof IRunControl.ISuspendedDMEvent) { + // Create a delta that the whole register group has changed. + parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); + } + if (e instanceof IRegisters.IBitFieldChangedDMEvent) { - /* - * Flush the cache. - */ - VMCacheManager.getVMCacheManager().flush(super.getVMProvider().getPresentationContext()); /* * Create a delta indicating the bit field has changed. */ - parent.addNode( createVMContext(((IRegisters.IBitFieldChangedDMEvent)e).getDMContext()), IModelDelta.STATE ); + parentDelta.addNode( createVMContext(((IRegisters.IBitFieldChangedDMEvent)e).getDMContext()), IModelDelta.STATE ); } + + if (e instanceof PropertyChangeEvent && + ((PropertyChangeEvent)e).getProperty() == IDebugVMConstants.CURRENT_FORMAT_STORAGE) + { + parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); + } - super.buildDeltaForDMEvent(e, parent, nodeOffset, rm); + rm.done(); } public CellEditor getCellEditor(IPresentationContext context, String columnId, Object element, Composite parent) { @@ -510,13 +509,15 @@ public class RegisterBitFieldLayoutNode extends AbstractExpressionLayoutNode imp /* * Note we are complex COMBO and return the right editor. */ - return new RegisterBitFieldLayoutCellModifier( fFormattedPrefStore, BitFieldEditorStyle.BITFIELDCOMBO, fDataAccess ); + return new RegisterBitFieldCellModifier( + getDMVMProvider(), fFormattedPrefStore, BitFieldEditorStyle.BITFIELDCOMBO, fDataAccess ); } else { /* * Text editor even if we need to clamp the value entered. */ - return new RegisterBitFieldLayoutCellModifier( fFormattedPrefStore, BitFieldEditorStyle.BITFIELDTEXT, fDataAccess ); + return new RegisterBitFieldCellModifier( + getDMVMProvider(), fFormattedPrefStore, BitFieldEditorStyle.BITFIELDTEXT, fDataAccess ); } } else { @@ -525,22 +526,22 @@ public class RegisterBitFieldLayoutNode extends AbstractExpressionLayoutNode imp } @Override - protected void testContextForExpression(Object element, final String expression, final DataRequestMonitor rm) { - if (!(element instanceof AbstractDMVMLayoutNode.DMVMContext)) { + protected void testElementForExpression(Object element, IExpression expression, DataRequestMonitor rm) { + if (!(element instanceof IDMVMContext)) { rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ rm.done(); return; } - final IBitFieldDMContext dmc = DMContexts.getAncestorOfType(((DMVMContext)element).getDMC(), IBitFieldDMContext.class); + final IBitFieldDMContext dmc = DMContexts.getAncestorOfType(((IDMVMContext)element).getDMContext(), IBitFieldDMContext.class); if (dmc == null) { rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ rm.done(); return; } - String bitFieldName = expression.substring(1); - if (bitFieldName.equals(dmc.getName())) { + String bitFieldName = parseExpressionForBitFieldName(expression.getExpressionText()); + if (dmc.getName().equals(bitFieldName)) { rm.setData(Boolean.TRUE); } else { rm.setData(Boolean.FALSE); @@ -548,6 +549,38 @@ public class RegisterBitFieldLayoutNode extends AbstractExpressionLayoutNode imp rm.done(); } + public boolean canParseExpression(IExpression expression) { + return parseExpressionForBitFieldName(expression.getExpressionText()) != null; + } + + /** + * Expected format: $$"Group Name"$Register_Name.Bit_Field_Name + */ + private String parseExpressionForBitFieldName(String expression) { + if (expression.startsWith("$$\"")) { //$NON-NLS-1$ + int secondQuoteIdx = expression.indexOf('"', "$$\"".length()); //$NON-NLS-1$ + if (secondQuoteIdx > 0) { + String registerSubString = expression.substring(secondQuoteIdx + 1); + if (registerSubString.length() != 0 && + registerSubString.charAt(0) == '$' && + Character.isLetterOrDigit(registerSubString.charAt(1))) + { + int registerEnd = 1; + while ( registerEnd < registerSubString.length() && + Character.isLetterOrDigit(registerSubString.charAt(registerEnd)) ) + { + registerEnd++; + } + if ((registerEnd + 1) < registerSubString.length() && '.' == registerSubString.charAt(registerEnd)) { + return registerSubString.substring(registerEnd + 1); + } + } + } + } + return null; + } + + public int getExpressionLength(String expression) { if (expression.charAt(0) == '.' && Character.isLetterOrDigit(expression.charAt(1))) { int length = 1; @@ -567,35 +600,43 @@ public class RegisterBitFieldLayoutNode extends AbstractExpressionLayoutNode imp } } - @Override - protected int getDeltaFlagsForExpressionPart(Object event) { + public int getDeltaFlagsForExpression(IExpression expression, Object event) { if (event instanceof IRunControl.ISuspendedDMEvent) { return IModelDelta.CONTENT; } + if (event instanceof PropertyChangeEvent && + ((PropertyChangeEvent)event).getProperty() == IDebugVMConstants.CURRENT_FORMAT_STORAGE) + { + return IModelDelta.CONTENT; + } + return IModelDelta.NO_CHANGE; } - @Override - public void buildDeltaForExpression(final IExpression expression, final int elementIdx, final String expressionText, final Object event, final VMDelta parentDelta, final TreePath path, final RequestMonitor rm) + public void buildDeltaForExpression(final IExpression expression, final int elementIdx, final Object event, final ModelDelta parentDelta, final TreePath path, final RequestMonitor rm) { if (event instanceof ISuspendedDMEvent) { - // Mark the partent delta indicating that elements were added and/or removed. - parentDelta.addFlags(IModelDelta.CONTENT); + // Mark the parent delta indicating that elements were added and/or removed. + parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); } else if (event instanceof IRegisters.IRegisterChangedDMEvent) { - parentDelta.addFlags(IModelDelta.CONTENT); + parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); } - - super.buildDeltaForExpression(expression, elementIdx, expressionText, event, parentDelta, path, rm); + rm.done(); } - @Override - protected void buildDeltaForExpressionElement(Object element, int elementIdx, Object event, VMDelta parentDelta, final RequestMonitor rm) + public void buildDeltaForExpressionElement(Object element, int elementIdx, Object event, ModelDelta parentDelta, final RequestMonitor rm) { if (event instanceof IBitFieldChangedDMEvent) { parentDelta.addNode(element, IModelDelta.STATE); } - super.buildDeltaForExpressionElement(element, elementIdx, event, parentDelta, rm); + if (event instanceof PropertyChangeEvent && + ((PropertyChangeEvent)event).getProperty() == IDebugVMConstants.CURRENT_FORMAT_STORAGE) + { + parentDelta.addNode(element, IModelDelta.CONTENT); + } + + rm.done(); } } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutValueCellModifier.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterCellModifier.java similarity index 86% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutValueCellModifier.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterCellModifier.java index 808f2c293a8..b3cec6066f3 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutValueCellModifier.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterCellModifier.java @@ -19,16 +19,22 @@ import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionCellModifier; import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValuePreferenceStore; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.update.AbstractCachingVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.update.UserEditEvent; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; @SuppressWarnings("restriction") -public class RegisterLayoutValueCellModifier extends WatchExpressionCellModifier { +public class RegisterCellModifier extends WatchExpressionCellModifier { + private AbstractCachingVMProvider fProvider; private SyncRegisterDataAccess fDataAccess = null; private IFormattedValuePreferenceStore fFormattedValuePreferenceStore; - public RegisterLayoutValueCellModifier(IFormattedValuePreferenceStore formattedValuePreferenceStore, SyncRegisterDataAccess access) { + public RegisterCellModifier(AbstractCachingVMProvider provider, + IFormattedValuePreferenceStore formattedValuePreferenceStore, SyncRegisterDataAccess access) + { + fProvider = provider; fDataAccess = access; fFormattedValuePreferenceStore = formattedValuePreferenceStore; } @@ -44,8 +50,8 @@ public class RegisterLayoutValueCellModifier extends WatchExpressionCellModifier * Used to make sure we are dealing with a valid register. */ protected IRegisterDMContext getRegisterDMC(Object element) { - if (element instanceof AbstractDMVMLayoutNode.DMVMContext) { - IDMContext dmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); + if (element instanceof IDMVMContext) { + IDMContext dmc = ((IDMVMContext)element).getDMContext(); return DMContexts.getAncestorOfType(dmc, IRegisterDMContext.class); } return null; @@ -95,7 +101,7 @@ public class RegisterLayoutValueCellModifier extends WatchExpressionCellModifier * Find the presentation context and then use it to get the current desired format. */ IVMContext ctx = (IVMContext) element; - IPresentationContext presCtx = ctx.getLayoutNode().getVMProvider().getPresentationContext(); + IPresentationContext presCtx = ctx.getVMNode().getVMProvider().getPresentationContext(); formatId = fFormattedValuePreferenceStore.getCurrentNumericFormat(presCtx); } @@ -134,7 +140,7 @@ public class RegisterLayoutValueCellModifier extends WatchExpressionCellModifier * Find the presentation context and then use it to get the current desired format. */ IVMContext ctx = (IVMContext) element; - IPresentationContext presCtx = ctx.getLayoutNode().getVMProvider().getPresentationContext(); + IPresentationContext presCtx = ctx.getVMNode().getVMProvider().getPresentationContext(); formatId = fFormattedValuePreferenceStore.getCurrentNumericFormat(presCtx); } @@ -143,6 +149,7 @@ public class RegisterLayoutValueCellModifier extends WatchExpressionCellModifier } fDataAccess.writeRegister(element, (String) value, formatId); + fProvider.handleEvent(new UserEditEvent(element)); } } else { super.modify(element, property, value); diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java similarity index 80% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java index 79cfdcec889..ae10054f4c6 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java @@ -10,14 +10,16 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.viewmodel.register; +import java.util.concurrent.RejectedExecutionException; + import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.datamodel.IDMEvent; import org.eclipse.dd.dsf.debug.service.IRegisters; import org.eclipse.dd.dsf.debug.service.IRunControl; import org.eclipse.dd.dsf.debug.service.IRegisters.IGroupChangedDMEvent; @@ -25,16 +27,14 @@ import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMData; import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; -import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.AbstractExpressionLayoutNode; +import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.AbstractExpressionVMNode; import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionCellModifier; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; -import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; -import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.dm.CompositeDMVMContext; -import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager; +import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.model.IDebugTarget; @@ -44,9 +44,11 @@ import org.eclipse.debug.core.model.IVariable; import org.eclipse.debug.internal.ui.DebugPluginImages; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementEditor; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapterExtension; import org.eclipse.jface.viewers.CellEditor; @@ -56,8 +58,8 @@ import org.eclipse.jface.viewers.TreePath; import org.eclipse.swt.widgets.Composite; @SuppressWarnings("restriction") -public class RegisterGroupLayoutNode extends AbstractExpressionLayoutNode - implements IElementEditor +public class RegisterGroupVMNode extends AbstractExpressionVMNode + implements IElementEditor, IElementLabelProvider { protected class RegisterGroupVMC extends DMVMContext implements IVariable @@ -122,7 +124,7 @@ public class RegisterGroupLayoutNode extends AbstractExpressionLayoutNode RegisterGroupVMC registerVmc = ((RegisterGroupVMC)variable); StringBuffer exprBuf = new StringBuffer(); - IRegisterGroupDMContext groupDmc = DMContexts.getAncestorOfType(registerVmc.getDMC(), IRegisterGroupDMContext.class); + IRegisterGroupDMContext groupDmc = DMContexts.getAncestorOfType(registerVmc.getDMContext(), IRegisterGroupDMContext.class); if (groupDmc != null) { exprBuf.append("$$\""); //$NON-NLS-1$ exprBuf.append(groupDmc.getName()); @@ -138,7 +140,7 @@ public class RegisterGroupLayoutNode extends AbstractExpressionLayoutNode final protected RegisterGroupExpressionFactory fRegisterGroupExpressionFactory = new RegisterGroupExpressionFactory(); private WatchExpressionCellModifier fWatchExpressionCellModifier = new WatchExpressionCellModifier(); - public RegisterGroupLayoutNode(AbstractVMProvider provider, DsfSession session, SyncRegisterDataAccess syncDataAccess) { + public RegisterGroupVMNode(AbstractDMVMProvider provider, DsfSession session, SyncRegisterDataAccess syncDataAccess) { super(provider, session, IRegisters.IRegisterGroupDMContext.class); fSyncRegisterDataAccess = syncDataAccess; } @@ -149,11 +151,8 @@ public class RegisterGroupLayoutNode extends AbstractExpressionLayoutNode @Override protected void updateElementsInSessionThread(final IChildrenUpdate update) { - if (!checkService(IRegisters.class, null, update)) return; - - CompositeDMVMContext compositeDmc = new CompositeDMVMContext(getVMProvider().getRootElement(), update.getElementPath()); getServicesTracker().getService(IRegisters.class).getRegisterGroups( - compositeDmc, + new CompositeDMVMContext(update), new DataRequestMonitor(getSession().getExecutor(), null) { @Override public void handleCompleted() { @@ -167,19 +166,33 @@ public class RegisterGroupLayoutNode extends AbstractExpressionLayoutNode } @Override - protected IVMContext createVMContext(IDMContext dmc) { + protected IDMVMContext createVMContext(IDMContext dmc) { return new RegisterGroupVMC(dmc); } - @Override + public void update(final ILabelUpdate[] updates) { + try { + getSession().getExecutor().execute(new DsfRunnable() { + public void run() { + updateLabelInSessionThread(updates); + }}); + } catch (RejectedExecutionException e) { + for (ILabelUpdate update : updates) { + handleFailedUpdate(update); + } + } + } + + protected void updateLabelInSessionThread(ILabelUpdate[] updates) { for (final ILabelUpdate update : updates) { - final IRegisterGroupDMContext dmc = findDmcInPath(update.getElementPath(), IRegisterGroupDMContext.class); + final IRegisterGroupDMContext dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IRegisterGroupDMContext.class); if (!checkDmc(dmc, update) || !checkService(IRegisters.class, null, update)) continue; - VMCacheManager.getVMCacheManager().getCache(update.getPresentationContext()) - .getModelData(getServicesTracker().getService(IRegisters.class, null), + getDMVMProvider().getModelData( + this, update, + getServicesTracker().getService(IRegisters.class, null), dmc, new DataRequestMonitor(getSession().getExecutor(), null) { @Override @@ -247,8 +260,7 @@ public class RegisterGroupLayoutNode extends AbstractExpressionLayoutNode } } - @Override - protected int getNodeDeltaFlagsForDMEvent(IDMEvent e) { + public int getDeltaFlags(Object e) { if (e instanceof IRunControl.ISuspendedDMEvent) { return IModelDelta.CONTENT; } @@ -261,28 +273,37 @@ public class RegisterGroupLayoutNode extends AbstractExpressionLayoutNode return IModelDelta.NO_CHANGE; } - @Override - protected void buildDeltaForDMEvent(IDMEvent e, VMDelta parent, int nodeOffset, RequestMonitor rm) { + public void buildDelta(Object e, ModelDelta parentDelta, int nodeOffset, RequestMonitor rm) { if (e instanceof IRunControl.ISuspendedDMEvent) { // Create a delta that indicates all groups have changed - parent.addFlags(IModelDelta.CONTENT); + parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); } else if (e instanceof IRegisters.IGroupsChangedDMEvent) { - // flush the cache - VMCacheManager.getVMCacheManager().flush(super.getVMProvider().getPresentationContext()); - // Create a delta that indicates all groups have changed - parent.addFlags(IModelDelta.CONTENT); + parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); } else if (e instanceof IRegisters.IGroupChangedDMEvent) { - // flush the cache - VMCacheManager.getVMCacheManager().flush(super.getVMProvider().getPresentationContext()); - // Create a delta that indicates that specific group changed - parent.addNode( createVMContext(((IGroupChangedDMEvent)e).getDMContext()), IModelDelta.STATE ); + parentDelta.addNode( createVMContext(((IGroupChangedDMEvent)e).getDMContext()), IModelDelta.STATE ); } - - super.buildDeltaForDMEvent(e, parent, nodeOffset, rm); + rm.done(); + } + + public boolean canParseExpression(IExpression expression) { + return parseExpressionForGroupName(expression.getExpressionText()) != null; + } + + /** + * Expected format: $$"Group Name"$Register_Name.Bit_Field_Name + */ + private String parseExpressionForGroupName(String expression) { + if (expression.startsWith("$$\"")) { //$NON-NLS-1$ + int secondQuoteIdx = expression.indexOf('"', "$$\"".length()); //$NON-NLS-1$ + if (secondQuoteIdx > 0) { + return expression.substring(3, secondQuoteIdx); + } + } + return null; } public int getExpressionLength(String expression) { @@ -295,8 +316,7 @@ public class RegisterGroupLayoutNode extends AbstractExpressionLayoutNode return -1; } - @Override - protected int getDeltaFlagsForExpressionPart(Object event) { + public int getDeltaFlagsForExpression(IExpression expression, Object event) { if (event instanceof IRunControl.ISuspendedDMEvent) { return IModelDelta.CONTENT; } @@ -304,19 +324,17 @@ public class RegisterGroupLayoutNode extends AbstractExpressionLayoutNode return IModelDelta.NO_CHANGE; } - @Override - public void buildDeltaForExpression(final IExpression expression, final int elementIdx, final String expressionText, final Object event, final VMDelta parentDelta, final TreePath path, final RequestMonitor rm) + public void buildDeltaForExpression(IExpression expression, int elementIdx, Object event, ModelDelta parentDelta, + TreePath path, RequestMonitor rm) { if (event instanceof IRunControl.ISuspendedDMEvent) { - // Mark the partent delta indicating that elements were added and/or removed. - parentDelta.addFlags(IModelDelta.CONTENT); + // Mark the parent delta indicating that elements were added and/or removed. + parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); } - - super.buildDeltaForExpression(expression, elementIdx, expressionText, event, parentDelta, path, rm); + rm.done(); } - @Override - protected void buildDeltaForExpressionElement(Object element, int elementIdx, Object event, VMDelta parentDelta, final RequestMonitor rm) + public void buildDeltaForExpressionElement(Object element, int elementIdx, Object event, ModelDelta parentDelta, final RequestMonitor rm) { if (event instanceof IRegisters.IGroupsChangedDMEvent) { parentDelta.addNode(element, IModelDelta.CONTENT); @@ -324,28 +342,25 @@ public class RegisterGroupLayoutNode extends AbstractExpressionLayoutNode if (event instanceof IRegisters.IGroupChangedDMEvent) { parentDelta.addNode(element, IModelDelta.STATE); } - - super.buildDeltaForExpressionElement(element, elementIdx, event, parentDelta, rm); + rm.done(); } @Override - protected void testContextForExpression(Object element, final String expression, final DataRequestMonitor rm) { - if (!(element instanceof AbstractDMVMLayoutNode.DMVMContext)) { + protected void testElementForExpression(Object element, IExpression expression, DataRequestMonitor rm) { + if (!(element instanceof IDMVMContext)) { rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ rm.done(); return; } - final IRegisterGroupDMContext dmc = DMContexts.getAncestorOfType(((DMVMContext)element).getDMC(), IRegisterGroupDMContext.class); + final IRegisterGroupDMContext dmc = DMContexts.getAncestorOfType(((IDMVMContext)element).getDMContext(), IRegisterGroupDMContext.class); if (dmc == null) { rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ rm.done(); return; } - int startIdx = "$$\"".length(); //$NON-NLS-1$ - int endIdx = expression.indexOf('"', startIdx); - String groupName = expression.substring(startIdx, endIdx); - if (groupName.equals(dmc.getName())) { + String groupName = parseExpressionForGroupName(expression.getExpressionText()); + if (dmc.getName().equals(groupName)) { rm.setData(Boolean.TRUE); } else { rm.setData(Boolean.FALSE); diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java similarity index 62% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java index 43afcdf3e95..f82b2d83e49 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java @@ -10,14 +10,16 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.viewmodel.register; +import java.util.concurrent.RejectedExecutionException; + import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.datamodel.IDMEvent; import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.dd.dsf.debug.service.IRegisters; import org.eclipse.dd.dsf.debug.service.IRunControl; @@ -29,17 +31,15 @@ import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMData; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext; import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; -import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.AbstractExpressionLayoutNode; +import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.AbstractExpressionVMNode; import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValuePreferenceStore; import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValueVMContext; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; -import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; -import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.dm.CompositeDMVMContext; -import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager; +import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.model.IDebugTarget; @@ -51,11 +51,14 @@ import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementEditor; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapterExtension; +import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.ICellModifier; import org.eclipse.jface.viewers.TextCellEditor; @@ -63,8 +66,8 @@ import org.eclipse.jface.viewers.TreePath; import org.eclipse.swt.widgets.Composite; @SuppressWarnings("restriction") -public class RegisterLayoutNode extends AbstractExpressionLayoutNode - implements IElementEditor +public class RegisterVMNode extends AbstractExpressionVMNode + implements IElementEditor, IElementLabelProvider { protected class RegisterVMC extends DMVMContext implements IVariable, IFormattedValueVMContext @@ -134,7 +137,7 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode StringBuffer exprBuf = new StringBuffer(); IRegisterGroupDMContext groupDmc = - DMContexts.getAncestorOfType(registerVmc.getDMC(), IRegisterGroupDMContext.class); + DMContexts.getAncestorOfType(registerVmc.getDMContext(), IRegisterGroupDMContext.class); if (groupDmc != null) { exprBuf.append("$$\""); //$NON-NLS-1$ exprBuf.append(groupDmc.getName()); @@ -142,7 +145,7 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode } IRegisterDMContext registerDmc = - DMContexts.getAncestorOfType(registerVmc.getDMC(), IRegisterDMContext.class); + DMContexts.getAncestorOfType(registerVmc.getDMContext(), IRegisterDMContext.class); if (registerDmc != null) { exprBuf.append('$'); exprBuf.append(registerDmc.getName()); @@ -157,7 +160,7 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode final private SyncRegisterDataAccess fSyncRegisterDataAccess; private final IFormattedValuePreferenceStore fFormattedPrefStore; - public RegisterLayoutNode(IFormattedValuePreferenceStore prefStore, AbstractVMProvider provider, DsfSession session, SyncRegisterDataAccess syncDataAccess) { + public RegisterVMNode(IFormattedValuePreferenceStore prefStore, AbstractDMVMProvider provider, DsfSession session, SyncRegisterDataAccess syncDataAccess) { super(provider, session, IRegisters.IRegisterDMContext.class); fSyncRegisterDataAccess = syncDataAccess; fFormattedPrefStore = prefStore; @@ -237,8 +240,8 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode */ final FormattedValueDMContext valueDmc = regService.getFormattedValueContext(dmc, finalFormatId); - VMCacheManager.getVMCacheManager().getCache( context ).getModelData(regService, - valueDmc, + getDMVMProvider().getModelData( + RegisterVMNode.this, update, regService, valueDmc, new DataRequestMonitor(getSession().getExecutor(), null) { @Override public void handleCompleted() { @@ -252,8 +255,9 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode update.setLabel(getData().getFormattedValue(), labelIndex); // color based on change history - FormattedValueDMData oldData = (FormattedValueDMData) VMCacheManager.getVMCacheManager() - .getCache(context).getArchivedModelData(valueDmc); + + FormattedValueDMData oldData = (FormattedValueDMData) getDMVMProvider().getArchivedModelData( + RegisterVMNode.this, update, valueDmc); if(oldData != null && !oldData.getFormattedValue().equals(getData().getFormattedValue())) { update.setBackground( DebugUIPlugin.getPreferenceColor( @@ -269,112 +273,116 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode } ); } + + + public void update(final ILabelUpdate[] updates) { + try { + getSession().getExecutor().execute(new DsfRunnable() { + public void run() { + updateLabelInSessionThread(updates); + }}); + } catch (RejectedExecutionException e) { + for (ILabelUpdate update : updates) { + handleFailedUpdate(update); + } + } + } + - /* - * We override the Abstract method because we now need to perform an extra level of data fetch - * to get the formatted value represenatation of the register. Before we obtained the data from - * the IDMData returned for the Register DMC. Now basically the level of information returned - * is attribute information and the formatted value requires a separate transaction. - * - * @see org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode#updateLabelInSessionThread(org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate[]) - */ - @Override protected void updateLabelInSessionThread(ILabelUpdate[] updates) { for (final ILabelUpdate update : updates) { - final IRegisterDMContext dmc = findDmcInPath(update.getElementPath(), IRegisters.IRegisterDMContext.class); + final IRegisterDMContext dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IRegisters.IRegisterDMContext.class); if (!checkDmc(dmc, update) || !checkService(IRegisters.class, null, update)) continue; - VMCacheManager.getVMCacheManager().getCache(update.getPresentationContext()) - .getModelData(getServicesTracker().getService(IRegisters.class), - dmc, - new DataRequestMonitor(getSession().getExecutor(), null) { - @Override - protected void handleCompleted() { - /* - * Check that the request was evaluated and data is still - * valid. The request could fail if the state of the - * service changed during the request, but the view model - * has not been updated yet. - */ - if (!getStatus().isOK()) { - assert getStatus().isOK() || - getStatus().getCode() != IDsfService.INTERNAL_ERROR || - getStatus().getCode() != IDsfService.NOT_SUPPORTED; - handleFailedUpdate(update); - return; - } - - /* - * If columns are configured, extract the selected values for each - * understood column. First we fill all of those columns which can - * be filled without the extra data mining. We also note if we do - * have to datamine. Any columns need to set the processing flag - * so we know we have further work to do. If there are more columns - * which need data extraction they need to be added in both "for" - * loops. - */ - String[] localColumns = update.getPresentationContext().getColumns(); - if (localColumns == null) localColumns = new String[] { IDebugVMConstants.COLUMN_ID__NAME }; - - boolean weAreExtractingFormattedData = false; - - for (int idx = 0; idx < localColumns.length; idx++) { - if (IDebugVMConstants.COLUMN_ID__NAME.equals(localColumns[idx])) { + getDMVMProvider().getModelData( + this, update, + getServicesTracker().getService(IRegisters.class), + dmc, + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + protected void handleCompleted() { + /* + * Check that the request was evaluated and data is still + * valid. The request could fail if the state of the + * service changed during the request, but the view model + * has not been updated yet. + */ + if (!getStatus().isOK()) { + assert getStatus().isOK() || + getStatus().getCode() != IDsfService.INTERNAL_ERROR || + getStatus().getCode() != IDsfService.NOT_SUPPORTED; + handleFailedUpdate(update); + return; + } + + /* + * If columns are configured, extract the selected values for each + * understood column. First we fill all of those columns which can + * be filled without the extra data mining. We also note if we do + * have to datamine. Any columns need to set the processing flag + * so we know we have further work to do. If there are more columns + * which need data extraction they need to be added in both "for" + * loops. + */ + String[] localColumns = update.getPresentationContext().getColumns(); + if (localColumns == null) localColumns = new String[] { IDebugVMConstants.COLUMN_ID__NAME }; + + boolean weAreExtractingFormattedData = false; + + for (int idx = 0; idx < localColumns.length; idx++) { + if (IDebugVMConstants.COLUMN_ID__NAME.equals(localColumns[idx])) { + update.setLabel(getData().getName(), idx); + update.setImageDescriptor(DebugPluginImages.getImageDescriptor(IDebugUIConstants.IMG_OBJS_REGISTER), idx); + } else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(localColumns[idx])) { + weAreExtractingFormattedData = true; + } else if (IDebugVMConstants.COLUMN_ID__TYPE.equals(localColumns[idx])) { + IRegisterDMData data = getData(); + String typeStr = "Unsigned"; //$NON-NLS-1$ + String ReadAttrStr = "ReadNone"; //$NON-NLS-1$ + String WriteAddrStr = "WriteNone"; //$NON-NLS-1$ + + if ( data.isFloat() ) { typeStr = "Floating Point"; } //$NON-NLS-1$ + + if ( data.isReadOnce() ) { ReadAttrStr = "ReadOnce"; } //$NON-NLS-1$ + else if ( data.isReadable() ) { ReadAttrStr = "Readable"; } //$NON-NLS-1$ + + if ( data.isReadOnce() ) { WriteAddrStr = "WriteOnce"; } //$NON-NLS-1$ + else if ( data.isReadable() ) { WriteAddrStr = "Writeable"; } //$NON-NLS-1$ + + typeStr += " - " + ReadAttrStr + "/" + WriteAddrStr; //$NON-NLS-1$ //$NON-NLS-2$ + update.setLabel(typeStr, idx); + } else if (IDebugVMConstants.COLUMN_ID__DESCRIPTION.equals(localColumns[idx])) { + update.setLabel(getData().getDescription(), idx); + } else if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(localColumns[idx])) { + IVMContext vmc = (IVMContext)update.getElement(); + IExpression expression = (IExpression)vmc.getAdapter(IExpression.class); + if (expression != null) { + update.setLabel(expression.getExpressionText(), idx); + } else { update.setLabel(getData().getName(), idx); - update.setImageDescriptor(DebugPluginImages.getImageDescriptor(IDebugUIConstants.IMG_OBJS_REGISTER), idx); - } else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(localColumns[idx])) { - weAreExtractingFormattedData = true; - } else if (IDebugVMConstants.COLUMN_ID__TYPE.equals(localColumns[idx])) { - IRegisterDMData data = getData(); - String typeStr = "Unsigned"; //$NON-NLS-1$ - String ReadAttrStr = "ReadNone"; //$NON-NLS-1$ - String WriteAddrStr = "WriteNone"; //$NON-NLS-1$ - - if ( data.isFloat() ) { typeStr = "Floating Point"; } //$NON-NLS-1$ - - if ( data.isReadOnce() ) { ReadAttrStr = "ReadOnce"; } //$NON-NLS-1$ - else if ( data.isReadable() ) { ReadAttrStr = "Readable"; } //$NON-NLS-1$ - - if ( data.isReadOnce() ) { WriteAddrStr = "WriteOnce"; } //$NON-NLS-1$ - else if ( data.isReadable() ) { WriteAddrStr = "Writeable"; } //$NON-NLS-1$ - - typeStr += " - " + ReadAttrStr + "/" + WriteAddrStr; //$NON-NLS-1$ //$NON-NLS-2$ - update.setLabel(typeStr, idx); - } else if (IDebugVMConstants.COLUMN_ID__DESCRIPTION.equals(localColumns[idx])) { - update.setLabel(getData().getDescription(), idx); - } else if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(localColumns[idx])) { - IVMContext vmc = (IVMContext)update.getElement(); - IExpression expression = (IExpression)vmc.getAdapter(IExpression.class); - if (expression != null) { - update.setLabel(expression.getExpressionText(), idx); - } else { - update.setLabel(getData().getName(), idx); - } - } + } } - - if ( ! weAreExtractingFormattedData ) { - update.done(); - } else { - for (int idx = 0; idx < localColumns.length; idx++) { - if (IDebugVMConstants.COLUMN_ID__VALUE.equals(localColumns[idx])) { - updateFormattedRegisterValue(update, idx, dmc); - } + } + + if ( ! weAreExtractingFormattedData ) { + update.done(); + } else { + for (int idx = 0; idx < localColumns.length; idx++) { + if (IDebugVMConstants.COLUMN_ID__VALUE.equals(localColumns[idx])) { + updateFormattedRegisterValue(update, idx, dmc); } } } - }, - getSession().getExecutor() - ); + } + }, + getSession().getExecutor()); } } @Override protected void updateElementsInSessionThread(final IChildrenUpdate update) { - CompositeDMVMContext compositeDmc = new CompositeDMVMContext(getVMProvider().getRootElement(), update.getElementPath()); - getServicesTracker().getService(IRegisters.class).getRegisters( - compositeDmc, + new CompositeDMVMContext(update), new DataRequestMonitor(getSession().getExecutor(), null) { @Override public void handleCompleted() { @@ -389,12 +397,11 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode } @Override - protected IVMContext createVMContext(IDMContext dmc) { + protected IDMVMContext createVMContext(IDMContext dmc) { return new RegisterVMC(dmc); } - @Override - protected int getNodeDeltaFlagsForDMEvent(IDMEvent e) { + public int getDeltaFlags(Object e) { // In theory we want each node to act independently in terms of events. It might be // the case that we would only have elements of this type at the root level. It is // the case that the current layout model always starts with the GROUPS followed by @@ -404,62 +411,83 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode // the GROUP LAYOUT node do this. Later we need to revisit the logic and make sure // there is a way for the nodes to operate independently and efficiently. // - // if (e instanceof IRunControl.ISuspendedDMEvent) { - // return IModelDelta.CONTENT; - // } + if (e instanceof IRunControl.ISuspendedDMEvent) { + return IModelDelta.CONTENT; + } if (e instanceof IRegisters.IRegistersChangedDMEvent) { - /* - * Flush the cache. - */ - VMCacheManager.getVMCacheManager().flush(super.getVMProvider().getPresentationContext()); - return IModelDelta.CONTENT; } if (e instanceof IRegisters.IRegisterChangedDMEvent) { - /* - * Flush the cache. - */ - VMCacheManager.getVMCacheManager().flush(super.getVMProvider().getPresentationContext()); - /* * Logically one would think that STATE should be specified here. But we specifiy CONTENT * as well so that if there are subregisters ( BIT FIELDS ) they will be forced to update * and show new values when the total register changes. */ - return IModelDelta.CONTENT | IModelDelta.STATE; + return IModelDelta.CONTENT; + } + + if (e instanceof PropertyChangeEvent && + ((PropertyChangeEvent)e).getProperty() == IDebugVMConstants.CURRENT_FORMAT_STORAGE) + { + return IModelDelta.CONTENT; } return IModelDelta.NO_CHANGE; } - @Override - protected void buildDeltaForDMEvent(IDMEvent e, VMDelta parent, int nodeOffset, RequestMonitor rm) { - // In theory we want each node to act independently in terms of events. It might be - // the case that we would only have elements of this type at the root level. It is - // the case that the current layout model always starts with the GROUPS followed by - // REGISTERS followed by BITFIELDS. But if we do this when a run-control event has - // occured we generate a DELTA for every element, which can create a massive list - // of entries all of which say update the entire view. So for now we will just have - // the GROUP LAYOUT node do this. Later we need to revisit the logic and make sure - // there is a way for the nodes to operate independently and efficiently. - // - // if (e instanceof IRunControl.ISuspendedDMEvent) { - // // Create a delta that the whole register group has changed. - // parent.addFlags(IModelDelta.CONTENT); - // } + public void buildDelta(Object e, ModelDelta parentDelta, int nodeOffset, RequestMonitor rm) { + if (e instanceof IRunControl.ISuspendedDMEvent) { + // Create a delta that the whole register group has changed. + parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); + } if (e instanceof IRegisters.IRegistersChangedDMEvent) { - parent.addFlags(IModelDelta.CONTENT);; + parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT);; } if (e instanceof IRegisters.IRegisterChangedDMEvent) { - parent.addNode( createVMContext(((IRegisterChangedDMEvent)e).getDMContext()), IModelDelta.CONTENT | IModelDelta.STATE ); + parentDelta.addNode( createVMContext(((IRegisterChangedDMEvent)e).getDMContext()), IModelDelta.CONTENT | IModelDelta.STATE ); } + + if (e instanceof PropertyChangeEvent && + ((PropertyChangeEvent)e).getProperty() == IDebugVMConstants.CURRENT_FORMAT_STORAGE) + { + parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); + } - super.buildDeltaForDMEvent(e, parent, nodeOffset, rm); + rm.done(); } + public boolean canParseExpression(IExpression expression) { + return parseExpressionForRegisterName(expression.getExpressionText()) != null; + } + + /** + * Expected format: $$"Group Name"$Register_Name.Bit_Field_Name + */ + private String parseExpressionForRegisterName(String expression) { + if (expression.startsWith("$$\"")) { //$NON-NLS-1$ + int secondQuoteIdx = expression.indexOf('"', "$$\"".length()); //$NON-NLS-1$ + if (secondQuoteIdx > 0) { + String registerSubString = expression.substring(secondQuoteIdx + 1); + if (registerSubString.length() != 0 && + registerSubString.charAt(0) == '$' && + Character.isLetterOrDigit(registerSubString.charAt(1))) + { + int registerEnd = 1; + while ( registerEnd < registerSubString.length() && + Character.isLetterOrDigit(registerSubString.charAt(registerEnd)) ) + { + registerEnd++; + } + return registerSubString.substring(1, registerEnd); + } + } + } + return null; + } + public int getExpressionLength(String expression) { if (expression.charAt(0) == '$' && Character.isLetterOrDigit(expression.charAt(1))) { int length = 1; @@ -473,21 +501,21 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode } @Override - protected void testContextForExpression(Object element, final String expression, final DataRequestMonitor rm) { - if (!(element instanceof AbstractDMVMLayoutNode.DMVMContext)) { + protected void testElementForExpression(Object element, IExpression expression, DataRequestMonitor rm) { + if (!(element instanceof IDMVMContext)) { rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ rm.done(); return; } - final IRegisterDMContext dmc = DMContexts.getAncestorOfType(((DMVMContext)element).getDMC(), IRegisterDMContext.class); + final IRegisterDMContext dmc = DMContexts.getAncestorOfType(((IDMVMContext)element).getDMContext(), IRegisterDMContext.class); if (dmc == null) { rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ rm.done(); return; } - String regName = expression.substring(1); - if (regName.equals(dmc.getName())) { + String regName = parseExpressionForRegisterName(expression.getExpressionText()); + if (dmc.getName().equals(regName)) { rm.setData(Boolean.TRUE); } else { rm.setData(Boolean.FALSE); @@ -502,28 +530,30 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode } } - @Override - protected int getDeltaFlagsForExpressionPart(Object event) { + public int getDeltaFlagsForExpression(IExpression expression, Object event) { if (event instanceof IRunControl.ISuspendedDMEvent) { return IModelDelta.CONTENT; } + if (event instanceof PropertyChangeEvent && + ((PropertyChangeEvent)event).getProperty() == IDebugVMConstants.CURRENT_FORMAT_STORAGE) + { + return IModelDelta.CONTENT; + } return IModelDelta.NO_CHANGE; } - @Override - public void buildDeltaForExpression(final IExpression expression, final int elementIdx, final String expressionText, final Object event, final VMDelta parentDelta, final TreePath path, final RequestMonitor rm) + public void buildDeltaForExpression(IExpression expression, int elementIdx, Object event, ModelDelta parentDelta, + TreePath path, RequestMonitor rm) { if (event instanceof IRunControl.ISuspendedDMEvent) { // Mark the parent delta indicating that elements were added and/or removed. - parentDelta.addFlags(IModelDelta.CONTENT); + parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); } - - super.buildDeltaForExpression(expression, elementIdx, expressionText, event, parentDelta, path, rm); + rm.done(); } - @Override - protected void buildDeltaForExpressionElement(Object element, int elementIdx, Object event, VMDelta parentDelta, final RequestMonitor rm) + public void buildDeltaForExpressionElement(Object element, int elementIdx, Object event, ModelDelta parentDelta, final RequestMonitor rm) { if (event instanceof IRegisters.IRegisterChangedDMEvent) { parentDelta.addNode(element, IModelDelta.STATE); @@ -533,7 +563,13 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode parentDelta.addNode(element, IModelDelta.STATE); } - super.buildDeltaForExpressionElement(element, elementIdx, event, parentDelta, rm); + if (event instanceof PropertyChangeEvent && + ((PropertyChangeEvent)event).getProperty() == IDebugVMConstants.CURRENT_FORMAT_STORAGE) + { + parentDelta.addNode(element, IModelDelta.CONTENT); + } + + rm.done(); } @@ -556,7 +592,7 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode } public ICellModifier getCellModifier(IPresentationContext context, Object element) { - - return new RegisterLayoutValueCellModifier( fFormattedPrefStore, fSyncRegisterDataAccess ); + return new RegisterCellModifier( + getDMVMProvider(), fFormattedPrefStore, fSyncRegisterDataAccess ); } } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java index 7e6c8207990..3927d23c824 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java @@ -10,27 +10,36 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.viewmodel.register; -import org.eclipse.dd.dsf.debug.ui.viewmodel.dm.AbstractDebugDMVMProviderWithCache; import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.FormattedValuePreferenceStore; +import org.eclipse.dd.dsf.debug.ui.viewmodel.update.BreakpointHitUpdatePolicy; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; -import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; -import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode; -import org.eclipse.dd.dsf.ui.viewmodel.dm.DMVMRootLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.IRootVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.IVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.dm.RootDMVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.update.AutomaticUpdatePolicy; +import org.eclipse.dd.dsf.ui.viewmodel.update.IVMUpdatePolicy; +import org.eclipse.dd.dsf.ui.viewmodel.update.ManualUpdatePolicy; import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; /** * Provides the VIEW MODEL for the DEBUG MODEL REGISTER view. */ @SuppressWarnings("restriction") -public class RegisterVMProvider extends AbstractDebugDMVMProviderWithCache +public class RegisterVMProvider extends AbstractDMVMProvider + implements IPropertyChangeListener { /* * Current default for register formatting. */ public RegisterVMProvider(AbstractVMAdapter adapter, IPresentationContext context, DsfSession session) { super(adapter, context, session); + + context.addPropertyChangeListener(this); /* * Create the register data access routines. @@ -40,30 +49,41 @@ public class RegisterVMProvider extends AbstractDebugDMVMProviderWithCache /* * Create the top level node to deal with the root selection. */ - IVMRootLayoutNode debugViewSelection = new DMVMRootLayoutNode(this); + IRootVMNode rootNode = new RootDMVMNode(this); /* * Create the Group nodes next. They represent the first level shown in the view. */ - IVMLayoutNode registerGroupNode = new RegisterGroupLayoutNode(this, getSession(), regAccess); - debugViewSelection.setChildNodes(new IVMLayoutNode[] { registerGroupNode }); + IVMNode registerGroupNode = new RegisterGroupVMNode(this, getSession(), regAccess); + addChildNodes(rootNode, new IVMNode[] { registerGroupNode }); /* * Create the next level which is the registers themselves. */ - IVMLayoutNode registerNode = new RegisterLayoutNode(FormattedValuePreferenceStore.getDefault(), this, getSession(), regAccess); - registerGroupNode.setChildNodes(new IVMLayoutNode[] { registerNode }); + IVMNode registerNode = new RegisterVMNode(FormattedValuePreferenceStore.getDefault(), this, getSession(), regAccess); + addChildNodes(registerGroupNode, new IVMNode[] { registerNode }); /* * Create the next level which is the bitfield level. */ - IVMLayoutNode bitFieldNode = new RegisterBitFieldLayoutNode(FormattedValuePreferenceStore.getDefault(), this, getSession(), regAccess); - registerNode.setChildNodes(new IVMLayoutNode[] { bitFieldNode }); + IVMNode bitFieldNode = new RegisterBitFieldVMNode(FormattedValuePreferenceStore.getDefault(), this, getSession(), regAccess); + addChildNodes(registerNode, new IVMNode[] { bitFieldNode }); /* * Now set this schema set as the layout set. */ - setRootLayoutNode(debugViewSelection); + setRootNode(rootNode); + } + + @Override + protected IVMUpdatePolicy[] createUpdateModes() { + return new IVMUpdatePolicy[] { new AutomaticUpdatePolicy(), new ManualUpdatePolicy(), new BreakpointHitUpdatePolicy() }; + } + + @Override + public void dispose() { + getPresentationContext().removePropertyChangeListener(this); + super.dispose(); } @Override @@ -75,4 +95,8 @@ public class RegisterVMProvider extends AbstractDebugDMVMProviderWithCache public String getColumnPresentationId(IPresentationContext context, Object element) { return RegisterColumnPresentation.ID; } + + public void propertyChange(PropertyChangeEvent event) { + handleEvent(event); + } } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java index ab6985389db..6f777e2623e 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java @@ -35,7 +35,7 @@ import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMData; import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; import org.osgi.framework.InvalidSyntaxException; import org.osgi.util.tracker.ServiceTracker; @@ -154,8 +154,8 @@ public class SyncRegisterDataAccess { } public IBitFieldDMContext getBitFieldDMC(Object element) { - if (element instanceof AbstractDMVMLayoutNode.DMVMContext) { - IDMContext dmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); + if (element instanceof IDMVMContext) { + IDMContext dmc = ((IDMVMContext)element).getDMContext(); return DMContexts.getAncestorOfType(dmc, IBitFieldDMContext.class); } return null; @@ -410,24 +410,24 @@ public class SyncRegisterDataAccess { } public IRegisterGroupDMContext getRegisterGroupDMC(Object element) { - if (element instanceof AbstractDMVMLayoutNode.DMVMContext) { - IDMContext dmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); + if (element instanceof IDMVMContext) { + IDMContext dmc = ((IDMVMContext)element).getDMContext(); return DMContexts.getAncestorOfType(dmc, IRegisterGroupDMContext.class); } return null; } public IRegisterDMContext getRegisterDMC(Object element) { - if (element instanceof AbstractDMVMLayoutNode.DMVMContext) { - IDMContext dmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); + if (element instanceof IDMVMContext) { + IDMContext dmc = ((IDMVMContext)element).getDMContext(); return DMContexts.getAncestorOfType(dmc, IRegisterDMContext.class); } return null; } public IFormattedDataDMContext getFormattedDMC(Object element) { - if (element instanceof AbstractDMVMLayoutNode.DMVMContext) { - IDMContext dmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); + if (element instanceof IDMVMContext) { + IDMContext dmc = ((IDMVMContext)element).getDMContext(); IRegisterDMContext regdmc = DMContexts.getAncestorOfType(dmc, IRegisterDMContext.class); return DMContexts.getAncestorOfType(regdmc, IFormattedDataDMContext.class); } @@ -795,8 +795,8 @@ public class SyncRegisterDataAccess { * session is stale, then bail out. */ IFormattedDataDMContext dmc = null; - if (element instanceof AbstractDMVMLayoutNode.DMVMContext) { - IDMContext vmcdmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); + if (element instanceof IDMVMContext) { + IDMContext vmcdmc = ((IDMVMContext)element).getDMContext(); IRegisterDMContext regdmc = DMContexts.getAncestorOfType(vmcdmc, IRegisterDMContext.class); dmc = DMContexts.getAncestorOfType(regdmc, IFormattedDataDMContext.class); } @@ -899,8 +899,8 @@ public class SyncRegisterDataAccess { * session is stale, then bail out. */ IFormattedDataDMContext dmc = null; - if (element instanceof AbstractDMVMLayoutNode.DMVMContext) { - IDMContext vmcdmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); + if (element instanceof IDMVMContext) { + IDMContext vmcdmc = ((IDMVMContext)element).getDMContext(); IRegisterDMContext regdmc = DMContexts.getAncestorOfType(vmcdmc, IRegisterDMContext.class); dmc = DMContexts.getAncestorOfType(regdmc, IFormattedDataDMContext.class); } @@ -939,8 +939,8 @@ public class SyncRegisterDataAccess { * session is stale, then bail out. */ IFormattedDataDMContext dmc = null; - if (element instanceof AbstractDMVMLayoutNode.DMVMContext) { - IDMContext vmcdmc = ((AbstractDMVMLayoutNode.DMVMContext)element).getDMC(); + if (element instanceof IDMVMContext) { + IDMContext vmcdmc = ((IDMVMContext)element).getDMContext(); IBitFieldDMContext bitfielddmc = DMContexts.getAncestorOfType(vmcdmc, IBitFieldDMContext.class); dmc = DMContexts.getAncestorOfType(bitfielddmc, IFormattedDataDMContext.class); } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/BreakpointHitUpdatePolicy.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/BreakpointHitUpdatePolicy.java new file mode 100644 index 00000000000..fc25fcd0cbc --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/BreakpointHitUpdatePolicy.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel.update; + +import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason; +import org.eclipse.dd.dsf.ui.viewmodel.update.IElementUpdateTester; +import org.eclipse.dd.dsf.ui.viewmodel.update.ManualUpdatePolicy; + +/** + * + */ +public class BreakpointHitUpdatePolicy extends ManualUpdatePolicy { + + public static String BREAKPOINT_HIT_UPDATE_POLICY_ID = "org.eclipse.dd.dsf.debug.ui.viewmodel.update.breakpointHitUpdatePolicy"; //$NON-NLS-1$ + + @Override + public String getID() { + return BREAKPOINT_HIT_UPDATE_POLICY_ID; + } + + @Override + public String getName() { + return "Breakpoint Hit"; + } + + @Override + public IElementUpdateTester getTesterTester(Object event) { + if(event instanceof ISuspendedDMEvent) { + ISuspendedDMEvent suspendedEvent = (ISuspendedDMEvent)event; + if(suspendedEvent.getReason().equals(StateChangeReason.BREAKPOINT)) { + return super.getTesterTester(REFRESH_EVENT); + } + } + return super.getTesterTester(event); + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshAlways.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshAlways.java deleted file mode 100644 index a5f8070440c..00000000000 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshAlways.java +++ /dev/null @@ -1,36 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Ted R Williams (Wind River Systems, Inc.) - initial implementation - *******************************************************************************/ - -package org.eclipse.dd.dsf.debug.ui.viewmodel.update; - -import org.eclipse.dd.dsf.datamodel.IDMEvent; -import org.eclipse.dd.dsf.debug.service.IRunControl; -import org.eclipse.dd.dsf.ui.viewmodel.update.VMCache; - -public class VMCacheRefreshAlways extends VMCache -{ - public VMCacheRefreshAlways() - { - super(); - } - - public VMCacheRefreshAlways(VMCache oldCache) - { - super(oldCache); - } - - @SuppressWarnings("unchecked") - @Override - public void handleEvent(IDMEvent event) { - if(event instanceof IRunControl.ISuspendedDMEvent) - flush(true); - } -} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshManual.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshManual.java deleted file mode 100644 index 86a1723fb2d..00000000000 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshManual.java +++ /dev/null @@ -1,32 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Ted R Williams (Wind River Systems, Inc.) - initial implementation - *******************************************************************************/ - -package org.eclipse.dd.dsf.debug.ui.viewmodel.update; - -import org.eclipse.dd.dsf.datamodel.IDMEvent; -import org.eclipse.dd.dsf.ui.viewmodel.update.VMCache; - -public class VMCacheRefreshManual extends VMCache -{ - public VMCacheRefreshManual() - { - super(); - } - - public VMCacheRefreshManual(VMCache oldCache) - { - super(oldCache); - } - - @SuppressWarnings("unchecked") - @Override - public void handleEvent(IDMEvent event) {} -} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshOnBreak.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshOnBreak.java deleted file mode 100644 index 9819ea70a8c..00000000000 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/VMCacheRefreshOnBreak.java +++ /dev/null @@ -1,42 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Ted R Williams (Wind River Systems, Inc.) - initial implementation - *******************************************************************************/ - -package org.eclipse.dd.dsf.debug.ui.viewmodel.update; - -import org.eclipse.dd.dsf.datamodel.IDMEvent; -import org.eclipse.dd.dsf.debug.service.IRunControl; -import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason; -import org.eclipse.dd.dsf.ui.viewmodel.update.VMCache; - -public class VMCacheRefreshOnBreak extends VMCache -{ - public VMCacheRefreshOnBreak() - { - super(); - } - - public VMCacheRefreshOnBreak(VMCache oldCache) - { - super(oldCache); - } - - @SuppressWarnings("unchecked") - @Override - public void handleEvent(IDMEvent event) { - if(event instanceof IRunControl.ISuspendedDMEvent) - { - if(((IRunControl.ISuspendedDMEvent) event).getReason().equals(StateChangeReason.BREAKPOINT)) - flush(true); - } - } -} - - diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshActionDelegate.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshActionDelegate.java index b3786a50a78..d4aace40560 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshActionDelegate.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshActionDelegate.java @@ -6,131 +6,45 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * Ted R Williams (Wind River Systems, Inc.) - initial implementation + * Wind River Systems - initial API and implementation *******************************************************************************/ - package org.eclipse.dd.dsf.debug.ui.viewmodel.update.actions; -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.dd.dsf.ui.viewmodel.IVMAdapter; +import org.eclipse.dd.dsf.debug.ui.viewmodel.actions.AbstractVMProviderActionDelegate; import org.eclipse.dd.dsf.ui.viewmodel.IVMProvider; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProviderWithCache; -import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; -import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer; -import org.eclipse.debug.ui.AbstractDebugView; -import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.dd.dsf.ui.viewmodel.update.ICachingVMProvider; import org.eclipse.debug.ui.contexts.DebugContextEvent; -import org.eclipse.debug.ui.contexts.IDebugContextListener; import org.eclipse.jface.action.IAction; import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.ui.IViewActionDelegate; import org.eclipse.ui.IViewPart; -import org.eclipse.ui.IViewSite; -@SuppressWarnings("restriction") -public class RefreshActionDelegate implements IViewActionDelegate, IDebugContextListener { +/** + * + */ +public class RefreshActionDelegate extends AbstractVMProviderActionDelegate { - protected IViewPart fView = null; - private Object fViewInput = null; - - public void init(IViewPart view) { - /* - * Save the view information for later reference and data retrieval. - */ - fView = view; - - /* - * Get the current selection from the DebugView so we can determine if we want this menu action to be live or not. - */ - IViewSite site = (IViewSite) view.getSite(); - String combinedViewId = site.getId() + (site.getSecondaryId() != null ? (":" + site.getSecondaryId()) : ""); //$NON-NLS-1$ //$NON-NLS-2$ - - DebugUITools.getDebugContextManager().getContextService(view.getSite().getWorkbenchWindow()).addPostDebugContextListener(this, combinedViewId); - ISelection sel = DebugUITools.getDebugContextManager().getContextService(view.getSite().getWorkbenchWindow()).getActiveContext(); - - if ( sel instanceof IStructuredSelection ) { - /* - * Save the view selection as well so we can later determine if we want our action to be valid or not. - */ - fViewInput = ( (IStructuredSelection) sel ).getFirstElement(); - } - } - - /* - * (non-Javadoc) - * @see org.eclipse.debug.ui.contexts.IDebugContextListener#debugContextChanged(org.eclipse.debug.ui.contexts.DebugContextEvent) - */ - public void debugContextChanged(DebugContextEvent event) { - /* - * This handler is called whenever a selection in the debug view is changed. So here is - * where we will know when we need to reenable the menu actions. - */ - ISelection sel = event.getContext(); - - if (sel instanceof IStructuredSelection) { - fViewInput = ((IStructuredSelection)sel).getFirstElement(); + public void run(IAction action) { + IVMProvider provider = getVMProvider(); + if (provider instanceof ICachingVMProvider) { + ((ICachingVMProvider)provider).refresh(); } } + + @Override + public void init(IViewPart view) { + super.init(view); + getAction().setEnabled(getVMProvider() instanceof ICachingVMProvider); + } + + @Override + public void debugContextChanged(DebugContextEvent event) { + super.debugContextChanged(event); + getAction().setEnabled(getVMProvider() instanceof ICachingVMProvider); + } - public void run(IAction action) { - /* - * Make sure we have a valid set of information. Otherwise we cannot go forward. - */ - if ( fView instanceof AbstractDebugView && fViewInput != null ) - { - Viewer viewer = ( (AbstractDebugView) fView).getViewer(); - - /* - * Now we need to make sure this is one of the Flexible Hierarchy viewws. - */ - if ( viewer instanceof TreeModelViewer ) { - /* - * Get the presentation context and see if there is a numeric property there. If so then this - * is a view implementation which supports changing the format. - */ - TreeModelViewer treeViewer = (TreeModelViewer) viewer; - IPresentationContext context = treeViewer.getPresentationContext(); - - /* - * Now go tell the view to update. We do so by finding the VM provider for this view - * and telling it to redraw the entire view. - */ - if (fViewInput instanceof IAdaptable) { - IVMAdapter adapter = (IVMAdapter) ((IAdaptable)fViewInput).getAdapter(IVMAdapter.class); - - if ( adapter != null ) { - IVMProvider provider = adapter.getVMProvider(context); - - if ( provider != null ) { - - if ( provider instanceof AbstractDMVMProviderWithCache ) { - AbstractDMVMProviderWithCache prov = (AbstractDMVMProviderWithCache) provider; - - prov.flush(); - return; - } - } - } - } - } - } - - /* - * As a fallback we will flush the cache without involving the provider if it for some - * reason does not measure up. - */ - - VMCacheManager.getVMCacheManager().flush(getContext()); - } - - public void selectionChanged(IAction action, ISelection selection) { - } - - private Object getContext() - { - return ((TreeModelViewer) ((AbstractDebugView) fView).getViewer()).getPresentationContext(); - } + @Override + public void selectionChanged(IAction action, ISelection selection) { + super.selectionChanged(action, selection); + getAction().setEnabled(getVMProvider() instanceof ICachingVMProvider); + } } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshAlwaysActionDelegate.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshAlwaysActionDelegate.java deleted file mode 100644 index 2631f78607e..00000000000 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshAlwaysActionDelegate.java +++ /dev/null @@ -1,35 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Ted R Williams (Wind River Systems, Inc.) - initial implementation - *******************************************************************************/ - -package org.eclipse.dd.dsf.debug.ui.viewmodel.update.actions; - -import org.eclipse.dd.dsf.debug.ui.viewmodel.update.VMCacheRefreshAlways; -import org.eclipse.dd.dsf.ui.viewmodel.update.VMCache; -import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager; -import org.eclipse.dd.dsf.ui.viewmodel.update.actions.AbstractRefreshActionDelegate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer; -import org.eclipse.debug.ui.AbstractDebugView; - -@SuppressWarnings("restriction") -public class RefreshAlwaysActionDelegate extends AbstractRefreshActionDelegate -{ - @Override - public Object getContext() - { - return ((TreeModelViewer) ((AbstractDebugView) fView).getViewer()).getPresentationContext(); - } - - @Override - public VMCache createCache() - { - return new VMCacheRefreshAlways(VMCacheManager.getVMCacheManager().getCache(getContext())); - } -} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshManualActionDelegate.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshManualActionDelegate.java deleted file mode 100644 index 7aabf2e3197..00000000000 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshManualActionDelegate.java +++ /dev/null @@ -1,35 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Ted R Williams (Wind River Systems, Inc.) - initial implementation - *******************************************************************************/ - -package org.eclipse.dd.dsf.debug.ui.viewmodel.update.actions; - -import org.eclipse.dd.dsf.debug.ui.viewmodel.update.VMCacheRefreshManual; -import org.eclipse.dd.dsf.ui.viewmodel.update.VMCache; -import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager; -import org.eclipse.dd.dsf.ui.viewmodel.update.actions.AbstractRefreshActionDelegate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer; -import org.eclipse.debug.ui.AbstractDebugView; - -@SuppressWarnings("restriction") -public class RefreshManualActionDelegate extends AbstractRefreshActionDelegate -{ - @Override - public Object getContext() - { - return ((TreeModelViewer) ((AbstractDebugView) fView).getViewer()).getPresentationContext(); - } - - @Override - public VMCache createCache() - { - return new VMCacheRefreshManual(VMCacheManager.getVMCacheManager().getCache(getContext())); - } -} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshOnBreakActionDelegate.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshOnBreakActionDelegate.java deleted file mode 100644 index b6eda44fc0b..00000000000 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshOnBreakActionDelegate.java +++ /dev/null @@ -1,35 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Ted R Williams (Wind River Systems, Inc.) - initial implementation - *******************************************************************************/ - -package org.eclipse.dd.dsf.debug.ui.viewmodel.update.actions; - -import org.eclipse.dd.dsf.debug.ui.viewmodel.update.VMCacheRefreshOnBreak; -import org.eclipse.dd.dsf.ui.viewmodel.update.VMCache; -import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager; -import org.eclipse.dd.dsf.ui.viewmodel.update.actions.AbstractRefreshActionDelegate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer; -import org.eclipse.debug.ui.AbstractDebugView; - -@SuppressWarnings("restriction") -public class RefreshOnBreakActionDelegate extends AbstractRefreshActionDelegate -{ - @Override - public Object getContext() - { - return ((TreeModelViewer) ((AbstractDebugView) fView).getViewer()).getPresentationContext(); - } - - @Override - public VMCache createCache() - { - return new VMCacheRefreshOnBreak(VMCacheManager.getVMCacheManager().getCache(getContext())); - } -} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/SelectUpdatePolicyAction.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/SelectUpdatePolicyAction.java new file mode 100644 index 00000000000..76e64c2fa43 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/SelectUpdatePolicyAction.java @@ -0,0 +1,128 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.viewmodel.update.actions; + +import org.eclipse.dd.dsf.debug.ui.viewmodel.actions.AbstractVMProviderActionDelegate; +import org.eclipse.dd.dsf.ui.viewmodel.IVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.update.ICachingVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.update.IVMUpdatePolicy; +import org.eclipse.debug.ui.contexts.DebugContextEvent; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.ActionContributionItem; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuCreator; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.events.MenuAdapter; +import org.eclipse.swt.events.MenuEvent; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MenuItem; +import org.eclipse.ui.IViewPart; + +/** + * + */ +public class SelectUpdatePolicyAction extends AbstractVMProviderActionDelegate implements IMenuCreator { + + + class SelectPolicy extends Action { + private ICachingVMProvider fVMProvider; + private IVMUpdatePolicy fUpdatePolicy; + + @Override + public void run() { + if (isChecked()) { + fVMProvider.setActiveUpdatePolicy(fUpdatePolicy); + } + } + + public SelectPolicy(ICachingVMProvider provider, IVMUpdatePolicy updatePolicy) { + super(updatePolicy.getName(), IAction.AS_RADIO_BUTTON); + fVMProvider = provider; + fUpdatePolicy = updatePolicy; + } + } + + + public Menu getMenu(Control parent) { + // Never called + return null; + } + + @Override + public void init(IViewPart view) { + super.init(view); + getAction().setEnabled(getVMProvider() instanceof ICachingVMProvider); + } + + @Override + public void init(IAction action) { + super.init(action); + action.setMenuCreator(this); + } + + public void run(IAction action) { + // Do nothing, this is a pull-down menu + } + + @Override + public void selectionChanged(IAction action, ISelection selection) { + if (action != getAction()) { + action.setMenuCreator(this); + } + super.selectionChanged(action, selection); + getAction().setEnabled(getVMProvider() instanceof ICachingVMProvider); + } + + @Override + public void debugContextChanged(DebugContextEvent event) { + super.debugContextChanged(event); + getAction().setEnabled(getVMProvider() instanceof ICachingVMProvider); + } + + public Menu getMenu(Menu parent) { + Menu menu = new Menu(parent); + menu.addMenuListener(new MenuAdapter() { + @Override + public void menuShown(MenuEvent e) { + Menu m = (Menu)e.widget; + MenuItem[] items = m.getItems(); + for (int i=0; i < items.length; i++) { + items[i].dispose(); + } + fillMenu(m); + } + }); + return menu; + } + + private void fillMenu(Menu menu) { + + IVMUpdatePolicy[] updatePolicies = new IVMUpdatePolicy[0]; + IVMUpdatePolicy activePolicy = null; + IVMProvider provider = getVMProvider(); + if (provider instanceof ICachingVMProvider) { + ICachingVMProvider cachingProvider = (ICachingVMProvider)provider; + updatePolicies = cachingProvider.getAvailableUpdatePolicies(); + activePolicy = cachingProvider.getActiveUpdatePolicy(); + + for (IVMUpdatePolicy updatePolicy : updatePolicies) { + SelectPolicy action = new SelectPolicy(cachingProvider, updatePolicy); + if (updatePolicy.equals(activePolicy)) { + action.setChecked(true); + } + ActionContributionItem item = new ActionContributionItem(action); + item.fill(menu, -1); + } + } + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutValueCellModifier.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableCellModifier.java similarity index 85% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutValueCellModifier.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableCellModifier.java index bce3f7cc0bc..5948872679e 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutValueCellModifier.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableCellModifier.java @@ -13,15 +13,21 @@ import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionCellModifier; import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValuePreferenceStore; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.update.AbstractCachingVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.update.UserEditEvent; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; @SuppressWarnings("restriction") -public class VariableLayoutValueCellModifier extends WatchExpressionCellModifier { +public class VariableCellModifier extends WatchExpressionCellModifier { + private AbstractCachingVMProvider fProvider; private SyncVariableDataAccess fDataAccess = null; private IFormattedValuePreferenceStore fPrefStore; - public VariableLayoutValueCellModifier(IFormattedValuePreferenceStore formattedValuePreferenceStore, SyncVariableDataAccess access) { + public VariableCellModifier(AbstractCachingVMProvider provider, + IFormattedValuePreferenceStore formattedValuePreferenceStore, SyncVariableDataAccess access) + { + fProvider = provider; fDataAccess = access; fPrefStore = formattedValuePreferenceStore; } @@ -69,7 +75,7 @@ public class VariableLayoutValueCellModifier extends WatchExpressionCellModifier * Find the presentation context and then use it to get the current desired format. */ IVMContext ctx = (IVMContext) element; - IPresentationContext presCtx = ctx.getLayoutNode().getVMProvider().getPresentationContext(); + IPresentationContext presCtx = ctx.getVMNode().getVMProvider().getPresentationContext(); formatId = fPrefStore.getCurrentNumericFormat(presCtx); } @@ -107,7 +113,7 @@ public class VariableLayoutValueCellModifier extends WatchExpressionCellModifier * Find the presentation context and then use it to get the current desired format. */ IVMContext ctx = (IVMContext) element; - IPresentationContext presCtx = ctx.getLayoutNode().getVMProvider().getPresentationContext(); + IPresentationContext presCtx = ctx.getVMNode().getVMProvider().getPresentationContext(); formatId = fPrefStore.getCurrentNumericFormat(presCtx); } @@ -115,7 +121,7 @@ public class VariableLayoutValueCellModifier extends WatchExpressionCellModifier formatId = IFormattedValues.NATURAL_FORMAT; } - fDataAccess.writeVariable(element, (String) value, formatId); + fProvider.handleEvent(new UserEditEvent(element)); } } else { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java similarity index 80% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java index d1c0fc135b5..fd876fc32f2 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java @@ -11,10 +11,14 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.variable; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.RejectedExecutionException; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.MultiRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.DMContexts; @@ -23,6 +27,7 @@ import org.eclipse.dd.dsf.debug.service.IExpressions; import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.dd.dsf.debug.service.IRunControl; import org.eclipse.dd.dsf.debug.service.IStack; +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionChangedDMEvent; import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMData; import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext; @@ -32,17 +37,16 @@ import org.eclipse.dd.dsf.debug.service.IStack.IVariableDMContext; import org.eclipse.dd.dsf.debug.service.IStack.IVariableDMData; import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; -import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.AbstractExpressionLayoutNode; +import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.AbstractExpressionVMNode; +import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.IExpressionUpdate; import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValuePreferenceStore; import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValueVMContext; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; -import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; -import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; -import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.dm.CompositeDMVMContext; -import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager; +import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.model.IDebugTarget; @@ -53,32 +57,27 @@ import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementEditor; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapterExtension; +import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.ICellModifier; import org.eclipse.jface.viewers.TextCellEditor; +import org.eclipse.jface.viewers.TreePath; import org.eclipse.swt.widgets.Composite; @SuppressWarnings({"restriction", "nls"}) -public class VariableLayoutNode extends AbstractExpressionLayoutNode implements IElementEditor { - - /** - * List of child nodes containing only a reference to this. This is what enables the view model - * provider to know about the recursive nature of subexpression nodes. - */ - private final IVMLayoutNode[] fChildLayoutNodes = { this }; - - @Override - public IVMLayoutNode[] getChildLayoutNodes() { - return fChildLayoutNodes; - } +public class VariableVMNode extends AbstractExpressionVMNode + implements IElementEditor, IElementLabelProvider +{ private final static int MAX_STRING_VALUE_LENGTH = 40; - @Override public int getDeltaFlags(Object e) { /* * @see buildDelta() @@ -91,22 +90,23 @@ public class VariableLayoutNode extends AbstractExpressionLayoutNode implements if ( e instanceof IExpressions.IExpressionChangedDMEvent) { return IModelDelta.STATE; } - + + if (e instanceof PropertyChangeEvent && + ((PropertyChangeEvent)e).getProperty() == IDebugVMConstants.CURRENT_FORMAT_STORAGE) + { + return IModelDelta.CONTENT; + } + return IModelDelta.NO_CHANGE; } - @Override - public void buildDelta(final Object event, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) { + public void buildDelta(final Object event, final ModelDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) { if (event instanceof IRunControl.ISuspendedDMEvent) { - parentDelta.addFlags(IModelDelta.CONTENT); + parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); } - else if ( event instanceof IExpressions.IExpressionChangedDMEvent) { - /* - * Flush the cache. - */ - VMCacheManager.getVMCacheManager().flush(super.getVMProvider().getPresentationContext()); - + + if ( event instanceof IExpressions.IExpressionChangedDMEvent) { /* * Logically one would think that STATE should be specified here. But we specifiy CONTENT * as well so that if there sub expressions which are affected in some way ( such as with @@ -114,6 +114,12 @@ public class VariableLayoutNode extends AbstractExpressionLayoutNode implements */ parentDelta.addNode( createVMContext(((IExpressions.IExpressionChangedDMEvent)event).getDMContext()), IModelDelta.CONTENT | IModelDelta.STATE ); } + + if (event instanceof PropertyChangeEvent && + ((PropertyChangeEvent)event).getProperty() == IDebugVMConstants.CURRENT_FORMAT_STORAGE) + { + parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); + } requestMonitor.done(); } @@ -189,7 +195,7 @@ public class VariableLayoutNode extends AbstractExpressionLayoutNode implements VariableExpressionVMC exprVmc = (VariableExpressionVMC) variable; - IExpressionDMContext exprDmc = DMContexts.getAncestorOfType(exprVmc.getDMC(), IExpressionDMContext.class); + IExpressionDMContext exprDmc = DMContexts.getAncestorOfType(exprVmc.getDMContext(), IExpressionDMContext.class); if (exprDmc != null) { return exprDmc.getExpression(); } @@ -200,32 +206,42 @@ public class VariableLayoutNode extends AbstractExpressionLayoutNode implements final protected VariableExpressionFactory fVariableExpressionFactory = new VariableExpressionFactory(); - public VariableLayoutNode(IFormattedValuePreferenceStore prefStore, AbstractVMProvider provider, - DsfSession session, SyncVariableDataAccess syncVariableDataAccess) { + public VariableVMNode(IFormattedValuePreferenceStore prefStore, AbstractDMVMProvider provider, + DsfSession session, SyncVariableDataAccess syncVariableDataAccess) + { super(provider, session, IExpressions.IExpressionDMContext.class); fFormattedPrefStore = prefStore; fSyncVariableDataAccess = syncVariableDataAccess; } @Override - protected IVMContext createVMContext(IDMContext dmc) { + protected IDMVMContext createVMContext(IDMContext dmc) { return new VariableExpressionVMC(dmc); } - /** - * We override this method because we now need to perform an extra level of data fetch to get the - * formatted value of the expression. - * - * @return void - */ - @Override + + public void update(final ILabelUpdate[] updates) { + try { + getSession().getExecutor().execute(new DsfRunnable() { + public void run() { + updateLabelInSessionThread(updates); + }}); + } catch (RejectedExecutionException e) { + for (ILabelUpdate update : updates) { + handleFailedUpdate(update); + } + } + } + + protected void updateLabelInSessionThread(ILabelUpdate[] updates) { for (final ILabelUpdate update : updates) { - final IExpressionDMContext dmc = findDmcInPath(update.getElementPath(), IExpressions.IExpressionDMContext.class); + final IExpressionDMContext dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IExpressions.IExpressionDMContext.class); - VMCacheManager.getVMCacheManager().getCache(update.getPresentationContext()) - .getModelData(getServicesTracker().getService(IExpressions.class, null), + getDMVMProvider().getModelData( + this, update, + getServicesTracker().getService(IExpressions.class, null), dmc, new DataRequestMonitor(getSession().getExecutor(), null) { @Override @@ -381,8 +397,9 @@ public class VariableLayoutNode extends AbstractExpressionLayoutNode implements */ final FormattedValueDMContext valueDmc = expressionService.getFormattedValueContext(dmc, finalFormatId); - VMCacheManager.getVMCacheManager().getCache(update.getPresentationContext()) - .getModelData(expressionService, + getDMVMProvider().getModelData( + VariableVMNode.this, update, + expressionService, valueDmc, new DataRequestMonitor(getSession().getExecutor(), null) { @Override @@ -403,11 +420,11 @@ public class VariableLayoutNode extends AbstractExpressionLayoutNode implements update.setLabel(stringValueBuf.toString(), labelIndex); // Color based on change history - FormattedValueDMData oldData = (FormattedValueDMData) VMCacheManager.getVMCacheManager() - .getCache(VariableLayoutNode.this.getVMProvider().getPresentationContext()) - .getArchivedModelData(valueDmc); + FormattedValueDMData oldData = (FormattedValueDMData) getDMVMProvider().getArchivedModelData( + VariableVMNode.this, update, valueDmc); - IExpressionDMData oldDMData = (IExpressionDMData) VMCacheManager.getVMCacheManager().getCache(update.getPresentationContext()).getArchivedModelData(dmc); + IExpressionDMData oldDMData = (IExpressionDMData) getDMVMProvider().getArchivedModelData( + VariableVMNode.this, update, dmc); String oldStringValue = oldDMData == null ? null : oldDMData.getStringValue(); // highlight the value if either the value (address) has changed or the string (memory at the value) has changed @@ -441,19 +458,51 @@ public class VariableLayoutNode extends AbstractExpressionLayoutNode implements } public ICellModifier getCellModifier(IPresentationContext context, Object element) { - return new VariableLayoutValueCellModifier(fFormattedPrefStore, fSyncVariableDataAccess); + return new VariableCellModifier(getDMVMProvider(), fFormattedPrefStore, fSyncVariableDataAccess); + } + + public boolean canParseExpression(IExpression expression) { + // Indicate that we can parse any expression that does not start with + // the reserved '$' and '#' characters. + String expressionText = expression.getExpressionText(); + return !expressionText.startsWith("$") && !expressionText.startsWith("#"); } @Override - protected void getElementForExpressionPart(IChildrenUpdate update, String expressionPartText, DataRequestMonitor rm) { - CompositeDMVMContext compositeDmc = new CompositeDMVMContext(getVMProvider().getRootElement(), update.getElementPath()); - - final IExpressions expressionService = getServicesTracker().getService(IExpressions.class); - IExpressionDMContext expressionDMC = expressionService.createExpression(compositeDmc, expressionPartText); - rm.setData(createVMContext(expressionDMC)); - rm.done(); + public void update(final IExpressionUpdate update) { + try { + getSession().getExecutor().execute(new Runnable() { + public void run() { + final IExpressions expressionService = getServicesTracker().getService(IExpressions.class); + if (expressionService != null) { + IExpressionDMContext expressionDMC = expressionService.createExpression( + new CompositeDMVMContext(update), + update.getExpression().getExpressionText()); + VariableExpressionVMC variableVmc = new VariableExpressionVMC(expressionDMC); + variableVmc.setExpression(update.getExpression()); + + update.setExpressionElement(variableVmc); + update.done(); + } else { + handleFailedUpdate(update); + } + } + }); + } catch (RejectedExecutionException e) { + handleFailedUpdate(update); + } } + + @Override + protected void handleFailedUpdate(IViewerUpdate update) { + if (update instanceof IExpressionUpdate) { + update.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Update failed", null)); //$NON-NLS-1$ + update.done(); + } else { + super.handleFailedUpdate(update); + } + } @Override protected void associateExpression(Object element, IExpression expression) { if (element instanceof VariableExpressionVMC) { @@ -461,36 +510,60 @@ public class VariableLayoutNode extends AbstractExpressionLayoutNode implements } } - @Override - protected int getDeltaFlagsForExpressionPart(Object event) { + public int getDeltaFlagsForExpression(IExpression expression, Object event) { if (event instanceof IRunControl.ISuspendedDMEvent) { return IModelDelta.CONTENT; + } + + if (event instanceof IExpressionChangedDMEvent) { + return IModelDelta.CONTENT; } + if (event instanceof PropertyChangeEvent && + ((PropertyChangeEvent)event).getProperty() == IDebugVMConstants.CURRENT_FORMAT_STORAGE) + { + return IModelDelta.CONTENT; + } return IModelDelta.NO_CHANGE; } - @Override - protected void testContextForExpression(Object element, String expression, DataRequestMonitor rm) { - /* - * Since we are overriding "getElementForExpression" we do not need to do anything here. But - * we are forced to supply this routine because it is abstract in the extending class. - */ + public void buildDeltaForExpression(IExpression expression, int elementIdx, Object event, ModelDelta parentDelta, + TreePath path, RequestMonitor rm) + { + rm.done(); } + + public void buildDeltaForExpressionElement(Object element, int elementIdx, Object event, ModelDelta parentDelta, + RequestMonitor rm) + { + if (event instanceof IRunControl.ISuspendedDMEvent) { + parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); + } + + if ( event instanceof IExpressions.IExpressionChangedDMEvent) { + /* + * Logically one would think that STATE should be specified here. But we specify CONTENT + * as well so that if there sub expressions which are affected in some way ( such as with + * an expanded union then they will show the changes also. + */ + parentDelta.addNode(element, IModelDelta.CONTENT); + } + - public int getExpressionLength(String expression) { - /* - * Since we are overriding "getElementForExpression" we do not need to do anything here. - * We just assume the entire expression is for us. - */ - return expression.length() ; + if (event instanceof PropertyChangeEvent && + ((PropertyChangeEvent)event).getProperty() == IDebugVMConstants.CURRENT_FORMAT_STORAGE) + { + parentDelta.addNode(element, IModelDelta.CONTENT); + } + + rm.done(); } - + @Override protected void updateElementsInSessionThread(final IChildrenUpdate update) { // Get the data model context object for the current node in the hierarchy. - final IExpressionDMContext expressionDMC = findDmcInPath(update.getElementPath(), IExpressionDMContext.class); + final IExpressionDMContext expressionDMC = findDmcInPath(update.getViewerInput(), update.getElementPath(), IExpressionDMContext.class); if ( expressionDMC != null ) { getSubexpressionsUpdateElementsInSessionThread( update ); @@ -502,7 +575,7 @@ public class VariableLayoutNode extends AbstractExpressionLayoutNode implements private void getSubexpressionsUpdateElementsInSessionThread(final IChildrenUpdate update) { - final IExpressionDMContext expressionDMC = findDmcInPath(update.getElementPath(), IExpressionDMContext.class); + final IExpressionDMContext expressionDMC = findDmcInPath(update.getViewerInput(), update.getElementPath(), IExpressionDMContext.class); if ( expressionDMC != null ) { @@ -542,7 +615,7 @@ public class VariableLayoutNode extends AbstractExpressionLayoutNode implements private void getLocalsUpdateElementsInSessionThread(final IChildrenUpdate update) { - final IFrameDMContext frameDmc = findDmcInPath(update.getElementPath(), IFrameDMContext.class); + final IFrameDMContext frameDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IFrameDMContext.class); // Get the services we need to use. @@ -641,8 +714,7 @@ public class VariableLayoutNode extends AbstractExpressionLayoutNode implements mrm.add(rm); - VMCacheManager.getVMCacheManager().getCache(VariableLayoutNode.this.getVMProvider().getPresentationContext()) - .getModelData(stackFrameService, localDMC, rm, getExecutor()); + getDMVMProvider().getModelData(VariableVMNode.this, update, stackFrameService, localDMC, rm, getExecutor()); } } }; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java index 5cd0380962c..c518f638978 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java @@ -8,23 +8,33 @@ */ package org.eclipse.dd.dsf.debug.ui.viewmodel.variable; -import org.eclipse.dd.dsf.debug.ui.viewmodel.dm.AbstractDebugDMVMProviderWithCache; import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.FormattedValuePreferenceStore; +import org.eclipse.dd.dsf.debug.ui.viewmodel.update.BreakpointHitUpdatePolicy; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; -import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; -import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode; -import org.eclipse.dd.dsf.ui.viewmodel.dm.DMVMRootLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.IRootVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.IVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.dm.RootDMVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.update.AutomaticUpdatePolicy; +import org.eclipse.dd.dsf.ui.viewmodel.update.IVMUpdatePolicy; +import org.eclipse.dd.dsf.ui.viewmodel.update.ManualUpdatePolicy; import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; @SuppressWarnings("restriction") -public class VariableVMProvider extends AbstractDebugDMVMProviderWithCache implements IColumnPresentationFactory { +public class VariableVMProvider extends AbstractDMVMProvider + implements IPropertyChangeListener, IColumnPresentationFactory +{ public VariableVMProvider(AbstractVMAdapter adapter, IPresentationContext context, DsfSession session) { super(adapter, context, session); + context.addPropertyChangeListener(this); + /* * Create the variable data access routines. */ @@ -33,18 +43,24 @@ public class VariableVMProvider extends AbstractDebugDMVMProviderWithCache imple /* * Create the top level node to deal with the root selection. */ - IVMRootLayoutNode debugViewSelection = new DMVMRootLayoutNode(this); + IRootVMNode rootNode = new RootDMVMNode(this); + setRootNode(rootNode); /* * Create the next level which represents members of structs/unions/enums and elements of arrays. */ - IVMLayoutNode subExpressioNode = new VariableLayoutNode(FormattedValuePreferenceStore.getDefault(), this, getSession(), varAccess); - debugViewSelection.setChildNodes(new IVMLayoutNode[] { subExpressioNode }); - - /* - * Now set this schema set as the layout set. - */ - setRootLayoutNode(debugViewSelection); + IVMNode subExpressioNode = new VariableVMNode(FormattedValuePreferenceStore.getDefault(), this, getSession(), varAccess); + addChildNodes(rootNode, new IVMNode[] { subExpressioNode }); + + // Configure the sub-expression node to be a child of itself. This way the content + // provider will recursively drill-down the variable hierarchy. + addChildNodes(subExpressioNode, new IVMNode[] { subExpressioNode }); + } + + @Override + public void dispose() { + getPresentationContext().removePropertyChangeListener(this); + super.dispose(); } @Override @@ -56,4 +72,14 @@ public class VariableVMProvider extends AbstractDebugDMVMProviderWithCache imple public String getColumnPresentationId(IPresentationContext context, Object element) { return VariableColumnPresentation.ID; } + + public void propertyChange(PropertyChangeEvent event) { + handleEvent(event); + } + + @Override + protected IVMUpdatePolicy[] createUpdateModes() { + return new IVMUpdatePolicy[] { new AutomaticUpdatePolicy(), new ManualUpdatePolicy(), new BreakpointHitUpdatePolicy() }; + } + } diff --git a/plugins/org.eclipse.dd.dsf.debug/build.properties b/plugins/org.eclipse.dd.dsf.debug/build.properties index 786b1df9364..bc3b0f2bf1f 100644 --- a/plugins/org.eclipse.dd.dsf.debug/build.properties +++ b/plugins/org.eclipse.dd.dsf.debug/build.properties @@ -3,4 +3,5 @@ output.. = bin/ bin.includes = META-INF/,\ .,\ plugin.xml,\ + plugin.properties,\ about.html diff --git a/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF index 2ffed4637d8..bf9157f877d 100644 --- a/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF @@ -15,6 +15,5 @@ Export-Package: org.eclipse.dd.dsf.ui.concurrent, org.eclipse.dd.dsf.ui.viewmodel, org.eclipse.dd.dsf.ui.viewmodel.dm, org.eclipse.dd.dsf.ui.viewmodel.properties, - org.eclipse.dd.dsf.ui.viewmodel.update, - org.eclipse.dd.dsf.ui.viewmodel.update.actions + org.eclipse.dd.dsf.ui.viewmodel.update Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/plugins/org.eclipse.dd.dsf.ui/build.properties b/plugins/org.eclipse.dd.dsf.ui/build.properties index 786b1df9364..bc3b0f2bf1f 100644 --- a/plugins/org.eclipse.dd.dsf.ui/build.properties +++ b/plugins/org.eclipse.dd.dsf.ui/build.properties @@ -3,4 +3,5 @@ output.. = bin/ bin.includes = META-INF/,\ .,\ plugin.xml,\ + plugin.properties,\ about.html diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/DisplayDsfExecutor.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/DisplayDsfExecutor.java index 7a5dfe600b1..8c47374294b 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/DisplayDsfExecutor.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/DisplayDsfExecutor.java @@ -22,11 +22,18 @@ import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor; +import org.eclipse.dd.dsf.concurrent.DsfExecutable; import org.eclipse.dd.dsf.concurrent.DsfExecutor; import org.eclipse.swt.SWT; import org.eclipse.swt.SWTException; import org.eclipse.swt.widgets.Display; +/** + * DSF executor which uses the display thread to run the submitted runnables + * and callables. The implementation is based on the default DSF executor + * which still creates its own thread. However this thread blocks when running + * each executable in the display thread. + */ public class DisplayDsfExecutor extends DefaultDsfExecutor { /** @@ -61,6 +68,15 @@ public class DisplayDsfExecutor extends DefaultDsfExecutor fDisplay = display; } + /** + * Override to check if we're in the display thread rather than the helper + * thread of the super-class. + */ + @Override + public boolean isInExecutorThread() { + return Thread.currentThread().equals(fDisplay.getThread()); + } + /** * Creates a callable wrapper, which delegates to the display to perform the * operation. The callable blocks the executor thread while each call @@ -70,7 +86,13 @@ public class DisplayDsfExecutor extends DefaultDsfExecutor * @return Wrapper callable. */ private Callable createSWTDispatchCallable(final Callable callable) { - return new Callable() { + // Check if executable wasn't executed already. + if (DEBUG_EXECUTOR && callable instanceof DsfExecutable) { + assert !((DsfExecutable)callable).getSubmitted() : "Executable was previously executed."; //$NON-NLS-1$ + ((DsfExecutable)callable).setSubmitted(); + } + + return new Callable() { @SuppressWarnings("unchecked") public V call() throws Exception { final Object[] v = new Object[1]; @@ -110,7 +132,14 @@ public class DisplayDsfExecutor extends DefaultDsfExecutor * @return Wrapper runnable. */ private Runnable createSWTDispatchRunnable(final Runnable runnable) { - return new Runnable() { + + // Check if executable wasn't executed already. + if (DEBUG_EXECUTOR && runnable instanceof DsfExecutable) { + assert !((DsfExecutable)runnable).getSubmitted() : "Executable was previously executed."; //$NON-NLS-1$ + ((DsfExecutable)runnable).setSubmitted(); + } + + return new Runnable() { public void run() { final Throwable[] e = new Throwable[1]; try { diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/ViewerCountingRequestMonitor.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/ViewerCountingRequestMonitor.java new file mode 100644 index 00000000000..674e83f5c60 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/ViewerCountingRequestMonitor.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.concurrent; + +import java.util.concurrent.Executor; + +import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; + +/** + * Counting multi data request monitor that takes a IViewerUpdate + * as a parent. If the IViewerUpdate is canceled, this request monitor becomes + * canceled as well. + * + * @see IViewerUpdate. + */ +@SuppressWarnings("restriction") +public class ViewerCountingRequestMonitor extends CountingRequestMonitor { + + private final IViewerUpdate fUpdate; + public ViewerCountingRequestMonitor(Executor executor, IViewerUpdate update) { + super(executor, null); + fUpdate = update; + } + + @Override + public synchronized boolean isCanceled() { + return fUpdate.isCanceled() || super.isCanceled(); + } + + @Override + protected void handleOK() { + fUpdate.done(); + } + + @Override + protected void handleError() { + fUpdate.setStatus(getStatus()); + fUpdate.done(); + } + + @Override + protected void handleCancel() { + fUpdate.setStatus(getStatus()); + fUpdate.done(); + } +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/ViewerDataRequestMonitor.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/ViewerDataRequestMonitor.java new file mode 100644 index 00000000000..b20e3cc04b6 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/ViewerDataRequestMonitor.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.concurrent; + +import java.util.concurrent.Executor; + +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; + +/** + * Data Request monitor that takean IViewerUpdate as a parent. + * If the IViewerUpdate is canceled, this request monitor becomes canceled as well. + * @see IViewerUpdate + */ +@SuppressWarnings("restriction") +public class ViewerDataRequestMonitor extends DataRequestMonitor { + + private final IViewerUpdate fUpdate; + public ViewerDataRequestMonitor(Executor executor, IViewerUpdate update) { + super(executor, null); + fUpdate = update; + } + + @Override + public synchronized boolean isCanceled() { + return fUpdate.isCanceled() || super.isCanceled(); + } + + @Override + protected void handleOK() { + fUpdate.done(); + } + + @Override + protected void handleError() { + fUpdate.setStatus(getStatus()); + fUpdate.done(); + } + + @Override + protected void handleCancel() { + fUpdate.setStatus(getStatus()); + fUpdate.done(); + } +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java index 12fd985be2e..b04f9a60e50 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java @@ -17,9 +17,6 @@ import java.util.concurrent.RejectedExecutionException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor; -import org.eclipse.dd.dsf.concurrent.DsfExecutor; -import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.DsfUIPlugin; @@ -41,7 +38,6 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; @SuppressWarnings("restriction") abstract public class AbstractVMAdapter implements IVMAdapter { - private final DsfExecutor fExecutor; private boolean fDisposed; private final Map fViewModelProviders = @@ -56,18 +52,8 @@ abstract public class AbstractVMAdapter implements IVMAdapter * @param session */ public AbstractVMAdapter() { - fExecutor = new DefaultDsfExecutor(); } - /** - * Returns the executor that will be used to communicate with the providers - * and the layout nodes. - * @return - */ - public DsfExecutor getExecutor() { - return fExecutor; - } - @ThreadSafe public IVMProvider getVMProvider(IPresentationContext context) { synchronized(fViewModelProviders) { @@ -85,93 +71,84 @@ abstract public class AbstractVMAdapter implements IVMAdapter } public void dispose() { - // Execute the shutdown in adapter's dispatch thread. - getExecutor().execute(new DsfRunnable() { - public void run() { - synchronized(fViewModelProviders) { - fDisposed = true; - for (IVMProvider provider : fViewModelProviders.values()) { + IVMProvider[] providers = new IVMProvider[0]; + synchronized(fViewModelProviders) { + providers = fViewModelProviders.values().toArray(new IVMProvider[fViewModelProviders.size()]); + fViewModelProviders.clear(); + fDisposed = true; + } + + for (final IVMProvider provider : providers) { + try { + provider.getExecutor().execute(new Runnable() { + public void run() { provider.dispose(); } - fViewModelProviders.clear(); - } - fExecutor.shutdown(); - } - }); + }); + } catch (RejectedExecutionException e) { + // Not much we can do at this point. + } + } } public void update(IHasChildrenUpdate[] updates) { - handleUpdates(updates); + IVMProvider provider = getVMProvider(updates[0].getPresentationContext()); + if (provider != null) { + updateProvider(provider, updates); + } else { + for (IViewerUpdate update : updates) { + update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, + "No model provider for update " + update, null)); //$NON-NLS-1$ + } + } } public void update(IChildrenCountUpdate[] updates) { - handleUpdates(updates); + IVMProvider provider = getVMProvider(updates[0].getPresentationContext()); + if (provider != null) { + updateProvider(provider, updates); + } else { + for (IViewerUpdate update : updates) { + update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, + "No model provider for update " + update, null)); //$NON-NLS-1$ + } + } } public void update(final IChildrenUpdate[] updates) { - handleUpdates(updates); - } - - private void handleUpdates(final IViewerUpdate[] updates) { - try { - getExecutor().execute(new DsfRunnable() { - public void run() { - IPresentationContext context = null; - int firstIdx = 0; - int curIdx = 0; - for (curIdx = 0; curIdx < updates.length; curIdx++) { - if (!updates[curIdx].getPresentationContext().equals(context)) { - if (context != null) { - callProviderWithUpdate(updates, firstIdx, curIdx); - } - context = updates[curIdx].getPresentationContext(); - firstIdx = curIdx; - } - } - callProviderWithUpdate(updates, firstIdx, curIdx); - } - }); - } catch(RejectedExecutionException e) { - for (IViewerUpdate update : updates) { - update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, "VM adapter executor not available", e)); //$NON-NLS-1$ - update.done(); - } - } - } - - private void callProviderWithUpdate(IViewerUpdate[] updates, int startIdx, int endIdx) { - final IVMProvider provider = getVMProvider(updates[0].getPresentationContext()); - if (provider == null) { + IVMProvider provider = getVMProvider(updates[0].getPresentationContext()); + if (provider != null) { + updateProvider(provider, updates); + } else { for (IViewerUpdate update : updates) { update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, - "No model provider for update " + update, null)); //$NON-NLS-1$ - update.done(); - } - return; - } - if (startIdx == 0 && endIdx == updates.length) { - if (updates instanceof IHasChildrenUpdate[]) provider.update((IHasChildrenUpdate[])updates); - else if (updates instanceof IChildrenCountUpdate[]) provider.update((IChildrenCountUpdate[])updates); - else if (updates instanceof IChildrenUpdate[]) provider.update((IChildrenUpdate[])updates); - } else { - if (updates instanceof IHasChildrenUpdate[]) { - IHasChildrenUpdate[] providerUpdates = new IHasChildrenUpdate[endIdx - startIdx]; - System.arraycopy(updates, startIdx, providerUpdates, 0, endIdx - startIdx); - provider.update(providerUpdates); - } - else if (updates instanceof IChildrenCountUpdate[]) { - IChildrenCountUpdate[] providerUpdates = new IChildrenCountUpdate[endIdx - startIdx]; - System.arraycopy(updates, startIdx, providerUpdates, 0, endIdx - startIdx); - provider.update(providerUpdates); - } - else if (updates instanceof IChildrenUpdate[]) { - IChildrenUpdate[] providerUpdates = new IChildrenUpdate[endIdx - startIdx]; - System.arraycopy(updates, startIdx, providerUpdates, 0, endIdx - startIdx); - provider.update(providerUpdates); + "No model provider for update " + update, null)); //$NON-NLS-1$ } } } - + + private void updateProvider(final IVMProvider provider, final IViewerUpdate[] updates) { + try { + provider.getExecutor().execute(new Runnable() { + public void run() { + if (updates instanceof IHasChildrenUpdate[]) { + provider.update((IHasChildrenUpdate[])updates); + } else if (updates instanceof IChildrenCountUpdate[]) { + provider.update((IChildrenCountUpdate[])updates); + } else if (updates instanceof IChildrenUpdate[]) { + provider.update((IChildrenUpdate[])updates); + } + } + }); + } catch (RejectedExecutionException e) { + for (IViewerUpdate update : updates) { + update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, + "Display is disposed, cannot complete update " + update, null)); //$NON-NLS-1$ + update.done(); + } + } + } + public IModelProxy createModelProxy(Object element, IPresentationContext context) { IVMProvider provider = getVMProvider(context); if (provider != null) { diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMContext.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMContext.java new file mode 100644 index 00000000000..5fab2eb44d7 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMContext.java @@ -0,0 +1,57 @@ +package org.eclipse.dd.dsf.ui.viewmodel; + +import org.eclipse.dd.dsf.ui.viewmodel.properties.IElementPropertiesProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory; + +/** + * Implementation of basic view model context interface. The main + * purpose of the VMC wrapper is to re-direct adapter queries to the IVMAdapter + * and the layout node that the given context was created by. + *

    + * Note: Deriving classes must override the Object.equals/hashCode methods. + * This is because the view model context objects are just wrappers that are + * created by the view model on demand, so the equals methods must use the + * object being wrapped to perform a meaningful comparison. + */ +@SuppressWarnings("restriction") +abstract public class AbstractVMContext implements IVMContext { + protected final IVMAdapter fVMAdapter; + protected final IVMNode fNode; + + public AbstractVMContext(IVMAdapter adapter, IVMNode node) { + fVMAdapter = adapter; + fNode = node; + } + + public IVMNode getVMNode() { return fNode; } + + /** + * IAdapter implementation returns the {@link IVMAdapter} instance for + * the interfaces that are actually implemented by the VM Adapter. + * These should at least include {@link IElementContentProvider}, + * {@link IModelProxyFactory}, and {@link IColumnPresentationFactory}. + * It also returns the {@link IVMNode} instance for adapters implemented + * by the context's node. The interfaces typically implemented by the + * node include {@link IElementLabelProvider} and {@link IElementPropertiesProvider}. + */ + @SuppressWarnings("unchecked") + public Object getAdapter(Class adapter) { + if (adapter.isInstance(fVMAdapter)) { + return fVMAdapter; + } else if (adapter.isInstance(fNode)) { + return fNode; + } + return null; + } + + /** Deriving classes must override. */ + @Override + abstract public boolean equals(Object obj); + + /** Deriving classes must override. */ + @Override + abstract public int hashCode(); +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java deleted file mode 100644 index 92dc16e0d3f..00000000000 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMLayoutNode.java +++ /dev/null @@ -1,517 +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.viewmodel; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.RejectedExecutionException; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.DsfExecutor; -import org.eclipse.dd.dsf.concurrent.MultiRequestMonitor; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; -import org.eclipse.jface.viewers.TreePath; - -/** - * Base implementation of the View Model layout node. - * The main functionality implemented here is for building the view model - * deltas (IModelDelta), based on the flags returned by child nodes. - */ -@SuppressWarnings("restriction") -abstract public class AbstractVMLayoutNode implements IVMLayoutNode { - - private final AbstractVMProvider fProvider; - private boolean fDisposed = false; - - /** Child schema nodes of this node. */ - private IVMLayoutNode[] fChildNodes = new IVMLayoutNode[0]; - - - public AbstractVMLayoutNode(AbstractVMProvider provider) { - fProvider = provider; - } - - /** - * Accessor method for sub-classes. - */ - protected DsfExecutor getExecutor() { - return fProvider.getExecutor(); - } - - public IVMProvider getVMProvider() { - return fProvider; - } - - public void setChildNodes(IVMLayoutNode[] childNodes) { - fChildNodes = childNodes; - } - - public IVMLayoutNode[] getChildLayoutNodes() { - return fChildNodes; - } - - public void dispose() { - fDisposed = true; - for (IVMLayoutNode childNode : getChildLayoutNodes()) { - childNode.dispose(); - } - } - - /** - * If any of the children nodes have delta flags, that means that this - * node has to generate a delta as well. - *

    Note: If a child node has a IModelDelta.CONTENT delta - * flag, it means that this flag will be added to this node's element. - * To allow for optimization change the child's IModelDelta.CONTENT - * flag into a IModelDelta.STATE flag. - */ - public int getDeltaFlags(Object e) { - int retVal = 0; - for (IVMLayoutNode childNode : getChildLayoutNodes()) { - int childNodeDeltaFlags = childNode.getDeltaFlags(e); - if ((childNodeDeltaFlags | IModelDelta.CONTENT) != 0) { - childNodeDeltaFlags &= ~IModelDelta.CONTENT; - childNodeDeltaFlags |= IModelDelta.STATE; - } - retVal |= childNode.getDeltaFlags(e); - } - return retVal; - } - - /** - * Base implementation that handles calling child layout nodes to build - * the model delta. The child nodes are called with all the elements - * in this node, which could be very inefficient. In order to build delta - * only for specific elements in this node, the class extending - * AbstractVMLayoutNode should override this method. - * @see IVMLayoutNode#buildDelta(Object, VMDelta, int, RequestMonitor) - */ - public void buildDelta(final Object event, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) { - // Find the child nodes that have deltas for the given event. - final Map childNodesWithDeltaFlags = getChildNodesWithDeltaFlags(event); - - // If no child layout nodes have deltas we can stop here. - if (childNodesWithDeltaFlags.size() == 0) { - requestMonitor.done(); - return; - } - - // Check if the child delta only has an IModelDelta.CONTENT or - // IModelDelta.STATE flags. If that's the case, we can skip - // creating a delta for this node, because the TreeUpdatePolicy does not - // use the full path from the delta to handle these flags. - // Similarly, the index argument is not necessary either. - boolean mustGetElements = false; - for (int childDelta : childNodesWithDeltaFlags.values()) { - if ((childDelta & ~IModelDelta.STATE) != 0) { - mustGetElements = true; - } - } - - if (!mustGetElements) { - callChildNodesToBuildDelta(childNodesWithDeltaFlags, parentDelta, event, requestMonitor); - } else { - // 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. - updateElements(new ElementsUpdate( - new DataRequestMonitor>(getExecutor(), null) { - @Override - protected void handleCompleted() { - if (fDisposed) return; - - // Check for an empty list of elements. If it's empty then we - // don't have to call the children nodes, so return here. - // No need to propagate error, there's no means or need to display it. - if (!getStatus().isOK() || getData().size() == 0) { - requestMonitor.done(); - return; - } - - final MultiRequestMonitor elementsDeltasMultiRequestMon = - new MultiRequestMonitor(getExecutor(), null) { - @Override - protected void handleCompleted() { - if (isDisposed()) return; - requestMonitor.done(); - } - }; - - // For each element from this node, create a new delta, - // and then call all the child nodes to build their delta. - for (int i = 0; i < getData().size(); i++) { - VMDelta delta = parentDelta.addNode(getData().get(i), nodeOffset + i, IModelDelta.NO_CHANGE); - callChildNodesToBuildDelta( - childNodesWithDeltaFlags, delta, event, - elementsDeltasMultiRequestMon.add(new RequestMonitor(getExecutor(), null) { - @Override - protected void handleCompleted() { - elementsDeltasMultiRequestMon.requestMonitorDone(this); - } - })); - } - } - }, - parentDelta)); - } - } - - /** - * Calls the specified child layout nodes to build the delta for the given event. - * @param nodes Map of layout nodes to be invoked, and the corresponding delta - * flags that they will generate. This map is generated with a call to - * {@link #getChildNodesWithDeltaFlags(Object)}. - * @param delta The delta object to build on. This delta should have been - * gerated by this node, unless the full delta path is not being calculated - * due to an optimization. - * @param event The event object that the delta is being built for. - * @param requestMonitor The result token to invoke when the delta is completed. - */ - protected void callChildNodesToBuildDelta(final Map nodes, final VMDelta delta, final Object event, final RequestMonitor requestMonitor) { - assert nodes.size() != 0; - - // Check if any of the child nodes are will generate IModelDelta.SELECT or - // IModelDelta.EXPAND flags. If so, we must calcuate the index for this - // VMC. - boolean calculateOffsets = false; - for (int childDelta : nodes.values()) { - if ( (childDelta & (IModelDelta.SELECT | IModelDelta.EXPAND)) != 0 ) { - calculateOffsets = true; - break; - } - } - - getChildNodesElementOffsets( - delta, !calculateOffsets, - new DataRequestMonitor>(getExecutor(), null) { - @Override - protected void handleCompleted() { - if (isDisposed()) return; - - final MultiRequestMonitor childrenBuildDeltaDoneCollector = - new MultiRequestMonitor(getExecutor(), null) { - @Override - protected void handleCompleted() { - if (isDisposed()) return; - requestMonitor.done(); - } - }; - - // Set the total count of number of children in the parent delta. - delta.setChildCount(getData().get(null)); - - for (IVMLayoutNode node : nodes.keySet()) { - node.buildDelta( - event, delta, getData().get(node), - childrenBuildDeltaDoneCollector.add(new RequestMonitor(getExecutor(), null) { - @Override - protected void handleCompleted() { - childrenBuildDeltaDoneCollector.requestMonitorDone(this); - }}) - ); - } - } - }); - } - - /** - * Calculates the indexes at which the elements of each of the child - * layout nodes begin. These indexes are necessary to correctly - * calculate the deltas for elements in the child nodes. - * @param delta The delta object to build on. This delta should have been - * gerated by this node, unless the full delta path is not being calculated - * due to an optimization. - * @param fakeIt If true, it causes this method to fill the return data - * structure with dummy values. The dummy values indicate that the indexes - * are not known and are acceptable in the delta if the delta flags being - * generated do not require full index information. - * @param rm Return token containing the results. The result data is a - * mapping between the child nodes and the indexes at which the child nodes' - * elements begin. There is a special value in the map with a null - * key, which contains the full element count for all the nodes. - */ - private void getChildNodesElementOffsets(IModelDelta delta, boolean fakeIt, final DataRequestMonitor> rm) { - assert getChildLayoutNodes().length != 0; - - if (!fakeIt) { - final Integer[] counts = new Integer[getChildLayoutNodes().length]; - final MultiRequestMonitor childrenCountMultiRequestMon = - new MultiRequestMonitor(getExecutor(), rm) { - @Override - protected void handleCompleted() { - if (isDisposed()) return; - super.handleCompleted(); - } - @Override - protected void handleOK() { - Map data = new HashMap(); - int offset = 0; - for (int i = 0; i < getChildLayoutNodes().length; i++) { - data.put(getChildLayoutNodes()[i], offset); - offset += counts[i]; - } - // As the final value, put the total count in the return map, with null key. - data.put(null, offset); - rm.setData(data); - rm.done(); - } - }; - - for (int i = 0; i < getChildLayoutNodes().length; i++) { - final int nodeIndex = i; - getChildLayoutNodes()[i].updateElementCount( - new ElementsCountUpdate( - childrenCountMultiRequestMon.add( - new DataRequestMonitor(getExecutor(), null) { - @Override - protected void handleCompleted() { - counts[nodeIndex] = getData(); - childrenCountMultiRequestMon.requestMonitorDone(this); - } - }), - delta) - ); - } - } else { - Map data = new HashMap(); - for (int i = 0; i < getChildLayoutNodes().length; i++) { - data.put(getChildLayoutNodes()[i], -1); - } - data.put(null, -1); - rm.setData(data); - rm.done(); - } - } - - protected boolean isDisposed() { - return fDisposed; - } - - /** - * Convenience method that returns the child layout nodes which return - * true to the hasDeltaFlags() test for the given - * event. - */ - protected Map getChildNodesWithDeltaFlags(Object e) { - Map nodes = new HashMap(); - for (final IVMLayoutNode childNode : getChildLayoutNodes()) { - int delta = childNode.getDeltaFlags(e); - if (delta != IModelDelta.NO_CHANGE) { - nodes.put(childNode, delta); - } - } - return nodes; - } - - /** - * Convenience method that returns a token value in case when the services - * that the layout node depends on, are not available. - */ - protected boolean checkUpdate(IViewerUpdate update) { - if (update.isCanceled()) { - update.done(); - return false; - } - if (fDisposed) { - handleFailedUpdate(update); - return false; - } - return true; - } - - /** - * A convenience method that completes update object in case of an error. - * Different types of update need to have some data configured to exhibit - * desired behavior in the viewer. - * @param update Update to handle. - */ - protected void handleFailedUpdate(IViewerUpdate update) { - if (update instanceof IHasChildrenUpdate) { - ((IHasChildrenUpdate)update).setHasChilren(false); - } else if (update instanceof IChildrenCountUpdate) { - ((IChildrenCountUpdate)update).setChildCount(0); - } else if (update instanceof ILabelUpdate) { - ILabelUpdate labelUpdate = (ILabelUpdate)update; - String[] columns = labelUpdate.getPresentationContext().getColumns(); - for (int i = 0; i < (columns != null ? columns.length : 1); i++) { - labelUpdate.setLabel("...", i); //$NON-NLS-1$ - } - } - update.done(); - } - - /** - * Implementation of basic View Model Context node functionality. The main - * purpose of the VMC wrapper is to re-direct adapter queries to the IVMAdapter - * and the layout node that the given context was created by. - *

    - * Note: Deriving classes must override the Object.equals/hashCode methods. - * This is because the VMC objects are just wrappers that are created - * by the view model on demand, so the equals methods must use the object - * being wrapped by the VMC to perform a meaningful comparison. - */ - abstract public static class AbstractVMContext implements IVMContext { - protected final IVMAdapter fVMAdapter; - protected final IVMLayoutNode fLayoutNode; - - public AbstractVMContext(IVMAdapter adapter, IVMLayoutNode node) { - fVMAdapter = adapter; - fLayoutNode = node; - } - - public IVMLayoutNode getLayoutNode() { return fLayoutNode; } - - /** - * IAdapter implementation returns the IVMAdapter instance for the - * interfaces that are actually implemented by the VM Adapter. These - * should at least include {@link IElementContentProvider}, - * {@link IModelProxyFactory}, and - * {@link IColumnPresentationFactory}. - */ - @SuppressWarnings("unchecked") - public Object getAdapter(Class adapter) { - if (adapter.isInstance(fVMAdapter)) { - return fVMAdapter; - } else if (adapter.isInstance(fLayoutNode)) { - return fLayoutNode; - } - return null; - } - - /** Deriving classes must override. */ - @Override - abstract public boolean equals(Object obj); - - /** Deriving classes must override. */ - @Override - abstract public int hashCode(); - } - - protected TreePath getTreePathFromDelta(IModelDelta delta) { - List elementList = new LinkedList(); - IModelDelta listDelta = delta; - elementList.add(0, listDelta.getElement()); - while (listDelta.getParentDelta() != null) { - elementList.add(0, listDelta.getElement()); - listDelta = listDelta.getParentDelta(); - } - return new TreePath(elementList.toArray()); - } - - protected class ViewerUpdate implements IViewerUpdate { - - final private RequestMonitor fRequestMonitor; - final private TreePath fTreePath; - private IStatus fStatus; - private boolean fCancelled = false; - - public ViewerUpdate(RequestMonitor requestMonitor, IModelDelta delta) { - fRequestMonitor = requestMonitor; - List elementList = new LinkedList(); - IModelDelta listDelta = delta; - elementList.add(0, listDelta.getElement()); - while (listDelta.getParentDelta() != null) { - elementList.add(0, listDelta.getElement()); - listDelta = listDelta.getParentDelta(); - } - fTreePath = new TreePath(elementList.toArray()); - } - - public ViewerUpdate(RequestMonitor requestMonitor, TreePath path) { - fRequestMonitor = requestMonitor; - fTreePath = path; - } - - public Object getViewerInput() { - return getVMProvider().getRootElement(); - } - - public Object getElement() { - return getElementPath().getLastSegment(); - } - - public IPresentationContext getPresentationContext() { return getVMProvider().getPresentationContext(); } - public TreePath getElementPath() { return fTreePath; } - public IStatus getStatus() { return fStatus; } - public void setStatus(IStatus status) { fStatus = status; } - public boolean isCanceled() { return fCancelled; } - public void cancel() { fCancelled = true; } - - public void done() { - try { - fRequestMonitor.done(); - } catch (RejectedExecutionException e) { - } - } - } - - protected class ElementsCountUpdate extends ViewerUpdate implements IChildrenCountUpdate { - private final DataRequestMonitor fElementCountRequestMonitor; - - public ElementsCountUpdate(DataRequestMonitor rm, IModelDelta delta) { - super(rm, delta); - fElementCountRequestMonitor = rm; - } - - public void setChildCount(int numChildren) { - fElementCountRequestMonitor.setData(numChildren); - } - } - - protected class ElementsUpdate extends ViewerUpdate implements IChildrenUpdate { - private final List fChildren = new ArrayList(); - private DataRequestMonitor> fElementUpdateRequestMonitor; - - public ElementsUpdate(DataRequestMonitor> rm, IModelDelta delta) { - super(rm, delta); - fElementUpdateRequestMonitor = rm; - fElementUpdateRequestMonitor.setData(fChildren); - } - - public ElementsUpdate(DataRequestMonitor> rm, TreePath path) { - super(rm, path); - fElementUpdateRequestMonitor = rm; - fElementUpdateRequestMonitor.setData(fChildren); - } - - public int getOffset() { - return -1; - } - - public int getLength() { - return -1; - } - - public void setChild(Object child, int offset) { - fChildren.add(offset, child); - } - - @Override - public String toString() { - return "VMElementsUpdate for all elements under parent = " + getElement(); //$NON-NLS-1$ - } - } - -} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMNode.java new file mode 100644 index 00000000000..e91fc401214 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMNode.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * 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.DsfExecutor; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; + +/** + * Base implementation of the view model node. + * The main functionality implemented here is for building the view model + * deltas (IModelDelta), based on the flags returned by child nodes. + */ +@SuppressWarnings("restriction") +abstract public class AbstractVMNode implements IVMNode { + + private final AbstractVMProvider fProvider; + private boolean fDisposed = false; + + public AbstractVMNode(AbstractVMProvider provider) { + fProvider = provider; + } + + /** + * Accessor method for sub-classes. + */ + protected DsfExecutor getExecutor() { + return fProvider.getExecutor(); + } + + public IVMProvider getVMProvider() { + return fProvider; + } + + public void dispose() { + fDisposed = true; + } + + public IVMContext getContextFromEvent(Object event) { + return null; + } + + protected boolean isDisposed() { + return fDisposed; + } + + /** + * Convenience method that returns a token value in case when the services + * that the layout node depends on, are not available. + */ + protected boolean checkUpdate(IViewerUpdate update) { + if (update.isCanceled()) { + update.done(); + return false; + } + if (fDisposed) { + handleFailedUpdate(update); + return false; + } + return true; + } + + /** + * A convenience method that completes update object in case of an error. + * Different types of update need to have some data configured to exhibit + * desired behavior in the viewer. + * @param update Update to handle. + */ + protected void handleFailedUpdate(IViewerUpdate update) { + if (update instanceof IHasChildrenUpdate) { + ((IHasChildrenUpdate)update).setHasChilren(false); + } else if (update instanceof IChildrenCountUpdate) { + ((IChildrenCountUpdate)update).setChildCount(0); + } else if (update instanceof ILabelUpdate) { + ILabelUpdate labelUpdate = (ILabelUpdate)update; + String[] columns = labelUpdate.getPresentationContext().getColumns(); + for (int i = 0; i < (columns != null ? columns.length : 1); i++) { + labelUpdate.setLabel("...", i); //$NON-NLS-1$ + } + } + update.done(); + } +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java index 0359bb59e1f..bfb34b0b151 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java @@ -12,74 +12,108 @@ package org.eclipse.dd.dsf.ui.viewmodel; import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.atomic.AtomicReference; -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.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfExecutor; -import org.eclipse.dd.dsf.concurrent.MultiRequestMonitor; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.service.IDsfService; -import org.eclipse.dd.dsf.ui.DsfUIPlugin; +import org.eclipse.dd.dsf.ui.concurrent.DisplayDsfExecutor; +import org.eclipse.dd.dsf.ui.concurrent.ViewerDataRequestMonitor; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; -import org.eclipse.debug.internal.ui.viewers.provisional.AbstractModelProxy; import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousContentAdapter; import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousLabelAdapter; +import org.eclipse.swt.widgets.Display; /** * 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 + * model provider functionality to the view model nodes that need * to be configured with each provider. - *

    + * + *

    * 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. * + *

    + * Clients are intended to extend this class. + * * @see IAsynchronousContentAdapter * @see IAsynchronousLabelAdapter * @see IModelProxy - * @see IVMLayoutNode + * @see IVMNode */ -@ConfinedToDsfExecutor("getVMAdapter#getExecutor") @SuppressWarnings("restriction") abstract public class AbstractVMProvider implements IVMProvider { + /** Reference to the VM adapter that owns this provider */ private final AbstractVMAdapter fVMAdapter; /** The presentation context that this provider is associated with */ private final IPresentationContext fPresentationContext; - - /** - * The current root element of this view model. This element is obtained - * from the argument to {@link #createModelProxy(Object, IPresentationContext)}. - */ - private Object fRootElement; + + /** + * The executor that this VM provider operates in. This executor will be + * initialized properly when we can access the display from the + * IPresentationContext object (bug 213629). For now utilize the + * assumption that there is only one display. + */ + private final DsfExecutor fExecutor = DisplayDsfExecutor.getDisplayDsfExecutor(Display.getDefault()); + + /** + * The element content provider implementation that this provider delegates to. + * Sub-classes may override the content strategy used for custom functionality. + */ + private final IElementContentProvider fContentStrategy; /** - * + * The list of active model proxies in this provider. A new model + * proxy is created when a viewer has a new input element + * (see {@link #createModelProxy(Object, IPresentationContext)}). + * Typically there will be only one active model proxy in a given + * provider. However, if a view model provider fills only a sub-tree + * in a viewer, and there are several sub-trees active in the same viewer + * at the same time, each of these sub-trees will have it's own model + * proxy. + */ + private List fActiveModelProxies = new LinkedList(); + + /** + * Convencience constant. + */ + private static final IVMNode[] EMPTY_NODES_ARRAY = new IVMNode[0]; + + + /** + * The mapping of parent to child nodes. + */ + private Map fChildNodesMap = + new HashMap(); + + /** + * Cached array of all the configued view model nodes. It is generated + * based on the child nodes map. + */ + private IVMNode[] fNodesListCache = null; + + /** + * Flag indicating that the provider is disposed. */ - private ModelProxy fModelProxy = new ModelProxy(); private boolean fDisposed = false; /** @@ -87,7 +121,7 @@ abstract public class AbstractVMProvider implements IVMProvider * null when first created, to allow sub-classes to prorperly configure the * root node in the sub-class constructor. */ - private AtomicReference fRootLayoutNodeRef = new AtomicReference(); + private IRootVMNode fRootNode; /** * Constructs the view model provider for given DSF session. The @@ -98,6 +132,7 @@ abstract public class AbstractVMProvider implements IVMProvider public AbstractVMProvider(AbstractVMAdapter adapter, IPresentationContext presentationContext) { fVMAdapter = adapter; fPresentationContext = presentationContext; + fContentStrategy = createContentStrategy(); } public IPresentationContext getPresentationContext() { @@ -109,345 +144,321 @@ abstract public class AbstractVMProvider implements IVMProvider } /** - * Sets the root node for this provider. + * Creates the strategy class that will be used to implement the content + * provider interface of this view model provider. This method can be + * overridden by sub-classes to provider custom content provider strategy. + *

    + * Note this method can be called by the base class constructor, therefore + * it should not reference any fields initialized in the sub-class. + * + * @return New content provider implementation. */ - @ThreadSafe - protected void setRootLayoutNode(IVMRootLayoutNode rootLayoutNode) { - final IVMRootLayoutNode oldRootLayoutNode = fRootLayoutNodeRef.getAndSet(rootLayoutNode); - if (oldRootLayoutNode != null) { - oldRootLayoutNode.dispose(); + protected IElementContentProvider createContentStrategy() { + return new DefaultVMContentProviderStrategy(this); + } + + /** + * Access method for the content provider strategy. + * + * @return Content provider implementation currently being used by this + * class. + */ + protected IElementContentProvider getContentStrategy() { + return fContentStrategy; + } + + /** + * Creates the strategy class that will be used to implement the content + * model proxy of this view model provider. It is normally called by + * {@link #createModelProxy(Object, IPresentationContext)} every time the + * input in the viewer is updated. This method can be overridden by + * sub-classes to provider custom model proxy strategy. + * + * @return New model proxy implementation. + */ + protected IVMModelProxy createModelProxyStrategy(Object rootElement) { + return new DefaultVMModelProxyStrategy(this, rootElement); + } + + /** + * Returns the list of active proxies in this provider. The returned + * list is not a copy and if a sub-class modifies this list, it will + * modify the current list of active proxies. This allows the + * sub-classes to change how the active proxies are managed and + * retained. + */ + protected List getActiveModelProxies() { + return fActiveModelProxies; + } + + /** + * Processes the given event in the given provider, sending model + * deltas if necessary. + */ + public void handleEvent(final Object event) { + for (final IVMModelProxy proxyStrategy : getActiveModelProxies()) { + if (proxyStrategy.isDeltaEvent(event)) { + proxyStrategy.createDelta( + event, + new DataRequestMonitor(getExecutor(), null) { + @Override + public void handleCompleted() { + if (getStatus().isOK()) { + proxyStrategy.fireModelChanged(getData()); + } + } + @Override public String toString() { + return "Result of a delta for event: '" + event.toString() + "' in VMP: '" + this + "'" + "\n" + getData().toString(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } + }); + } } } - - @ThreadSafe - protected synchronized ModelProxy getModelProxy() { - return fModelProxy; + + + public IRootVMNode getRootVMNode() { + return fRootNode; + } + + public IVMNode[] getAllVMNodes() { + if (fNodesListCache != null) { + return fNodesListCache; + } + List list = new ArrayList(); + for (IVMNode node : fChildNodesMap.keySet()) { + if (node != null) { + list.add(node); + } + } + fNodesListCache = list.toArray(new IVMNode[list.size()]);; + return fNodesListCache; + } + + public IVMNode[] getChildVMNodes(IVMNode node) { + IVMNode[] retVal = fChildNodesMap.get(node); + if (retVal != null) { + return retVal; + } + return EMPTY_NODES_ARRAY; + } + + /** + * Configures the given array of nodes as children of the given parent node. + * Sub-classes should call this method to define the hierarchy of nodes. + */ + protected void addChildNodes(IVMNode parentNode, IVMNode[] childNodes) { + // Add to the child nodes array. + IVMNode[] existingChildNodes = fChildNodesMap.get(parentNode); + if (existingChildNodes == null) { + fChildNodesMap.put(parentNode, childNodes); + } else { + IVMNode[] newNodes = new IVMNode[existingChildNodes.length + childNodes.length]; + System.arraycopy(existingChildNodes, 0, newNodes, 0, existingChildNodes.length); + System.arraycopy(childNodes, 0, newNodes, existingChildNodes.length, childNodes.length); + fChildNodesMap.put(parentNode, newNodes); + } + + // Make sure that each new expression node has an entry of its own. + for (IVMNode childNode : childNodes) { + addNode(childNode); + } + + fNodesListCache = null; } - @ThreadSafe - public synchronized Object getRootElement() { - return fRootElement; + /** + * Adds the given node to configured nodes, without creating any + * parent-child relationship for it. It is useful for providers which do have + * a strict tree hierarchy of ndoes. + */ + protected void addNode(IVMNode node) { + if (!fChildNodesMap.containsKey(node)) { + fChildNodesMap.put(node, EMPTY_NODES_ARRAY); + } } - - @ThreadSafe - public IVMRootLayoutNode getRootLayoutNode() { - return fRootLayoutNodeRef.get(); + + /** + * Clears all configured nodes. This allows a subclass to reset and + * reconfigure its nodes. + */ + protected void clearNodes() { + for (IVMNode node : fChildNodesMap.keySet()) { + node.dispose(); + } + fChildNodesMap.clear(); + fRootNode = null; + } + + /** + * Sets the root node for this provider. + */ + protected void setRootNode(IRootVMNode rootNode) { + fRootNode = rootNode; } /** Called to dispose the provider. */ public void dispose() { - fDisposed = true; - if (fRootLayoutNodeRef.get() != null) { - fRootLayoutNodeRef.get().dispose(); - } + clearNodes(); + fRootNode = null; + } + + public void update(final IHasChildrenUpdate[] updates) { + fContentStrategy.update(updates); + } + + public void update(final IChildrenCountUpdate[] updates) { + fContentStrategy.update(updates); + } + + public void update(final IChildrenUpdate[] updates) { + fContentStrategy.update(updates); } /** - * Allows other subsystems to force the layout mode associated with the specified - * VM context to refresh. If null is passed then the RootLayoutNode is told to refresh. + * Calls the given view model node to perform the given updates. This + * method is called by view model provider and it's helper classes instead + * of calling the IVMNode method directly, in order to allow additional + * processing of the udpate. For example the AbstractCachingVMProvider + * overrides this method to optionally return the results for an update from + * a cache. */ - public void refresh(final IVMContext element) { - try { - getExecutor().execute(new Runnable() { - public void run() { - if (isDisposed()) return; + protected void updateNode(final IVMNode node, IHasChildrenUpdate[] updates) { + IHasChildrenUpdate[] updateProxies = new IHasChildrenUpdate[updates.length]; + for (int i = 0; i < updates.length; i++) { + final IHasChildrenUpdate update = updates[i]; + updateProxies[i] = new VMHasChildrenUpdate( + update, + new ViewerDataRequestMonitor(getExecutor(), updates[i]) { + @Override + protected void handleOK() { + update.setHasChilren(getData()); + update.done(); + } - if ( element == null ) { - VMDelta rootDelta = new VMDelta(getRootElement(), IModelDelta.CONTENT); - getModelProxy().fireModelChangedNonDispatch(rootDelta); + @Override + protected void handleError() { + if (getStatus().getCode() == IDsfService.NOT_SUPPORTED) { + updateNode( + node, + new VMChildrenUpdate[] { new VMChildrenUpdate( + update, -1, -1, + new ViewerDataRequestMonitor>(getExecutor(), update) { + @Override + protected void handleOK() { + update.setHasChilren( !getData().isEmpty() ); + update.done(); + } + }) + }); + + } else { + update.setStatus(getStatus()); + update.done(); + } } - else { - VMDelta elementDelta = new VMDelta(element, IModelDelta.CONTENT); - getModelProxy().fireModelChangedNonDispatch(elementDelta); - } - - }}); - } catch (RejectedExecutionException e) { - // Ignore. This exception could be thrown if the provider is being - // shut down. + + }); } - return; + node.update(updateProxies); } + /** + * Calls the given view model node to perform the given updates. This + * method is called by view model provider and it's helper classes instead + * of calling the IVMNode method directly, in order to allow additional + * processing of the udpate. For example the AbstractCachingVMProvider + * overrides this method to optionally return the results for an update from + * a cache. + */ + protected void updateNode(final IVMNode node, IChildrenCountUpdate[] updates) { + IChildrenCountUpdate[] updateProxies = new IChildrenCountUpdate[updates.length]; + for (int i = 0; i < updates.length; i++) { + final IChildrenCountUpdate update = updates[i]; + updateProxies[i] = new VMChildrenCountUpdate( + update, + new ViewerDataRequestMonitor(getExecutor(), updates[i]) { + @Override + protected void handleOK() { + update.setChildCount(getData()); + update.done(); + } + + @Override + protected void handleError() { + if (getStatus().getCode() == IDsfService.NOT_SUPPORTED) { + updateNode( + node, + new VMChildrenUpdate[] { new VMChildrenUpdate( + update, -1, -1, + new ViewerDataRequestMonitor>(getExecutor(), update) { + @Override + protected void handleOK() { + update.setChildCount( getData().size() ); + update.done(); + } + }) + }); + + } + } + + }); + } + node.update(updateProxies); + } + + /** + * Calls the given view model node to perform the given updates. This + * method is called by view model provider and it's helper classes instead + * of calling the IVMNode method directly, in order to allow additional + * processing of the udpate. For example the AbstractCachingVMProvider + * overrides this method to optionally return the results for an update from + * a cache. + */ + protected void updateNode(IVMNode node, IChildrenUpdate[] updates) { + node.update(updates); + } + + + /** + * Returns whether this provider has been disposed. + */ protected boolean isDisposed() { return fDisposed; } - + /** - * Convenience method to access the View Model's executor. + * The abstract provider uses a the display-thread executor so that the + * provider will operate on the same thread as the viewer. This way no + * synchronization is necessary when the provider is called by the viewer. + * Also, the display thread is likely to be shut down long after any of the + * view models are disposed, so the users of this abstract provider do not + * need to worry about the executor throwing the {@link RejectedExecutionException} + * exception. */ - public DsfExecutor getExecutor() { return fVMAdapter.getExecutor(); } - - - public void update(IHasChildrenUpdate[] updates) { - // Sort the updates by the layout node. - Map> nodeUpdatesMap = new HashMap>(); - for (IHasChildrenUpdate update : updates) { - // Get the VM Context for last element in path. - IVMLayoutNode layoutNode = getLayoutNodeForElement(update.getElement()); - if (layoutNode == null) { - // Stale update, most likely as a result of the layout nodes being - // changed. Just ignore it. - update.done(); - continue; - } - if (!nodeUpdatesMap.containsKey(layoutNode)) { - nodeUpdatesMap.put(layoutNode, new ArrayList()); - } - nodeUpdatesMap.get(layoutNode).add(update); - } - - // Iterate through the nodes in the sorted map. - for (IVMLayoutNode node : nodeUpdatesMap.keySet()) { - updateNode(node, nodeUpdatesMap.get(node).toArray(new IHasChildrenUpdate[nodeUpdatesMap.get(node).size()])); - } - } - - private void updateNode(IVMLayoutNode node, final IHasChildrenUpdate[] updates) { - // If parent element's layout node has no children, just set the - // result and coninue to next element. - if (node.getChildLayoutNodes().length == 0) { - for (IHasChildrenUpdate update : updates) { - update.setHasChilren(false); - update.done(); - } - return; - } - - // Create a matrix of element updates: - // The first dimension "i" is the list of children updates that came from the viewer. - // For each of these updates, there are "j" number of elment updates corresponding - // to the number of child layout nodes in this node. - // Each children update from the viewer is complete when all the child layout nodes - // fill in their elements update. - // Once the matrix is constructed, the child layout nodes are given the list of updates - // equal to the updates requested by the viewer. - VMHasElementsUpdate[][] elementsUpdates = - new VMHasElementsUpdate[node.getChildLayoutNodes().length][updates.length]; - for (int i = 0; i < updates.length; i ++) - { - final IHasChildrenUpdate update = updates[i]; - - final MultiRequestMonitor> hasChildrenMultiRequestMon = - new MultiRequestMonitor>(getExecutor(), null) { - @Override - protected void handleCompleted() { - // Status is OK, only if all request monitors are OK. - if (getStatus().isOK()) { - boolean isContainer = false; - for (DataRequestMonitor hasElementsDone : getRequestMonitors()) { - isContainer |= hasElementsDone.getStatus().isOK() && - hasElementsDone.getData().booleanValue(); - } - update.setHasChilren(isContainer); - } else { - update.setStatus(getStatus()); - } - update.done(); - } - }; - - for (int j = 0; j < node.getChildLayoutNodes().length; j++) - { - elementsUpdates[j][i] = new VMHasElementsUpdate( - update, - hasChildrenMultiRequestMon.add( - new DataRequestMonitor(getExecutor(), null) { - @Override - protected void handleCompleted() { - hasChildrenMultiRequestMon.requestMonitorDone(this); - } - })); - } - } - - for (int j = 0; j < node.getChildLayoutNodes().length; j++) { - node.getChildLayoutNodes()[j].updateHasElements(elementsUpdates[j]); - } + public DsfExecutor getExecutor() { + return fExecutor; } - - public void update(final IChildrenCountUpdate[] updates) { - for (final IChildrenCountUpdate update : updates) { - if (update.isCanceled()) { - update.done(); - continue; - } - - getChildrenCountsForNode( - update, - new DataRequestMonitor(getExecutor(), null) { - @Override - protected void handleCompleted() { - if (getStatus().isOK()) { - int numChildren = 0; - for (Integer count : getData()) { - numChildren += count.intValue(); - } - update.setChildCount(numChildren); - } else { - update.setChildCount(0); - } - update.done(); - } - }); - } - } - - public void update(IChildrenUpdate[] updates) { - for (final IChildrenUpdate update : updates) { - getChildrenCountsForNode( - update, - new DataRequestMonitor(getExecutor(), null) { - @Override - protected void handleCompleted() { - if (!getStatus().isOK()) { - update.done(); - return; - } - updateChildrenWithCounts(update, getData()); - } - }); - } - } - - - private void getChildrenCountsForNode(IViewerUpdate update, final DataRequestMonitor rm) { - if (isDisposed()) return; + public IModelProxy createModelProxy(Object element, IPresentationContext context) { + assert getExecutor().isInExecutorThread(); - // Get the VM Context for last element in path. - final IVMLayoutNode layoutNode = getLayoutNodeForElement(update.getElement()); - if (layoutNode == null) { - // Stale update. Just ignore. - rm.setStatus(new Status( - IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Stale update.", null)); //$NON-NLS-1$ - rm.done(); - return; - } - - IVMLayoutNode[] childNodes = layoutNode.getChildLayoutNodes(); - - // If parent element's layout node has no children, just mark done and - // return. - if (childNodes.length == 0) { - rm.setData(new Integer[0]); - rm.done(); - return; - } - - - // Get the mapping of all the counts. - final Integer[] counts = new Integer[childNodes.length]; - final MultiRequestMonitor childrenCountMultiReqMon = - new MultiRequestMonitor(getExecutor(), rm) { - @Override - protected void handleCompleted() { - if (!fDisposed) super.handleCompleted(); - } - - @Override - protected void handleOK() { - rm.setData(counts); - rm.done(); - } - }; - - for (int i = 0; i < childNodes.length; i++) { - final int nodeIndex = i; - childNodes[i].updateElementCount( - new VMElementsCountUpdate( - update, - childrenCountMultiReqMon.add( - new DataRequestMonitor(getExecutor(), null) { - @Override - protected void handleOK() { - counts[nodeIndex] = getData(); - } - - @Override - protected void handleCompleted() { - super.handleCompleted(); - childrenCountMultiReqMon.requestMonitorDone(this); - } - })) - ); - } - } - - private void updateChildrenWithCounts(final IChildrenUpdate update, Integer[] nodeElementCounts) { - final IVMLayoutNode layoutNode = getLayoutNodeForElement(update.getElement()); - if (layoutNode == null) { - // Stale update. Just ignore. - update.done(); - return; - } - - // Create the multi request monitor to mark update when querying all - // children nodes is finished. - final MultiRequestMonitor elementsMultiRequestMon = - new MultiRequestMonitor(getExecutor(), null) { - @Override - protected void handleCompleted() { - update.done(); - } - }; - - // Iterate through all child nodes and if requested range matches, call them to - // get their elements. - int updateStartIdx = update.getOffset(); - int updateEndIdx = update.getOffset() + update.getLength(); - int idx = 0; - IVMLayoutNode[] layoutNodes = layoutNode.getChildLayoutNodes(); - for (int i = 0; i < layoutNodes.length; i++) { - final int nodeStartIdx = idx; - final int nodeEndIdx = idx + nodeElementCounts[i]; - idx = nodeEndIdx; - - // Check if update range overlaps the node's range. - if (updateStartIdx <= nodeEndIdx && updateEndIdx > nodeStartIdx) { - final int elementsStartIdx = Math.max(updateStartIdx - nodeStartIdx, 0); - final int elementsEndIdx = Math.min(updateEndIdx - nodeStartIdx, nodeElementCounts[i]); - final int elementsLength = elementsEndIdx - elementsStartIdx; - if (elementsLength > 0) { - layoutNodes[i].updateElements( - new VMElementsUpdate( - update, elementsStartIdx, elementsLength, - elementsMultiRequestMon.add(new DataRequestMonitor>(getExecutor(), null) { - @Override - protected void handleCompleted() { - if (getStatus().isOK()) { - for (int i = 0; i < elementsLength; i++) { - update.setChild(getData().get(i), elementsStartIdx + nodeStartIdx + i); - } - } - elementsMultiRequestMon.requestMonitorDone(this); - } - })) - ); - } + // Iterate through the current active proxies to try to find a proxy with the same + // element and re-use it if found. At the same time purge proxies that are no longer + IVMModelProxy proxy = null; + for (Iterator itr = getActiveModelProxies().iterator(); itr.hasNext();) { + IVMModelProxy next = itr.next(); + if (next == null && next.getRootElement().equals(element)) { + proxy = next; + } else if (next.isDisposed()) { + itr.remove(); } } - - // Guard against invalid queries. - if (elementsMultiRequestMon.getRequestMonitors().isEmpty()) { - update.done(); + if (proxy == null) { + proxy = createModelProxyStrategy(element); + getActiveModelProxies().add(proxy); } - - } - - public ModelProxy createModelProxy(Object element, IPresentationContext context) { - /* - * Model proxy is the object that correlates events from the data model - * into view model deltas that the view can process. This method is called - * by the viewer when a new input object is set to the view. We need to create - * a new instance of the ModelProxy object with every call, because the viewer - * disposes the old proxy before calling this method. - */ - synchronized(this) { - fRootElement = element; - fModelProxy = new ModelProxy(); - } - return fModelProxy; + return proxy; } /** @@ -466,6 +477,7 @@ abstract public class AbstractVMProvider implements IVMProvider * @see IColumnPresentationFactory#createColumnPresentation(IPresentationContext, Object) */ public IColumnPresentation createColumnPresentation(IPresentationContext context, Object element) { + assert fExecutor.isInExecutorThread(); return null; } @@ -500,119 +512,5 @@ abstract public class AbstractVMProvider implements IVMProvider public void update(IViewerInputUpdate update) { update.setInputElement(update.getElement()); update.done(); - } - - - /** - * 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. - */ - protected IVMLayoutNode getLayoutNodeForElement(Object element) { - /* - * First check to see if the parent object is the root object of the - * hierarchy. If that's the case, then retrieve the correcponding - * root VMC from the root node, and pass this root vmc to the root's - * child layout nodes. - */ - IVMRootLayoutNode rootLayoutNode = getRootLayoutNode(); - if (rootLayoutNode == null) { - return null; - } - else if (element.equals(getRootElement())) { - return rootLayoutNode; - } - else if (element 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)element).getLayoutNode(), - new IVMLayoutNode[] { rootLayoutNode } )) - { - return ((IVMContext)element).getLayoutNode(); - } - } - 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; - } - - - protected void handleEvent(final Object event) { - // We're in session's executor thread. Re-dispach to VM Adapter - // executor thread and then call root layout node. - try { - getExecutor().execute(new Runnable() { - public void run() { - if (isDisposed()) return; - - IVMRootLayoutNode rootLayoutNode = getRootLayoutNode(); - if (rootLayoutNode != null && rootLayoutNode.getDeltaFlags(event) != 0) { - rootLayoutNode.createDelta( - event, - new DataRequestMonitor(getExecutor(), null) { - @Override - public void handleCompleted() { - if (getStatus().isOK()) { - getModelProxy().fireModelChangedNonDispatch(getData()); - } - } - @Override public String toString() { - return "Result of a delta for event: '" + event.toString() + "' in VMP: '" + AbstractVMProvider.this + "'" + "\n" + getData().toString(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - } - }); - } - }}); - } catch (RejectedExecutionException e) { - // Ignore. This exception could be thrown if the provider is being - // shut down. - } - } - - @ThreadSafe - protected class ModelProxy extends AbstractModelProxy { - /** - * 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; } - }; - - /** - * 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) { - Job job = new Job("Processing view model delta.") { //$NON-NLS-1$ - @Override - protected IStatus run(IProgressMonitor monitor) { - fireModelChanged(delta); - return Status.OK_STATUS; - } - }; - job.setPriority(Job.INTERACTIVE); - job.setRule(fModelChangeRule); - job.schedule(); - } - - } + } } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMContentProviderStrategy.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMContentProviderStrategy.java new file mode 100644 index 00000000000..afff0d73f4c --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMContentProviderStrategy.java @@ -0,0 +1,370 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.MultiRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; + +/** + * The default strategy for implementing the IElementContentProvider + * functionality for an IVMProvider. It implements an algorithm to populate + * contents of the view in accordance with the tree structure of the + * view model nodes configured in the view model provider. + *

    + * This class may be used by an IVMProvider directly, or it + * may be be extended to customize for the provider's needs. + *

    + * This class is closely linked with a view model provider which is required + * for the constructor. The view model provider is used to access the correct + * executor and the node hierarchy. + */ +@ConfinedToDsfExecutor("#getExecutor()") +@SuppressWarnings("restriction") +public class DefaultVMContentProviderStrategy implements IElementContentProvider { + + private final AbstractVMProvider fVMProvider; + + public DefaultVMContentProviderStrategy(AbstractVMProvider provider) { + fVMProvider = provider; + } + + /** + * Returns the view model provider that this strategy is configured for. + * @return + */ + protected AbstractVMProvider getVMProvider() { return fVMProvider; } + + public void update(final IHasChildrenUpdate[] updates) { + if (updates.length == 0) return; + + // Optimization: if all the updates belong to the same node, avoid creating any new lists/arrays. + boolean allNodesTheSame = true; + IVMNode firstNode = getNodeForElement(updates[0].getElement()); + for (int i = 1; i < updates.length; i++) { + if (firstNode != getNodeForElement(updates[i].getElement())) { + allNodesTheSame = false; + break; + } + } + + if (allNodesTheSame) { + updateNode(firstNode, updates); + } else { + // Sort the updates by the node. + Map> nodeUpdatesMap = new HashMap>(); + for (IHasChildrenUpdate update : updates) { + // Get the VM Context for last element in path. + IVMNode node = getNodeForElement(update.getElement()); + if (node == null) { + // Stale update, most likely as a result of the nodes being + // changed. Just ignore it. + update.done(); + continue; + } + if (!nodeUpdatesMap.containsKey(node)) { + nodeUpdatesMap.put(node, new ArrayList()); + } + nodeUpdatesMap.get(node).add(update); + } + + // Iterate through the nodes in the sorted map. + for (IVMNode node : nodeUpdatesMap.keySet()) { + updateNode(node, nodeUpdatesMap.get(node).toArray(new IHasChildrenUpdate[nodeUpdatesMap.get(node).size()])); + } + } + } + + private void updateNode(IVMNode node, final IHasChildrenUpdate[] updates) { + // If parent element's node has no children, just set the + // result and continue to next element. + final IVMNode[] childNodes = getVMProvider().getChildVMNodes(node); + if (childNodes.length == 0) { + for (IHasChildrenUpdate update : updates) { + update.setHasChilren(false); + update.done(); + } + return; + } + + // Create a matrix of element updates: + // The first dimension "i" is the list of children updates that came from the viewer. + // For each of these updates, there are "j" number of elment updates corresponding + // to the number of child nodes in this node. + // Each children update from the viewer is complete when all the child nodes + // fill in their elements update. + // Once the matrix is constructed, the child nodes are given the list of updates + // equal to the updates requested by the viewer. + VMHasChildrenUpdate[][] elementsUpdates = + new VMHasChildrenUpdate[childNodes.length][updates.length]; + for (int i = 0; i < updates.length; i ++) + { + final IHasChildrenUpdate update = updates[i]; + + final MultiRequestMonitor> hasChildrenMultiRequestMon = + new MultiRequestMonitor>(getVMProvider().getExecutor(), null) { + @Override + protected void handleCompleted() { + // Status is OK, only if all request monitors are OK. + if (getStatus().isOK()) { + boolean isContainer = false; + for (DataRequestMonitor hasElementsDone : getRequestMonitors()) { + isContainer |= hasElementsDone.getStatus().isOK() && + hasElementsDone.getData().booleanValue(); + } + update.setHasChilren(isContainer); + } else { + update.setStatus(getStatus()); + } + update.done(); + } + }; + + for (int j = 0; j < childNodes.length; j++) + { + elementsUpdates[j][i] = new VMHasChildrenUpdate( + update, + hasChildrenMultiRequestMon.add( + new DataRequestMonitor(getVMProvider().getExecutor(), null) { + @Override + protected void handleCompleted() { + hasChildrenMultiRequestMon.requestMonitorDone(this); + } + })); + } + } + + for (int j = 0; j < childNodes.length; j++) { + getVMProvider().updateNode(childNodes[j], elementsUpdates[j]); + } + } + + + public void update(final IChildrenCountUpdate[] updates) { + for (final IChildrenCountUpdate update : updates) { + IVMNode node = getNodeForElement(update.getElement()); + + if (node != null && !update.isCanceled()) { + IVMNode[] childNodes = getVMProvider().getChildVMNodes(node); + + if (childNodes.length == 0) { + update.setChildCount(0); + update.done(); + } else if (childNodes.length == 1) { + getVMProvider().updateNode(childNodes[0], new IChildrenCountUpdate[] { update } ); + } else { + getChildrenCountsForNode( + update, + node, + new DataRequestMonitor(getVMProvider().getExecutor(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + int numChildren = 0; + for (Integer count : getData()) { + numChildren += count.intValue(); + } + update.setChildCount(numChildren); + } else { + update.setChildCount(0); + } + update.done(); + } + }); + } + } else if (update.isCanceled()) { + update.done(); + } + + } + } + + public void update(final IChildrenUpdate[] updates) { + for (final IChildrenUpdate update : updates) { + // Get the VM Context for last element in path. + final IVMNode node = getNodeForElement(update.getElement()); + if (node != null && !update.isCanceled()) { + IVMNode[] childNodes = getVMProvider().getChildVMNodes(node); + if (childNodes.length == 0) { + // Invalid update, just mark done. + update.done(); + } else if (childNodes.length == 1) { + getVMProvider().updateNode(childNodes[0], new IChildrenUpdate[] { update }); + } else { + getChildrenCountsForNode( + update, + node, + new DataRequestMonitor(getVMProvider().getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + update.done(); + return; + } + + updateChildrenWithCounts(update, node, getData()); + } + }); + } + } else { + // Stale update. Just ignore. + update.done(); + } + + } + } + + + /** + * Calculates the number of elements in each child node for the element in + * update. These counts are then used to delegate the children update to + * the correct nodes. + */ + private void getChildrenCountsForNode(IViewerUpdate update, IVMNode updateNode, final DataRequestMonitor rm) { + + IVMNode[] childNodes = getVMProvider().getChildVMNodes(updateNode); + + // Check for an invalid call + assert childNodes.length != 0; + + // Get the mapping of all the counts. + final Integer[] counts = new Integer[childNodes.length]; + final MultiRequestMonitor childrenCountMultiReqMon = + new MultiRequestMonitor(getVMProvider().getExecutor(), rm) { + @Override + protected void handleOK() { + rm.setData(counts); + rm.done(); + } + }; + + for (int i = 0; i < childNodes.length; i++) { + final int nodeIndex = i; + getVMProvider().updateNode( + childNodes[i], + new IChildrenCountUpdate[] { + new VMChildrenCountUpdate( + update, + childrenCountMultiReqMon.add( + new DataRequestMonitor(getVMProvider().getExecutor(), null) { + @Override + protected void handleOK() { + counts[nodeIndex] = getData(); + } + + @Override + protected void handleCompleted() { + super.handleCompleted(); + childrenCountMultiReqMon.requestMonitorDone(this); + } + })) + }); + } + } + + /** + * Splits the given children update among the configured child nodes. Then calls + * each child node to complete the update. + */ + private void updateChildrenWithCounts(final IChildrenUpdate update, IVMNode node, Integer[] nodeElementCounts) { + // Create the multi request monitor to mark update when querying all + // children nodes is finished. + final MultiRequestMonitor elementsMultiRequestMon = + new MultiRequestMonitor(getVMProvider().getExecutor(), null) { + @Override + protected void handleCompleted() { + update.done(); + } + }; + + // Iterate through all child nodes and if requested range matches, call them to + // get their elements. + int updateStartIdx = update.getOffset(); + int updateEndIdx = update.getOffset() + update.getLength(); + int idx = 0; + IVMNode[] nodes = getVMProvider().getChildVMNodes(node); + for (int i = 0; i < nodes.length; i++) { + final int nodeStartIdx = idx; + final int nodeEndIdx = idx + nodeElementCounts[i]; + idx = nodeEndIdx; + + // Check if update range overlaps the node's range. + if (updateStartIdx <= nodeEndIdx && updateEndIdx > nodeStartIdx) { + final int elementsStartIdx = Math.max(updateStartIdx - nodeStartIdx, 0); + final int elementsEndIdx = Math.min(updateEndIdx - nodeStartIdx, nodeElementCounts[i]); + final int elementsLength = elementsEndIdx - elementsStartIdx; + if (elementsLength > 0) { + getVMProvider().updateNode( + nodes[i], + new IChildrenUpdate[] { + new VMChildrenUpdate( + update, elementsStartIdx, elementsLength, + elementsMultiRequestMon.add(new DataRequestMonitor>(getVMProvider().getExecutor(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + for (int i = 0; i < elementsLength; i++) { + update.setChild(getData().get(i), elementsStartIdx + nodeStartIdx + i); + } + } + elementsMultiRequestMon.requestMonitorDone(this); + } + })) + } + ); + } + } + } + + // Guard against invalid queries. + assert !elementsMultiRequestMon.getRequestMonitors().isEmpty(); + } + + /** + * 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. + */ + protected IVMNode getNodeForElement(Object element) { + if (element instanceof IVMContext) { + IVMNode node = ((IVMContext)element).getVMNode(); + if (isOurNode(((IVMContext)element).getVMNode())) { + return node; + } + } + return getVMProvider().getRootVMNode(); + } + + /** + * Convenience method which checks whether given layout node is a node + * that is configured in this ViewModelProvider. + */ + private boolean isOurNode(IVMNode node) { + for (IVMNode nodeToSearch : getVMProvider().getAllVMNodes()) { + if (nodeToSearch.equals(node)) return true; + } + return false; + } + +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMModelProxyStrategy.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMModelProxyStrategy.java new file mode 100644 index 00000000000..6acd5eb1884 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMModelProxyStrategy.java @@ -0,0 +1,615 @@ +/******************************************************************************* + * Copyright (c) 2005, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Wind River Systems - adapted to use with DSF + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.ISafeRunnable; +import org.eclipse.core.runtime.ListenerList; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; +import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.MultiRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.debug.internal.ui.DebugUIPlugin; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelChangedListener; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; +import org.eclipse.jface.viewers.Viewer; + + +/** + * This is the default implementation of {@link IModelProxy} interface for + * use by a view model provider. It implements an algorithm to walk the + * tree hierarchy of nodes configured with a provider in order to compose + * an {@link IModelDelta} for a given data model event. + *

    + * This class is closely linked with a view model provider which is required + * for the constructor. The view model provider is used to access the correct + * executor and the node hierarchy. + */ +@ConfinedToDsfExecutor("#getProvider()#getExecutor()") +@SuppressWarnings("restriction") +public class DefaultVMModelProxyStrategy implements IVMModelProxy { + + private final AbstractVMProvider fProvider; + private final Object fRootElement; + private IPresentationContext fContext; + private Viewer fViewer; + private boolean fDisposed = false; + private ListenerList fListeners = new ListenerList(); + + /** + * Debug flag indicating whether the deltas should be traced in stdout. + */ + private static boolean DEBUG_DELTAS = false; + + static { + DEBUG_DELTAS = DebugUIPlugin.DEBUG && "true".equals( //$NON-NLS-1$ + Platform.getDebugOption("org.eclipse.debug.ui/debug/viewers/deltas")); //$NON-NLS-1$ + } + + /** + * Creates this model proxy strategy for the given provider. + */ + public DefaultVMModelProxyStrategy(AbstractVMProvider provider, Object rootElement) { + fProvider = provider; + fRootElement = rootElement; + } + + public boolean isDeltaEvent(Object event) { + IRootVMNode rootNode = getVMProvider().getRootVMNode(); + return rootNode != null && + rootNode.isDeltaEvent(getRootElement(), event) && + getDeltaFlags(rootNode, null, event) != 0; + } + + + /** + * Returns the view model provider that this strategy is configured for. + * @return + */ + protected AbstractVMProvider getVMProvider() { + return fProvider; + } + + + private Object[] getListeners() { + return fListeners.getListeners(); + } + + public void addModelChangedListener(IModelChangedListener listener) { + fListeners.add(listener); + } + + public void removeModelChangedListener(IModelChangedListener listener) { + fListeners.remove(listener); + } + + public Object getRootElement() { + return fRootElement; + } + + /** + * Notifies registered listeners of the given delta. + * + * @param delta model delta to broadcast + */ + public void fireModelChanged(IModelDelta delta) { + final IModelDelta root = getRootDelta(delta); + Object[] listeners = getListeners(); + if (DEBUG_DELTAS) { + DebugUIPlugin.debug("FIRE DELTA: " + delta.toString()); //$NON-NLS-1$ + } + for (int i = 0; i < listeners.length; i++) { + final IModelChangedListener listener = (IModelChangedListener) listeners[i]; + ISafeRunnable safeRunnable = new ISafeRunnable() { + public void handleException(Throwable exception) { + DebugUIPlugin.log(exception); + } + + public void run() throws Exception { + listener.modelChanged(root, DefaultVMModelProxyStrategy.this); + } + + }; + SafeRunner.run(safeRunnable); + } + } + + /** + * Convenience method that returns the root node of the given delta. + * + * @param delta delta node + * @return returns the root of the given delta + */ + protected IModelDelta getRootDelta(IModelDelta delta) { + IModelDelta parent = delta.getParentDelta(); + while (parent != null) { + delta = parent; + parent = delta.getParentDelta(); + } + return delta; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.IModelProxy#dispose() + */ + public void dispose() { + fDisposed = true; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.IModelProxy#init(org.eclipse.debug.internal.ui.viewers.IPresentationContext) + */ + public void init(IPresentationContext context) { + fDisposed = false; + fContext = context; + } + + /** + * Returns the context this model proxy is installed in. + * + * @return presentation context, or null if this + * model proxy has been disposed + */ + public IPresentationContext getPresentationContext() { + return fContext; + } + + /* (non-Javadoc) + * + * Subclasses should override as required. + * + * @see org.eclipse.debug.internal.ui.viewers.provisional.IModelProxy#installed(org.eclipse.jface.viewers.Viewer) + */ + public void installed(Viewer viewer) { + fViewer = viewer; + } + + /** + * Returns the viewer this proxy is installed in. + * + * @return viewer or null if not installed + */ + protected Viewer getViewer() { + return fViewer; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy#isDisposed() + */ + public boolean isDisposed() { + return fDisposed; + } + + /** + * Recursively calls the VM nodes in the hierarchy of the given node + * to calculate the delta flags that are + *

    + * Note: If a child node has a IModelDelta.CONTENT delta + * flag, it means that this flag will be added to this node's element. + * To allow for optimization change the child's IModelDelta.CONTENT + * flag into a IModelDelta.STATE flag. + * + * @param node + * @param event + * @return + */ + protected int getDeltaFlags(IVMNode node, ModelDelta parentDelta, Object event) { + int flags = node.getDeltaFlags(event); + for (IVMNode childNode : getVMProvider().getChildVMNodes(node)) { + if (!childNode.equals(node)) { + int childNodeDeltaFlags = getDeltaFlags(childNode, parentDelta, event); + if ((childNodeDeltaFlags & IModelDelta.CONTENT) != 0) { + childNodeDeltaFlags &= ~IModelDelta.CONTENT; + childNodeDeltaFlags |= IModelDelta.STATE; + } + flags |= childNodeDeltaFlags; + } + } + // Optimization: If the parent delta contains the "content" flag, we do + // not need to add it to the child. This can shorten delta processing + // considerably so check for it. + while (parentDelta != null) { + if ( (parentDelta.getFlags() & IModelDelta.CONTENT) != 0 ) { + flags = flags & ~IModelDelta.CONTENT & ~IModelDelta.STATE; + break; + } + parentDelta = (ModelDelta)parentDelta.getParentDelta(); + } + return flags; + } + + /** + * Default implementation creates a delta assuming that the root node + * is the input object into the view. + */ + public void createDelta(final Object event, final DataRequestMonitor rm) { + final IRootVMNode rootNode = getVMProvider().getRootVMNode(); + + // Always create the rootDelta, no matter what delta flags the child nodes have. + rootNode.createRootDelta( + getRootElement(), event, + new DataRequestMonitor(getVMProvider().getExecutor(), rm) { + @Override + protected void handleOK() { + // Find the root delta for the whole view to use when firing the delta. + // Note: the view root is going to be different than the model root + // in case when the view model provider is registered to populate only + // a sub-tree of a view. + final IModelDelta viewRootDelta = getRootDelta(getData()); + + // Find the child nodes that have deltas for the given event. + final Map childNodesWithDeltaFlags = getChildNodesWithDeltaFlags(rootNode, getData(), event); + + // If no child nodes have deltas we can stop here. + if (childNodesWithDeltaFlags.size() == 0) { + rm.done(); + rm.setData(viewRootDelta); + return; + } + + callChildNodesToBuildDelta( + rootNode, + childNodesWithDeltaFlags, getData(), event, + new RequestMonitor(getVMProvider().getExecutor(), rm) { + @Override + protected void handleOK() { + rm.setData(viewRootDelta); + rm.done(); + } + }); + } + }); + } + + protected void buildChildDeltas(final IVMNode node, final Object event, final ModelDelta parentDelta, + final int nodeOffset, final RequestMonitor rm) + { + final IVMContext vmc = node.getContextFromEvent(event); + + if (vmc != null) { + buildChildDeltasForEventContext(vmc, node, event, parentDelta, nodeOffset, rm); + } else { + // The DMC for this node was not found in the event. Call the + // super-class to resort to the default behavior which may add a + // delta for every element in this node. + buildChildDeltasForAllContexts(node, event, parentDelta, nodeOffset, rm); + } + } + + protected void buildChildDeltasForEventContext(final IVMContext vmc, final IVMNode node, final Object event, + final ModelDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) + { + final Map childNodeDeltas = getChildNodesWithDeltaFlags(node, parentDelta, event); + if (childNodeDeltas.size() == 0) { + // There are no child nodes with deltas, just return to parent. + requestMonitor.done(); + return; + } + + // Check if any of the child nodes are will generate IModelDelta.SELECT or + // IModelDelta.EXPAND flags. If so, we must calculate the index for this + // VMC. + boolean calculateIndex = false; + if (nodeOffset >= 0) { + for (int childDelta : childNodeDeltas.values()) { + if ( (childDelta & (IModelDelta.SELECT | IModelDelta.EXPAND)) != 0 ) { + calculateIndex = true; + break; + } + } + } + + if (calculateIndex) { + // Calculate the index of this node by retrieving all the + // elements and then finding the DMC that the event is for. + getVMProvider().updateNode( + node, + new IChildrenUpdate[] { + new VMChildrenUpdate( + parentDelta, getVMProvider().getPresentationContext(), -1, -1, + new DataRequestMonitor>(getVMProvider().getExecutor(), null) { + @Override + protected void handleCompleted() { + if (isDisposed()) return; + + // Check for an empty list of elements. If it's empty then we + // don't have to call the children nodes, so return here. + // No need to propagate error, there's no means or need to display it. + if (!getStatus().isOK() || getData().isEmpty()) { + requestMonitor.done(); + return; + } + + // Find the index. + int i; + for (i = 0; i < getData().size(); i++) { + if (vmc.equals(getData().get(i))) break; + } + if (i == getData().size()) { + // Element not found, no need to generate the delta. + requestMonitor.done(); + return; + } + + // Optimization: Try to find a delta with a matching element, if found use it. + // Otherwise create a new delta for the event element. + int elementIndex = nodeOffset + i; + ModelDelta delta = parentDelta.getChildDelta(vmc); + if (delta == null || delta.getIndex() != elementIndex) { + delta = parentDelta.addNode(vmc, elementIndex, IModelDelta.NO_CHANGE); + } + + callChildNodesToBuildDelta(node, childNodeDeltas, delta, event, requestMonitor); + } + }) + }); + } else { + // Optimization: Try to find a delta with a matching element, if found use it. + // Otherwise create a new delta for the event element. + ModelDelta delta = parentDelta.getChildDelta(vmc); + if (delta == null) { + delta = parentDelta.addNode(vmc, IModelDelta.NO_CHANGE); + } + callChildNodesToBuildDelta(node, childNodeDeltas, delta, event, requestMonitor); + } + } + + /** + * Base implementation that handles calling child nodes to build + * the model delta. The child nodes are called with all the elements + * in this node, which could be very inefficient. In order to build delta + * only for specific elements in this node, the class extending + * AbstractVMNode should override this method. + * @see IVMNode#buildDelta(Object, ModelDelta, int, RequestMonitor) + */ + protected void buildChildDeltasForAllContexts(final IVMNode node, final Object event, final ModelDelta parentDelta, + final int nodeOffset, final RequestMonitor requestMonitor) + { + // Find the child nodes that have deltas for the given event. + final Map childNodesWithDeltaFlags = getChildNodesWithDeltaFlags(node, parentDelta, event); + + // If no child nodes have deltas we can stop here. + if (childNodesWithDeltaFlags.size() == 0) { + requestMonitor.done(); + return; + } + + // Check if the child delta only has an IModelDelta.STATE flag. + // If that's the case, we can skip creating a delta for this node, + // because the TreeUpdatePolicy does not use the full path from the + // delta to handle these flags. Similarly, the index argument is + // not necessary either. + boolean mustGetElements = false; + for (int childDelta : childNodesWithDeltaFlags.values()) { + if ((childDelta & ~IModelDelta.STATE) != 0) { + mustGetElements = true; + } + } + + if (!mustGetElements) { + callChildNodesToBuildDelta(node, childNodesWithDeltaFlags, parentDelta, event, requestMonitor); + } else { + // The given child 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. + getVMProvider().updateNode( + node, + new IChildrenUpdate[] { + new VMChildrenUpdate( + parentDelta, getVMProvider().getPresentationContext(), -1, -1, + new DataRequestMonitor>(getVMProvider().getExecutor(), null) { + @Override + protected void handleCompleted() { + if (fDisposed) return; + + // Check for an empty list of elements. If it's empty then we + // don't have to call the children nodes, so return here. + // No need to propagate error, there's no means or need to display it. + if (!getStatus().isOK() || getData().size() == 0) { + requestMonitor.done(); + return; + } + + final MultiRequestMonitor elementsDeltasMultiRequestMon = + new MultiRequestMonitor(getVMProvider().getExecutor(), null) { + @Override + protected void handleCompleted() { + if (isDisposed()) return; + requestMonitor.done(); + } + }; + + // For each element from this node, create a new delta, + // and then call all the child nodes to build their delta. + for (int i = 0; i < getData().size(); i++) { + int elementIndex = nodeOffset >= 0 ? nodeOffset + i : -1; + ModelDelta delta = + parentDelta.addNode(getData().get(i), elementIndex, IModelDelta.NO_CHANGE); + callChildNodesToBuildDelta( + node, childNodesWithDeltaFlags, delta, event, + elementsDeltasMultiRequestMon.add(new RequestMonitor(getVMProvider().getExecutor(), null) { + @Override + protected void handleCompleted() { + elementsDeltasMultiRequestMon.requestMonitorDone(this); + } + })); + } + } + }) + }); + } + } + + /** + * Calls the specified child nodes to build the delta for the given event. + * @param childNodes Map of nodes to be invoked, and the corresponding delta + * flags that they will generate. This map is generated with a call to + * {@link #getChildNodesWithDeltaFlags(Object)}. + * @param delta The delta object to build on. This delta should have been + * generated by this node, unless the full delta path is not being calculated + * due to an optimization. + * @param event The event object that the delta is being built for. + * @param requestMonitor The result token to invoke when the delta is completed. + */ + protected void callChildNodesToBuildDelta(final IVMNode node, final Map childNodes, final ModelDelta delta, final Object event, final RequestMonitor requestMonitor) { + assert childNodes.size() != 0; + + // Check if any of the child nodes are will generate IModelDelta.SELECT or + // IModelDelta.EXPAND flags. If so, we must calculate the index for this + // VMC. + boolean calculateOffsets = false; + for (int childDelta : childNodes.values()) { + if ( (childDelta & (IModelDelta.SELECT | IModelDelta.EXPAND)) != 0 ) { + calculateOffsets = true; + break; + } + } + + getChildNodesElementOffsets( + node, delta, calculateOffsets, + new DataRequestMonitor>(getVMProvider().getExecutor(), null) { + @Override + protected void handleCompleted() { + if (isDisposed()) return; + + final CountingRequestMonitor multiRm = new CountingRequestMonitor(getVMProvider().getExecutor(), requestMonitor); + int multiRmCount = 0; + + // Set the total count of number of children in the parent delta. + delta.setChildCount(getData().get(null)); + + for (final IVMNode childNode : childNodes.keySet()) { + // Avoid descending into recursive node hierarchy's when calculating the delta. + if (node.equals(childNode)) continue; + + final int nodeOffset = getData().get(childNode); + childNode.buildDelta( + event, delta, nodeOffset, + new RequestMonitor(getVMProvider().getExecutor(), multiRm) { + @Override + protected void handleOK() { + buildChildDeltas( + childNode, event, delta, nodeOffset, new RequestMonitor(getVMProvider().getExecutor(), multiRm)); + } + }); + multiRmCount++; + } + multiRm.setDoneCount(multiRmCount); + } + }); + } + + /** + * Calculates the indexes at which the elements of each of the child + * nodes begin. These indexes are necessary to correctly + * calculate the deltas for elements in the child nodes. + * @param delta The delta object to build on. This delta should have been + * generated by this node, unless the full delta path is not being calculated + * due to an optimization. + * @param doCalculdateOffsets If true, the method calls each node to get its + * element count. If false, it causes this method to fill the return data + * structure with dummy values. The dummy values indicate that the indexes + * are not known and are acceptable in the delta if the delta flags being + * generated do not require full index information. + * @param rm Return token containing the results. The result data is a + * mapping between the child nodes and the indexes at which the child nodes' + * elements begin. There is a special value in the map with a null + * key, which contains the full element count for all the nodes. + */ + private void getChildNodesElementOffsets(IVMNode node, IModelDelta delta, boolean calculdateOffsets, final DataRequestMonitor> rm) { + final IVMNode[] childNodes = getVMProvider().getChildVMNodes(node); + assert childNodes.length != 0; + + if (calculdateOffsets) { + final Integer[] counts = new Integer[childNodes.length]; + final MultiRequestMonitor childrenCountMultiRequestMon = + new MultiRequestMonitor(getVMProvider().getExecutor(), rm) { + @Override + protected void handleCompleted() { + if (isDisposed()) return; + super.handleCompleted(); + } + @Override + protected void handleOK() { + Map data = new HashMap(); + int offset = 0; + for (int i = 0; i < childNodes.length; i++) { + data.put(childNodes[i], offset); + offset += counts[i]; + } + // As the final value, put the total count in the return map, with null key. + data.put(null, offset); + rm.setData(data); + rm.done(); + } + }; + + for (int i = 0; i < childNodes.length; i++) { + final int nodeIndex = i; + getVMProvider().updateNode( + childNodes[i], + new IChildrenCountUpdate[] { + new VMChildrenCountUpdate( + delta, getVMProvider().getPresentationContext(), + childrenCountMultiRequestMon.add( + new DataRequestMonitor(getVMProvider().getExecutor(), null) { + @Override + protected void handleCompleted() { + counts[nodeIndex] = getData(); + childrenCountMultiRequestMon.requestMonitorDone(this); + } + }) + ) + }); + } + } else { + Map data = new HashMap(); + for (int i = 0; i < childNodes.length; i++) { + data.put(childNodes[i], -1); + } + data.put(null, -1); + rm.setData(data); + rm.done(); + } + } + + /** + * Convenience method that returns the child nodes which return + * true to the hasDeltaFlags() test for the given + * event. + */ + protected Map getChildNodesWithDeltaFlags(IVMNode node, ModelDelta parentDelta, Object e) { + Map nodes = new HashMap(); + for (final IVMNode childNode : getVMProvider().getChildVMNodes(node)) { + if (!childNode.equals(node)) { + int delta = getDeltaFlags(childNode, parentDelta, e); + if (delta != IModelDelta.NO_CHANGE) { + nodes.put(childNode, delta); + } + } + } + return nodes; + } + + +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IRootVMNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IRootVMNode.java new file mode 100644 index 00000000000..ff32002244b --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IRootVMNode.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel; + +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; + +/** + * Special type of the view model 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 IRootVMNode extends IVMNode{ + + /** + * Returns whether the given event should be processed for delta generation. + * Root node is different than other nodes in that there is only one root + * element in the view model provider hierarchy. This method allows the root + * node to match up the root object of the provider with the given event. If + * the root node can determine that the given event does not apply to the root + * object, it should return false so that the event is ignored. + * + * @param rootObject The root object of the VM provider + * @param event + * @return + */ + public boolean isDeltaEvent(Object rootObject, Object event); + + /** + * Version of the {@link IVMNode#buildDelta(Object, ViewModelDelta, org.eclipse.dd.dsf.concurrent.RequestMonitor)} + * 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 rm Result notification, contains the root of the delta. + */ + public void createRootDelta(Object rootObject, Object event, DataRequestMonitor rm); +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMContext.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMContext.java index aeacc41e922..e10ba43376f 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMContext.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMContext.java @@ -14,13 +14,16 @@ import org.eclipse.core.runtime.IAdaptable; import org.eclipse.dd.dsf.concurrent.Immutable; /** - * View Model element which is stored as the data object of nodes in the viewer. + * View model element which is stored as the data object of nodes in the viewer. + * The implementation of this interface is usually a wrapper object for an object + * from some data model, which is then used to correctly implement the + * {@link #equals(Object)} and {@link #hashCode()} methods of this wrapper. */ @Immutable public interface IVMContext extends IAdaptable { /** - * Returns the layout node that originated this element. + * Returns the view model node that originated this element. */ - public IVMLayoutNode getLayoutNode(); + public IVMNode getVMNode(); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMModelProxy.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMModelProxy.java new file mode 100644 index 00000000000..07afe0dae52 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMModelProxy.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel; + +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy; + +/** + * + */ +@SuppressWarnings("restriction") +public interface IVMModelProxy extends IModelProxy { + + public Object getRootElement(); + + public boolean isDeltaEvent(Object event); + + public void createDelta(final Object event, final DataRequestMonitor rm); + + public void fireModelChanged(IModelDelta delta); + +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMNode.java similarity index 55% rename from plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMLayoutNode.java rename to plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMNode.java index fc0ce2ae030..04d8f727229 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMNode.java @@ -12,82 +12,46 @@ package org.eclipse.dd.dsf.ui.viewmodel; import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; /** - * View model layout nodes are combined together into a tree, to collectively + * View model nodes are configured with a view model provider to collectively * define the layout of a view. Each layout node generates elements of type - * IVMContext which are then stored in the viewer. - *

    - * 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. + * {@link IVMContext} which are then stored in the viewer. + * + *

    + * NOTE: This interface extends IElementContentProvider but it has + * slightly different parameter requirements. For the + * {@link IElementContentProvider#update(IChildrenUpdate[])} method, this class + * can accept an update where {@link IChildrenUpdate#getOffset()} and + * {@link IChildrenUpdate#getLength()} may return -1. In this case the + * implementation should return all available elements for the given parent.
    + * Also the for the {@link IElementContentProvider#update(IHasChildrenUpdate[])} and + * {@link IElementContentProvider#update(IChildrenCountUpdate[])} methods, the + * implementation may return an error with an error code of {@link IDsfService#NOT_SUPPORTED}. + * In this case the caller of this update should call + * {@link IElementContentProvider#update(IChildrenUpdate[])} + * instead. + * * @see AbstractDMVMProvider + * @see IElementContentProvider */ @ConfinedToDsfExecutor("") @SuppressWarnings("restriction") -public interface IVMLayoutNode +public interface IVMNode extends IElementContentProvider { /** - * Retrieves the associated VM Provider. + * Retrieves the view model provider that this node is configured with. */ public IVMProvider getVMProvider(); - /** - * Retrieves information whether for a given path in the viewer, - * there are any elements available in this node. - * - * @param updates The update objects which need to be filled in with results - * calculated by this method. - * Even though the "children" interface is reused, the updates refer to the - * elements of this layout node, and not it's children. - */ - public void updateHasElements(IHasChildrenUpdate[] updates); - - /** - * Retrieves the number of available elements in this node for the given - * path in the viewer. - * - * @param updates The update object which needs to be filled in with result - * calculated by this method. - * Even though the "children" interface is reused, the updates refer to the - * elements of this layout node, and not it's children. - */ - public void updateElementCount(IChildrenCountUpdate update); - - /** - * Retrieves the element objects of this node for the given path in the - * viewer, and for the given range of indexes.
    - * NOTE: update.getOffset() and update.getLength() may return -1. - * The range of children, denoted by ILabelUpdate.getOffset() - * and ILabelUpdate.getLength(), may not be specified, in which case these - * methods may return -1. This means that all the elements should be - * retrieved for this node.
    - * - * @param updates The update object which needs to be filled in with result - * calculated by this method. - * Even though the "children" interface is reused, the updates refer to the - * elements of this layout node, and not it's children. - */ - public void updateElements(IChildrenUpdate update); - - - /** - * Configures the child layout nodes for this node. - * @param childNodes - */ - public void setChildNodes(IVMLayoutNode[] childNodes); - - /** - * Returns the list of child layout nodes which are configured for this node. - */ - public IVMLayoutNode[] getChildLayoutNodes(); - /** * Returns the potential delta flags that would be generated by this node * for the given event. @@ -126,8 +90,24 @@ public interface IVMLayoutNode * @param requestMonitor Return token, which notifies the caller that the calculation is * complete. */ - public void buildDelta(Object event, VMDelta parent, int nodeOffset, RequestMonitor requestMonitor); - + public void buildDelta(Object event, ModelDelta parent, int nodeOffset, RequestMonitor requestMonitor); + + /** + * Returns the view model element for the given data model event. This method + * is optional and it allows the view model provider to optimize event processing + * by avoiding the need to retrieve all possible elements for the given node. + *

    + * For example: If a threads node implementation is given a thread stopped event in + * for this method, and the stopped event included a reference to the thread. Then + * the implementation should create a view model context for that thread and return it + * here. + * + * @param event The event to check for the data model object. + * @return A view model object if it can be calculated, null + * if it cannot. + */ + public IVMContext getContextFromEvent(Object event); + /** * Releases the resources held by this node. */ diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java index 60960351190..2a924b2b09f 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java @@ -1,6 +1,8 @@ package org.eclipse.dd.dsf.ui.viewmodel; -import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import java.util.concurrent.Executor; + +import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory; @@ -8,11 +10,31 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationCont import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputProvider; /** - * The View Model Provider handles the layout of a given model within a + * The view model provider handles the layout of a given model within a * single viewer. The View Model Adapter delegates calls for view content to - * this object for a view that this provider handles. + * this object for a view that this provider handles. + * + *

    + * A given view model provider is typically configured with a number of + * {@link IVMNode} objects which are organized in a parent-child hierarchy. + * The node hierarchy has a root node which is retrieved using {@link #getRootVMNode()}. + * + *

    + * Note on concurency: The view model provider is single-threaded and it has to be + * accessed only using the Executor returned by {@link #getExecutor()}. + * The thread of this executor should be the display thread used by the viewer + * corresponding to the view model provider. Currently the flexible hierarchy + * interfaces that this interface extends do not guarantee that their methods + * will be called on the display thread, although from their use we are making + * this assumption (bug 213629). {@link IElementContentProvider} is an + * exception to this, it is called by the TreeModelViewer on a background + * thread, however it is not expected that the viewer will be calling the + * IVMProvider directly. Rather, it is expected that the viewer will call + * {@link IVMAdapter} which implements IElementContentProvider, + * and IVMAdapter implementation is expected to switch to + * provider's thread before delegating the call to it. */ -@ThreadSafe +@ConfinedToDsfExecutor("#getExecutor()") @SuppressWarnings("restriction") public interface IVMProvider extends IElementContentProvider, IModelProxyFactory, IColumnPresentationFactory, IViewerInputProvider @@ -23,19 +45,25 @@ public interface IVMProvider public IVMAdapter getVMAdapter(); /** - * Returns the root layout node that is configured in this provider. - * It may return null, if a root node is not yet configured. + * Returns the executor that needs to be used to access this provider. */ - public IVMRootLayoutNode getRootLayoutNode(); + public Executor getExecutor(); /** - * Returns the root element of the view model. If the given view model is - * used to populate the entire contents of the view, then this is the input - * element for the viewer. If the view model is used to populate only a - * sub-tree section of the view, then this is the root element of that - * sub-tree. + * Returns the root node that is configured in this provider. + * It may return null, if a root node is not yet configured. */ - public Object getRootElement(); + public IRootVMNode getRootVMNode(); + + /** + * Returns an array of nodes which are configured as child nodes of the given node. + */ + public IVMNode[] getChildVMNodes(IVMNode node); + + /** + * Retrieves the list of all nodes configured for this provider. + */ + public IVMNode[] getAllVMNodes(); /** * Returns the presentation context of the viewer that this provider @@ -43,12 +71,6 @@ public interface IVMProvider */ public IPresentationContext getPresentationContext(); - /** - * Allows other subsystems to force the layout mode associated with the specified - * VM context to refresh. If null is passed then the RootLayoutNode is told to refresh. - */ - public void refresh(IVMContext element); - /** * Cleans up the resources associated with this provider. */ diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMRootLayoutNode.java deleted file mode 100644 index 019b577ba32..00000000000 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMRootLayoutNode.java +++ /dev/null @@ -1,32 +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.viewmodel; - -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.debug.internal.ui.viewers.model.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{ - - /** - * Version of the {@link IVMLayoutNode#buildDelta(Object, ViewModelDelta, org.eclipse.dd.dsf.concurrent.RequestMonitor)} - * 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 rm Result notification, contains the root of the delta. - */ - public void createDelta(Object event, DataRequestMonitor rm); -} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/RootVMNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/RootVMNode.java new file mode 100644 index 00000000000..5bdda2c409c --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/RootVMNode.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel; + +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; + +/** + * Default implementation of a root view model node. This class may be sub-classed + * to implement model-specific event handling. + */ +@SuppressWarnings("restriction") +public class RootVMNode extends AbstractVMNode implements IRootVMNode { + + public RootVMNode(AbstractVMProvider provider) { + super(provider); + } + + public void update(IChildrenUpdate[] updates) { + throw new UnsupportedOperationException("Root view model node should never be queried for list of elements."); //$NON-NLS-1$ + } + + public void update(IChildrenCountUpdate[] updates) { + throw new UnsupportedOperationException("Root view model node should never be queried for list of elements."); //$NON-NLS-1$ + } + + public void update(IHasChildrenUpdate[] updates) { + throw new UnsupportedOperationException("Root view model node should never be queried for list of elements."); //$NON-NLS-1$ + } + + /** + * Default implementation does not examine the event and assumes that every + * event should be processed to generate a delta. + */ + public boolean isDeltaEvent(Object rootObject, Object event) { + return true; + } + + /** + * Default implementation creates a delta assuming that the root layout node + * is the input object into the view. + */ + public void createRootDelta(Object rootObject, Object event, final DataRequestMonitor rm) { + rm.setData(new ModelDelta(rootObject, 0, IModelDelta.NO_CHANGE)); + rm.done(); + } + + + public int getDeltaFlags(Object event) { + return IModelDelta.NO_CHANGE; + } + + public void buildDelta(Object event, ModelDelta parent, int nodeOffset, RequestMonitor requestMonitor) { + requestMonitor.done(); + } +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMElementsCountUpdate.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMChildrenCountUpdate.java similarity index 62% rename from plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMElementsCountUpdate.java rename to plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMChildrenCountUpdate.java index 2ae96edb483..764513deec4 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMElementsCountUpdate.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMChildrenCountUpdate.java @@ -12,22 +12,35 @@ package org.eclipse.dd.dsf.ui.viewmodel; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; +import org.eclipse.jface.viewers.TreePath; /** - * Helper class implementation of an update object to use with IElementContentProvider. - * @see IElementContentProvider + * Helper class implementation of the {@link IChildrenCountUpdate} update object. + * + * @see VMViewerUpdate */ @SuppressWarnings("restriction") -public class VMElementsCountUpdate extends VMViewerUpdate implements IChildrenCountUpdate { +public class VMChildrenCountUpdate extends VMViewerUpdate implements IChildrenCountUpdate { final private DataRequestMonitor fCountRequestMonitor; - public VMElementsCountUpdate(IViewerUpdate clientUpdate, DataRequestMonitor rm) { + public VMChildrenCountUpdate(IViewerUpdate clientUpdate, DataRequestMonitor rm) { super(clientUpdate, rm); fCountRequestMonitor = rm; } + public VMChildrenCountUpdate(IModelDelta delta, IPresentationContext presentationContext, DataRequestMonitor rm) { + super(delta, presentationContext, rm); + fCountRequestMonitor = rm; + } + + public VMChildrenCountUpdate(TreePath elementPath, Object viewerInput, IPresentationContext presentationContext, DataRequestMonitor rm) { + super(elementPath, viewerInput, presentationContext, rm); + fCountRequestMonitor = rm; + } + public void setChildCount(int count) { fCountRequestMonitor.setData(count); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMElementsUpdate.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMChildrenUpdate.java similarity index 51% rename from plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMElementsUpdate.java rename to plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMChildrenUpdate.java index 4de36383354..5083a0679f9 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMElementsUpdate.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMChildrenUpdate.java @@ -19,25 +19,49 @@ import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.DsfUIPlugin; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; +import org.eclipse.jface.viewers.TreePath; /** - * Helper class implementation of an update object to use with IElementContentProvider. - * @see IElementContentProvider + * Helper class implementation of the {@link IChildrenUpdate} update object. + * + * @see VMViewerUpdate */ @SuppressWarnings("restriction") -public class VMElementsUpdate extends VMViewerUpdate implements IChildrenUpdate { +public class VMChildrenUpdate extends VMViewerUpdate implements IChildrenUpdate { private final int fOffset; private final int fLength; protected final List fElements; - public VMElementsUpdate(IChildrenUpdate clientUpdate, int offset, int length, DataRequestMonitor> requestMonitor) { + public VMChildrenUpdate(IViewerUpdate clientUpdate, int offset, int length, + DataRequestMonitor> requestMonitor) + { super(clientUpdate, requestMonitor); fOffset = offset; fLength = length; fElements = length > 0 ? new ArrayList(length) : new ArrayList(); } + public VMChildrenUpdate(IModelDelta delta, IPresentationContext presentationContext, int offset, int length, + DataRequestMonitor> rm) + { + super(delta, presentationContext, rm); + fOffset = offset; + fLength = length; + fElements = length > 0 ? new ArrayList(length) : new ArrayList(); + } + + public VMChildrenUpdate(TreePath elementPath, Object viewerInput, IPresentationContext presentationContext, + int offset, int length, DataRequestMonitor> rm) + { + super(elementPath, viewerInput, presentationContext, rm); + fOffset = offset; + fLength = length; + fElements = length > 0 ? new ArrayList(length) : new ArrayList(); + } + public int getOffset() { return fOffset; } @@ -74,10 +98,37 @@ public class VMElementsUpdate extends VMViewerUpdate implements IChildrenUpdate @Override public void done() { @SuppressWarnings("unchecked") - DataRequestMonitor> rm = (DataRequestMonitor>)fRequestMonitor; - if (fElements.size() == fLength || fLength == -1 ) { - rm.setData(fElements); - } else { + DataRequestMonitor> rm = (DataRequestMonitor>)getRequestMonitor(); + + /* See https://bugs.eclipse.org/bugs/show_bug.cgi?id=202109 + * + * A flexible hierarchy bug/optimization causes query with incorrect + * IChildrenUpdate[] array length. + * + * We found this while deleting a register node. Example: + * + * the register view displays: + * PC + * EAX + * EBX + * ECX + * EDX + * + * we delete EBX and force a context refresh. + * + * flexible hierarchy queries for IChildrenUpdate[5] and IChildrenCountUpdate at + * the same time. + * + * VMElementsUpdate, used by VMCache to wrap the IChildrenUpdate, generates an + * IStatus.ERROR with message "Incomplete elements of updates" when fElements + * count (provided by service) does not match the length provided by the original + * update query. + * + * Workaround, always set the elements array in the request monitor, but still set + * the error status. + */ + rm.setData(fElements); + if (rm.getStatus().isOK() && fLength != -1 && fElements.size() != fLength) { rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, "Incomplete elements of updates", null)); //$NON-NLS-1$ } super.done(); diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java deleted file mode 100644 index 800d163a303..00000000000 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java +++ /dev/null @@ -1,330 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2006 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - * Wind River Systems - adapted to use in DSF - *******************************************************************************/ -package org.eclipse.dd.dsf.ui.viewmodel; - -import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDeltaVisitor; -import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; - -/** - * This delta class mostly just duplicates the ModelDelta implemention, but - * it allows clients to modify the flags after the original object is - * constructed. - * - * @see IModelDelta#getNodes() - */ -@SuppressWarnings("restriction") -public class VMDelta extends ModelDelta { - - private VMDelta fParent; - private Object fElement; - private int fFlags; - private VMDelta[] fNodes = EMPTY_NODES; - private Object fReplacement; - private int fIndex; - private static final VMDelta[] EMPTY_NODES = new VMDelta[0]; - private int fChildCount = -1; - - /** - * Constructs a new delta for the given element. - * - * @param vmcElement model element - * @param flags change flags - */ - public VMDelta(Object element, int flags) { - super(element, flags); - fElement = element; - fFlags = flags; - } - - /** - * Constructs a new delta for the given element to be replaced - * with the specified replacement element. - * - * @param vmcElement model element - * @param replacement replacement element - * @param flags change flags - */ - public VMDelta(Object element, Object replacement, int flags) { - super(element, replacement, flags); - fElement = element; - fReplacement = replacement; - fFlags = flags; - } - - /** - * Constructs a new delta for the given element to be inserted at - * the specified index. - * - * @param vmcElement model element - * @param index insertion position - * @param flags change flags - */ - public VMDelta(Object element, int index, int flags) { - super(element, index, flags); - fElement = element; - fIndex = index; - fFlags = flags; - } - - /** - * Constructs a new delta for the given element at the specified index - * relative to its parent with the given number of children. - * - * @param element model element - * @param index insertion position - * @param flags change flags - * @param childCount number of children this node has - */ - public VMDelta(Object element, int index, int flags, int childCount) { - super(element, index, flags, childCount); - fElement = element; - fIndex = index; - fFlags = flags; - fChildCount = childCount; - } - - /** - * Returns the non-VMC element if one is set, otherwise returns the VMC - * element of this delta node. - * @see org.eclipse.debug.internal.ui.viewers.IModelDelta#getElement() - */ - @Override - public Object getElement() { - return fElement; - } - - /* (non-Javadoc) - * @see org.eclipse.debug.internal.ui.viewers.IModelDelta#getFlags() - */ - @Override - public int getFlags() { - return fFlags; - } - - public void addFlags(int flags) { - fFlags |= flags; - } - - public void setChildCount(int count) { - fChildCount = count; - } - - /** - * Adds a child node to this delta with the given element and change flags, - * and returns the child delta. - * - * @param element child element to add - * @param flags change flags for child - * @return newly created child delta - */ - @Override - public VMDelta addNode(Object element, int flags) { - VMDelta node = new VMDelta(element, flags); - node.setParent(this); - addDelta(node); - return node; - } - - /** - * Adds a child node to this delta to replace the given element with the - * specified replacement element and change flags, and returns the - * newly created child delta. - * - * @param element child element to add to this delta - * @param replacement replacement element for the child element - * @param flags change flags - * @return newly created child delta - */ - @Override - public VMDelta addNode(Object element, Object replacement, int flags) { - VMDelta node = new VMDelta(element, replacement, flags); - node.setParent(this); - addDelta(node); - return node; - } - - /** - * Adds a child delta to this delta to insert the specified element at - * the given index, and returns the newly created child delta. - * - * @param element child element in insert - * @param index index of insertion - * @param flags change flags - * @return newly created child delta - */ - @Override - public VMDelta addNode(Object element, int index, int flags) { - VMDelta node = new VMDelta(element, index, flags); - node.setParent(this); - addDelta(node); - return node; - } - - /** - * Adds a child delta to this delta at the specified index with the - * given number of children, and returns the newly created child delta. - * - * @param element child element in insert - * @param index index of the element relative to parent - * @param flags change flags - * @param numChildren the number of children the element has - * @return newly created child delta - */ - @Override - public VMDelta addNode(Object element, int index, int flags, int numChildren) { - VMDelta node = new VMDelta(element, index, flags, numChildren); - node.setParent(this); - addDelta(node); - return node; - } - - /** - * Sets the parent delta of this delta - * - * @param node parent delta - */ - void setParent(VMDelta node) { - fParent = node; - } - - /* (non-Javadoc) - * @see org.eclipse.debug.internal.ui.viewers.IModelDelta#getParent() - */ - @Override - public VMDelta getParentDelta() { - return fParent; - } - - /* (non-Javadoc) - * @see org.eclipse.debug.internal.ui.viewers.IModelDelta#getReplacementElement() - */ - @Override - public Object getReplacementElement() { - return fReplacement; - } - - /* (non-Javadoc) - * @see org.eclipse.debug.internal.ui.viewers.IModelDelta#getIndex() - */ - @Override - public int getIndex() { - return fIndex; - } - - /* (non-Javadoc) - * @see org.eclipse.debug.internal.ui.viewers.IModelDelta#getNodes() - */ - @Override - public VMDelta[] getChildDeltas() { - return fNodes; - } - - private void addDelta(VMDelta delta) { - if (fNodes.length == 0) { - fNodes = new VMDelta[]{delta}; - } else { - VMDelta[] nodes = new VMDelta[fNodes.length + 1]; - System.arraycopy(fNodes, 0, nodes, 0, fNodes.length); - nodes[fNodes.length] = delta; - fNodes = nodes; - } - } - - @Override - public String toString() { - StringBuffer buf = new StringBuffer(); - buf.append("Model Delta Start\n"); //$NON-NLS-1$ - appendDetail(buf, this); - buf.append("Model Delta End\n"); //$NON-NLS-1$ - return buf.toString(); - } - - private void appendDetail(StringBuffer buf, VMDelta delta) { - buf.append("\tElement: "); //$NON-NLS-1$ - buf.append(delta.getElement()); - buf.append('\n'); - buf.append("\t\tFlags: "); //$NON-NLS-1$ - int flags = delta.getFlags(); - if (flags == 0) { - buf.append("NO_CHANGE"); //$NON-NLS-1$ - } else { - if ((flags & IModelDelta.ADDED) > 0) { - buf.append("ADDED | "); //$NON-NLS-1$ - } - if ((flags & IModelDelta.CONTENT) > 0) { - buf.append("CONTENT | "); //$NON-NLS-1$ - } - if ((flags & IModelDelta.EXPAND) > 0) { - buf.append("EXPAND | "); //$NON-NLS-1$ - } - if ((flags & IModelDelta.INSERTED) > 0) { - buf.append("INSERTED | "); //$NON-NLS-1$ - } - if ((flags & IModelDelta.REMOVED) > 0) { - buf.append("REMOVED | "); //$NON-NLS-1$ - } - if ((flags & IModelDelta.REPLACED) > 0) { - buf.append("REPLACED | "); //$NON-NLS-1$ - } - if ((flags & IModelDelta.SELECT) > 0) { - buf.append("SELECT | "); //$NON-NLS-1$ - } - if ((flags & IModelDelta.STATE) > 0) { - buf.append("STATE | "); //$NON-NLS-1$ - } - if ((flags & IModelDelta.INSTALL) > 0) { - buf.append("INSTALL | "); //$NON-NLS-1$ - } - if ((flags & IModelDelta.UNINSTALL) > 0) { - buf.append("UNINSTALL | "); //$NON-NLS-1$ - } - } - buf.append('\n'); - buf.append("\t\tIndex: "); //$NON-NLS-1$ - buf.append(delta.fIndex); - buf.append(" Child Count: "); //$NON-NLS-1$ - buf.append(delta.fChildCount); - buf.append('\n'); - IModelDelta[] nodes = delta.getChildDeltas(); - for (int i = 0; i < nodes.length; i++) { - appendDetail(buf, (VMDelta)nodes[i]); - } - } - - /* (non-Javadoc) - * @see org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta#getChildCount() - */ - @Override - public int getChildCount() { - return fChildCount; - } - - /* (non-Javadoc) - * @see org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta#accept(org.eclipse.debug.internal.ui.viewers.provisional.IModelDeltaVisitor) - */ - @Override - public void accept(IModelDeltaVisitor visitor) { - doAccept(visitor, 0); - } - - @Override - protected void doAccept(IModelDeltaVisitor visitor, int depth) { - if (visitor.visit(this, depth)) { - ModelDelta[] childDeltas = getChildDeltas(); - for (int i = 0; i < childDeltas.length; i++) { - ((VMDelta)childDeltas[i]).doAccept(visitor, depth+1); - } - } - } - -} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMHasElementsUpdate.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMHasChildrenUpdate.java similarity index 57% rename from plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMHasElementsUpdate.java rename to plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMHasChildrenUpdate.java index b466b8d5717..1ec49ec22df 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMHasElementsUpdate.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMHasChildrenUpdate.java @@ -11,23 +11,37 @@ package org.eclipse.dd.dsf.ui.viewmodel; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; +import org.eclipse.jface.viewers.TreePath; /** - * Helper class implementation of an update object to use with IElementContentProvider. - * @see IElementContentProvider + * Helper class implementation of the {@link IHasChildrenUpdate} update object. + * + * @see VMViewerUpdate */ @SuppressWarnings("restriction") -public class VMHasElementsUpdate extends VMViewerUpdate implements IHasChildrenUpdate { +public class VMHasChildrenUpdate extends VMViewerUpdate implements IHasChildrenUpdate { final private DataRequestMonitor fHasElemsRequestMonitor; - public VMHasElementsUpdate(IHasChildrenUpdate clientUpdate, DataRequestMonitor rm) { + public VMHasChildrenUpdate(IViewerUpdate clientUpdate, DataRequestMonitor rm) { super(clientUpdate, rm); fHasElemsRequestMonitor = rm; } + public VMHasChildrenUpdate(IModelDelta delta, IPresentationContext presentationContext, DataRequestMonitor rm) { + super(delta, presentationContext, rm); + fHasElemsRequestMonitor = rm; + } + + public VMHasChildrenUpdate(TreePath elementPath, Object viewerInput, IPresentationContext presentationContext, DataRequestMonitor rm) { + super(elementPath, viewerInput, presentationContext, rm); + fHasElemsRequestMonitor = rm; + } + public void setHasChilren(boolean hasChildren) { fHasElemsRequestMonitor.setData(hasChildren); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMRootLayoutNode.java deleted file mode 100644 index bfc29baab47..00000000000 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMRootLayoutNode.java +++ /dev/null @@ -1,107 +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.viewmodel; - -import java.util.Map; - -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; - -/** - * Default implementation of a root layout node. This class may be sub-classed - * to implement model-specific event handling. - */ -@SuppressWarnings("restriction") -public class VMRootLayoutNode extends AbstractVMLayoutNode implements IVMRootLayoutNode { - - public VMRootLayoutNode(AbstractVMProvider provider) { - super(provider); - } - - /** - * This implementation only fulfills the requirements of the super-interface. - * There is no use case for a root node implementing this method, but its - * easier to just implement it for sake of uniformity of model. - */ - public void updateElements(IChildrenUpdate update) { - // Ignore startIdx, endIdx, since there's only one element to be had. - update.setChild(getVMProvider().getRootElement(), 0); - update.done(); - } - - /** - * This implementation only fulfills 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 updateElementCount(IChildrenCountUpdate update) { - update.setChildCount(1); - update.done(); - } - - /** - * This implementation only fulfills the requirements of the super-interface. - * There is no use case for a root node implementing this method, but its - * easier to just implement it for sake of uniformity of model. - */ - public void updateHasElements(IHasChildrenUpdate[] updates) { - for (IHasChildrenUpdate update : updates) { - update.setHasChilren(true); - update.done(); - } - } - - /** - * This implementation only fulfills the requirements of the super-interface. - * There is no use case for a root node implementing this method, but its - * easier to just implement it for sake of uniformity of model. - */ - public void updateLabel(@SuppressWarnings("unused") - IVMContext vmc, ILabelUpdate update) { - update.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 DataRequestMonitor rm) { - final Map childNodeDeltas = getChildNodesWithDeltaFlags(event); - assert childNodeDeltas.size() != 0 : "Caller should make sure that there are deltas for given event."; //$NON-NLS-1$ - - // Always create the rootDelta, no matter what delta flags the child nodes have. - final VMDelta rootDelta = new VMDelta(getVMProvider().getRootElement(), IModelDelta.NO_CHANGE); - - callChildNodesToBuildDelta( - childNodeDeltas, rootDelta, event, - new RequestMonitor(getExecutor(), rm) { - @Override - protected void handleCompleted() { - if (!isDisposed()) super.handleCompleted(); - } - - @Override - public void handleOK() { - rm.setData(rootDelta); - rm.done(); - } - }); - } - - public Object getRootObject() { - return getVMProvider().getRootElement(); - } -} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java index 0ed79ad8e06..ab87341ae38 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java @@ -10,41 +10,161 @@ *******************************************************************************/ package org.eclipse.dd.dsf.ui.viewmodel; +import java.util.LinkedList; +import java.util.List; import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.atomic.AtomicBoolean; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.ui.DsfUIPlugin; +import org.eclipse.debug.core.IRequest; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; import org.eclipse.jface.viewers.TreePath; /** - * Helper class implementation of an update object to use with IElementContentProvider. - * @see IElementContentProvider + * Helper class implementation of the update objects used with + * {@link IElementContentProvider}, {@link IElementLabelProvider}, + * and {@link IElementMementoProvider}. The viewer update can be constructed + * using a higher level update object or a set of parameters to fulfill the + * IViewerUpdate interface. */ @SuppressWarnings("restriction") public class VMViewerUpdate implements IViewerUpdate { - final protected RequestMonitor fRequestMonitor; - final protected IViewerUpdate fClientUpdate; + /** + * The request monitor to be called when this update is completed. + */ + final private RequestMonitor fRequestMonitor; + + /** + * A higher-level update that this update is based on. If specified, the given + * update is used to delegate calls to {@link #cancel()} and {@link #isCanceled()}. + */ + final private IViewerUpdate fClientUpdate; + + /** + * The flag indicating whether this update was cancelled. This flag is not used + * if the {@link #fClientUpdate} is initialized. + */ + final private AtomicBoolean fCanceled; + + /** + * The viewer input object for this update. + */ + final private Object fViewerInput; + + /** + * The element object of this update. + */ + final private Object fElement; + + /** + * The element path of this update. + */ + final private TreePath fElementPath; + + /** + * The presentation context of this update. + */ + final private IPresentationContext fPresentationContext; + + /** + * Creates a viewer update based on a higher-level update. The update element + * information as well as cancel requests are delegated to the given client + * update. + *

    + * Note: this update will not automatically call the client update's + * {@link IRequest#done()} method. The user of this update should supply + * a request monitor which properly completes the client update. + * + * @param clientUpdate Client update that this update is based on. + * @param requestMonitor Call-back invoked when this update completes. + */ public VMViewerUpdate(IViewerUpdate clientUpdate, RequestMonitor requestMonitor) { + fViewerInput = clientUpdate.getViewerInput(); + fElement = clientUpdate.getElement(); + fElementPath = clientUpdate.getElementPath(); + fPresentationContext = clientUpdate.getPresentationContext(); fRequestMonitor = requestMonitor; fClientUpdate = clientUpdate; + fCanceled = null; } - public Object getViewerInput() { return fClientUpdate.getViewerInput(); } - public Object getElement() { return fClientUpdate.getElement(); } - public TreePath getElementPath() { return fClientUpdate.getElementPath(); } - public IPresentationContext getPresentationContext() { return fClientUpdate.getPresentationContext(); } + /** + * Request monitor which uses a model delta to calculate the element information. + * This update is useful when calculating a model delta for a given view model node. + * + * @param delta Model delta of a parent element. + * @param presentationContext Presentation context for this update. + * @param requestMonitor Call-back invoked when this update completes. + */ + public VMViewerUpdate(IModelDelta delta, IPresentationContext presentationContext, RequestMonitor requestMonitor) { + List elementList = new LinkedList(); + IModelDelta listDelta = delta; + elementList.add(0, listDelta.getElement()); + while (listDelta.getParentDelta() != null) { + listDelta = listDelta.getParentDelta(); + elementList.add(0, listDelta.getElement()); + } + fViewerInput = elementList.get(0); + fElement = elementList.get(elementList.size() - 1); + elementList.remove(0); + fElementPath = new TreePath(elementList.toArray()); + fPresentationContext = presentationContext; + fRequestMonitor = requestMonitor; + fClientUpdate = null; + fCanceled = new AtomicBoolean(false); + } + /** + * Creates a viewer update with the given parameters. + * + * @param elementPath The path to the element for which the update is generated. + * @param viewerInput Input into the viewer of the update. + * @param presentationContext Presentation context for this update. + * @param requestMonitor Call-back invoked when this update completes. + */ + public VMViewerUpdate(TreePath elementPath, Object viewerInput, IPresentationContext presentationContext, RequestMonitor requestMonitor) { + fViewerInput = viewerInput; + fElement = elementPath.getSegmentCount() != 0 ? elementPath.getLastSegment() : viewerInput; + fElementPath = elementPath; + fPresentationContext = presentationContext; + fRequestMonitor = requestMonitor; + fClientUpdate = null; + fCanceled = new AtomicBoolean(false); + } + + protected RequestMonitor getRequestMonitor() { + return fRequestMonitor; + } + + public Object getViewerInput() { return fViewerInput; } + public Object getElement() { return fElement; } + public TreePath getElementPath() { return fElementPath; } + public IPresentationContext getPresentationContext() { return fPresentationContext; } public IStatus getStatus() { return fRequestMonitor.getStatus(); } public void setStatus(IStatus status) { fRequestMonitor.setStatus(status); } - public boolean isCanceled() { return fClientUpdate.isCanceled(); } + + public boolean isCanceled() { + if (fClientUpdate != null) { + return fClientUpdate.isCanceled(); + } else { + return fCanceled.get(); + } + } public void cancel() { - fClientUpdate.cancel(); + if (fClientUpdate != null) { + fClientUpdate.cancel(); + } else { + fCanceled.set(true); + } } public void done() { diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java deleted file mode 100644 index fbd7567ff0a..00000000000 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMLayoutNode.java +++ /dev/null @@ -1,481 +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.viewmodel.dm; - -import java.util.List; -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.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.DsfRunnable; -import org.eclipse.dd.dsf.concurrent.Immutable; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.datamodel.DMContexts; -import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.datamodel.IDMEvent; -import org.eclipse.dd.dsf.service.DsfServicesTracker; -import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; -import org.eclipse.dd.dsf.ui.DsfUIPlugin; -import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMLayoutNode; -import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; -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.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.ITreeSelection; -import org.eclipse.jface.viewers.TreePath; - - -/** - * 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 AbstractDMVMLayoutNode extends AbstractVMLayoutNode - implements IElementLabelProvider -{ - - /** - * IVMContext implementation used for this schema node. - */ - @Immutable - public class DMVMContext extends AbstractVMContext { - private final IDMContext fDmc; - - public DMVMContext(IDMContext dmc) { - super(getVMProvider().getVMAdapter(), AbstractDMVMLayoutNode.this); - fDmc = dmc; - } - - public IDMContext getDMC() { return fDmc; } - - /** - * The IAdaptable implementation. If the adapter is the DM context, - * return the context, otherwise delegate to IDMContext.getAdapter(). - */ - @Override - @SuppressWarnings("unchecked") - public Object getAdapter(Class adapter) { - Object superAdapter = super.getAdapter(adapter); - if (superAdapter != null) { - return superAdapter; - } else if (adapter.isInstance(fDmc)) { - return fDmc; - } else { - return fDmc.getAdapter(adapter); - } - } - - @Override - public boolean equals(Object other) { - if (!(other instanceof AbstractDMVMLayoutNode.DMVMContext)) return false; - DMVMContext otherVmc = (DMVMContext)other; - return AbstractDMVMLayoutNode.this.equals(otherVmc.getLayoutNode()) && - fDmc.equals(otherVmc.fDmc); - } - - @Override - public int hashCode() { - return AbstractDMVMLayoutNode.this.hashCode() + fDmc.hashCode(); - } - - @Override - public String toString() { - return fDmc.toString(); - } - } - - private DsfSession fSession; - - private DsfServicesTracker fServicesTracker; - - /** - * Concrete class type that the elements of this schema node are based on. - * Even though the data model type is a parameter the DMContextVMLayoutNode, - * this type is erased at runtime, so a concrete class typs of the DMC - * is needed for instanceof chacks. - */ - private Class 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 AbstractDMVMLayoutNode(AbstractVMProvider provider, DsfSession session, Class dmcClassType) { - super(provider); - fSession = session; - fServicesTracker = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), session.getId()); - fDMCClassType = dmcClassType; - } - - - @Override - public void dispose() { - fServicesTracker.dispose(); - super.dispose(); - } - - protected DsfSession getSession() { - return fSession; - } - - protected DsfServicesTracker getServicesTracker() { - return fServicesTracker; - } - - @Override - protected boolean checkUpdate(IViewerUpdate update) { - if (!super.checkUpdate(update)) return false; - - // Extract the VMC from the update (whatever the update sub-class. - Object element = update.getElement(); - if (element instanceof AbstractDMVMLayoutNode.DMVMContext) { - // If update element is a DMC, check if session is still alive. - IDMContext dmc = ((DMVMContext)element).getDMC(); - if (dmc.getSessionId() != getSession().getId() || !DsfSession.isSessionActive(dmc.getSessionId())) { - handleFailedUpdate(update); - return false; - } - } - return true; - } - - /** - * Convenience method that checks whether the given dmc context is null. If it is null, an - * appropriate error message is set in the update. - * @param dmc Data Model Context (DMC) to check. - * @param update Update to handle in case the DMC is null. - * @return true if the DMC is NOT null, indicating that it's OK to proceed. - */ - protected boolean checkDmc(IDMContext dmc, IViewerUpdate update) { - if (dmc == null) { - update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, - "No valid context found.", null)); //$NON-NLS-1$ - handleFailedUpdate(update); - return false; - } - return true; - } - - /** - * A convenience method that checks whether a given service exists. If the service does not - * exist, the update is filled in with the appropriate error message. - * @param serviceClass Service class to find. - * @param filter Service filter to use in addition to the service class name. - * @param update Update object to fill in. - * @return true if service IS found, indicating that it's OK to proceed. - */ - protected boolean checkService(Class serviceClass, String filter, IViewerUpdate update) { - if (getServicesTracker().getService(serviceClass, filter) == null) { - update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, - "Service " + serviceClass.getName() + " not available.", null)); //$NON-NLS-1$ //$NON-NLS-2$ - handleFailedUpdate(update); - return false; - } - return true; - } - - public void updateHasElements(final IHasChildrenUpdate[] updates) { - try { - getSession().getExecutor().execute(new DsfRunnable() { - public void run() { - updateHasElementsInSessionThread(updates); - }}); - } catch (RejectedExecutionException e) { - for (IHasChildrenUpdate update : updates) { - handleFailedUpdate(update); - } - } - } - - protected void updateHasElementsInSessionThread(IHasChildrenUpdate[] updates) { - for (final IHasChildrenUpdate update : updates) { - if (!checkUpdate(update)) continue; - - updateElementsInSessionThread( - new ElementsUpdate( - new DataRequestMonitor>(getSession().getExecutor(), null) { - @Override - protected void handleCompleted() { - if (!checkUpdate(update)) return; - if (getStatus().isOK()) { - update.setHasChilren(getData().size() != 0); - } else { - update.setHasChilren(false); - } - update.done(); - } - }, - update.getElementPath()) - ); - } - } - - public void updateElementCount(final IChildrenCountUpdate update) { - if (!checkUpdate(update)) return; - - try { - getSession().getExecutor().execute(new DsfRunnable() { - public void run() { - // After every dispatch, must check if update still valid. - if (!checkUpdate(update)) return; - updateElementCountInSessionThread(update); - }}); - } catch (RejectedExecutionException e) { - handleFailedUpdate(update); - } - } - - protected void updateElementCountInSessionThread(final IChildrenCountUpdate update) { - updateElementsInSessionThread( - new ElementsUpdate( - new DataRequestMonitor>(getSession().getExecutor(), null) { - @Override - protected void handleCompleted() { - if (!checkUpdate(update)) return; - if (getStatus().isOK()) { - update.setChildCount(getData().size()); - } else { - update.setChildCount(0); - } - update.done(); - } - }, - update.getElementPath()) - ); - } - - public void updateElements(final IChildrenUpdate update) { - if (!checkUpdate(update)) return; - - try { - getSession().getExecutor().execute(new DsfRunnable() { - public void run() { - // After every dispatch, must check if update still valid. - if (!checkUpdate(update)) return; - updateElementsInSessionThread(update); - }}); - } catch (RejectedExecutionException e) { - handleFailedUpdate(update); - } - } - - abstract protected void updateElementsInSessionThread(IChildrenUpdate update); - - public void update(final ILabelUpdate[] updates) { - try { - getSession().getExecutor().execute(new DsfRunnable() { - public void run() { - // After every dispatch, must check if update still valid. - updateLabelInSessionThread(updates); - }}); - } catch (RejectedExecutionException e) { - for (ILabelUpdate update : updates) { - handleFailedUpdate(update); - } - } - } - - abstract protected void updateLabelInSessionThread(ILabelUpdate[] updates); - - @Override - public int getDeltaFlags(Object e) { - int flags = 0; - if (e instanceof IDMEvent) { - flags = getNodeDeltaFlagsForDMEvent((IDMEvent)e); - } - return flags | super.getDeltaFlags(e); - } - - protected int getNodeDeltaFlagsForDMEvent(@SuppressWarnings("unused") IDMEvent e) { - return IModelDelta.NO_CHANGE; - } - - @Override - public void buildDelta(final Object e, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) { - if (e instanceof IDMEvent) { - // Call handler for Data Model events. But check to make sure - // that session is still active. - if (DsfSession.isSessionActive(getSession().getId())) { - getSession().getExecutor().execute(new DsfRunnable() { - public void run() { - buildDeltaForDMEvent((IDMEvent)e, parentDelta, nodeOffset, requestMonitor); - } - }); - } else { - if (isDisposed()) return; - requestMonitor.done(); - } - } else { - super.buildDelta(e, parentDelta, nodeOffset, requestMonitor); - } - } - - /** - * Handle all Data Model events. If a DM context in the event contains - * a context of the type tracked by this node, then this base implementation - * will only create a delta node for this one element. - */ - protected void buildDeltaForDMEvent(final IDMEvent event, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) { - IDMContext dmc = DMContexts.getAncestorOfType(event.getDMContext(), fDMCClassType); - - if (dmc != null) { - // Create the VM context based on the DM context from the DM event. - final IVMContext vmc = createVMContext(DMContexts.getAncestorOfType(event.getDMContext(), fDMCClassType)); - - final Map childNodeDeltas = getChildNodesWithDeltaFlags(event); - if (childNodeDeltas.size() == 0) { - // There are no child nodes with deltas, just return to parent. - requestMonitor.done(); - return; - } - - // Check if any of the child nodes are will generate IModelDelta.SELECT or - // IModelDelta.EXPAND flags. If so, we must calcuate the index for this - // VMC. - boolean calculateIndex = false; - for (int childDelta : childNodeDeltas.values()) { - if ( (childDelta & (IModelDelta.SELECT | IModelDelta.EXPAND)) != 0 ) { - calculateIndex = true; - break; - } - } - - if (calculateIndex) { - // Calculate the index of this node by retrieving all the - // elements and then finding the DMC that the event is for. - updateElements(new ElementsUpdate( - new DataRequestMonitor>(getExecutor(), null) { - @Override - protected void handleCompleted() { - if (isDisposed()) return; - - // Check for an empty list of elements. If it's empty then we - // don't have to call the children nodes, so return here. - // No need to propagate error, there's no means or need to display it. - if (!getStatus().isOK() || getData().isEmpty()) { - requestMonitor.done(); - return; - } - - // Find the index. - int i; - for (i = 0; i < getData().size(); i++) { - if (vmc.equals(getData().get(i))) break; - } - if (i == getData().size()) { - // Element not found, no need to generate the delta. - requestMonitor.done(); - return; - } - - VMDelta delta = parentDelta.addNode(vmc, nodeOffset + i, IModelDelta.NO_CHANGE); - callChildNodesToBuildDelta(childNodeDeltas, delta, event, requestMonitor); - } - }, - parentDelta)); - } else { - VMDelta delta = parentDelta.addNode(vmc, IModelDelta.NO_CHANGE); - callChildNodesToBuildDelta(childNodeDeltas, delta, event, requestMonitor); - } - } else { - // The DMC for this node was not found in the event. Call the - // super-class to resort to the default behavior which may add a - // delta for every element in this node. - super.buildDelta(event, parentDelta, nodeOffset, requestMonitor); - } - } - - /** - * 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(IDMContext[] dmcs) { - IVMContext[] vmContexts = new IVMContext[dmcs.length]; - for (int i = 0; i < dmcs.length; i++) { - vmContexts[i] = new DMVMContext(dmcs[i]); - } - return vmContexts; - } - - protected void fillUpdateWithVMCs(IChildrenUpdate update, IDMContext[] dmcs) { - int startIdx = update.getOffset() != -1 ? update.getOffset() : 0; - int endIdx = update.getLength() != -1 ? startIdx + update.getLength() : dmcs.length; - // Ted: added bounds limitation of dmcs.length - // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=202109 - for (int i = startIdx; i < endIdx && i < dmcs.length; i++) { - update.setChild(createVMContext(dmcs[i]), i); - } - } - - protected IVMContext createVMContext(IDMContext dmc) { - return new DMVMContext(dmc); - } - - /** - * Searches for a DMC of given type in the tree patch contained in given - * VMC. Only a DMC in the same session will be returned. - * @param 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 T findDmcInPath(TreePath path, Class dmcType) { - T retVal = null; - for (int i = path.getSegmentCount() - 1; i >= 0; i--) { - if (path.getSegment(i) instanceof AbstractDMVMLayoutNode.DMVMContext) { - IDMContext dmc = ((DMVMContext)path.getSegment(i)).getDMC(); - if ( dmc.getSessionId().equals(getSession().getId()) ) { - retVal = DMContexts.getAncestorOfType(dmc, dmcType); - if (retVal != null) break; - } - } - } - // Search the root object of the layout hierarchy. - if (retVal == null) { - Object inputObject = getVMProvider().getRootElement(); - if (inputObject instanceof ITreeSelection) { - ITreeSelection inputSelection = (ITreeSelection)inputObject; - if (inputSelection.getPaths().length == 1) { - retVal = findDmcInPath(inputSelection.getPaths()[0], dmcType); - } - } else if (inputObject instanceof IStructuredSelection) { - Object rootElement = ((IStructuredSelection)inputObject).getFirstElement(); - if (rootElement instanceof AbstractDMVMLayoutNode.DMVMContext) { - retVal = DMContexts.getAncestorOfType(((DMVMContext)rootElement).getDMC(), dmcType); - } - } else if (inputObject instanceof AbstractDMVMLayoutNode.DMVMContext) { - retVal = DMContexts.getAncestorOfType(((DMVMContext)inputObject).getDMC(), dmcType); - } - } - - return retVal; - } -} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMNode.java new file mode 100644 index 00000000000..e3df240e8e7 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMNode.java @@ -0,0 +1,334 @@ +/******************************************************************************* + * 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.dm; + +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +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.service.IDsfService; +import org.eclipse.dd.dsf.ui.DsfUIPlugin; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.IVMNode; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITreeSelection; +import org.eclipse.jface.viewers.TreePath; + + +/** + * View model 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 AbstractDMVMNode extends AbstractVMNode implements IVMNode { + + /** + * IVMContext implementation used for this schema node. + */ + @Immutable + protected class DMVMContext extends AbstractVMContext implements IDMVMContext { + private final IDMContext fDmc; + + public DMVMContext(IDMContext dmc) { + super(getVMProvider().getVMAdapter(), AbstractDMVMNode.this); + fDmc = dmc; + } + + public IDMContext getDMContext() { return fDmc; } + + /** + * The IAdaptable implementation. If the adapter is the DM context, + * return the context, otherwise delegate to IDMContext.getAdapter(). + */ + @Override + @SuppressWarnings("unchecked") + public Object getAdapter(Class adapter) { + Object superAdapter = super.getAdapter(adapter); + if (superAdapter != null) { + return superAdapter; + } else if (adapter.isInstance(fDmc)) { + return fDmc; + } else { + return fDmc.getAdapter(adapter); + } + } + + @Override + public boolean equals(Object other) { + if (!(other instanceof AbstractDMVMNode.DMVMContext)) return false; + DMVMContext otherVmc = (DMVMContext)other; + return AbstractDMVMNode.this.equals(otherVmc.getVMNode()) && + fDmc.equals(otherVmc.fDmc); + } + + @Override + public int hashCode() { + return AbstractDMVMNode.this.hashCode() + fDmc.hashCode(); + } + + @Override + public String toString() { + return fDmc.toString(); + } + } + + private DsfSession fSession; + + private DsfServicesTracker fServicesTracker; + + /** + * Concrete class type that the elements of this schema node are based on. + * Even though the data model type is a parameter the DMContextVMLayoutNode, + * this type is erased at runtime, so a concrete class typs of the DMC + * is needed for instanceof chacks. + */ + private Class fDMCClassType; + + /** + * Constructor initializes instance data, except for the child nodes. + * Child nodes must be initialized by calling setChildNodes() + * @param session + * @param dmcClassType + * @see #setChildNodes(IVMNode[]) + */ + public AbstractDMVMNode(AbstractDMVMProvider provider, DsfSession session, Class dmcClassType) { + super(provider); + fSession = session; + fServicesTracker = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), session.getId()); + fDMCClassType = dmcClassType; + } + + @Override + public void dispose() { + fServicesTracker.dispose(); + super.dispose(); + } + + @Override + public IVMContext getContextFromEvent(Object event) { + if (event instanceof IDMEvent) { + IDMEvent dmEvent = (IDMEvent)event; + IDMContext dmc = DMContexts.getAncestorOfType(dmEvent.getDMContext(), fDMCClassType); + if (dmc != null) { + return createVMContext(dmc); + } + } + return null; + } + + protected AbstractDMVMProvider getDMVMProvider() { + return (AbstractDMVMProvider)getVMProvider(); + } + + protected DsfSession getSession() { + return fSession; + } + + protected DsfServicesTracker getServicesTracker() { + return fServicesTracker; + } + + @Override + protected boolean checkUpdate(IViewerUpdate update) { + if (!super.checkUpdate(update)) return false; + + // Extract the VMC from the update (whatever the update sub-class. + Object element = update.getElement(); + if (element instanceof IDMVMContext) { + // If update element is a DMC, check if session is still alive. + IDMContext dmc = ((IDMVMContext)element).getDMContext(); + if (dmc.getSessionId() != getSession().getId() || !DsfSession.isSessionActive(dmc.getSessionId())) { + handleFailedUpdate(update); + return false; + } + } + return true; + } + + /** + * Convenience method that checks whether the given dmc context is null. If it is null, an + * appropriate error message is set in the update. + * @param dmc Data Model Context (DMC) to check. + * @param update Update to handle in case the DMC is null. + * @return true if the DMC is NOT null, indicating that it's OK to proceed. + */ + protected boolean checkDmc(IDMContext dmc, IViewerUpdate update) { + if (dmc == null) { + update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, + "No valid context found.", null)); //$NON-NLS-1$ + handleFailedUpdate(update); + return false; + } + return true; + } + + /** + * A convenience method that checks whether a given service exists. If the service does not + * exist, the update is filled in with the appropriate error message. + * @param serviceClass Service class to find. + * @param filter Service filter to use in addition to the service class name. + * @param update Update object to fill in. + * @return true if service IS found, indicating that it's OK to proceed. + */ + protected boolean checkService(Class serviceClass, String filter, IViewerUpdate update) { + if (getServicesTracker().getService(serviceClass, filter) == null) { + update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, + "Service " + serviceClass.getName() + " not available.", null)); //$NON-NLS-1$ //$NON-NLS-2$ + handleFailedUpdate(update); + return false; + } + return true; + } + + public void update(final IHasChildrenUpdate[] updates) { + try { + getSession().getExecutor().execute(new DsfRunnable() { + public void run() { + for (IHasChildrenUpdate update : updates) { + if (!checkUpdate(update)) continue; + updateHasElementsInSessionThread(update); + } + }}); + } catch (RejectedExecutionException e) { + for (IViewerUpdate update : updates) { + handleFailedUpdate(update); + } + } + } + + protected void updateHasElementsInSessionThread(final IHasChildrenUpdate update) { + update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.NOT_SUPPORTED, "Not implemented, clients should call to update all children instead.", null)); //$NON-NLS-1$ + update.done(); + } + + public void update(final IChildrenCountUpdate[] updates) { + try { + getSession().getExecutor().execute(new DsfRunnable() { + public void run() { + for (IChildrenCountUpdate update : updates) { + if (!checkUpdate(update)) continue; + updateElementCountInSessionThread(update); + } + }}); + } catch (RejectedExecutionException e) { + for (IViewerUpdate update : updates) { + handleFailedUpdate(update); + } + } + } + + protected void updateElementCountInSessionThread(final IChildrenCountUpdate update) { + update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.NOT_SUPPORTED, "Not implemented, clients should call to update all children instead.", null)); //$NON-NLS-1$ + update.done(); + } + + public void update(final IChildrenUpdate[] updates) { + try { + getSession().getExecutor().execute(new DsfRunnable() { + public void run() { + // After every dispatch, must check if update still valid. + for (IChildrenUpdate update : updates) { + if (!checkUpdate(update)) continue; + updateElementsInSessionThread(update); + } + }}); + } catch (RejectedExecutionException e) { + for (IViewerUpdate update : updates) { + handleFailedUpdate(update); + } + } + } + + abstract protected void updateElementsInSessionThread(IChildrenUpdate update); + + /** + * 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(IDMContext[] dmcs) { + IVMContext[] vmContexts = new IVMContext[dmcs.length]; + for (int i = 0; i < dmcs.length; i++) { + vmContexts[i] = createVMContext(dmcs[i]); + } + return vmContexts; + } + + protected void fillUpdateWithVMCs(IChildrenUpdate update, IDMContext[] dmcs) { + int startIdx = update.getOffset() != -1 ? update.getOffset() : 0; + int endIdx = update.getLength() != -1 ? startIdx + update.getLength() : dmcs.length; + // Ted: added bounds limitation of dmcs.length + // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=202109 + for (int i = startIdx; i < endIdx && i < dmcs.length; i++) { + update.setChild(createVMContext(dmcs[i]), i); + } + } + + protected IDMVMContext createVMContext(IDMContext dmc) { + return new DMVMContext(dmc); + } + + /** + * Searches for a DMC of given type in the tree patch contained in given + * VMC. Only a DMC in the same session will be returned. + * @param 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. + */ + public T findDmcInPath(Object inputObject, TreePath path, Class dmcType) { + T retVal = null; + for (int i = path.getSegmentCount() - 1; i >= 0; i--) { + if (path.getSegment(i) instanceof IDMVMContext) { + IDMContext dmc = ((IDMVMContext)path.getSegment(i)).getDMContext(); + if ( dmc.getSessionId().equals(getSession().getId()) ) { + retVal = DMContexts.getAncestorOfType(dmc, dmcType); + if (retVal != null) break; + } + } + } + // Search the root object of the layout hierarchy. + if (retVal == null) { + if (inputObject instanceof ITreeSelection) { + ITreeSelection inputSelection = (ITreeSelection)inputObject; + if (inputSelection.getPaths().length == 1) { + retVal = findDmcInPath(null, inputSelection.getPaths()[0], dmcType); + } + } else if (inputObject instanceof IStructuredSelection) { + Object rootElement = ((IStructuredSelection)inputObject).getFirstElement(); + if (rootElement instanceof IDMVMContext) { + retVal = DMContexts.getAncestorOfType(((IDMVMContext)rootElement).getDMContext(), dmcType); + } + } else if (inputObject instanceof IDMVMContext) { + retVal = DMContexts.getAncestorOfType(((IDMVMContext)inputObject).getDMContext(), dmcType); + } + } + + return retVal; + } +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProvider.java index 2391170d2db..dffba582f48 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProvider.java @@ -17,8 +17,8 @@ import org.eclipse.dd.dsf.datamodel.IDMEvent; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; -import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; -import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.IVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.update.AbstractCachingVMProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousContentAdapter; @@ -27,7 +27,7 @@ import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousLabelAdapt /** * 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 + * model provider functionality to the view model nodes that need * to be configured with each provider. *

    * The view model provider, often does not provide the model for the entire @@ -37,11 +37,11 @@ import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousLabelAdapt * @see IAsynchronousContentAdapter * @see IAsynchronousLabelAdapter * @see IModelProxy - * @see IVMLayoutNode + * @see IVMNode */ @ConfinedToDsfExecutor("fSession#getExecutor") @SuppressWarnings("restriction") -abstract public class AbstractDMVMProvider extends AbstractVMProvider +abstract public class AbstractDMVMProvider extends AbstractCachingVMProvider { private final DsfSession fSession; @@ -93,10 +93,8 @@ abstract public class AbstractDMVMProvider extends AbstractVMProvider super.dispose(); } - protected DsfSession getSession() { return fSession; } + public DsfSession getSession() { return fSession; } - - /** * Handle "data model changed" event by generating a delta object for each * view and passing it to the corresponding view model provider. The view @@ -106,8 +104,21 @@ abstract public class AbstractDMVMProvider extends AbstractVMProvider */ @DsfServiceEventHandler public void eventDispatched(final IDMEvent event) { + // We're in session's executor thread (session in which the event originated). + // Re-dispach to the view model provider executor thread and then call the + // model proxy strategy to handle the event. if (isDisposed()) return; - - handleEvent(event); + + try { + getExecutor().execute(new Runnable() { + public void run() { + if (isDisposed()) return; + handleEvent(event); + } + }); + } catch (RejectedExecutionException e) { + // Ignore. This exception could be thrown if the provider is being + // shut down. + } } } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProviderWithCache.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProviderWithCache.java deleted file mode 100644 index 09a13baf573..00000000000 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProviderWithCache.java +++ /dev/null @@ -1,74 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Ted R Williams (Wind River Systems, Inc.) - initial implementation - *******************************************************************************/ - -package org.eclipse.dd.dsf.ui.viewmodel.dm; - -import org.eclipse.dd.dsf.datamodel.IDMEvent; -import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; -import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; -import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; -import org.eclipse.dd.dsf.service.DsfServiceEventHandler; - -@SuppressWarnings("restriction") -public abstract class AbstractDMVMProviderWithCache extends AbstractDMVMProvider - implements VMCacheManager.CacheListener -{ - @DsfServiceEventHandler - @Override - public void eventDispatched(IDMEvent event) { - VMCacheManager.getVMCacheManager().getCache(getPresentationContext()).handleEvent(event); - super.eventDispatched(event); - } - - @SuppressWarnings("restriction") - public void cacheFlushed(Object context) { - if(getPresentationContext().equals(context)) - getModelProxy().fireModelChanged(new ModelDelta(getRootElement(),IModelDelta.CONTENT)); - } - - public AbstractDMVMProviderWithCache(AbstractVMAdapter adapter, IPresentationContext presentationContext, DsfSession session) { - super(adapter, presentationContext, session); - - VMCacheManager.getVMCacheManager().addCacheListener(getPresentationContext(), this); - } - - public void flush() { - VMCacheManager.getVMCacheManager().flush(getPresentationContext()); - } - - @Override - public void update(IHasChildrenUpdate[] updates) { - super.update(VMCacheManager.getVMCacheManager().getCache(getPresentationContext()).update(updates)); - } - - @Override - public void update(IChildrenCountUpdate[] updates) { - super.update(VMCacheManager.getVMCacheManager().getCache(getPresentationContext()).update(updates)); - } - - @Override - public void update(final IChildrenUpdate[] updates) { - super.update(VMCacheManager.getVMCacheManager().getCache(getPresentationContext()).update(updates)); - } - - @Override - public void dispose() - { - VMCacheManager.getVMCacheManager().removeCacheListener(getPresentationContext(), this); - super.dispose(); - } -} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/CompositeDMVMContext.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/CompositeDMVMContext.java index dce32ee6f0a..e763f86ae94 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/CompositeDMVMContext.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/CompositeDMVMContext.java @@ -13,9 +13,9 @@ package org.eclipse.dd.dsf.ui.viewmodel.dm; import java.util.ArrayList; import java.util.List; -import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.CompositeDMContext; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode.DMVMContext; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; import org.eclipse.jface.viewers.TreePath; /** @@ -23,6 +23,7 @@ import org.eclipse.jface.viewers.TreePath; * update. This object allows the view model to pass complete data model context * information found in the view to the services. */ +@SuppressWarnings("restriction") public class CompositeDMVMContext extends CompositeDMContext { /** @@ -37,19 +38,26 @@ public class CompositeDMVMContext extends CompositeDMContext { */ private IDMContext[] fParents; + /** + * Creates a composite context based in a viewer update. + */ + public CompositeDMVMContext(IViewerUpdate update) { + this(update.getViewerInput(), update.getElementPath()); + } + /** - * Creates a composite context based on view model + * Creates a composite context based on a viewer input and a tree path. */ public CompositeDMVMContext(Object viewerInputObject, TreePath treePath) { super(EMPTY_CONTEXTS_ARRAY); List parentsList = new ArrayList(treePath.getSegmentCount() + 1); for (int i = treePath.getSegmentCount() - 1; i >=0 ; i--) { - if (treePath.getSegment(i) instanceof DMVMContext) { - parentsList.add( ((DMVMContext)treePath.getSegment(i)).getDMC() ); + if (treePath.getSegment(i) instanceof IDMVMContext) { + parentsList.add( ((IDMVMContext)treePath.getSegment(i)).getDMContext() ); } } - if (viewerInputObject instanceof DMVMContext) { - parentsList.add( ((DMVMContext)viewerInputObject).getDMC() ); + if (viewerInputObject instanceof IDMVMContext) { + parentsList.add( ((IDMVMContext)viewerInputObject).getDMContext() ); } fParents = parentsList.toArray(new IDMContext[parentsList.size()]); diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionVMContext.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/IDMVMContext.java similarity index 59% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionVMContext.java rename to plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/IDMVMContext.java index 73d6a53f155..56e9a145111 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionVMContext.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/IDMVMContext.java @@ -8,12 +8,20 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; +package org.eclipse.dd.dsf.ui.viewmodel.dm; +import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; /** - * + * Interface for a view model context based on a DSF data model context. */ -public interface IExpressionVMContext extends IVMContext { +public interface IDMVMContext extends IVMContext { + + public static Object REFRESH_EVENT = new Object(); + + /** + * returns the data model context that this view model context wraps. + */ + public IDMContext getDMContext(); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/DMVMRootLayoutNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/RootDMVMNode.java similarity index 59% rename from plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/DMVMRootLayoutNode.java rename to plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/RootDMVMNode.java index c04df1f6002..82f7282abc2 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/DMVMRootLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/RootDMVMNode.java @@ -14,10 +14,8 @@ 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.AbstractVMProvider; -import org.eclipse.dd.dsf.ui.viewmodel.VMRootLayoutNode; -import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode.DMVMContext; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.dd.dsf.ui.viewmodel.IRootVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.RootVMNode; /** * This is is a standard root node which listens to the selection in Debug View. @@ -30,11 +28,10 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; * node also has to use the first element as the root object instead of the * whole selection. */ -@SuppressWarnings("restriction") -public class DMVMRootLayoutNode extends VMRootLayoutNode - implements IVMRootLayoutNode +public class RootDMVMNode extends RootVMNode + implements IRootVMNode { - public DMVMRootLayoutNode(AbstractVMProvider provider) { + public RootDMVMNode(AbstractVMProvider provider) { super(provider); } @@ -60,39 +57,30 @@ public class DMVMRootLayoutNode extends VMRootLayoutNode * determine whether a delta is needed. */ @Override - public int getDeltaFlags(Object event) { - IDMContext inputDmc = getSelectedDMC(); - if (event instanceof IDMEvent && inputDmc != null) { - boolean potentialMatchFound = false; - boolean matchFound = false; - - IDMContext eventDmc = ((IDMEvent)event).getDMContext(); - for (IDMContext eventDmcAncestor : DMContexts.toList(eventDmc)) { - IDMContext inputDmcAncestor = DMContexts.getAncestorOfType(inputDmc, eventDmcAncestor.getClass()); - if (inputDmcAncestor != null) { - potentialMatchFound = true; - if (inputDmcAncestor.equals(eventDmcAncestor)) { - return super.getDeltaFlags(event); + public boolean isDeltaEvent(Object rootObject, Object event) { + if (rootObject instanceof IDMVMContext) { + IDMContext inputDmc = ((IDMVMContext)rootObject).getDMContext(); + if (event instanceof IDMEvent && inputDmc != null) { + boolean potentialMatchFound = false; + boolean matchFound = false; + + IDMContext eventDmc = ((IDMEvent)event).getDMContext(); + for (IDMContext eventDmcAncestor : DMContexts.toList(eventDmc)) { + IDMContext inputDmcAncestor = DMContexts.getAncestorOfType(inputDmc, eventDmcAncestor.getClass()); + if (inputDmcAncestor != null) { + potentialMatchFound = true; + if (inputDmcAncestor.equals(eventDmcAncestor)) { + return true; + } } } - } - if (potentialMatchFound && !matchFound) { - return IModelDelta.NO_CHANGE; + if (potentialMatchFound && !matchFound) { + return false; + } } } - - return super.getDeltaFlags(event); - } - - private IDMContext getSelectedDMC() { - Object rootObject = getVMProvider().getRootElement(); - if (rootObject instanceof DMVMContext) - { - // Correct cast: (AbstractDMVMLayoutNode.DMVMContext) breaks the javac compiler - @SuppressWarnings("unchecked") - DMVMContext vmc = (DMVMContext)rootObject; - return vmc.getDMC(); - } - return null; + + return true; } + } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/IPropertiesUpdate.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/IPropertiesUpdate.java index c81586edba4..410c14d7744 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/IPropertiesUpdate.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/IPropertiesUpdate.java @@ -5,6 +5,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; /** * Context sensitive properties update request for an element. */ +@SuppressWarnings("restriction") public interface IPropertiesUpdate extends IViewerUpdate { /** * Returns the list of element properties that the provider should set. diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelText.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelText.java index 298eec8d851..03ed11d12d6 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelText.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelText.java @@ -31,7 +31,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; @SuppressWarnings("restriction") public class LabelText extends LabelAttribute { - public static final MessageFormat DEFAULT_MESSAGE = new MessageFormat(""); + public static final MessageFormat DEFAULT_MESSAGE = new MessageFormat(MessagesForProperties.DefaultLabelMessage_label); /** * Message format used to generate the label text. diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/MessagesForProperties.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/MessagesForProperties.java new file mode 100644 index 00000000000..1ce21b75a8c --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/MessagesForProperties.java @@ -0,0 +1,17 @@ +package org.eclipse.dd.dsf.ui.viewmodel.properties; + +import org.eclipse.osgi.util.NLS; + +class MessagesForProperties extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.dd.dsf.ui.viewmodel.properties.messages"; //$NON-NLS-1$ + + public static String DefaultLabelMessage_label; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, MessagesForProperties.class); + } + + private MessagesForProperties() { + } +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/PropertyBasedLabelProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/PropertyBasedLabelProvider.java index f13ccd36c18..00a200ddf30 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/PropertyBasedLabelProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/PropertyBasedLabelProvider.java @@ -77,7 +77,7 @@ public class PropertyBasedLabelProvider @Override public void done() { @SuppressWarnings("unchecked") - DataRequestMonitor> rm = (DataRequestMonitor>)fRequestMonitor; + DataRequestMonitor> rm = (DataRequestMonitor>)getRequestMonitor(); if (fProperties == null || fValues.size() >= fProperties.length) { rm.setData(fValues); } else { diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/messages.properties b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/messages.properties new file mode 100644 index 00000000000..c543eab93b4 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/messages.properties @@ -0,0 +1 @@ +DefaultLabelMessage_label= diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java new file mode 100644 index 00000000000..5c5fa52eba4 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java @@ -0,0 +1,761 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel.update; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Executor; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +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.ui.concurrent.ViewerCountingRequestMonitor; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.IVMModelProxy; +import org.eclipse.dd.dsf.ui.viewmodel.IVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.VMChildrenCountUpdate; +import org.eclipse.dd.dsf.ui.viewmodel.VMChildrenUpdate; +import org.eclipse.dd.dsf.ui.viewmodel.VMHasChildrenUpdate; +import org.eclipse.dd.dsf.ui.viewmodel.properties.IElementPropertiesProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; +import org.eclipse.jface.viewers.TreePath; + +/** + * Base implementation of a caching view model provider. + */ +@SuppressWarnings("restriction") +public class AbstractCachingVMProvider extends AbstractVMProvider implements ICachingVMProvider { + + private static final int MAX_CACHE_SIZE = 1000; + + /** + * Class representing a key to an element's data in the cache. The main + * components of this key are the viewer input and the path, they uniquely + * identify an element. The root element is used to track when a given + * root element is no longer in the cache and can therefore be disposed. + * The node is needed because different nodes have different lists of + * children for the same parent element. + */ + private static class ElementDataKey { + ElementDataKey(Object rootElement, IVMNode node, Object viewerInput, TreePath path) { + fRootElement = rootElement; + fNode = node; + fViewerInput = viewerInput; + fPath = path; + } + + final Object fRootElement; + final IVMNode fNode; + final Object fViewerInput; + final TreePath fPath; + + @Override + public String toString() { + return fViewerInput + "." + fPath.toString() + "(" + fNode + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof ElementDataKey)) return false; + ElementDataKey key = (ElementDataKey)obj; + return + (fNode == null && key.fNode == null || (fNode != null && fNode.equals(key.fNode))) && + (fRootElement == null && key.fRootElement == null || (fRootElement != null && fRootElement.equals(key.fRootElement))) && + (fViewerInput == null && key.fViewerInput == null || (fViewerInput != null && fViewerInput.equals(key.fViewerInput))) && + (fPath == null && key.fPath == null || (fPath != null && fPath.equals(key.fPath))); + } + + @Override + public int hashCode() { + return + (fRootElement != null ? fRootElement.hashCode() : 0) + + (fNode != null ? fNode.hashCode() : 0) + + (fViewerInput != null ? fViewerInput.hashCode() : 0) + + (fPath != null ? fPath.hashCode() : 0); + } + } + + /** + * A base calss for the entry in the cache. Since the cache maintains + * a double-linked list through all the entries, the linked list references + * are maintained in this class. + */ + private static class Entry { + final Object fKey; + + Entry fNext; + Entry fPrevious; + + Entry(Object key) { + fKey = key; + } + + void insert(Entry nextEntry) { + fNext = nextEntry; + fPrevious = nextEntry.fPrevious; + fPrevious.fNext = this; + fNext.fPrevious = this; + } + + void remove() { + fPrevious.fNext = fNext; + fNext.fPrevious = fPrevious; + } + } + + /** + * Entry with cached element data. + */ + static class ElementDataEntry extends Entry { + ElementDataEntry(ElementDataKey key) { + super(key); + } + + Boolean fDirty = false; + Boolean fHasChildren = null; + Integer fChildrenCount = null; + boolean fAllChildrenKnown = false; + Map fChildren = null; + Map fDataOrStatus = new HashMap(1); + Map fArchiveData = new HashMap(1);; + + @Override + public String toString() { + return fKey.toString() + " = " + //$NON-NLS-1$ + "[hasChildren=" + fHasChildren + ", " +//$NON-NLS-1$ //$NON-NLS-2$ + "childrenCount=" + fChildrenCount + //$NON-NLS-1$ + ", children=" + fChildren + //$NON-NLS-1$ + ", data/status=" + fDataOrStatus + //$NON-NLS-1$ + ", oldData=" + fArchiveData + "]"; //$NON-NLS-1$ //$NON-NLS-2$ + } + } + + /** + * A key for a special marker entry in the cache. This marker entry is used + * to optimize repeated flushing of the cache. + * @see AbstractCachingVMProvider#flush(List) + */ + private static class FlushMarkerKey { + private Object fRootElement; + private IElementUpdateTester fElementTester; + + FlushMarkerKey(Object rootElement, IElementUpdateTester pathTester) { + fRootElement = rootElement; + fElementTester = pathTester; + } + + boolean includes(FlushMarkerKey key) { + return fRootElement.equals(key.fRootElement) && + fElementTester.includes(key.fElementTester); + } + + int getUpdateFlags(ElementDataKey key) { + if (fRootElement.equals(key.fRootElement)) { + return fElementTester.getUpdateFlags(key.fViewerInput, key.fPath); + } + return 0; + } + } + + /** + * Marker used to keep track of whether any entries with the given + * root element are present in the cache. + */ + private static class RootElementMarkerKey { + + private Object fRootElement; + + RootElementMarkerKey(Object rootElement) { + fRootElement = rootElement; + } + } + + class RootElementMarkerEntry extends Entry { + RootElementMarkerEntry(RootElementMarkerKey key) { + super(key); + } + + @Override + void remove() { + super.remove(); + rootElementRemovedFromCache(((RootElementMarkerKey)fKey).fRootElement); + } + } + + protected static String SELECTED_UPDATE_MODE = "org.eclipse.dd.dsf.ui.viewmodel.update.selectedUpdateMode"; //$NON-NLS-1$ + + private IVMUpdatePolicy fCurrentUpdatePolicy; + + private IVMUpdatePolicy[] fAvailableUpdatePolicies; + + public Map fRootMarkers = new HashMap(); + + /** + * Hash map holding cache data. To store the cache information, the cache uses a + * combination of this hash map and a double-linked list running through all + * the entries in the cache. The linked list is used to organize the cache entries + * in least recently used (LRU) order. This ordering is then used to delete least + * recently used entries in the cache and keep the cache from growing indefinitely. + * Also, the ordering is used to optimize the flushing of the cache data (see + * {@link FlushMarkerKey} for more details). + */ + private final Map fCacheData = new HashMap(200, 0.75f); + + /** + * Pointer to the first cache entry in the double-linked list of cache entries. + */ + private final Entry fCacheListHead; + + + public AbstractCachingVMProvider(AbstractVMAdapter adapter, IPresentationContext presentationContext) { + super(adapter, presentationContext); + + fCacheListHead = new Entry(null); + fCacheListHead.fNext = fCacheListHead; + fCacheListHead.fPrevious = fCacheListHead; + + String updateModeId = (String)presentationContext.getProperty(SELECTED_UPDATE_MODE); + if (updateModeId != null) { + for (IVMUpdatePolicy updateMode : getAvailableUpdatePolicies()) { + if (updateMode.getID().equals(updateModeId)) { + fCurrentUpdatePolicy = updateMode; + } + } + } + + fAvailableUpdatePolicies = createUpdateModes(); + fCurrentUpdatePolicy = fAvailableUpdatePolicies[0]; + } + + protected IVMUpdatePolicy[] createUpdateModes() { + return new IVMUpdatePolicy[] { new AutomaticUpdatePolicy() }; + } + + public IVMUpdatePolicy[] getAvailableUpdatePolicies() { + return fAvailableUpdatePolicies; + } + + public IVMUpdatePolicy getActiveUpdatePolicy() { + return fCurrentUpdatePolicy; + } + + public void setActiveUpdatePolicy(IVMUpdatePolicy updatePolicy) { + fCurrentUpdatePolicy = updatePolicy; + } + + public void refresh() { + IElementUpdateTester elementTester = getActiveUpdatePolicy().getTesterTester(ManualUpdatePolicy.REFRESH_EVENT); + + List flushKeys = new LinkedList(); + + for (final IVMModelProxy proxyStrategy : getActiveModelProxies()) { + flushKeys.add(new FlushMarkerKey(proxyStrategy.getRootElement(), elementTester)); + } + + flush(flushKeys); + + for (final IVMModelProxy proxyStrategy : getActiveModelProxies()) { + if (!proxyStrategy.isDisposed()) { + proxyStrategy.fireModelChanged(new ModelDelta(proxyStrategy.getRootElement(), IModelDelta.CONTENT)); + } + } + } + + @Override + protected void updateNode(IVMNode node, IHasChildrenUpdate[] updates) { + LinkedList missUpdates = new LinkedList(); + for(final IHasChildrenUpdate update : updates) { + ElementDataKey key = makeEntryKey(node, update); + final ElementDataEntry entry = getElementDataEntry(key); + if (entry.fHasChildren != null) { + update.setHasChilren(entry.fHasChildren.booleanValue()); + update.done(); + } else { + missUpdates.add( + new VMHasChildrenUpdate(update, new DataRequestMonitor(getExecutor(), null) { + @Override + protected void handleCompleted() { + if(getStatus().isOK()) { + entry.fHasChildren = this.getData(); + update.setHasChilren(getData()); + } + update.done(); + } + })); + } + } + + if (!missUpdates.isEmpty()) { + super.updateNode(node, missUpdates.toArray(new IHasChildrenUpdate[missUpdates.size()])); + } + } + + @Override + protected void updateNode(IVMNode node, IChildrenCountUpdate[] updates) { + // Given our knowledge of DefaultVMContentProviderStragety, make an + // assumption about the updates argument: there should always be + // exactly one update in this array. + assert updates.length == 1; + final IChildrenCountUpdate update = updates[0]; + + ElementDataKey key = makeEntryKey(node, update); + final ElementDataEntry entry = getElementDataEntry(key); + if(entry.fChildrenCount != null) { + update.setChildCount(entry.fChildrenCount.intValue()); + update.done(); + } else { + updates[0] = new VMChildrenCountUpdate(update, new DataRequestMonitor(getExecutor(), null) { + @Override + protected void handleCompleted() { + if(getStatus().isOK()) { + entry.fChildrenCount = this.getData(); + update.setChildCount(getData()); + } + update.done(); + } + }); + super.updateNode(node, updates); + } + } + + @Override + protected void updateNode(IVMNode node, IChildrenUpdate[] updates) { + // Given our knowledge of DefaultVMContentProviderStragety, make an + // assumption about the updates argument: there should always be + // exactly one update in this array. + assert updates.length == 1; + final IChildrenUpdate update = updates[0]; + + ElementDataKey key = makeEntryKey(node, update); + + final ElementDataEntry entry = getElementDataEntry(key); + if (entry.fChildren == null || (update.getOffset() < 0 && !entry.fAllChildrenKnown)) { + // We need to retrieve all the children if we don't have any children information. + // Or if the client requested all children (offset = -1, length -1) and we have not + // retrieved that before. + updates[0] = new VMChildrenUpdate( + update, update.getOffset(), update.getLength(), + new DataRequestMonitor>(getExecutor(), null) + { + @Override + protected void handleCompleted() + { + if(getData() != null) { + // Check if the udpate retrieved all children by specifying "offset = -1, length = -1" + int updateOffset = update.getOffset(); + if (updateOffset < 0) { + updateOffset = 0; + entry.fAllChildrenKnown = true; + } + + // Estimate size of children map. + Integer childrenCount = entry.fChildrenCount; + childrenCount = childrenCount != null ? childrenCount : 0; + int capacity = Math.max((childrenCount.intValue() * 4)/3, 32); + // Create a new map, but only if it hasn't been created yet by another update. + if (entry.fChildren == null) { + entry.fChildren = new HashMap(capacity); + } + + // Set the children to map and update. + for(int j = 0; j < getData().size(); j++) { + int offset = updateOffset + j; + Object child = getData().get(j); + + entry.fChildren.put(offset, child); + update.setChild(child, offset); + } + } + update.done(); + } + }); + super.updateNode(node, updates); + } else if (update.getOffset() < 0 ) { + // The udpate requested all children. Fill in all children assuming that + // the children array is complete. + + // The following assert should never fail given the first if statement. + assert entry.fAllChildrenKnown; + + // we have all of the children in cache; return from cache + for(int position = 0; position < entry.fChildren.size(); position++) { + update.setChild(entry.fChildren.get(position), position); + } + update.done(); + } else { + // Make the list of missing children. If we've retrieved the + List childrenMissingFromCache = new LinkedList(); + for (int i = update.getOffset(); i < update.getOffset() + update.getLength(); i++) { + childrenMissingFromCache.add(i); + } + childrenMissingFromCache.removeAll(entry.fChildren.keySet()); + + if (childrenMissingFromCache.size() > 0) { + // perform a partial update; we only have some of the children of the update request + + List partialUpdates = new ArrayList(2); + + final CountingRequestMonitor multiRm = new ViewerCountingRequestMonitor(getExecutor(), update); + + while(childrenMissingFromCache.size() > 0) + { + final int offset = childrenMissingFromCache.get(0); + childrenMissingFromCache.remove(0); + int length = 1; + while(childrenMissingFromCache.size() > 0 && childrenMissingFromCache.get(0) == offset + length) + { + length++; + childrenMissingFromCache.remove(0); + } + + partialUpdates.add(new VMChildrenUpdate( + update, offset, length, + new DataRequestMonitor>(getExecutor(), multiRm) { + @Override + protected void handleCompleted() { + if (getData() != null) { + for (int i = 0; i < getData().size(); i++) { + update.setChild(getData().get(i), offset + i); + } + } + multiRm.done(); + } + })); + } + + super.updateNode( node, partialUpdates.toArray(new IChildrenUpdate[partialUpdates.size()]) ); + multiRm.setDoneCount(partialUpdates.size()); + } else { + // we have all of the children in cache; return from cache + for(int position = update.getOffset(); position < update.getOffset() + update.getLength(); position++) { + update.setChild(entry.fChildren.get(position), position); + } + update.done(); + } + } + + } + + /** + * Flushes the cache with given DMC as the root element. + * @param dmcToFlush DM Context which is the root of the flush operation. Entries + * for all DMCs that have this DMC as their ancestor will be flushed. If this + * parameter is null, then all entries are flushed. + * @param archive + */ + private void flush(List flushKeys) { + // To flush the cache data for given context, we have to iterate through all the contexts + // in cache. For each entry that has the given context as a parent, perform the flush. + List flushKeysCopy = new ArrayList(flushKeys.size()); + flushKeysCopy.addAll(flushKeys); + + // Iterate through the cache entries backwards. This means that we will be + // iterating in order of most-recently-used to least-recently-used. + Entry entry = fCacheListHead.fPrevious; + while (entry != fCacheListHead && flushKeysCopy.size() != 0) { + for (Iterator flushKeyItr = flushKeysCopy.iterator(); flushKeyItr.hasNext();) { + FlushMarkerKey flushKey = flushKeyItr.next(); + + if (entry.fKey instanceof FlushMarkerKey) { + FlushMarkerKey entryFlushKey = (FlushMarkerKey)entry.fKey; + // If the context currently being flushed includes the flush + // context in current entry, remove the current entry since it will + // be replaced with one at the end of the list. + // Use special handling for null contexts, which we treat like it's an + // ancestor of all other contexts. + if (flushKey.includes(entryFlushKey)) { + fCacheData.remove(entryFlushKey); + entry.remove(); + } + + // If the flush context in current entry includes the current context + // being flushed, we can stop iterating through the cache entries + // now. + if (entryFlushKey.includes(flushKey)) { + flushKeyItr.remove(); + } + } + else if (entry instanceof ElementDataEntry) { + ElementDataEntry elementDataEntry = (ElementDataEntry)entry; + int updateFlags = flushKey.getUpdateFlags((ElementDataKey)elementDataEntry.fKey); + if ((updateFlags & IVMUpdatePolicy.FLUSH) != 0) { + if ((updateFlags & IVMUpdatePolicy.ARCHIVE) != 0) { + // We are saving current data for change history, check if the data is valid. + // If it valid, save it for archive, if it's not valid old archive data will be used + // if there is any. And if there is no old archive data, just remove the cache entry. + for (Iterator> itr = elementDataEntry.fDataOrStatus.entrySet().iterator(); + itr.hasNext();) + { + Map.Entry dataOrStatusEntry = itr.next(); + if (dataOrStatusEntry.getValue() instanceof IDMData) { + elementDataEntry.fArchiveData.put(dataOrStatusEntry.getKey(), (IDMData)dataOrStatusEntry.getValue()); + } + } + elementDataEntry.fDataOrStatus.clear(); + if (elementDataEntry.fArchiveData.isEmpty()) { + fCacheData.remove(entry.fKey); + entry.remove(); + } + } else { + // We are not changing the archived data. If archive data exists in the entry, leave it. + // Otherwise remove the whole entry. + if (!elementDataEntry.fArchiveData.isEmpty()) { + elementDataEntry.fDataOrStatus.clear(); + } else { + fCacheData.remove(entry.fKey); + entry.remove(); + } + } + elementDataEntry.fHasChildren = null; + elementDataEntry.fChildrenCount = null; + elementDataEntry.fChildren = null; + } else if ((updateFlags & IVMUpdatePolicy.DIRTY) != 0) { + elementDataEntry.fDirty = true; + } + } + } + entry = entry.fPrevious; + } + + for (FlushMarkerKey flushKey : flushKeys) { + // Insert a marker for this flush operation. + Entry flushMarkerEntry = new Entry(flushKey); + fCacheData.put(flushKey, flushMarkerEntry); + flushMarkerEntry.insert(fCacheListHead); + } + } + + + + + @Override + public void handleEvent(final Object event) { + IElementUpdateTester elementTester = getActiveUpdatePolicy().getTesterTester(event); + + List flushKeys = new LinkedList(); + List proxies = new LinkedList(); + + for (final IVMModelProxy proxyStrategy : getActiveModelProxies()) { + if (proxyStrategy.isDeltaEvent(event)) { + flushKeys.add(new FlushMarkerKey(proxyStrategy.getRootElement(), elementTester)); + proxies.add(proxyStrategy); + } + } + + flush(flushKeys); + + for (final IVMModelProxy proxyStrategy : proxies) { + if (!proxyStrategy.isDisposed() && proxyStrategy.isDeltaEvent(event)) { + proxyStrategy.createDelta( + event, + new DataRequestMonitor(getExecutor(), null) { + @Override + public void handleCompleted() { + + if (getStatus().isOK()) { + proxyStrategy.fireModelChanged(getData()); + } + } + @Override public String toString() { + return "Result of a delta for event: '" + event.toString() + "' in VMP: '" + this + "'" + "\n" + getData().toString(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } + }); + } + } + } + + /** + * Override default implementation to avoid automatically removing disposed proxies from + * list of active proxies. The caching provider only removes a proxy after its root element + * is no longer in the cache. + */ + @Override + public IModelProxy createModelProxy(Object element, IPresentationContext context) { + assert getExecutor().isInExecutorThread(); + + // Iterate through the current active proxies to try to find a proxy with the same + // element and re-use it if found. At the same time purge proxies that are no longer + IVMModelProxy proxy = null; + for (Iterator itr = getActiveModelProxies().iterator(); itr.hasNext();) { + IVMModelProxy next = itr.next(); + if (next == null && next.getRootElement().equals(element)) { + proxy = next; + } + } + if (proxy == null) { + proxy = createModelProxyStrategy(element); + getActiveModelProxies().add(proxy); + } + return proxy; + } + + + /** + * Called when a given all cache entries for the given root element have + * been removed from the cache. In order to property track changed elements, + * the caching VM provider does not immediately remove entries for a given root + * element, when the viewer root element changes. Instead it keeps this root + * element and keeps processing deltas for that root element until the + * cache entries for this element are gone. + */ + protected void rootElementRemovedFromCache(Object rootElement) { + fRootMarkers.remove(rootElement); + + for (Iterator proxiesItr = getActiveModelProxies().iterator(); proxiesItr.hasNext();) { + IVMModelProxy proxy = proxiesItr.next(); + if (proxy.isDisposed() && proxy.getRootElement().equals(rootElement) ) { + proxiesItr.remove(); + } + } + } + + /** + * Convenience class that searches for teh root element for the given + * update and creates an element cache entry key. + */ + private ElementDataKey makeEntryKey(IVMNode node, IViewerUpdate update) { + Object rootElement = update.getViewerInput(); // Default + outer: for (IVMModelProxy proxy : getActiveModelProxies()) { + Object proxyRoot = proxy.getRootElement(); + if (proxyRoot.equals(update.getViewerInput())) { + rootElement = proxyRoot; + break; + } + TreePath path = update.getElementPath(); + for (int i = 0; i < path.getSegmentCount(); i++) { + if (proxyRoot.equals(path.getSegment(i))) { + rootElement = proxyRoot; + break outer; + } + } + } + + return new ElementDataKey(rootElement, node, update.getElement(), update.getElementPath()); + } + + /** + * This is the only method that should be used to access a cache entry. + * It creates a new entry if needed and it maintains the ordering in + * the least-recently-used linked list. + */ + private ElementDataEntry getElementDataEntry(ElementDataKey key) { + assert key != null; + ElementDataEntry entry = (ElementDataEntry)fCacheData.get(key); + if (entry == null) { + // Create a new entry and add it to the end of the list. + entry = new ElementDataEntry(key); + addEntry(key, entry); + } else { + // Entry exists, move it to the end of the list. + entry.remove(); + entry.insert(fCacheListHead); + } + + // Update they root element marker. + RootElementMarkerKey rootMarker = fRootMarkers.get(key.fRootElement); + if (rootMarker == null) { + rootMarker = new RootElementMarkerKey(key.fRootElement); + fRootMarkers.put(key.fRootElement, rootMarker); + } + Entry rootMarkerEntry = fCacheData.get(rootMarker); + if (rootMarkerEntry == null) { + rootMarkerEntry = new RootElementMarkerEntry(rootMarker); + addEntry(rootMarker, rootMarkerEntry); + } else { + rootMarkerEntry.remove(); + rootMarkerEntry.insert(fCacheListHead); + } + + return entry; + } + + /** + * Convenience method used by {@link #getElementDataEntry(ElementDataKey)} + */ + private void addEntry(Object key, Entry entry) { + fCacheData.put(key, entry); + entry.insert(fCacheListHead); + // If we are at capacity in the cache, remove the entry from head. + if (fCacheData.size() > MAX_CACHE_SIZE) { + fCacheData.remove(fCacheListHead.fNext.fKey); + fCacheListHead.fNext.remove(); + } + } + + /** + * Retrieves the deprecated IDMData object for the given IDMContext. This + * method should be removed once the use of IDMData is replaced with + * {@link IElementPropertiesProvider}. + */ + @Deprecated + public void getModelData(IVMNode node, IViewerUpdate update, IDMService service, final IDMContext dmc, + final DataRequestMonitor rm, Executor executor) + { + ElementDataKey key = makeEntryKey(node, update); + final ElementDataEntry entry = getElementDataEntry(key); + Object dataOrStatus = entry.fDataOrStatus.get(dmc); + if(dataOrStatus != null) { + if (dataOrStatus instanceof IDMData) { + rm.setData( (IDMData)dataOrStatus ); + } else { + rm.setStatus((IStatus)dataOrStatus ); + } + rm.done(); + } else { + service.getModelData(dmc, + new DataRequestMonitor(executor, rm) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + entry.fDataOrStatus.put(dmc, getData()); + rm.setData(getData()); + } else { + entry.fDataOrStatus.put(dmc, getStatus()); + rm.setStatus(getStatus()); + } + rm.done(); + } + } + ); + } + } + + /** + * Retrieves the deprecated IDMData object for the given IDMContext. This + * method should be removed once the use of IDMData is replaced with + * {@link IElementPropertiesProvider}. + */ + @Deprecated + public IDMData getArchivedModelData(IVMNode node, IViewerUpdate update, IDMContext dmc) { + ElementDataKey key = makeEntryKey(node, update); + final ElementDataEntry entry = getElementDataEntry(key); + if ( entry.fArchiveData != null) { + return entry.fArchiveData.get(dmc); + } + return null; + } + +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AutomaticUpdatePolicy.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AutomaticUpdatePolicy.java new file mode 100644 index 00000000000..7d75fcc589f --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AutomaticUpdatePolicy.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel.update; + +import org.eclipse.jface.viewers.TreePath; + +/** + * An "automatic" update policy which causes the view model provider cache to + * be flushed whenever an event causes a delta to be generated in the given + * model. + */ +public class AutomaticUpdatePolicy implements IVMUpdatePolicy { + + public static String AUTOMATIC_UPDATE_POLICY_ID = "org.eclipse.dd.dsf.ui.viewmodel.update.defaultUpdatePolicy"; //$NON-NLS-1$ + + public static IElementUpdateTester fgUpdateTester = new IElementUpdateTester() { + public int getUpdateFlags(Object viewerInput, TreePath path) { + return FLUSH | ARCHIVE; + } + + public boolean includes(IElementUpdateTester tester) { + return tester.equals(this); + } + }; + + public String getID() { + return AUTOMATIC_UPDATE_POLICY_ID; + } + + public String getName() { + return "Automatic"; + } + + public IElementUpdateTester getTesterTester(Object event) { + return fgUpdateTester; + } +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/ICachingVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/ICachingVMProvider.java new file mode 100644 index 00000000000..2a7825fba65 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/ICachingVMProvider.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel.update; + +import org.eclipse.dd.dsf.ui.viewmodel.IVMProvider; + +/** + * A view model provider which supports caching of data returned by view model + * nodes. The methods in this interface allow clients to configure how the + * cache should be updated in response to different events. + */ +public interface ICachingVMProvider extends IVMProvider { + + /** + * Returns the update policies that the given provider supports. + */ + public IVMUpdatePolicy[] getAvailableUpdatePolicies(); + + /** + * Returns the active update policy. + */ + public IVMUpdatePolicy getActiveUpdatePolicy(); + + /** + * Sets the active update policy. This has to be one of the update + * policies supported by the provider. + */ + public void setActiveUpdatePolicy(IVMUpdatePolicy mode); + + /** + * Forces the view to flush its cache and re-fetch data from the view + * model nodes. + */ + public void refresh(); + +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/IElementUpdateTester.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/IElementUpdateTester.java new file mode 100644 index 00000000000..45a401277c9 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/IElementUpdateTester.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel.update; + +import org.eclipse.jface.viewers.TreePath; + +/** + * Tester object used to determine how individual update cache + * entries should be updated during a flush operation. + * + * @see IVMUpdatePolicy + */ +public interface IElementUpdateTester { + + /** + * Returns the flags indicating what updates should be performed on the + * cache entry of the given element. + */ + public int getUpdateFlags(Object viewerInput, TreePath path); + + /** + * Returns whether update represented by this tester includes another + * update. For example if update A was created as a result of an element X, + * and update B was created for an element Y, and element X is a parent of + * element Y, then tester A should include tester B. Also a tester should + * always include itself. + *

    + * This method is used to optimize the repeated flushing of the cache as + * it allows the cache to avoid needlessly updating the same cache entries. + */ + public boolean includes(IElementUpdateTester tester); + +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/IVMUpdatePolicy.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/IVMUpdatePolicy.java new file mode 100644 index 00000000000..cc83d4f0db7 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/IVMUpdatePolicy.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel.update; + + +/** + * Interface for an update policy. The main function of an update policy is + * to create an element tester for each given event. The element tester + * is then used to update the viewer cache. + */ +public interface IVMUpdatePolicy { + + /** + * Flag indicating that a given entry in the cache should be cleared. + */ + public static int FLUSH = 0x1; + + /** + * Flag indicating that a given entry in the cache should be cleared + * and saved for purpose of change tracking. + */ + public static int ARCHIVE = FLUSH | 0x2; // Flush is required when archiving. + + /** + * Flag indicating that the a given cache entry should be marked as dirty. + * A dirty cache entry is one that is known not to be consistent with + * target data. + */ + public static int DIRTY = 0x4; + + /** + * Returns unique ID of this update policy. + */ + public String getID(); + + /** + * Returns the user-presentable name of this update policy. + */ + public String getName(); + + /** + * Creates an element tester for the given event. + */ + public IElementUpdateTester getTesterTester(Object event); +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/ManualUpdatePolicy.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/ManualUpdatePolicy.java new file mode 100644 index 00000000000..c4e302f8fb1 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/ManualUpdatePolicy.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel.update; + +import java.util.Set; + +import org.eclipse.jface.viewers.TreePath; + + +/** + * An "manual" update policy which causes the view model provider cache to be + * flushed only as a result of an explicit user action. + */ +public class ManualUpdatePolicy implements IVMUpdatePolicy { + + public static String MANUAL_UPDATE_POLICY_ID = "org.eclipse.dd.dsf.ui.viewmodel.update.manualUpdatePolicy"; //$NON-NLS-1$ + + public static Object REFRESH_EVENT = new Object(); + + private static class UserEditEventUpdateTester implements IElementUpdateTester { + private final Set fElements; + + public UserEditEventUpdateTester(Set elements) { + fElements = elements; + } + + public int getUpdateFlags(Object viewerInput, TreePath path) { + if (fElements.contains(viewerInput)) { + return FLUSH; + } + for (int i = 0; i < path.getSegmentCount(); i++) { + if (fElements.contains(path.getSegment(i))) { + return FLUSH; + } + } + return 0; + } + + public boolean includes(IElementUpdateTester tester) { + return + tester instanceof UserEditEventUpdateTester && + fElements.equals(((UserEditEventUpdateTester)tester).fElements); + } + } + + private static IElementUpdateTester fgUpdateTester = new IElementUpdateTester() { + public int getUpdateFlags(Object viewerInput, TreePath path) { + return DIRTY; + } + + public boolean includes(IElementUpdateTester tester) { + return tester.equals(this); + } + }; + + private static IElementUpdateTester fgRefreshUpdateTester = new IElementUpdateTester() { + public int getUpdateFlags(Object viewerInput, TreePath path) { + return FLUSH | ARCHIVE; + } + + public boolean includes(IElementUpdateTester tester) { + return tester.equals(this) || tester.equals(fgUpdateTester) || tester instanceof UserEditEventUpdateTester; + } + }; + + public String getID() { + return MANUAL_UPDATE_POLICY_ID; + } + + public String getName() { + return "Manual"; + } + + public IElementUpdateTester getTesterTester(Object event) { + if (event.equals(REFRESH_EVENT)) { + return fgRefreshUpdateTester; + } + return fgUpdateTester; + } + +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/UserEditEvent.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/UserEditEvent.java new file mode 100644 index 00000000000..afe12d236d6 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/UserEditEvent.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel.update; + +import java.util.HashSet; +import java.util.Set; + +/** + * An event representing a user editing of the data in the viewer. Typically, when + * a viewer is configured to be in a manual update mode, if user edits a value, the + * viewer should still update at least the value that the user editor. This event + * is used to accomplish that behavior. + */ +public class UserEditEvent { + private final Set fElements; + + public UserEditEvent(Object element) { + fElements = new HashSet(); + fElements.add(element); + } + + public UserEditEvent(Set elements) { + fElements = elements; + } + + public Set getElements() { + return fElements; + } +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java deleted file mode 100644 index ec6438f0727..00000000000 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCache.java +++ /dev/null @@ -1,384 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Ted R Williams (Wind River Systems, Inc.) - initial implementation - *******************************************************************************/ - -package org.eclipse.dd.dsf.ui.viewmodel.update; - -import java.util.HashMap; -import java.util.List; -import java.util.Vector; -import java.util.concurrent.Executor; - -import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor; -import org.eclipse.dd.dsf.concurrent.DsfExecutor; -import org.eclipse.dd.dsf.concurrent.MultiRequestMonitor; -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.ui.viewmodel.VMElementsCountUpdate; -import org.eclipse.dd.dsf.ui.viewmodel.VMElementsUpdate; -import org.eclipse.dd.dsf.ui.viewmodel.VMHasElementsUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; - -@SuppressWarnings("restriction") -public abstract class VMCache -{ - protected Executor fExecutor = new DefaultDsfExecutor(); - - protected HashMap fChildrenCounts = new HashMap(); - - protected HashMap> fChildren = new HashMap>(); - - protected HashMap fHasChildren = new HashMap(); - - protected HashMap fData = new HashMap(); - - protected HashMap fDataArchive = fData; - - public HashMap[] getCacheData() - { - return new HashMap[] { fHasChildren, fChildrenCounts, fChildren, fData, fDataArchive }; - } - - public VMCache() - { - - } - - // Suppress warnings related to the lost type information in getCacheData() - @SuppressWarnings("unchecked") - public VMCache(VMCache oldCache) - { - if(oldCache != null) - { - HashMap oldCacheData[] = oldCache.getCacheData(); - - fHasChildren = (HashMap)oldCacheData[0]; - fChildrenCounts = (HashMap)oldCacheData[1]; - fChildren = (HashMap>)oldCacheData[2]; - fData = (HashMap)oldCacheData[3]; - fDataArchive = (HashMap)oldCacheData[4]; - } - } - - protected void flush(boolean archive) - { - if(archive) - fDataArchive = fData; - fData = new HashMap(); - fChildrenCounts.clear(); - fChildren.clear(); - fHasChildren.clear(); - } - - /** - * Returns whether the data in this cache should used when servicing - * view updates. If this method returns false all updates will be - * sent to the view model, although the retrieved data should still - * be stored in the cache if {@link #isCacheWriteEnabled()} returns true. - * @return - */ - protected boolean isCacheReadEnabled() - { - return true; - } - - /** - * Returns true if data retrieved from the view model should be cached. - * If this returns false, then the state of the cache is frozen. - */ - protected boolean isCacheWriteEnabled() - { - return true; - } - - @SuppressWarnings("restriction") - public IHasChildrenUpdate[] update(IHasChildrenUpdate[] updates) { - if(!isCacheReadEnabled()) - return updates; - - Vector missVector = new Vector(); - for(IHasChildrenUpdate update : updates) - { - if(fHasChildren.containsKey(update.getElement()) && isCacheReadEnabled()) - { - update.setHasChilren(fHasChildren.get(update.getElement()).booleanValue()); - update.done(); - } - else - { - missVector.addElement(update); - } - } - - updates = new IHasChildrenUpdate[missVector.size()]; - for(int i = 0; i < updates.length; i++) - { - final IHasChildrenUpdate update = missVector.elementAt(i); - updates[i] = new VMHasElementsUpdate(update, new DataRequestMonitor(fExecutor, null) - { - @Override - protected void handleCompleted() - { - if(getStatus().isOK()) - { - if(isCacheWriteEnabled()) - fHasChildren.put(update.getElement(), this.getData()); - update.setHasChilren(getData()); - } - update.done(); - } - }); - } - - return updates; - } - - @SuppressWarnings("restriction") - public IChildrenCountUpdate[] update(IChildrenCountUpdate[] updates) - { - if(!isCacheReadEnabled()) - return updates; - - Vector missVector = new Vector(); - for(IChildrenCountUpdate update : updates) - { - if(fChildrenCounts.containsKey(update.getElement()) && isCacheReadEnabled()) - { - update.setChildCount(fChildrenCounts.get(update.getElement())); - update.done(); - } - else - { - missVector.addElement(update); - } - } - - updates = new IChildrenCountUpdate[missVector.size()]; - for(int i = 0; i < updates.length; i++) - { - final IChildrenCountUpdate update = missVector.elementAt(i); - updates[i] = new VMElementsCountUpdate(update, new DataRequestMonitor(fExecutor, null) - { - @Override - protected void handleCompleted() { - if(getStatus().isOK()) - { - if(isCacheWriteEnabled()) - fChildrenCounts.put(update.getElement(), this.getData()); - update.setChildCount(this.getData()); - } - update.done(); - } - }); - } - - return updates; - } - - @SuppressWarnings("restriction") - public IChildrenUpdate[] update(IChildrenUpdate[] updates) { - if(!isCacheReadEnabled()) - return updates; - - Vector updatesEntirelyMissingFromCache = new Vector(); - for(final IChildrenUpdate update : updates) - { - if(fChildren.containsKey(update.getElement()) && isCacheReadEnabled()) - { - Vector childrenMissingFromCache = new Vector(); - for(int i = update.getOffset(); i < update.getOffset() + update.getLength(); i++) - childrenMissingFromCache.addElement(i); - childrenMissingFromCache.removeAll(fChildren.get(update.getElement()).keySet()); - - if(childrenMissingFromCache.size() > 0) - { - // perform a partial update; we only have some of the children of the update request - - final HashMap>,IChildrenUpdate> associationsRequestMonitorToChildUpdate - = new HashMap>,IChildrenUpdate>(); - - final MultiRequestMonitor>> childrenMultiRequestMon = - new MultiRequestMonitor>>(fExecutor, null) { - @Override - protected void handleCompleted() { - // Status is OK, only if all request monitors are OK. - if (getStatus().isOK()) - { - for (DataRequestMonitor> monitor : getRequestMonitors()) - { - int offset = associationsRequestMonitorToChildUpdate.get(monitor).getOffset(); - for(Object child : monitor.getData()) - update.setChild(child, offset++); - } - } else { - update.setStatus(getStatus()); - } - update.done(); - } - }; - - while(childrenMissingFromCache.size() > 0) - { - int offset = childrenMissingFromCache.elementAt(0); - childrenMissingFromCache.removeElementAt(0); - int length = 1; - while(childrenMissingFromCache.size() > 0 && childrenMissingFromCache.elementAt(0) == offset + length) - { - length++; - childrenMissingFromCache.removeElementAt(0); - } - - DataRequestMonitor> partialUpdateMonitor = new DataRequestMonitor>(fExecutor, null) - { - @Override - protected void handleCompleted() - { - - childrenMultiRequestMon.requestMonitorDone(this); - } - }; - - final IChildrenUpdate partialUpdate = new VMElementsUpdate(update, offset, length, - childrenMultiRequestMon.add(partialUpdateMonitor)); - - associationsRequestMonitorToChildUpdate.put(partialUpdateMonitor, partialUpdate); - - updatesEntirelyMissingFromCache.add(partialUpdate); - - } - } - else - { - // we have all of the children in cache; return from cache - for(int position = update.getOffset(); position < update.getOffset() + update.getLength(); position++) - update.setChild(fChildren.get(update.getElement()).get(position), position); - update.done(); - } - } - else - { - updatesEntirelyMissingFromCache.addElement(update); - } - } - - updates = new IChildrenUpdate[updatesEntirelyMissingFromCache.size()]; - for(int i = 0; i < updates.length; i++) - { - final IChildrenUpdate update = updatesEntirelyMissingFromCache.elementAt(i); - updates[i] = - new VMElementsUpdate( - update, update.getOffset(), update.getLength(), - new DataRequestMonitor>(fExecutor, null) - { - @Override - protected void handleCompleted() - { - if(getData() != null) - { - for(int j = 0; j < getData().size(); j++) - { - if(isCacheWriteEnabled()) - { - if(!fChildren.containsKey(update.getElement())) - fChildren.put(update.getElement(), new HashMap()); - - fChildren.get(update.getElement()).put(update.getOffset() + j, getData().get(j)); - } - - update.setChild(getData().get(j), update.getOffset() + j); - } - } - update.done(); - } - }) - { - /* See https://bugs.eclipse.org/bugs/show_bug.cgi?id=202109 - * - * A flexible hierarchy bug/optimization causes query with incorrect - * IChildrenUpdate[] array length. - * - * We found this while deleting a register node. Example: - * - * the register view displays: - * PC - * EAX - * EBX - * ECX - * EDX - * - * we delete EBX and force a context refresh. - * - * flexible hierarchy queries for IChildrenUpdate[5] and IChildrenCountUpdate at - * the same time. - * - * VMElementsUpdate, used by VMCache to wrap the IChildrenUpdate, generates an - * IStatus.ERROR with message "Incomplete elements of updates" when fElements - * count (provided by service) does not match the length provided by the original - * update query. - * - * Workaround, respect getData() != null instead of IStatus.OK, override - * VMElementsUpdate.done() to set elements regardless of count - */ - @Override - public void done() { - @SuppressWarnings("unchecked") - DataRequestMonitor> rm = (DataRequestMonitor>)fRequestMonitor; - rm.setData(fElements); - super.done(); - } - }; - } - - return updates; - } - - @SuppressWarnings("unchecked") - @ConfinedToDsfExecutor("DsfSession.getSession(dmc.getSessionId()).getExecutor()") - public void getModelData(IDMService service, final IDMContext dmc, final DataRequestMonitor rm, DsfExecutor executor) - { - if(fData.containsKey(dmc) && isCacheReadEnabled()) - { - rm.setData( fData.get(dmc)); - rm.done(); - } - else - { - service.getModelData(dmc, - new DataRequestMonitor(executor, rm) { - @Override - protected void handleOK() { - if(isCacheWriteEnabled()) - fData.put(dmc, getData()); - rm.setData(getData()); - rm.done(); - } - } - ); - } - } - - @SuppressWarnings("unchecked") - public IDMData getArchivedModelData(IDMContext dmc) - { - return fDataArchive.get(dmc); - } - - @SuppressWarnings("unchecked") - public abstract void handleEvent(IDMEvent event); - -} - - diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCacheManager.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCacheManager.java deleted file mode 100644 index ecbb5270141..00000000000 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/VMCacheManager.java +++ /dev/null @@ -1,112 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Ted R Williams (Wind River Systems, Inc.) - initial implementation - *******************************************************************************/ - -package org.eclipse.dd.dsf.ui.viewmodel.update; - -import java.util.HashMap; -import java.util.Vector; - -import org.eclipse.dd.dsf.datamodel.IDMEvent; - - -public class VMCacheManager -{ - private static VMCacheManager fInstance = null; - - private HashMap fAssociations = new HashMap(); - - public interface CacheListener - { - public void cacheFlushed(Object context); - } - - private HashMap> fListeners = new HashMap>(); - - public VMCacheManager() - { - } - - public static VMCacheManager getVMCacheManager() - { - if(fInstance == null) - fInstance = new VMCacheManager(); - - return fInstance; - } - - public VMCache getCache(Object context) - { - if(!fAssociations.containsKey(context)) - fAssociations.put(context, new VMCache() - { - @SuppressWarnings("unchecked") - @Override - public void handleEvent(IDMEvent event) { - } - - @Override - public boolean isCacheReadEnabled() - { - return false; - } - - @Override - public boolean isCacheWriteEnabled() - { - return false; - } - }); - - return fAssociations.get(context); - } - - public void registerCache(Object context, VMCache cache) - { - fAssociations.put(context, cache); - } - - public void addCacheListener(Object context, CacheListener listener) - { - if(!fListeners.containsKey(context)) - fListeners.put(context, new Vector()); - - fListeners.get(context).addElement(listener); - } - - public void removeCacheListener(Object context, CacheListener listener) - { - if(!fListeners.containsKey(context)) - { - fListeners.get(context).removeElement(listener); - if(fListeners.get(context).isEmpty()) - fListeners.remove(context); - } - } - - private void fireCacheFlushed(Object context) - { - if(fListeners.containsKey(context)) - { - for(CacheListener listener : fListeners.get(context)) - listener.cacheFlushed(context); - } - } - - public void flush(Object context) - { - getCache(context).flush(false); - fireCacheFlushed(context); - } - -} - - - diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/actions/AbstractRefreshActionDelegate.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/actions/AbstractRefreshActionDelegate.java deleted file mode 100644 index 88d0f2da26e..00000000000 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/actions/AbstractRefreshActionDelegate.java +++ /dev/null @@ -1,40 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Ted R Williams (Wind River Systems, Inc.) - initial implementation - *******************************************************************************/ - -package org.eclipse.dd.dsf.ui.viewmodel.update.actions; - -import org.eclipse.dd.dsf.ui.viewmodel.update.VMCache; -import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.ui.IViewActionDelegate; -import org.eclipse.ui.IViewPart; - -public abstract class AbstractRefreshActionDelegate implements IViewActionDelegate { - - protected IViewPart fView; - - public void init(IViewPart view) { - fView = view; - } - - public void run(IAction action) { - VMCacheManager.getVMCacheManager().registerCache(getContext(), createCache()); - } - - public void selectionChanged(IAction action, ISelection selection) { - } - - protected abstract Object getContext(); - - protected abstract VMCache createCache(); - -} diff --git a/plugins/org.eclipse.dd.dsf/build.properties b/plugins/org.eclipse.dd.dsf/build.properties index 786b1df9364..bc3b0f2bf1f 100644 --- a/plugins/org.eclipse.dd.dsf/build.properties +++ b/plugins/org.eclipse.dd.dsf/build.properties @@ -3,4 +3,5 @@ output.. = bin/ bin.includes = META-INF/,\ .,\ plugin.xml,\ + plugin.properties,\ about.html diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java index e72be2757c3..e8504340207 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java @@ -90,6 +90,10 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor return Thread.currentThread().equals( ((DsfThreadFactory)getThreadFactory()).fThread ); } + protected String getName() { + return fName; + } + static void logException(Throwable t) { DsfPlugin plugin = DsfPlugin.getDefault(); if (plugin == null) return; @@ -114,14 +118,14 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor // // Utilities used for tracing. // - static boolean DEBUG_EXECUTOR = false; - static String DEBUG_EXECUTOR_NAME = ""; - static boolean ASSERTIONS_ENABLED = false; + protected static boolean DEBUG_EXECUTOR = false; + protected static String DEBUG_EXECUTOR_NAME = ""; //$NON-NLS-1$ + protected static boolean ASSERTIONS_ENABLED = false; static { DEBUG_EXECUTOR = DsfPlugin.DEBUG && "true".equals( //$NON-NLS-1$ Platform.getDebugOption("org.eclipse.dd.dsf/debug/executor")); //$NON-NLS-1$ DEBUG_EXECUTOR_NAME = DsfPlugin.DEBUG - ? Platform.getDebugOption("org.eclipse.dd.dsf/debug/executorName") : ""; //$NON-NLS-1$ + ? Platform.getDebugOption("org.eclipse.dd.dsf/debug/executorName") : ""; //$NON-NLS-1$ //$NON-NLS-2$ assert (ASSERTIONS_ENABLED = true) == true; } @@ -253,9 +257,7 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor fRunnable = runnable; // Check if executable wasn't executed already. - if (fRunnable instanceof DsfExecutable && - DEBUG_EXECUTOR && ("".equals(DEBUG_EXECUTOR_NAME) || fName.equals(DEBUG_EXECUTOR_NAME))) //$NON-NLS-1$ - { + if (DEBUG_EXECUTOR && fRunnable instanceof DsfExecutable) { assert !((DsfExecutable)fRunnable).getSubmitted() : "Executable was previously executed."; //$NON-NLS-1$ ((DsfExecutable)fRunnable).setSubmitted(); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java index 4391606ddd5..0e3bf249c3d 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java @@ -61,7 +61,7 @@ public class DsfExecutable { * Flag indicating whether this executable was ever executed by an * executor. Used for tracing only. */ - private boolean fSubmitted = false; + private volatile boolean fSubmitted = false; @SuppressWarnings("unchecked") public DsfExecutable() { @@ -96,7 +96,7 @@ public class DsfExecutable { } } - boolean getSubmitted() { + public boolean getSubmitted() { return fSubmitted; } @@ -104,7 +104,7 @@ public class DsfExecutable { * Marks this executable to indicate that it has been executed by the * executor. To be invoked only by DsfExecutor. */ - void setSubmitted() { + public void setSubmitted() { fSubmitted = true; } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ImmediateExecutor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ImmediateExecutor.java index 64316554eff..a2644024477 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ImmediateExecutor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ImmediateExecutor.java @@ -12,6 +12,9 @@ package org.eclipse.dd.dsf.concurrent; import java.util.concurrent.Executor; +import org.eclipse.core.runtime.Platform; +import org.eclipse.dd.dsf.DsfPlugin; + /** * Executor that executes a runnable immediately as it is submitted. This * executor is useful for clients that need to create RequestMonitor @@ -20,6 +23,16 @@ import java.util.concurrent.Executor; */ public class ImmediateExecutor implements Executor { + /** + * Debug flag used for tracking runnables that were never executed, + * or executed multiple times. + */ + protected static boolean DEBUG_EXECUTOR = false; + static { + DEBUG_EXECUTOR = DsfPlugin.DEBUG && "true".equals( //$NON-NLS-1$ + Platform.getDebugOption("org.eclipse.dd.dsf/debug/executor")); //$NON-NLS-1$ + } + private static ImmediateExecutor fInstance = new ImmediateExecutor(); /** @@ -36,6 +49,11 @@ public class ImmediateExecutor implements Executor { } public void execute(Runnable command) { + // Check if executable wasn't executed already. + if (DEBUG_EXECUTOR && command instanceof DsfExecutable) { + assert !((DsfExecutable)command).getSubmitted() : "Executable was previously executed."; //$NON-NLS-1$ + ((DsfExecutable)command).setSubmitted(); + } command.run(); } } From 0d12dc03382795a90d79390ff74b1641e163587f Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Mon, 21 Jan 2008 18:06:10 +0000 Subject: [PATCH 217/834] [192019] Got rid of getExpressionLength() which is no longer used. --- .../viewmodel/register/RegisterBitFieldVMNode.java | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java index 2a48579faa4..5513c4642ba 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java @@ -581,18 +581,6 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode } - public int getExpressionLength(String expression) { - if (expression.charAt(0) == '.' && Character.isLetterOrDigit(expression.charAt(1))) { - int length = 1; - while( length < expression.length() && Character.isLetterOrDigit(expression.charAt(length)) ) { - length++; - } - return length; - } else { - return -1; - } - } - @Override protected void associateExpression(Object element, IExpression expression) { if (element instanceof BitFieldVMC) { From 2f16b2b95f5826346db0fd310721ec88fe50902f Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Mon, 21 Jan 2008 19:29:30 +0000 Subject: [PATCH 218/834] [216034] Fixed to compile with platform 3.4 M5. --- .../viewmodel/numberformat/detail/NumberFormatDetailPane.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/NumberFormatDetailPane.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/NumberFormatDetailPane.java index 4f31826ed11..503b87a9dc2 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/NumberFormatDetailPane.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/NumberFormatDetailPane.java @@ -53,7 +53,6 @@ import org.eclipse.debug.internal.ui.actions.variables.details.DetailPaneMaxLeng import org.eclipse.debug.internal.ui.actions.variables.details.DetailPaneWordWrapAction; import org.eclipse.debug.internal.ui.preferences.IDebugPreferenceConstants; import org.eclipse.debug.internal.ui.views.variables.IndexedValuePartition; -import org.eclipse.debug.internal.ui.views.variables.StatusLineContributionItem; import org.eclipse.debug.internal.ui.views.variables.details.DetailMessages; import org.eclipse.debug.ui.IDebugModelPresentation; import org.eclipse.debug.ui.IDebugUIConstants; @@ -109,6 +108,7 @@ import org.eclipse.ui.texteditor.IAbstractTextEditorHelpContextIds; import org.eclipse.ui.texteditor.ITextEditorActionConstants; import org.eclipse.ui.texteditor.IUpdate; import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds; +import org.eclipse.ui.texteditor.StatusLineContributionItem; public class NumberFormatDetailPane implements IDetailPane, IAdaptable, IPropertyChangeListener { From e6f90cea7a553befe9188180dae1db8b790c098e Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Mon, 21 Jan 2008 19:31:58 +0000 Subject: [PATCH 219/834] [192019] Reverted to use VMDelta which was erroneously removed in UI refactoring. --- .../expression/ExpressionManagerVMNode.java | 4 +- .../expression/ExpressionVMProvider.java | 5 +- ...xpressionVMProviderModelProxyStrategy.java | 10 +- .../expression/IExpressionVMNode.java | 6 +- .../ui/viewmodel/launch/LaunchRootVMNode.java | 8 +- .../viewmodel/launch/StackFramesVMNode.java | 10 +- .../launch/StandardProcessVMNode.java | 3 +- .../ui/viewmodel/modules/ModulesVMNode.java | 4 +- .../register/RegisterBitFieldVMNode.java | 8 +- .../register/RegisterGroupVMNode.java | 8 +- .../ui/viewmodel/register/RegisterVMNode.java | 8 +- .../ui/viewmodel/variable/VariableVMNode.java | 8 +- .../DefaultVMModelProxyStrategy.java | 16 +- .../dd/dsf/ui/viewmodel/IRootVMNode.java | 3 +- .../eclipse/dd/dsf/ui/viewmodel/IVMNode.java | 3 +- .../dd/dsf/ui/viewmodel/RootVMNode.java | 7 +- .../eclipse/dd/dsf/ui/viewmodel/VMDelta.java | 330 ++++++++++++++++++ 17 files changed, 385 insertions(+), 56 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerVMNode.java index e39d2c5b485..a25f962abdb 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerVMNode.java @@ -22,6 +22,7 @@ import org.eclipse.dd.dsf.ui.concurrent.ViewerCountingRequestMonitor; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMContext; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMNode; import org.eclipse.dd.dsf.ui.viewmodel.IVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.IExpressionManager; import org.eclipse.debug.core.model.IExpression; @@ -34,7 +35,6 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdat import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; -import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; import org.eclipse.debug.ui.DebugUITools; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.jface.resource.JFaceResources; @@ -296,7 +296,7 @@ public class ExpressionManagerVMNode extends AbstractVMNode return retVal; } - public void buildDelta(final Object event, final ModelDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) { + public void buildDelta(final Object event, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) { // Add a flag if the list of expressions has changed. if (event instanceof ExpressionsChangedEvent) { parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java index c3d4ffac01e..6cdd02889fd 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java @@ -24,10 +24,11 @@ import org.eclipse.dd.dsf.debug.ui.viewmodel.variable.SyncVariableDataAccess; import org.eclipse.dd.dsf.debug.ui.viewmodel.variable.VariableVMNode; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; +import org.eclipse.dd.dsf.ui.viewmodel.DefaultVMContentProviderStrategy; import org.eclipse.dd.dsf.ui.viewmodel.IRootVMNode; import org.eclipse.dd.dsf.ui.viewmodel.IVMModelProxy; import org.eclipse.dd.dsf.ui.viewmodel.IVMNode; -import org.eclipse.dd.dsf.ui.viewmodel.DefaultVMContentProviderStrategy; +import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.dm.RootDMVMNode; import org.eclipse.dd.dsf.ui.viewmodel.update.AutomaticUpdatePolicy; @@ -143,7 +144,7 @@ public class ExpressionVMProvider extends AbstractDMVMProvider * methods. */ public void buildDeltaForExpression(final IExpression expression, final int expressionElementIdx, final Object event, - final ModelDelta parentDelta, final TreePath path, final RequestMonitor rm) + final VMDelta parentDelta, final TreePath path, final RequestMonitor rm) { // Workaround: find the first active proxy and use it. if (!getActiveModelProxies().isEmpty()) { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderModelProxyStrategy.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderModelProxyStrategy.java index f17aabc25a2..6cc7480e085 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderModelProxyStrategy.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderModelProxyStrategy.java @@ -15,11 +15,11 @@ import java.util.Map; import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.ui.viewmodel.IVMNode; import org.eclipse.dd.dsf.ui.viewmodel.DefaultVMModelProxyStrategy; +import org.eclipse.dd.dsf.ui.viewmodel.IVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.debug.core.model.IExpression; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; -import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; import org.eclipse.jface.viewers.TreePath; /** @@ -59,7 +59,7 @@ public class ExpressionVMProviderModelProxyStrategy extends DefaultVMModelProxyS } public void buildDeltaForExpression(IExpression expression, int expressionElementIdx, Object event, - ModelDelta parentDelta, TreePath path, RequestMonitor rm) + VMDelta parentDelta, TreePath path, RequestMonitor rm) { final IExpressionVMNode matchingNode = getExpressionVMProvider().findNodeToParseExpression(null, expression); @@ -72,7 +72,7 @@ public class ExpressionVMProviderModelProxyStrategy extends DefaultVMModelProxyS } private void buildNodeDeltaForExpression(final IExpressionVMNode node, final IExpression expression, - final int expressionElementIdx, final Object event, final ModelDelta parentDelta, final TreePath path, + final int expressionElementIdx, final Object event, final VMDelta parentDelta, final TreePath path, final RequestMonitor rm) { node.buildDeltaForExpression( @@ -108,7 +108,7 @@ public class ExpressionVMProviderModelProxyStrategy extends DefaultVMModelProxyS } private void buildDeltaForExpressionElement(final IExpressionVMNode node, Object expressionElement, - final int expressionElementIdx, final Object event, final ModelDelta parentDelta, final TreePath path, + final int expressionElementIdx, final Object event, final VMDelta parentDelta, final TreePath path, final RequestMonitor rm) { CountingRequestMonitor multiRm = new CountingRequestMonitor(getVMProvider().getExecutor(), rm); diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionVMNode.java index 56ef08b816a..ffe51869417 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionVMNode.java @@ -12,8 +12,8 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.ui.viewmodel.IVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.debug.core.model.IExpression; -import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; import org.eclipse.jface.viewers.TreePath; /** @@ -49,12 +49,12 @@ public interface IExpressionVMNode extends IVMNode { * Adds delta flags to the given parent delta based on the expression object * given. */ - public void buildDeltaForExpression(IExpression expression, int elementIdx, Object event, ModelDelta parentDelta, + public void buildDeltaForExpression(IExpression expression, int elementIdx, Object event, VMDelta parentDelta, TreePath path, RequestMonitor rm); /** * Adds delta to the given parent delta based on the given element which was created base on * an expression parsed by this node. */ - public void buildDeltaForExpressionElement(Object element, int elementIdx, Object event, ModelDelta parentDelta, final RequestMonitor rm); + public void buildDeltaForExpressionElement(Object element, int elementIdx, Object event, VMDelta parentDelta, final RequestMonitor rm); } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/LaunchRootVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/LaunchRootVMNode.java index bedac741b08..1c0af5b33b5 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/LaunchRootVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/LaunchRootVMNode.java @@ -21,6 +21,7 @@ import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.IRootVMNode; import org.eclipse.dd.dsf.ui.viewmodel.RootVMNode; +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; @@ -28,7 +29,6 @@ import org.eclipse.debug.core.ILaunchManager; import org.eclipse.debug.core.model.IDebugElement; import org.eclipse.debug.core.model.IProcess; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; -import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; /** * Layout node for the standard ILaunch object. This node can only be used at @@ -87,7 +87,7 @@ public class LaunchRootVMNode extends RootVMNode } @Override - public void createRootDelta(Object rootObject, Object event, final DataRequestMonitor rm) { + public void createRootDelta(Object rootObject, Object event, final DataRequestMonitor rm) { if (!(rootObject instanceof ILaunch)) { rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Invalid root element configured with launch root node.", null)); //$NON-NLS-1$ return; @@ -101,8 +101,8 @@ public class LaunchRootVMNode extends RootVMNode */ ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager(); List launchList = Arrays.asList(manager.getLaunches()); - final ModelDelta viewRootDelta = new ModelDelta(manager, 0, IModelDelta.NO_CHANGE, launchList.size()); - final ModelDelta rootDelta = viewRootDelta.addNode(rootLaunch, launchList.indexOf(rootLaunch), IModelDelta.NO_CHANGE); + final VMDelta viewRootDelta = new VMDelta(manager, 0, IModelDelta.NO_CHANGE, launchList.size()); + final VMDelta rootDelta = viewRootDelta.addNode(rootLaunch, launchList.indexOf(rootLaunch), IModelDelta.NO_CHANGE); // Generate delta for launch node. if (event instanceof LaunchesEvent) { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java index 3a913d371cb..e13ea7cfa8d 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java @@ -31,6 +31,7 @@ import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.VMChildrenUpdate; +import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMNode; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; @@ -40,7 +41,6 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdat import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; import org.eclipse.debug.ui.DebugUITools; import org.eclipse.debug.ui.IDebugUIConstants; @@ -287,7 +287,7 @@ public class StackFramesVMNode extends AbstractDMVMNode return IModelDelta.NO_CHANGE; } - public void buildDelta(final Object e, final ModelDelta parent, final int nodeOffset, final RequestMonitor rm) { + public void buildDelta(final Object e, final VMDelta parent, final int nodeOffset, final RequestMonitor rm) { if (e instanceof IContainerSuspendedDMEvent) { IExecutionDMContext threadDmc = null; if (parent.getElement() instanceof IDMVMContext) { @@ -306,7 +306,7 @@ public class StackFramesVMNode extends AbstractDMVMNode } } - private void buildDeltaForSuspendedEvent(final ISuspendedDMEvent e, final IExecutionDMContext executionCtx, final IExecutionDMContext triggeringCtx, final ModelDelta parentDelta, final int nodeOffset, final RequestMonitor rm) { + private void buildDeltaForSuspendedEvent(final ISuspendedDMEvent e, final IExecutionDMContext executionCtx, final IExecutionDMContext triggeringCtx, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor rm) { IRunControl runControlService = getServicesTracker().getService(IRunControl.class); IStack stackService = getServicesTracker().getService(IStack.class); if (stackService == null || runControlService == null) { @@ -353,7 +353,7 @@ public class StackFramesVMNode extends AbstractDMVMNode } } - private void buildDeltaForResumedEvent(final IResumedDMEvent e, final ModelDelta parentDelta, final int nodeOffset, final RequestMonitor rm) { + private void buildDeltaForResumedEvent(final IResumedDMEvent e, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor rm) { IStack stackService = getServicesTracker().getService(IStack.class); if (stackService == null) { // Required services have not initialized yet. Ignore the event. @@ -371,7 +371,7 @@ public class StackFramesVMNode extends AbstractDMVMNode rm.done(); } - private void buildDeltaForSteppingTimedOutEvent(final IStepQueueManager.ISteppingTimedOutEvent e, final ModelDelta parentDelta, final int nodeOffset, final RequestMonitor rm) { + private void buildDeltaForSteppingTimedOutEvent(final IStepQueueManager.ISteppingTimedOutEvent e, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor rm) { // Repaint the stack frame images to have the running symbol. parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); rm.done(); diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessVMNode.java index 751dfc99553..e1e0a7d18cb 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessVMNode.java @@ -16,6 +16,7 @@ import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMNode; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.IVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.ILaunch; @@ -184,7 +185,7 @@ public class StandardProcessVMNode extends AbstractVMNode { return myFlags; } - public void buildDelta(Object e, ModelDelta parent, int nodeOffset, RequestMonitor requestMonitor) { + public void buildDelta(Object e, VMDelta parent, int nodeOffset, RequestMonitor requestMonitor) { if (e instanceof DebugEvent && ((DebugEvent)e).getSource() instanceof IProcess) { DebugEvent de = (DebugEvent)e; if (de.getKind() == DebugEvent.CHANGE) { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMNode.java index 78155c4191d..d660b5edc20 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMNode.java @@ -25,13 +25,13 @@ import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.ui.IDsfDebugUIConstants; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMNode; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; -import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; @SuppressWarnings("restriction") public class ModulesVMNode extends AbstractDMVMNode @@ -142,7 +142,7 @@ public class ModulesVMNode extends AbstractDMVMNode return IModelDelta.NO_CHANGE; } - public void buildDelta(Object e, ModelDelta parentDelta, int nodeOffset, RequestMonitor rm) { + public void buildDelta(Object e, VMDelta parentDelta, int nodeOffset, RequestMonitor rm) { if (e instanceof IRunControl.ISuspendedDMEvent) { // Create a delta that indicates all groups have changed parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java index 5513c4642ba..c49e683dfe7 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java @@ -41,6 +41,7 @@ import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterBitFieldCellModifi import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; import org.eclipse.debug.core.DebugException; @@ -55,7 +56,6 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProv import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; -import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapterExtension; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.viewers.CellEditor; @@ -424,7 +424,7 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode return IModelDelta.NO_CHANGE; } - public void buildDelta(Object e, ModelDelta parentDelta, int nodeOffset, RequestMonitor rm) { + public void buildDelta(Object e, VMDelta parentDelta, int nodeOffset, RequestMonitor rm) { if (e instanceof IRunControl.ISuspendedDMEvent) { // Create a delta that the whole register group has changed. parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); @@ -602,7 +602,7 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode return IModelDelta.NO_CHANGE; } - public void buildDeltaForExpression(final IExpression expression, final int elementIdx, final Object event, final ModelDelta parentDelta, final TreePath path, final RequestMonitor rm) + public void buildDeltaForExpression(final IExpression expression, final int elementIdx, final Object event, final VMDelta parentDelta, final TreePath path, final RequestMonitor rm) { if (event instanceof ISuspendedDMEvent) { // Mark the parent delta indicating that elements were added and/or removed. @@ -613,7 +613,7 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode rm.done(); } - public void buildDeltaForExpressionElement(Object element, int elementIdx, Object event, ModelDelta parentDelta, final RequestMonitor rm) + public void buildDeltaForExpressionElement(Object element, int elementIdx, Object event, VMDelta parentDelta, final RequestMonitor rm) { if (event instanceof IBitFieldChangedDMEvent) { parentDelta.addNode(element, IModelDelta.STATE); diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java index ae10054f4c6..aa70784c236 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java @@ -32,6 +32,7 @@ import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionCellModif import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.dm.CompositeDMVMContext; import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; @@ -48,7 +49,6 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProv import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; -import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapterExtension; import org.eclipse.jface.viewers.CellEditor; @@ -273,7 +273,7 @@ public class RegisterGroupVMNode extends AbstractExpressionVMNode return IModelDelta.NO_CHANGE; } - public void buildDelta(Object e, ModelDelta parentDelta, int nodeOffset, RequestMonitor rm) { + public void buildDelta(Object e, VMDelta parentDelta, int nodeOffset, RequestMonitor rm) { if (e instanceof IRunControl.ISuspendedDMEvent) { // Create a delta that indicates all groups have changed parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); @@ -324,7 +324,7 @@ public class RegisterGroupVMNode extends AbstractExpressionVMNode return IModelDelta.NO_CHANGE; } - public void buildDeltaForExpression(IExpression expression, int elementIdx, Object event, ModelDelta parentDelta, + public void buildDeltaForExpression(IExpression expression, int elementIdx, Object event, VMDelta parentDelta, TreePath path, RequestMonitor rm) { if (event instanceof IRunControl.ISuspendedDMEvent) { @@ -334,7 +334,7 @@ public class RegisterGroupVMNode extends AbstractExpressionVMNode rm.done(); } - public void buildDeltaForExpressionElement(Object element, int elementIdx, Object event, ModelDelta parentDelta, final RequestMonitor rm) + public void buildDeltaForExpressionElement(Object element, int elementIdx, Object event, VMDelta parentDelta, final RequestMonitor rm) { if (event instanceof IRegisters.IGroupsChangedDMEvent) { parentDelta.addNode(element, IModelDelta.CONTENT); diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java index f82b2d83e49..159c44a2c1f 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java @@ -37,6 +37,7 @@ import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValueVMConte import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.dm.CompositeDMVMContext; import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; @@ -55,7 +56,6 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProv import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; -import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapterExtension; import org.eclipse.jface.util.PropertyChangeEvent; @@ -436,7 +436,7 @@ public class RegisterVMNode extends AbstractExpressionVMNode return IModelDelta.NO_CHANGE; } - public void buildDelta(Object e, ModelDelta parentDelta, int nodeOffset, RequestMonitor rm) { + public void buildDelta(Object e, VMDelta parentDelta, int nodeOffset, RequestMonitor rm) { if (e instanceof IRunControl.ISuspendedDMEvent) { // Create a delta that the whole register group has changed. parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); @@ -543,7 +543,7 @@ public class RegisterVMNode extends AbstractExpressionVMNode return IModelDelta.NO_CHANGE; } - public void buildDeltaForExpression(IExpression expression, int elementIdx, Object event, ModelDelta parentDelta, + public void buildDeltaForExpression(IExpression expression, int elementIdx, Object event, VMDelta parentDelta, TreePath path, RequestMonitor rm) { if (event instanceof IRunControl.ISuspendedDMEvent) { @@ -553,7 +553,7 @@ public class RegisterVMNode extends AbstractExpressionVMNode rm.done(); } - public void buildDeltaForExpressionElement(Object element, int elementIdx, Object event, ModelDelta parentDelta, final RequestMonitor rm) + public void buildDeltaForExpressionElement(Object element, int elementIdx, Object event, VMDelta parentDelta, final RequestMonitor rm) { if (event instanceof IRegisters.IRegisterChangedDMEvent) { parentDelta.addNode(element, IModelDelta.STATE); diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java index fd876fc32f2..87baf190bd2 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java @@ -44,6 +44,7 @@ import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValueVMConte import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.dm.CompositeDMVMContext; import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; @@ -62,7 +63,6 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapterExtension; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.viewers.CellEditor; @@ -100,7 +100,7 @@ public class VariableVMNode extends AbstractExpressionVMNode return IModelDelta.NO_CHANGE; } - public void buildDelta(final Object event, final ModelDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) { + public void buildDelta(final Object event, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) { if (event instanceof IRunControl.ISuspendedDMEvent) { parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); @@ -527,13 +527,13 @@ public class VariableVMNode extends AbstractExpressionVMNode return IModelDelta.NO_CHANGE; } - public void buildDeltaForExpression(IExpression expression, int elementIdx, Object event, ModelDelta parentDelta, + public void buildDeltaForExpression(IExpression expression, int elementIdx, Object event, VMDelta parentDelta, TreePath path, RequestMonitor rm) { rm.done(); } - public void buildDeltaForExpressionElement(Object element, int elementIdx, Object event, ModelDelta parentDelta, + public void buildDeltaForExpressionElement(Object element, int elementIdx, Object event, VMDelta parentDelta, RequestMonitor rm) { if (event instanceof IRunControl.ISuspendedDMEvent) { diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMModelProxyStrategy.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMModelProxyStrategy.java index 6acd5eb1884..4a3739f5439 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMModelProxyStrategy.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMModelProxyStrategy.java @@ -248,7 +248,7 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy { // Always create the rootDelta, no matter what delta flags the child nodes have. rootNode.createRootDelta( getRootElement(), event, - new DataRequestMonitor(getVMProvider().getExecutor(), rm) { + new DataRequestMonitor(getVMProvider().getExecutor(), rm) { @Override protected void handleOK() { // Find the root delta for the whole view to use when firing the delta. @@ -281,7 +281,7 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy { }); } - protected void buildChildDeltas(final IVMNode node, final Object event, final ModelDelta parentDelta, + protected void buildChildDeltas(final IVMNode node, final Object event, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor rm) { final IVMContext vmc = node.getContextFromEvent(event); @@ -297,7 +297,7 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy { } protected void buildChildDeltasForEventContext(final IVMContext vmc, final IVMNode node, final Object event, - final ModelDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) + final VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) { final Map childNodeDeltas = getChildNodesWithDeltaFlags(node, parentDelta, event); if (childNodeDeltas.size() == 0) { @@ -354,7 +354,7 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy { // Optimization: Try to find a delta with a matching element, if found use it. // Otherwise create a new delta for the event element. int elementIndex = nodeOffset + i; - ModelDelta delta = parentDelta.getChildDelta(vmc); + VMDelta delta = (VMDelta)parentDelta.getChildDelta(vmc); if (delta == null || delta.getIndex() != elementIndex) { delta = parentDelta.addNode(vmc, elementIndex, IModelDelta.NO_CHANGE); } @@ -366,7 +366,7 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy { } else { // Optimization: Try to find a delta with a matching element, if found use it. // Otherwise create a new delta for the event element. - ModelDelta delta = parentDelta.getChildDelta(vmc); + VMDelta delta = (VMDelta)parentDelta.getChildDelta(vmc); if (delta == null) { delta = parentDelta.addNode(vmc, IModelDelta.NO_CHANGE); } @@ -382,7 +382,7 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy { * AbstractVMNode should override this method. * @see IVMNode#buildDelta(Object, ModelDelta, int, RequestMonitor) */ - protected void buildChildDeltasForAllContexts(final IVMNode node, final Object event, final ModelDelta parentDelta, + protected void buildChildDeltasForAllContexts(final IVMNode node, final Object event, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) { // Find the child nodes that have deltas for the given event. @@ -443,7 +443,7 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy { // and then call all the child nodes to build their delta. for (int i = 0; i < getData().size(); i++) { int elementIndex = nodeOffset >= 0 ? nodeOffset + i : -1; - ModelDelta delta = + VMDelta delta = parentDelta.addNode(getData().get(i), elementIndex, IModelDelta.NO_CHANGE); callChildNodesToBuildDelta( node, childNodesWithDeltaFlags, delta, event, @@ -471,7 +471,7 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy { * @param event The event object that the delta is being built for. * @param requestMonitor The result token to invoke when the delta is completed. */ - protected void callChildNodesToBuildDelta(final IVMNode node, final Map childNodes, final ModelDelta delta, final Object event, final RequestMonitor requestMonitor) { + protected void callChildNodesToBuildDelta(final IVMNode node, final Map childNodes, final VMDelta delta, final Object event, final RequestMonitor requestMonitor) { assert childNodes.size() != 0; // Check if any of the child nodes are will generate IModelDelta.SELECT or diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IRootVMNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IRootVMNode.java index ff32002244b..7af91afcdde 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IRootVMNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IRootVMNode.java @@ -11,7 +11,6 @@ package org.eclipse.dd.dsf.ui.viewmodel; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; /** * Special type of the view model node, which can be used as a root node @@ -42,5 +41,5 @@ public interface IRootVMNode extends IVMNode{ * @param event Event to process. * @param rm Result notification, contains the root of the delta. */ - public void createRootDelta(Object rootObject, Object event, DataRequestMonitor rm); + public void createRootDelta(Object rootObject, Object event, DataRequestMonitor rm); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMNode.java index 04d8f727229..90036d72736 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMNode.java @@ -19,7 +19,6 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; -import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; /** * View model nodes are configured with a view model provider to collectively @@ -90,7 +89,7 @@ public interface IVMNode extends IElementContentProvider * @param requestMonitor Return token, which notifies the caller that the calculation is * complete. */ - public void buildDelta(Object event, ModelDelta parent, int nodeOffset, RequestMonitor requestMonitor); + public void buildDelta(Object event, VMDelta parent, int nodeOffset, RequestMonitor requestMonitor); /** * Returns the view model element for the given data model event. This method diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/RootVMNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/RootVMNode.java index 5bdda2c409c..ae2895f8b39 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/RootVMNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/RootVMNode.java @@ -16,7 +16,6 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpd import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; -import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; /** * Default implementation of a root view model node. This class may be sub-classed @@ -53,8 +52,8 @@ public class RootVMNode extends AbstractVMNode implements IRootVMNode { * Default implementation creates a delta assuming that the root layout node * is the input object into the view. */ - public void createRootDelta(Object rootObject, Object event, final DataRequestMonitor rm) { - rm.setData(new ModelDelta(rootObject, 0, IModelDelta.NO_CHANGE)); + public void createRootDelta(Object rootObject, Object event, final DataRequestMonitor rm) { + rm.setData(new VMDelta(rootObject, 0, IModelDelta.NO_CHANGE)); rm.done(); } @@ -63,7 +62,7 @@ public class RootVMNode extends AbstractVMNode implements IRootVMNode { return IModelDelta.NO_CHANGE; } - public void buildDelta(Object event, ModelDelta parent, int nodeOffset, RequestMonitor requestMonitor) { + public void buildDelta(Object event, VMDelta parent, int nodeOffset, RequestMonitor requestMonitor) { requestMonitor.done(); } } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java new file mode 100644 index 00000000000..800d163a303 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java @@ -0,0 +1,330 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Wind River Systems - adapted to use in DSF + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel; + +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDeltaVisitor; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; + +/** + * This delta class mostly just duplicates the ModelDelta implemention, but + * it allows clients to modify the flags after the original object is + * constructed. + * + * @see IModelDelta#getNodes() + */ +@SuppressWarnings("restriction") +public class VMDelta extends ModelDelta { + + private VMDelta fParent; + private Object fElement; + private int fFlags; + private VMDelta[] fNodes = EMPTY_NODES; + private Object fReplacement; + private int fIndex; + private static final VMDelta[] EMPTY_NODES = new VMDelta[0]; + private int fChildCount = -1; + + /** + * Constructs a new delta for the given element. + * + * @param vmcElement model element + * @param flags change flags + */ + public VMDelta(Object element, int flags) { + super(element, flags); + fElement = element; + fFlags = flags; + } + + /** + * Constructs a new delta for the given element to be replaced + * with the specified replacement element. + * + * @param vmcElement model element + * @param replacement replacement element + * @param flags change flags + */ + public VMDelta(Object element, Object replacement, int flags) { + super(element, replacement, flags); + fElement = element; + fReplacement = replacement; + fFlags = flags; + } + + /** + * Constructs a new delta for the given element to be inserted at + * the specified index. + * + * @param vmcElement model element + * @param index insertion position + * @param flags change flags + */ + public VMDelta(Object element, int index, int flags) { + super(element, index, flags); + fElement = element; + fIndex = index; + fFlags = flags; + } + + /** + * Constructs a new delta for the given element at the specified index + * relative to its parent with the given number of children. + * + * @param element model element + * @param index insertion position + * @param flags change flags + * @param childCount number of children this node has + */ + public VMDelta(Object element, int index, int flags, int childCount) { + super(element, index, flags, childCount); + fElement = element; + fIndex = index; + fFlags = flags; + fChildCount = childCount; + } + + /** + * Returns the non-VMC element if one is set, otherwise returns the VMC + * element of this delta node. + * @see org.eclipse.debug.internal.ui.viewers.IModelDelta#getElement() + */ + @Override + public Object getElement() { + return fElement; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.IModelDelta#getFlags() + */ + @Override + public int getFlags() { + return fFlags; + } + + public void addFlags(int flags) { + fFlags |= flags; + } + + public void setChildCount(int count) { + fChildCount = count; + } + + /** + * Adds a child node to this delta with the given element and change flags, + * and returns the child delta. + * + * @param element child element to add + * @param flags change flags for child + * @return newly created child delta + */ + @Override + public VMDelta addNode(Object element, int flags) { + VMDelta node = new VMDelta(element, flags); + node.setParent(this); + addDelta(node); + return node; + } + + /** + * Adds a child node to this delta to replace the given element with the + * specified replacement element and change flags, and returns the + * newly created child delta. + * + * @param element child element to add to this delta + * @param replacement replacement element for the child element + * @param flags change flags + * @return newly created child delta + */ + @Override + public VMDelta addNode(Object element, Object replacement, int flags) { + VMDelta node = new VMDelta(element, replacement, flags); + node.setParent(this); + addDelta(node); + return node; + } + + /** + * Adds a child delta to this delta to insert the specified element at + * the given index, and returns the newly created child delta. + * + * @param element child element in insert + * @param index index of insertion + * @param flags change flags + * @return newly created child delta + */ + @Override + public VMDelta addNode(Object element, int index, int flags) { + VMDelta node = new VMDelta(element, index, flags); + node.setParent(this); + addDelta(node); + return node; + } + + /** + * Adds a child delta to this delta at the specified index with the + * given number of children, and returns the newly created child delta. + * + * @param element child element in insert + * @param index index of the element relative to parent + * @param flags change flags + * @param numChildren the number of children the element has + * @return newly created child delta + */ + @Override + public VMDelta addNode(Object element, int index, int flags, int numChildren) { + VMDelta node = new VMDelta(element, index, flags, numChildren); + node.setParent(this); + addDelta(node); + return node; + } + + /** + * Sets the parent delta of this delta + * + * @param node parent delta + */ + void setParent(VMDelta node) { + fParent = node; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.IModelDelta#getParent() + */ + @Override + public VMDelta getParentDelta() { + return fParent; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.IModelDelta#getReplacementElement() + */ + @Override + public Object getReplacementElement() { + return fReplacement; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.IModelDelta#getIndex() + */ + @Override + public int getIndex() { + return fIndex; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.IModelDelta#getNodes() + */ + @Override + public VMDelta[] getChildDeltas() { + return fNodes; + } + + private void addDelta(VMDelta delta) { + if (fNodes.length == 0) { + fNodes = new VMDelta[]{delta}; + } else { + VMDelta[] nodes = new VMDelta[fNodes.length + 1]; + System.arraycopy(fNodes, 0, nodes, 0, fNodes.length); + nodes[fNodes.length] = delta; + fNodes = nodes; + } + } + + @Override + public String toString() { + StringBuffer buf = new StringBuffer(); + buf.append("Model Delta Start\n"); //$NON-NLS-1$ + appendDetail(buf, this); + buf.append("Model Delta End\n"); //$NON-NLS-1$ + return buf.toString(); + } + + private void appendDetail(StringBuffer buf, VMDelta delta) { + buf.append("\tElement: "); //$NON-NLS-1$ + buf.append(delta.getElement()); + buf.append('\n'); + buf.append("\t\tFlags: "); //$NON-NLS-1$ + int flags = delta.getFlags(); + if (flags == 0) { + buf.append("NO_CHANGE"); //$NON-NLS-1$ + } else { + if ((flags & IModelDelta.ADDED) > 0) { + buf.append("ADDED | "); //$NON-NLS-1$ + } + if ((flags & IModelDelta.CONTENT) > 0) { + buf.append("CONTENT | "); //$NON-NLS-1$ + } + if ((flags & IModelDelta.EXPAND) > 0) { + buf.append("EXPAND | "); //$NON-NLS-1$ + } + if ((flags & IModelDelta.INSERTED) > 0) { + buf.append("INSERTED | "); //$NON-NLS-1$ + } + if ((flags & IModelDelta.REMOVED) > 0) { + buf.append("REMOVED | "); //$NON-NLS-1$ + } + if ((flags & IModelDelta.REPLACED) > 0) { + buf.append("REPLACED | "); //$NON-NLS-1$ + } + if ((flags & IModelDelta.SELECT) > 0) { + buf.append("SELECT | "); //$NON-NLS-1$ + } + if ((flags & IModelDelta.STATE) > 0) { + buf.append("STATE | "); //$NON-NLS-1$ + } + if ((flags & IModelDelta.INSTALL) > 0) { + buf.append("INSTALL | "); //$NON-NLS-1$ + } + if ((flags & IModelDelta.UNINSTALL) > 0) { + buf.append("UNINSTALL | "); //$NON-NLS-1$ + } + } + buf.append('\n'); + buf.append("\t\tIndex: "); //$NON-NLS-1$ + buf.append(delta.fIndex); + buf.append(" Child Count: "); //$NON-NLS-1$ + buf.append(delta.fChildCount); + buf.append('\n'); + IModelDelta[] nodes = delta.getChildDeltas(); + for (int i = 0; i < nodes.length; i++) { + appendDetail(buf, (VMDelta)nodes[i]); + } + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta#getChildCount() + */ + @Override + public int getChildCount() { + return fChildCount; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta#accept(org.eclipse.debug.internal.ui.viewers.provisional.IModelDeltaVisitor) + */ + @Override + public void accept(IModelDeltaVisitor visitor) { + doAccept(visitor, 0); + } + + @Override + protected void doAccept(IModelDeltaVisitor visitor, int depth) { + if (visitor.visit(this, depth)) { + ModelDelta[] childDeltas = getChildDeltas(); + for (int i = 0; i < childDeltas.length; i++) { + ((VMDelta)childDeltas[i]).doAccept(visitor, depth+1); + } + } + } + +} From 5dd23d30288de29523d19aba2020a6ef3c57c68f Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 24 Jan 2008 04:17:17 +0000 Subject: [PATCH 220/834] [192019] Added the missing setFlags() override, without which many of the views didn't work after the refactoring. --- .../src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java index 800d163a303..ac52e8d9834 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java @@ -111,10 +111,16 @@ public class VMDelta extends ModelDelta { return fFlags; } - public void addFlags(int flags) { - fFlags |= flags; + /** + * Sets this delta's flags. + * + * @param flags + */ + @Override + public void setFlags(int flags) { + fFlags = flags; } - + public void setChildCount(int count) { fChildCount = count; } From bd4954956112a19294613417b02b949c05b99164 Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Thu, 31 Jan 2008 15:58:01 +0000 Subject: [PATCH 221/834] IDMContext.java - spelling DsfServiceID.java - new helper utility class use to generate class IDs DsfMemoryBlockRetrieval.java - uses DsfServiceID now SyncRegisterDataAccess.java - uses DsfServiceID now AlarmCellModifier.java - uses DsfServiceID now DisplayDsfExecutor.java - changed getDisplayDsfExecutor to return DisplayDsfExecutor instead opf DsfExecutor. AbstractCachingVMProvider.java - spelling/format --- .../register/SyncRegisterDataAccess.java | 19 ++------- .../debug/model/DsfMemoryBlockRetrieval.java | 9 +---- .../dsf/ui/concurrent/DisplayDsfExecutor.java | 4 +- .../update/AbstractCachingVMProvider.java | 9 +---- .../eclipse/dd/dsf/datamodel/IDMContext.java | 2 +- .../eclipse/dd/dsf/service/DsfServiceID.java | 39 +++++++++++++++++++ 6 files changed, 48 insertions(+), 34 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServiceID.java diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java index 6f777e2623e..e5842737c37 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java @@ -33,6 +33,7 @@ import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMData; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMData; import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.service.DsfServiceID; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; @@ -62,11 +63,12 @@ public class SyncRegisterDataAccess { @ThreadSafe private synchronized IRegisters getService() { + String serviceId = DsfServiceID.createServiceId( IRegisters.class, fSession.getId() ); if (fServiceTracker == null) { try { fServiceTracker = new ServiceTracker( DsfDebugUIPlugin.getBundleContext(), - DsfDebugUIPlugin.getBundleContext().createFilter(getServiceFilter()), null); + DsfDebugUIPlugin.getBundleContext().createFilter(serviceId), null); fServiceTracker.open(); } catch (InvalidSyntaxException e) { return null; @@ -75,21 +77,6 @@ public class SyncRegisterDataAccess { return (IRegisters) fServiceTracker.getService(); } - private String getServiceFilter() { - StringBuffer filter = new StringBuffer(); - filter.append("(&"); //$NON-NLS-1$ - filter.append("(OBJECTCLASS="); //$NON-NLS-1$ - filter.append(IRegisters.class.getName()); - filter.append(')'); - filter.append('('); - filter.append(IDsfService.PROP_SESSION_ID); - filter.append('='); - filter.append(fSession.getId()); - filter.append(')'); - filter.append(')'); - return filter.toString(); - } - @ThreadSafe public synchronized void dispose() { if ( fServiceTracker != null ) { diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java index 51ec8716f60..542cab5a128 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java @@ -33,6 +33,7 @@ import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext; import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData; import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryDMContext; +import org.eclipse.dd.dsf.service.DsfServiceID; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.debug.core.DebugException; @@ -93,13 +94,7 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl // amalgamated one because it is less error prone (and we are lazy). // Create a tracker for the MemoryService - String memoryServiceFilter = "(&" + //$NON-NLS-1$ - "(OBJECTCLASS=" //$NON-NLS-1$ - + IMemory.class.getName() - + ")" + //$NON-NLS-1$ - "(" + IDsfService.PROP_SESSION_ID //$NON-NLS-1$ - + "=" + dmc.getSessionId() + ")" + //$NON-NLS-1$//$NON-NLS-2$ - ")"; //$NON-NLS-1$ + String memoryServiceFilter = DsfServiceID.createServiceId( IMemory.class, dmc.getSessionId() ); try { fMemoryServiceTracker = new ServiceTracker( diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/DisplayDsfExecutor.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/DisplayDsfExecutor.java index 8c47374294b..6738afc9bff 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/DisplayDsfExecutor.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/DisplayDsfExecutor.java @@ -23,7 +23,6 @@ import java.util.concurrent.TimeUnit; import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor; import org.eclipse.dd.dsf.concurrent.DsfExecutable; -import org.eclipse.dd.dsf.concurrent.DsfExecutor; import org.eclipse.swt.SWT; import org.eclipse.swt.SWTException; import org.eclipse.swt.widgets.Display; @@ -46,7 +45,7 @@ public class DisplayDsfExecutor extends DefaultDsfExecutor * @param display Display to create an executor for. * @return The new (or re-used) executor. */ - public static DsfExecutor getDisplayDsfExecutor(Display display) { + public static DisplayDsfExecutor getDisplayDsfExecutor(Display display) { synchronized (fExecutors) { DisplayDsfExecutor executor = fExecutors.get(display); if (executor == null) { @@ -255,7 +254,6 @@ public class DisplayDsfExecutor extends DefaultDsfExecutor @Override public boolean isShutdown() { - // TODO Auto-generated method stub return super.isShutdown(); } } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java index 5c5fa52eba4..b60827b5529 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java @@ -99,7 +99,7 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa } /** - * A base calss for the entry in the cache. Since the cache maintains + * A base class for the entry in the cache. Since the cache maintains * a double-linked list through all the entries, the linked list references * are maintained in this class. */ @@ -394,7 +394,7 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa }); super.updateNode(node, updates); } else if (update.getOffset() < 0 ) { - // The udpate requested all children. Fill in all children assuming that + // The update requested all children. Fill in all children assuming that // the children array is complete. // The following assert should never fail given the first if statement. @@ -548,9 +548,6 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa } } - - - @Override public void handleEvent(final Object event) { IElementUpdateTester elementTester = getActiveUpdatePolicy().getTesterTester(event); @@ -611,7 +608,6 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa } return proxy; } - /** * Called when a given all cache entries for the given root element have @@ -757,5 +753,4 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa } return null; } - } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMContext.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMContext.java index 075dd49fc72..14379cf57cb 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMContext.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMContext.java @@ -45,7 +45,7 @@ public interface IDMContext extends IAdaptable * originated. The session ID allows clients to choose the correct * dispatch thread with which to access the service, and it allows the * service to be uniquely identified among other sessions. - * @return Session ID of the service that originated the cotnext. + * @return Session ID of the service that originated the context. */ public String getSessionId(); diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServiceID.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServiceID.java new file mode 100644 index 00000000000..ceb587e2f5d --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServiceID.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.dsf.service; + +/** + * Convenience class to create the somewhat complicated service ID which + * can then be used with the DsfServicesTracker or OSGI services tracker + * to find a desired service. + */ + +public class DsfServiceID { + + @SuppressWarnings("unchecked") + public static String createServiceId(Class serviceClass, String sessionId) { + + String serviceId = + "(&" + //$NON-NLS-1$ + "(OBJECTCLASS=" + //$NON-NLS-1$ + serviceClass.getName() + + ")" + //$NON-NLS-1$ + "(" + //$NON-NLS-1$ + IDsfService.PROP_SESSION_ID + + "=" + //$NON-NLS-1$ + sessionId + + ")" + //$NON-NLS-1$ + ")" ; //$NON-NLS-1$ + + return serviceId; + } +} From 2beca6714572c4f1b361f8cf318983030ad4e87f Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 31 Jan 2008 18:54:15 +0000 Subject: [PATCH 222/834] [192019] View Model refactoring cont.: fixed refactoring bugs found during PDA development. --- .../sourcelookup/MISourceDisplayAdapter.java | 2 +- .../viewmodel/launch/StackFramesVMNode.java | 1 + .../register/SyncRegisterDataAccess.java | 4 ++-- .../dd/dsf/debug/model/DsfMemoryBlock.java | 2 +- .../debug/model/DsfMemoryBlockRetrieval.java | 4 ++-- .../dsf/ui/concurrent/DisplayDsfExecutor.java | 21 ++++++------------- .../update/AbstractCachingVMProvider.java | 5 +++++ .../{DsfServiceID.java => DsfServices.java} | 18 +++++++++------- 8 files changed, 28 insertions(+), 29 deletions(-) rename plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/{DsfServiceID.java => DsfServices.java} (66%) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java index 18eb513a053..3b51b20ed0f 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java @@ -416,7 +416,7 @@ public class MISourceDisplayAdapter implements ISourceDisplay fServicesTracker.dispose(); fSourceLookup.removeParticipants(new ISourceLookupParticipant[] {fSourceLookupParticipant}); - // fSourceLookupParticipant is disposed by teh source lookup director + // fSourceLookupParticipant is disposed by the source lookup director // Need to remove annotations in UI thread. //fIPManager.removeAllAnnotations(); diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java index e13ea7cfa8d..2e5f11b5c9e 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java @@ -262,6 +262,7 @@ public class StackFramesVMNode extends AbstractDMVMNode @Override protected void handleFailedUpdate(IViewerUpdate update) { if (update instanceof ILabelUpdate) { + update.done(); // Avoid repainting the label if it's not available. This only slows // down the display. } else { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java index e5842737c37..f7f3a08eccc 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java @@ -33,7 +33,7 @@ import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMData; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMData; import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; -import org.eclipse.dd.dsf.service.DsfServiceID; +import org.eclipse.dd.dsf.service.DsfServices; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; @@ -63,7 +63,7 @@ public class SyncRegisterDataAccess { @ThreadSafe private synchronized IRegisters getService() { - String serviceId = DsfServiceID.createServiceId( IRegisters.class, fSession.getId() ); + String serviceId = DsfServices.createServiceFilter( IRegisters.class, fSession.getId() ); if (fServiceTracker == null) { try { fServiceTracker = new ServiceTracker( diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java index 08d217fee8b..9e5ad02079d 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java @@ -415,7 +415,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens final Addr64 address = new Addr64(bigAddress); final int word_size = 1; - // Use a Query to synchronise the downstream calls + // Use a Query to synchronize the downstream calls Query query = new Query() { @Override protected void execute(final DataRequestMonitor drm) { diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java index 542cab5a128..922f5a3adde 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java @@ -33,7 +33,7 @@ import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext; import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData; import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryDMContext; -import org.eclipse.dd.dsf.service.DsfServiceID; +import org.eclipse.dd.dsf.service.DsfServices; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.debug.core.DebugException; @@ -94,7 +94,7 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl // amalgamated one because it is less error prone (and we are lazy). // Create a tracker for the MemoryService - String memoryServiceFilter = DsfServiceID.createServiceId( IMemory.class, dmc.getSessionId() ); + String memoryServiceFilter = DsfServices.createServiceFilter( IMemory.class, dmc.getSessionId() ); try { fMemoryServiceTracker = new ServiceTracker( diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/DisplayDsfExecutor.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/DisplayDsfExecutor.java index 6738afc9bff..ddede1c2a5f 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/DisplayDsfExecutor.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/DisplayDsfExecutor.java @@ -113,10 +113,13 @@ public class DisplayDsfExecutor extends DefaultDsfExecutor } } - if(e[0] instanceof RuntimeException) + if(e[0] instanceof RuntimeException) { throw (RuntimeException) e[0]; - else if(e[0] instanceof Exception) + } else if (e[0] instanceof Error) { + throw (Error) e[0]; + } else if(e[0] instanceof Exception) { throw (Exception) e[0]; + } return (V) v[0]; } @@ -140,15 +143,10 @@ public class DisplayDsfExecutor extends DefaultDsfExecutor return new Runnable() { public void run() { - final Throwable[] e = new Throwable[1]; try { fDisplay.syncExec(new Runnable() { public void run() { - try { - runnable.run(); - } catch(Throwable exception) { - e[0] = exception; - } + runnable.run(); } }); } catch (SWTException swtException) { @@ -156,8 +154,6 @@ public class DisplayDsfExecutor extends DefaultDsfExecutor DisplayDsfExecutor.super.shutdown(); } } - if(e[0] instanceof RuntimeException) - throw (RuntimeException) e[0]; } }; } @@ -251,9 +247,4 @@ public class DisplayDsfExecutor extends DefaultDsfExecutor public List shutdownNow() { return (List)Collections.EMPTY_LIST; } - - @Override - public boolean isShutdown() { - return super.isShutdown(); - } } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java index b60827b5529..98e7b4acc76 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java @@ -301,6 +301,8 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa if(getStatus().isOK()) { entry.fHasChildren = this.getData(); update.setHasChilren(getData()); + } else { + update.setStatus(getStatus()); } update.done(); } @@ -333,6 +335,8 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa if(getStatus().isOK()) { entry.fChildrenCount = this.getData(); update.setChildCount(getData()); + } else { + update.setStatus(getStatus()); } update.done(); } @@ -753,4 +757,5 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa } return null; } + } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServiceID.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServices.java similarity index 66% rename from plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServiceID.java rename to plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServices.java index ceb587e2f5d..bfa835454c0 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServiceID.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServices.java @@ -12,16 +12,18 @@ package org.eclipse.dd.dsf.service; /** - * Convenience class to create the somewhat complicated service ID which - * can then be used with the DsfServicesTracker or OSGI services tracker - * to find a desired service. + * Utility class containing status methods to use with DSF services. */ +public class DsfServices { -public class DsfServiceID { - - @SuppressWarnings("unchecked") - public static String createServiceId(Class serviceClass, String sessionId) { - + /** + * Creates a properly formatted OSGi service filter for a DSF service based + * on service class and session ID. + * @param serviceClass Class of the service to create the filter for. + * @param sessionId Session ID of the session that the service belongs to. + * @return Filter string to identify the given service. + */ + public static String createServiceFilter(Class serviceClass, String sessionId) { String serviceId = "(&" + //$NON-NLS-1$ "(OBJECTCLASS=" + //$NON-NLS-1$ From b7c32e2b66bdc6c452a507fb95f4f6658592c2ff Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Fri, 1 Feb 2008 14:25:37 +0000 Subject: [PATCH 223/834] Fix for bug 214806 --- .../debug/ui/viewmodel/variable/VariableCellModifier.java | 5 +++++ .../src/org/eclipse/dd/dsf/debug/service/IExpressions.java | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableCellModifier.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableCellModifier.java index 5948872679e..dc61745caee 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableCellModifier.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableCellModifier.java @@ -9,6 +9,7 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.variable; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMData; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionCellModifier; import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValuePreferenceStore; @@ -53,6 +54,10 @@ public class VariableCellModifier extends WatchExpressionCellModifier { if (getVariableDMC(element) == null) return false; + IExpressionDMData exprData = fDataAccess.readVariable(element); + + if ( ( exprData != null ) && ( ! exprData.isEditable() ) ) return false; + return true ; } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java index 4158552a8c9..9919384dbb3 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java @@ -122,6 +122,11 @@ public interface IExpressions extends IFormattedValues { * This method needs to be defined. */ IRegisters.IRegisterDMContext getRegister(); + + /** + * @return True if this expression's value can be edited. False otherwise. + */ + boolean isEditable(); } /** From 857c836ecfbfe14ad5c22d3d9339f2e1ebe9bbc7 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Fri, 1 Feb 2008 17:37:34 +0000 Subject: [PATCH 224/834] Fix for Bug 217460 User modifying an expression was not working --- .../dd/dsf/debug/ui/viewmodel/variable/VariableCellModifier.java | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableCellModifier.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableCellModifier.java index dc61745caee..86b8c63fa80 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableCellModifier.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableCellModifier.java @@ -126,6 +126,7 @@ public class VariableCellModifier extends WatchExpressionCellModifier { formatId = IFormattedValues.NATURAL_FORMAT; } + fDataAccess.writeVariable(element, (String) value, formatId); fProvider.handleEvent(new UserEditEvent(element)); } } From 8fda4772aa64eaa388cb92ed9414940a2c52d3e3 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Fri, 8 Feb 2008 20:58:49 +0000 Subject: [PATCH 225/834] Fix for Bug 214806 New canWriteExpression() method is added to IExpressions and is used to know if the user should be given the option to edit the value of an expression in the views. --- .../variable/SyncVariableDataAccess.java | 107 ++++++++++++++++-- .../variable/VariableCellModifier.java | 10 +- .../dd/dsf/debug/service/IExpressions.java | 16 ++- 3 files changed, 112 insertions(+), 21 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java index 41100d7cc2c..34060bfc2fe 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java @@ -106,7 +106,7 @@ public class SyncVariableDataAccess { @Override protected void execute(final DataRequestMonitor rm) { /* - * Guard agains the session being disposed. If session is disposed + * Guard against the session being disposed. If session is disposed * it could mean that the executor is shut-down, which in turn could * mean that we can't complete the RequestMonitor argument. in that * case, cancel to notify waiting thread. @@ -159,7 +159,7 @@ public class SyncVariableDataAccess { public IExpressionDMData readVariable(Object element) { /* - * Get the DMC and the session. If element is not an register DMC, or + * Get the DMC and the session. If element is not an expression DMC, or * session is stale, then bail out. */ IExpressionDMContext dmc = getExpressionDMC(element); @@ -169,7 +169,7 @@ public class SyncVariableDataAccess { /* * Create the query to request the value from service. Note: no need to - * guard agains RejectedExecutionException, because + * guard against RejectedExecutionException, because * DsfSession.getSession() above would only return an active session. */ GetVariableValueQuery query = new GetVariableValueQuery(dmc); @@ -226,7 +226,7 @@ public class SyncVariableDataAccess { } /* - * Write the bit field using a string/format style. + * Write the expression value using a string/format style. */ service.writeExpression( fDmc, @@ -272,7 +272,7 @@ public class SyncVariableDataAccess { /* * Create the query to write the value to the service. Note: no need to - * guard agains RejectedExecutionException, because + * guard against RejectedExecutionException, because * DsfSession.getSession() above would only return an active session. */ SetVariableValueQuery query = new SetVariableValueQuery(dmc, value, formatId); @@ -337,7 +337,7 @@ public class SyncVariableDataAccess { } /* - * Write the bit field using a string/format style. + * Get the available formats from the service. */ service.getAvailableFormats( fDmc, @@ -381,7 +381,7 @@ public class SyncVariableDataAccess { /* * Create the query to write the value to the service. Note: no need to - * guard agains RejectedExecutionException, because + * guard against RejectedExecutionException, because * DsfSession.getSession() above would only return an active session. */ GetSupportFormatsValueQuery query = new GetSupportFormatsValueQuery(dmc); @@ -479,7 +479,7 @@ public class SyncVariableDataAccess { /* * Create the query to write the value to the service. Note: no need to - * guard agains RejectedExecutionException, because + * guard against RejectedExecutionException, because * DsfSession.getSession() above would only return an active session. */ GetFormattedValueValueQuery query = new GetFormattedValueValueQuery(dmc, formatId); @@ -499,4 +499,95 @@ public class SyncVariableDataAccess { return null; } } + + private class CanWriteExpressionQuery extends Query { + + private IExpressionDMContext fDmc; + + public CanWriteExpressionQuery(IExpressionDMContext dmc) { + super(); + fDmc = dmc; + } + + @Override + protected void execute(final DataRequestMonitor rm) { + /* + * We're in another dispatch, so we must guard against executor + * shutdown again. + */ + final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); + if (session == null) { + cancel(false); + return; + } + + /* + * Guard against a disposed service + */ + IExpressions service = getService(); + if (service == null) { + rm .setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + service.canWriteExpression(fDmc, new DataRequestMonitor(session.getExecutor(), rm) { + @Override + protected void handleCompleted() { + /* + * We're in another dispatch, so we must guard against executor shutdown again. + */ + if (!DsfSession.isSessionActive(session.getId())) { + CanWriteExpressionQuery.this.cancel(false); + return; + } + super.handleCompleted(); + } + + @Override + protected void handleOK() { + /* + * All good set return value. + */ + rm.setData(getData()); + rm.done(); + } + }); + } + } + + public boolean canWriteExpression(Object element) { + /* + * Get the DMC and the session. If element is not an expression DMC, or + * session is stale, then bail out. + */ + IExpressionDMContext dmc = getExpressionDMC(element); + if (dmc == null) return false; + DsfSession session = DsfSession.getSession(dmc.getSessionId()); + if (session == null) return false; + + /* + * Create the query to make the request to the service. Note: no need to + * guard against RejectedExecutionException, because + * DsfSession.getSession() above would only return an active session. + */ + CanWriteExpressionQuery query = new CanWriteExpressionQuery(dmc); + session.getExecutor().execute(query); + + /* + * Now we have the data, go and get it. Since the call is completed now + * the ".get()" will not suspend it will immediately return with the + * data. + */ + try { + return query.get(); + } catch (InterruptedException e) { + assert false; + return false; + } catch (ExecutionException e) { + return false; + } + } + + } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableCellModifier.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableCellModifier.java index 86b8c63fa80..222b01c536c 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableCellModifier.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableCellModifier.java @@ -9,7 +9,6 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.variable; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; -import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMData; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionCellModifier; import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValuePreferenceStore; @@ -51,14 +50,11 @@ public class VariableCellModifier extends WatchExpressionCellModifier { if (IDebugVMConstants.COLUMN_ID__VALUE.equals(property)) { // Make sure we are are dealing with a valid set of information. - if (getVariableDMC(element) == null) + if (getVariableDMC(element) == null) { return false; + } - IExpressionDMData exprData = fDataAccess.readVariable(element); - - if ( ( exprData != null ) && ( ! exprData.isEditable() ) ) return false; - - return true ; + return fDataAccess.canWriteExpression(element); } return super.canModify(element, property); diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java index 9919384dbb3..c77145be767 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java @@ -121,12 +121,7 @@ public interface IExpressions extends IFormattedValues { /** * This method needs to be defined. */ - IRegisters.IRegisterDMContext getRegister(); - - /** - * @return True if this expression's value can be edited. False otherwise. - */ - boolean isEditable(); + IRegisters.IRegisterDMContext getRegister(); } /** @@ -217,6 +212,15 @@ public interface IExpressions extends IFormattedValues { */ void getBaseExpressions(IExpressionDMContext exprContext, DataRequestMonitor rm); + /** + * This method indicates if an expression can be written to. + * + * @param expressionContext: The data model context representing an expression. + * + * @param rm: Data Request monitor containing True if this expression's value can be edited. False otherwise. + */ + void canWriteExpression(IExpressionDMContext expressionContext, DataRequestMonitor rm); + /** * This method supports the writing/modifying the value of the expression. * From db8b348da7c73cedd4f63e01af9bb0e8134dc53f Mon Sep 17 00:00:00 2001 From: Francois Chouinard Date: Mon, 11 Feb 2008 17:32:56 +0000 Subject: [PATCH 226/834] BreakpointManager patch fro M5. --- .../META-INF/MANIFEST.MF | 5 ++- .../service/IDsfBreakpointExtension.java | 44 +++++++++++++++++++ .../META-INF/MANIFEST.MF | 2 +- .../org.eclipse.dd.dsf/META-INF/MANIFEST.MF | 2 +- 4 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IDsfBreakpointExtension.java diff --git a/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF index 42715ebf451..8edc247599b 100644 --- a/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF @@ -2,14 +2,15 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Debug Services Framework Debug Bundle-Vendor: Eclipse.org -Bundle-SymbolicName: org.eclipse.dd.dsf.debug +Bundle-SymbolicName: org.eclipse.dd.dsf.debug;singleton:=true Bundle-Version: 1.0.0.qualifier 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, - org.eclipse.cdt.core + org.eclipse.cdt.core, + org.eclipse.cdt.debug.core Eclipse-LazyStart: true Export-Package: org.eclipse.dd.dsf.debug.model, org.eclipse.dd.dsf.debug.service, diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IDsfBreakpointExtension.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IDsfBreakpointExtension.java new file mode 100644 index 00000000000..6bd9dbf68c8 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IDsfBreakpointExtension.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.service; + +import org.eclipse.cdt.debug.core.model.ICBreakpointExtension; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; + +/** + * An extension to {@link ICBreakpoint} with model-specific breakpoint + * attributes. Different debug models can use the standard C breakpoints that + * extend the basic ICBreakpoint. The can use this extension + * mechanism to edit and store model-specific data in the original breakpoint + * object. + * + * A breakpoint extension is defined by an extension of kind + * "org.eclipse.cdt.debug.core.BreakpointExtension". + * The ICBreakpoint implementation instantiates breakpoint + * extensions registered for its specific marker type when a client requests + * extensions for a given debug model type. Thus the extension classes and + * plugins that declare them are not loaded unless requested by a client. + * + * @see ICBreakpoint#getExtension(String, Class) + */ +public interface IDsfBreakpointExtension extends ICBreakpointExtension { + + public void setTargetFilter( IContainerDMContext target ) throws CoreException; + public void removeTargetFilter( IContainerDMContext target ) throws CoreException; + public IContainerDMContext[] getTargetFilters() throws CoreException; + + public void setThreadFilters( IExecutionDMContext[] threads ) throws CoreException; + public void removeThreadFilters( IExecutionDMContext[] threads ) throws CoreException; + public IExecutionDMContext[] getThreadFilters( IContainerDMContext target ) throws CoreException; + +} diff --git a/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF index bf9157f877d..7eda21ec60b 100644 --- a/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Debug Services Framework UI Bundle-Vendor: Eclipse.org -Bundle-SymbolicName: org.eclipse.dd.dsf.ui +Bundle-SymbolicName: org.eclipse.dd.dsf.ui;singleton:=true Bundle-Version: 1.0.0.qualifier Bundle-Activator: org.eclipse.dd.dsf.ui.DsfUIPlugin Bundle-Localization: plugin diff --git a/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF index 7464f6a24e4..14dea406cf1 100644 --- a/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Debug Services Framework Core Bundle-Vendor: Eclipse.org -Bundle-SymbolicName: org.eclipse.dd.dsf +Bundle-SymbolicName: org.eclipse.dd.dsf;singleton:=true Bundle-Version: 1.0.0.qualifier Bundle-Activator: org.eclipse.dd.dsf.DsfPlugin Bundle-Localization: plugin From e9b345d4fa0c8f12a2a9eadf75a1299ee70d5429 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Mon, 11 Feb 2008 22:25:19 +0000 Subject: [PATCH 227/834] [218573] Added process created event handling to make sure that new processes appear in Debug view. --- .../dd/dsf/debug/ui/viewmodel/launch/StandardProcessVMNode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessVMNode.java index e1e0a7d18cb..9a0a4cb0e20 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessVMNode.java @@ -208,7 +208,7 @@ public class StandardProcessVMNode extends AbstractVMNode { } protected void handleCreate(DebugEvent event, ModelDelta parent) { - // do nothing - Launch change notification handles this + parent.setFlags(parent.getFlags() | IModelDelta.CONTENT); } protected void handleTerminate(DebugEvent event, ModelDelta parent) { From 3dd4c544e1bad9949799dfc3ce5171dc065de51f Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Mon, 11 Feb 2008 22:33:16 +0000 Subject: [PATCH 228/834] Added EVALUATION to the StateChangeReason enum. --- .../src/org/eclipse/dd/dsf/debug/service/IRunControl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java index 1b1c5e50454..a7f5b14bab8 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java @@ -44,7 +44,7 @@ public interface IRunControl extends IDMService public interface IContainerDMContext extends IExecutionDMContext {} /** Flag indicating reason context state change. */ - public enum StateChangeReason { UNKNOWN, USER_REQUEST, STEP, BREAKPOINT, EXCEPTION, CONTAINER, WATCHPOINT, SIGNAL, SHAREDLIB, ERROR }; + public enum StateChangeReason { UNKNOWN, USER_REQUEST, STEP, BREAKPOINT, EXCEPTION, CONTAINER, WATCHPOINT, SIGNAL, SHAREDLIB, ERROR, EVALUATION }; /** * Indicates that the given thread has suspended. From c10f8e47d0b17fed1dbe1a7fb13eb58e9f853d31 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Mon, 11 Feb 2008 22:33:38 +0000 Subject: [PATCH 229/834] Fixed a potential NPE. --- .../dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java index 2b826894e10..17f6612dca9 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java @@ -54,7 +54,7 @@ public class DsfMISourceLookupParticipant implements ISourceLookupParticipant { public DsfMISourceLookupParticipant(DsfSession session) { fSessionId = session.getId(); - fExecutor = DsfSession.getSession(fSessionId).getExecutor(); + fExecutor = session.getExecutor(); fServicesTracker = new DsfServicesTracker(DsfDebugPlugin.getBundleContext(), fSessionId); } From cedbca9401863066fd4b0a9323f5693503f122c2 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Mon, 11 Feb 2008 22:52:17 +0000 Subject: [PATCH 230/834] Added comment annotations. --- .../org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMNode.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMNode.java index e3df240e8e7..9bdb2d6569d 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMNode.java @@ -14,6 +14,7 @@ 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.Immutable; import org.eclipse.dd.dsf.datamodel.DMContexts; @@ -219,6 +220,7 @@ abstract public class AbstractDMVMNode extends AbstractVMNode implements IVMNode } } + @ConfinedToDsfExecutor("getSession().getExecutor()") protected void updateHasElementsInSessionThread(final IHasChildrenUpdate update) { update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.NOT_SUPPORTED, "Not implemented, clients should call to update all children instead.", null)); //$NON-NLS-1$ update.done(); @@ -240,6 +242,7 @@ abstract public class AbstractDMVMNode extends AbstractVMNode implements IVMNode } } + @ConfinedToDsfExecutor("getSession().getExecutor()") protected void updateElementCountInSessionThread(final IChildrenCountUpdate update) { update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.NOT_SUPPORTED, "Not implemented, clients should call to update all children instead.", null)); //$NON-NLS-1$ update.done(); @@ -262,6 +265,7 @@ abstract public class AbstractDMVMNode extends AbstractVMNode implements IVMNode } } + @ConfinedToDsfExecutor("getSession().getExecutor()") abstract protected void updateElementsInSessionThread(IChildrenUpdate update); /** From 91e43c46ad2f35eb88e6345bb7bb5a0e26de56fd Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Mon, 11 Feb 2008 23:56:56 +0000 Subject: [PATCH 231/834] [179096] Added suspend trigger to open debug perspective on suspend. --- .../META-INF/MANIFEST.MF | 3 + .../debug/ui/contexts/DsfSuspendTrigger.java | 121 ++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/contexts/DsfSuspendTrigger.java diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF index ec919b9fc41..09411a94f98 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF @@ -23,6 +23,7 @@ Eclipse-LazyStart: true Export-Package: org.eclipse.dd.dsf.debug.ui, org.eclipse.dd.dsf.debug.ui.actions, + org.eclipse.dd.dsf.debug.ui.contexts, org.eclipse.dd.dsf.debug.ui.sourcelookup, org.eclipse.dd.dsf.debug.ui.viewmodel, org.eclipse.dd.dsf.debug.ui.viewmodel.expression, @@ -30,5 +31,7 @@ Export-Package: org.eclipse.dd.dsf.debug.ui.viewmodel.modules, org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat, org.eclipse.dd.dsf.debug.ui.viewmodel.register, + org.eclipse.dd.dsf.debug.ui.viewmodel.update, + org.eclipse.dd.dsf.debug.ui.viewmodel.update.actions, org.eclipse.dd.dsf.debug.ui.viewmodel.variable Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/contexts/DsfSuspendTrigger.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/contexts/DsfSuspendTrigger.java new file mode 100644 index 00000000000..e9394594cc4 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/contexts/DsfSuspendTrigger.java @@ -0,0 +1,121 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.ui.contexts; + +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.ISafeRunnable; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.ListenerList; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +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.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.ui.contexts.ISuspendTrigger; +import org.eclipse.debug.ui.contexts.ISuspendTriggerListener; + +/** + * DSF implementation of the ISuspendTrigger interface. The suspend trigger + * is used by the IDE to trigger activation of the debug perspective when + * the debugger suspends. + * + * @see ISuspendTrigger + */ +@ConfinedToDsfExecutor("fSession.getExecutor()") +public class DsfSuspendTrigger implements ISuspendTrigger { + + private final DsfSession fSession; + private final ILaunch fLaunch; + private boolean fDisposed = false; + private boolean fEventListenerRegisterd = false; + + @ThreadSafe + private final ListenerList fListeners = new ListenerList(); + + @ThreadSafe + public DsfSuspendTrigger(DsfSession session, ILaunch launch) { + fSession = session; + fLaunch = launch; + try { + fSession.getExecutor().execute(new DsfRunnable() { + public void run() { + if (!fDisposed) { + fSession.addServiceEventListener(DsfSuspendTrigger.this, null); + fEventListenerRegisterd = true; + } + } + }); + } catch(RejectedExecutionException e) {} + } + + @ThreadSafe + public void addSuspendTriggerListener(ISuspendTriggerListener listener) { + if (fListeners != null) { + fListeners.add(listener); + } + } + + @ThreadSafe + public void removeSuspendTriggerListener(ISuspendTriggerListener listener) { + if (fListeners != null) { + fListeners.remove(listener); + } + } + + public void dispose() { + if (fEventListenerRegisterd) { + fSession.removeServiceEventListener(this); + } + fDisposed = true; + } + + @DsfServiceEventHandler + public void eventDispatched(IRunControl.ISuspendedDMEvent e) { + final Object[] listeners = fListeners.getListeners(); + if (listeners.length != 0) { + new Job("DSF Suspend Trigger Notify") { //$NON-NLS-1$ + { + setSystem(true); + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + final MultiStatus status = new MultiStatus(DsfDebugUIPlugin.PLUGIN_ID, 0, "DSF Suspend Trigger Notify Job Status", null); //$NON-NLS-1$ + for (int i = 0; i < listeners.length; i++) { + final ISuspendTriggerListener listener = (ISuspendTriggerListener) listeners[i]; + SafeRunner.run(new ISafeRunnable() { + public void run() throws Exception { + listener.suspended(fLaunch, null); + } + + public void handleException(Throwable exception) { + status.add(new Status( + IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, "Exception while calling suspend trigger listeners", exception)); //$NON-NLS-1$ + } + + }); + } + return status; + } + }.schedule(); + } + } + +} From 6321552cfe11b8c0a496f9b6c35ec5a431c705b8 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 12 Feb 2008 00:03:36 +0000 Subject: [PATCH 232/834] [216376] Changed expression nodes to use new 3.4M5 watch expression APIs. --- .../register/RegisterBitFieldVMNode.java | 34 +++++-------------- .../register/RegisterGroupVMNode.java | 34 +++++-------------- .../ui/viewmodel/register/RegisterVMNode.java | 34 +++++-------------- .../ui/viewmodel/variable/VariableVMNode.java | 34 +++++-------------- 4 files changed, 32 insertions(+), 104 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java index c49e683dfe7..83bc2e40d09 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java @@ -44,19 +44,14 @@ import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; -import org.eclipse.debug.core.DebugException; -import org.eclipse.debug.core.ILaunch; -import org.eclipse.debug.core.model.IDebugTarget; import org.eclipse.debug.core.model.IExpression; -import org.eclipse.debug.core.model.IValue; -import org.eclipse.debug.core.model.IVariable; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementEditor; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; -import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapterExtension; +import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapter2; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.ComboBoxCellEditor; @@ -71,7 +66,7 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode { protected class BitFieldVMC extends DMVMContext - implements IVariable, IFormattedValueVMContext + implements IFormattedValueVMContext { private IExpression fExpression; public BitFieldVMC(IDMContext dmc) { @@ -91,7 +86,7 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode public Object getAdapter(Class adapter) { if (fExpression != null && adapter.isAssignableFrom(fExpression.getClass())) { return fExpression; - } else if (adapter.isAssignableFrom(IWatchExpressionFactoryAdapterExtension.class)) { + } else if (adapter.isAssignableFrom(IWatchExpressionFactoryAdapter2.class)) { return fBitFieldExpressionFactory; } else { return super.getAdapter(adapter); @@ -112,29 +107,16 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode public int hashCode() { return super.hashCode() + (fExpression != null ? fExpression.hashCode() : 0); } - - public String getName() throws DebugException { return toString(); } - public String getReferenceTypeName() throws DebugException { return ""; } //$NON-NLS-1$ - public IValue getValue() throws DebugException { return null; } - public boolean hasValueChanged() throws DebugException { return false; } - public void setValue(IValue value) throws DebugException {} - public void setValue(String expression) throws DebugException {} - public boolean supportsValueModification() { return false; } - public boolean verifyValue(IValue value) throws DebugException { return false; } - public boolean verifyValue(String expression) throws DebugException { return false; } - public IDebugTarget getDebugTarget() { return null;} - public ILaunch getLaunch() { return null; } - public String getModelIdentifier() { return DsfDebugUIPlugin.PLUGIN_ID; } } - protected class BitFieldExpressionFactory implements IWatchExpressionFactoryAdapterExtension { + protected class BitFieldExpressionFactory implements IWatchExpressionFactoryAdapter2 { - public boolean canCreateWatchExpression(IVariable variable) { - return variable instanceof BitFieldVMC; + public boolean canCreateWatchExpression(Object element) { + return element instanceof BitFieldVMC; } - public String createWatchExpression(IVariable variable) throws CoreException { - BitFieldVMC bitFieldVmc = ((BitFieldVMC)variable); + public String createWatchExpression(Object element) throws CoreException { + BitFieldVMC bitFieldVmc = ((BitFieldVMC)element); StringBuffer exprBuf = new StringBuffer(); IRegisterGroupDMContext groupDmc = diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java index aa70784c236..06d1a9d0154 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java @@ -36,12 +36,7 @@ import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.dm.CompositeDMVMContext; import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; -import org.eclipse.debug.core.DebugException; -import org.eclipse.debug.core.ILaunch; -import org.eclipse.debug.core.model.IDebugTarget; import org.eclipse.debug.core.model.IExpression; -import org.eclipse.debug.core.model.IValue; -import org.eclipse.debug.core.model.IVariable; import org.eclipse.debug.internal.ui.DebugPluginImages; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementEditor; @@ -50,7 +45,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.ui.IDebugUIConstants; -import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapterExtension; +import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapter2; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.ICellModifier; import org.eclipse.jface.viewers.TextCellEditor; @@ -62,7 +57,7 @@ public class RegisterGroupVMNode extends AbstractExpressionVMNode implements IElementEditor, IElementLabelProvider { - protected class RegisterGroupVMC extends DMVMContext implements IVariable + protected class RegisterGroupVMC extends DMVMContext { private IExpression fExpression; public RegisterGroupVMC(IDMContext dmc) { @@ -78,7 +73,7 @@ public class RegisterGroupVMNode extends AbstractExpressionVMNode public Object getAdapter(Class adapter) { if (fExpression != null && adapter.isAssignableFrom(fExpression.getClass())) { return fExpression; - } else if (adapter.isAssignableFrom(IWatchExpressionFactoryAdapterExtension.class)) { + } else if (adapter.isAssignableFrom(IWatchExpressionFactoryAdapter2.class)) { return fRegisterGroupExpressionFactory; } else { return super.getAdapter(adapter); @@ -99,29 +94,16 @@ public class RegisterGroupVMNode extends AbstractExpressionVMNode public int hashCode() { return super.hashCode() + (fExpression != null ? fExpression.hashCode() : 0); } - - public String getName() throws DebugException { return toString(); } - public String getReferenceTypeName() throws DebugException { return ""; } //$NON-NLS-1$ - public IValue getValue() throws DebugException { return null; } - public boolean hasValueChanged() throws DebugException { return false; } - public void setValue(IValue value) throws DebugException {} - public void setValue(String expression) throws DebugException {} - public boolean supportsValueModification() { return false; } - public boolean verifyValue(IValue value) throws DebugException { return false; } - public boolean verifyValue(String expression) throws DebugException { return false; } - public IDebugTarget getDebugTarget() { return null;} - public ILaunch getLaunch() { return null; } - public String getModelIdentifier() { return DsfDebugUIPlugin.PLUGIN_ID; } } - protected class RegisterGroupExpressionFactory implements IWatchExpressionFactoryAdapterExtension { + protected class RegisterGroupExpressionFactory implements IWatchExpressionFactoryAdapter2 { - public boolean canCreateWatchExpression(IVariable variable) { - return variable instanceof RegisterGroupVMC; + public boolean canCreateWatchExpression(Object element) { + return element instanceof RegisterGroupVMC; } - public String createWatchExpression(IVariable variable) throws CoreException { - RegisterGroupVMC registerVmc = ((RegisterGroupVMC)variable); + public String createWatchExpression(Object element) throws CoreException { + RegisterGroupVMC registerVmc = ((RegisterGroupVMC)element); StringBuffer exprBuf = new StringBuffer(); IRegisterGroupDMContext groupDmc = DMContexts.getAncestorOfType(registerVmc.getDMContext(), IRegisterGroupDMContext.class); diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java index 159c44a2c1f..6d45b85d03f 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java @@ -41,12 +41,7 @@ import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.dm.CompositeDMVMContext; import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; -import org.eclipse.debug.core.DebugException; -import org.eclipse.debug.core.ILaunch; -import org.eclipse.debug.core.model.IDebugTarget; import org.eclipse.debug.core.model.IExpression; -import org.eclipse.debug.core.model.IValue; -import org.eclipse.debug.core.model.IVariable; import org.eclipse.debug.internal.ui.DebugPluginImages; import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; @@ -57,7 +52,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.ui.IDebugUIConstants; -import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapterExtension; +import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapter2; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.ICellModifier; @@ -70,7 +65,7 @@ public class RegisterVMNode extends AbstractExpressionVMNode implements IElementEditor, IElementLabelProvider { protected class RegisterVMC extends DMVMContext - implements IVariable, IFormattedValueVMContext + implements IFormattedValueVMContext { private IExpression fExpression; public RegisterVMC(IDMContext dmc) { @@ -86,7 +81,7 @@ public class RegisterVMNode extends AbstractExpressionVMNode public Object getAdapter(Class adapter) { if (fExpression != null && adapter.isAssignableFrom(fExpression.getClass())) { return fExpression; - } else if (adapter.isAssignableFrom(IWatchExpressionFactoryAdapterExtension.class)) { + } else if (adapter.isAssignableFrom(IWatchExpressionFactoryAdapter2.class)) { return fRegisterExpressionFactory; } else { return super.getAdapter(adapter); @@ -111,29 +106,16 @@ public class RegisterVMNode extends AbstractExpressionVMNode public IFormattedValuePreferenceStore getPreferenceStore() { return fFormattedPrefStore; } - - public String getName() throws DebugException { return toString(); } - public String getReferenceTypeName() throws DebugException { return ""; } //$NON-NLS-1$ - public IValue getValue() throws DebugException { return null; } - public boolean hasValueChanged() throws DebugException { return false; } - public void setValue(IValue value) throws DebugException {} - public void setValue(String expression) throws DebugException {} - public boolean supportsValueModification() { return false; } - public boolean verifyValue(IValue value) throws DebugException { return false; } - public boolean verifyValue(String expression) throws DebugException { return false; } - public IDebugTarget getDebugTarget() { return null;} - public ILaunch getLaunch() { return null; } - public String getModelIdentifier() { return DsfDebugUIPlugin.PLUGIN_ID; } } - protected class RegisterExpressionFactory implements IWatchExpressionFactoryAdapterExtension { + protected class RegisterExpressionFactory implements IWatchExpressionFactoryAdapter2 { - public boolean canCreateWatchExpression(IVariable variable) { - return variable instanceof RegisterVMC; + public boolean canCreateWatchExpression(Object element) { + return element instanceof RegisterVMC; } - public String createWatchExpression(IVariable variable) throws CoreException { - RegisterVMC registerVmc = ((RegisterVMC)variable); + public String createWatchExpression(Object element) throws CoreException { + RegisterVMC registerVmc = ((RegisterVMC)element); StringBuffer exprBuf = new StringBuffer(); IRegisterGroupDMContext groupDmc = diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java index 87baf190bd2..26ed1b8e26c 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java @@ -48,12 +48,7 @@ import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.dm.CompositeDMVMContext; import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; -import org.eclipse.debug.core.DebugException; -import org.eclipse.debug.core.ILaunch; -import org.eclipse.debug.core.model.IDebugTarget; import org.eclipse.debug.core.model.IExpression; -import org.eclipse.debug.core.model.IValue; -import org.eclipse.debug.core.model.IVariable; import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; @@ -63,7 +58,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; -import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapterExtension; +import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapter2; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.ICellModifier; @@ -128,7 +123,7 @@ public class VariableVMNode extends AbstractExpressionVMNode private final SyncVariableDataAccess fSyncVariableDataAccess; - public class VariableExpressionVMC extends DMVMContext implements IFormattedValueVMContext, IVariable { + public class VariableExpressionVMC extends DMVMContext implements IFormattedValueVMContext { private IExpression fExpression; @@ -149,7 +144,7 @@ public class VariableVMNode extends AbstractExpressionVMNode public Object getAdapter(Class adapter) { if (fExpression != null && adapter.isAssignableFrom(fExpression.getClass())) { return fExpression; - } else if (adapter.isAssignableFrom(IWatchExpressionFactoryAdapterExtension.class)) { + } else if (adapter.isAssignableFrom(IWatchExpressionFactoryAdapter2.class)) { return fVariableExpressionFactory; } else { return super.getAdapter(adapter); @@ -170,30 +165,17 @@ public class VariableVMNode extends AbstractExpressionVMNode public int hashCode() { return super.hashCode() + (fExpression != null ? fExpression.hashCode() : 0); } - - public String getName() throws DebugException { return toString(); } - public String getReferenceTypeName() throws DebugException { return ""; } //$NON-NLS-1$ - public IValue getValue() throws DebugException { return null; } - public boolean hasValueChanged() throws DebugException { return false; } - public void setValue(IValue value) throws DebugException {} - public void setValue(String expression) throws DebugException {} - public boolean supportsValueModification() { return false; } - public boolean verifyValue(IValue value) throws DebugException { return false; } - public boolean verifyValue(String expression) throws DebugException { return false; } - public IDebugTarget getDebugTarget() { return null;} - public ILaunch getLaunch() { return null; } - public String getModelIdentifier() { return DsfDebugUIPlugin.PLUGIN_ID; } } - protected class VariableExpressionFactory implements IWatchExpressionFactoryAdapterExtension { + protected class VariableExpressionFactory implements IWatchExpressionFactoryAdapter2 { - public boolean canCreateWatchExpression(IVariable variable) { - return variable instanceof VariableExpressionVMC; + public boolean canCreateWatchExpression(Object element) { + return element instanceof VariableExpressionVMC; } - public String createWatchExpression(IVariable variable) throws CoreException { + public String createWatchExpression(Object element) throws CoreException { - VariableExpressionVMC exprVmc = (VariableExpressionVMC) variable; + VariableExpressionVMC exprVmc = (VariableExpressionVMC) element; IExpressionDMContext exprDmc = DMContexts.getAncestorOfType(exprVmc.getDMContext(), IExpressionDMContext.class); if (exprDmc != null) { From c7f6460147442c065e8e1f26da0fbe82fb6fb77b Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Tue, 12 Feb 2008 20:23:27 +0000 Subject: [PATCH 233/834] Bugzilla 218654. This commit shows some files contain errors. This is because they are being compiled against M4. I will rebuild against M5 shortly. I did a diff of the files and the changes are exactly what I wanted. They will compile against HEAD and M5 when that is resolved. --- .../ui/viewmodel/register/RegisterGroupVMNode.java | 3 +-- .../debug/ui/viewmodel/register/RegisterVMNode.java | 3 +-- .../debug/ui/viewmodel/variable/VariableVMNode.java | 3 +-- .../dd/dsf/ui/viewmodel/dm/AbstractDMVMNode.java | 12 +++++++++++- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java index 06d1a9d0154..69380da24dc 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java @@ -34,7 +34,6 @@ import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; -import org.eclipse.dd.dsf.ui.viewmodel.dm.CompositeDMVMContext; import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; import org.eclipse.debug.core.model.IExpression; import org.eclipse.debug.internal.ui.DebugPluginImages; @@ -134,7 +133,7 @@ public class RegisterGroupVMNode extends AbstractExpressionVMNode @Override protected void updateElementsInSessionThread(final IChildrenUpdate update) { getServicesTracker().getService(IRegisters.class).getRegisterGroups( - new CompositeDMVMContext(update), + createCompositeDMVMContext(update), new DataRequestMonitor(getSession().getExecutor(), null) { @Override public void handleCompleted() { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java index 6d45b85d03f..b222bed823e 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java @@ -39,7 +39,6 @@ import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; -import org.eclipse.dd.dsf.ui.viewmodel.dm.CompositeDMVMContext; import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; import org.eclipse.debug.core.model.IExpression; import org.eclipse.debug.internal.ui.DebugPluginImages; @@ -364,7 +363,7 @@ public class RegisterVMNode extends AbstractExpressionVMNode @Override protected void updateElementsInSessionThread(final IChildrenUpdate update) { getServicesTracker().getService(IRegisters.class).getRegisters( - new CompositeDMVMContext(update), + createCompositeDMVMContext(update), new DataRequestMonitor(getSession().getExecutor(), null) { @Override public void handleCompleted() { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java index 26ed1b8e26c..9a594f7ab21 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java @@ -46,7 +46,6 @@ import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; -import org.eclipse.dd.dsf.ui.viewmodel.dm.CompositeDMVMContext; import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; import org.eclipse.debug.core.model.IExpression; import org.eclipse.debug.internal.ui.DebugUIPlugin; @@ -458,7 +457,7 @@ public class VariableVMNode extends AbstractExpressionVMNode final IExpressions expressionService = getServicesTracker().getService(IExpressions.class); if (expressionService != null) { IExpressionDMContext expressionDMC = expressionService.createExpression( - new CompositeDMVMContext(update), + createCompositeDMVMContext(update), update.getExpression().getExpressionText()); VariableExpressionVMC variableVmc = new VariableExpressionVMC(expressionDMC); variableVmc.setExpression(update.getExpression()); diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMNode.java index 9bdb2d6569d..d265947d89b 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMNode.java @@ -297,6 +297,16 @@ abstract public class AbstractDMVMNode extends AbstractVMNode implements IVMNode return new DMVMContext(dmc); } + /** + * Creates a default CompositeDMVMContext which represents the selection. + * This can be overridden by view model providers which for their own purposes. + * @param update defines the selection to be updated to + * @return DM Context which represent the current selection + */ + protected IDMContext createCompositeDMVMContext(IViewerUpdate update) { + return new CompositeDMVMContext(update); + } + /** * Searches for a DMC of given type in the tree patch contained in given * VMC. Only a DMC in the same session will be returned. @@ -305,7 +315,7 @@ abstract public class AbstractDMVMNode extends AbstractVMNode implements IVMNode * @param dmcType Class object for matching the type. * @return DMC, or null if not found. */ - public T findDmcInPath(Object inputObject, TreePath path, Class dmcType) { + protected T findDmcInPath(Object inputObject, TreePath path, Class dmcType) { T retVal = null; for (int i = path.getSegmentCount() - 1; i >= 0; i--) { if (path.getSegment(i) instanceof IDMVMContext) { From 7920546af5ff95bf0530bc70e6767bd0cd15b1d6 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 12 Feb 2008 22:51:10 +0000 Subject: [PATCH 234/834] [218557] Replaced IBreakpointsManager interface with a generic BreakpointsMediator and IBreakpointAttributeTranslator. --- .../debug/service/BreakpointsMediator.java | 838 ++++++++++++++++++ .../IBreakpointAttributeTranslator.java | 36 + .../debug/service/IBreakpointsManager.java | 43 - 3 files changed, 874 insertions(+), 43 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/BreakpointsMediator.java create mode 100644 plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpointAttributeTranslator.java delete mode 100644 plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpointsManager.java diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/BreakpointsMediator.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/BreakpointsMediator.java new file mode 100644 index 00000000000..2adec9cf43a --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/BreakpointsMediator.java @@ -0,0 +1,838 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River 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 - Initial API and implementation + * Ericsson - Low-level breakpoints integration + *******************************************************************************/ + +package org.eclipse.dd.dsf.debug.service; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.core.resources.IMarkerDelta; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.debug.DsfDebugPlugin; +import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointDMContext; +import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; +import org.eclipse.dd.dsf.service.AbstractDsfService; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.IBreakpointListener; +import org.eclipse.debug.core.IBreakpointManager; +import org.eclipse.debug.core.IBreakpointManagerListener; +import org.eclipse.debug.core.model.IBreakpoint; +import org.osgi.framework.BundleContext; + +/** + * + */ +public class BreakpointsMediator extends AbstractDsfService implements IBreakpointManagerListener, IBreakpointListener +{ + + /** + * The attribute translator that this service will use to map the platform + * breakpiont attributes to the corresponding target attributes, and vice + * versa. + */ + private IBreakpointAttributeTranslator fAttributeTranslator; + + /** + * DSF Debug service for creating breakpoints. + */ + IBreakpoints fBreakpoints; + + /** + * Platform breakpoint manager + */ + IBreakpointManager fBreakpointManager; + + + /////////////////////////////////////////////////////////////////////////// + // Breakpoints tracking + /////////////////////////////////////////////////////////////////////////// + + /** + * Holds the set of platform breakpoints with their corresponding back-end + * breakpoint attributes, per context (i.e. each platform breakpoint is + * replicated for each execution context). + * - Context entry added/removed on start/stopTrackingBreakpoints() + * - Augmented on breakpointAdded() + * - Modified on breakpointChanged() + * - Diminished on breakpointRemoved() + */ + private Map>>> fPlatformBPs = + new HashMap>>>(); + + /** + * Holds the mapping from platform breakpoint to the corresponding target + * breakpoint(s), per context. There can be multiple back-end BPs for a + * single platform BP in the case of [1] multiple target contexts, and/or + * [2] thread filtering. + * Updated when: + * - We start/stop tracking an execution context + * - A platform breakpoint is added/removed + * - A thread filter is applied/removed + */ + private Map>> fBreakpointDMContexts = + new HashMap>>(); + + /** + * Due to the very asynchronous nature of DSF, a new breakpoint request can + * pop up at any time before an ongoing one is completed. The following set + * is used to store requests until the ongoing operation completes. + */ + private Set fPendingRequests = new HashSet(); + + /** + * @see fPendingRequests + */ + private Set fPendingBreakpoints = new HashSet(); + + /////////////////////////////////////////////////////////////////////////// + // AbstractDsfService + /////////////////////////////////////////////////////////////////////////// + + /** + * The service constructor + * + * @param session + * @param debugModelId + */ + public BreakpointsMediator(DsfSession session, IBreakpointAttributeTranslator attributeTranslator) { + super(session); + fAttributeTranslator = attributeTranslator; + } + + @Override + public void initialize(final RequestMonitor rm) { + // - Collect references for the services we interact with + // - Register to interesting events + // - Obtain the list of platform breakpoints + // - Register the service for interested parties + super.initialize( + new RequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + doInitialize(rm); + }}); + } + + /** + * Asynchronous service initialization + * + * @param requestMonitor + */ + private void doInitialize(RequestMonitor rm) { + + // Get the services references + fBreakpoints = getServicesTracker().getService(IBreakpoints.class); + fBreakpointManager = DebugPlugin.getDefault().getBreakpointManager(); + fAttributeTranslator.initialize(this); + + // Register to the useful events + fBreakpointManager.addBreakpointListener(this); + fBreakpointManager.addBreakpointManagerListener( this ); + + // Register this service + register(new String[] { BreakpointsMediator.class.getName() }, + new Hashtable()); + + rm.done(); + } + + @Override + public void shutdown(final RequestMonitor rm) { + // - Un-register the service + // - Stop listening to events + // - Remove the breakpoints installed by this service + // + // Since we are shutting down, there is no overwhelming need + // to keep the maps coherent... + + // Stop accepting requests and events + unregister(); + fBreakpointManager.removeBreakpointListener(this); + fBreakpointManager.removeBreakpointManagerListener( this ); + fAttributeTranslator.dispose(); + + // Cleanup the breakpoints that are still installed by the service. + // Use a counting monitor which will call mom to complete the shutdown + // after the breakpoints are un-installed (successfully or not). + CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm) { + @Override + protected void handleCompleted() { + BreakpointsMediator.super.shutdown(rm); + } + }; + + // We have to make a copy of the fPlatformBPs keys because uninstallBreakpoints() + // modifies the map as it walks through it. + List platformBPKeysCopy = new ArrayList(fPlatformBPs.size()); + platformBPKeysCopy.addAll(0, fPlatformBPs.keySet()); + for (IBreakpointsTargetDMContext dmc : platformBPKeysCopy) { + stopTrackingBreakpoints(dmc, countingRm); + } + countingRm.setDoneCount(platformBPKeysCopy.size()); + } + + @Override + protected BundleContext getBundleContext() { + return DsfDebugPlugin.getBundleContext(); + } + + /////////////////////////////////////////////////////////////////////////// + // IBreakpointsManager + /////////////////////////////////////////////////////////////////////////// + + + /** + * Install and begin tracking breakpoints for given context. The service + * will keep installing new breakpoints that appear in the IDE for this + * context until {@link #uninstallBreakpoints(IDMContext)} is called for that + * context. + * @param dmc Context to start tracking breakpoints for. + * @param rm Completion callback. + */ + public void startTrackingBreakpoints(IBreakpointsTargetDMContext dmc, final RequestMonitor rm) { + // - Augment the maps with the new execution context + // - Install the platform breakpoints on the selected target + + // Validate the context + final IBreakpointsTargetDMContext breakpointsDmc = DMContexts.getAncestorOfType(dmc, IBreakpointsTargetDMContext.class); + if (breakpointsDmc == null) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid context type", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + // Make sure a mapping for this execution context does not already exist + Map>> platformBPs = fPlatformBPs.get(dmc); + if (platformBPs != null) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, INTERNAL_ERROR, "Context already initialized", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + // Create entries in the breakpoint tables for the new context. These entries should only + // be removed when this service stops tracking breakpoints for the given context. + fPlatformBPs.put(breakpointsDmc, new HashMap>>()); + fBreakpointDMContexts.put(breakpointsDmc, new HashMap>()); + + // Install the platform breakpoints (stored in fPlatformBPs) on the target. + // We need to use a background thread for this operation because we are + // accessing the resources system to retrieve the breakpoint attributes. + // Accessing the resources system potentially requires using global locks. + // Also we will be calling IBreakpointAttributeTranslator which is prohibited + // from being called on the session executor thread. + new Job("MI Debugger: Install initial breakpoint list.") { //$NON-NLS-1$ + { setSystem(true); } + + // Get the stored breakpoints from the platform BreakpointManager + // and install them on the target + @Override + protected IStatus run(IProgressMonitor monitor) { + // Read initial breakpoints from platform. Copy the breakpoint attributes into a local map. + // Note that we cannot write data into fPlatformBPs table here directly because we are not + // executing on the dispatch thread. + final Map>> initialPlatformBPs = + new HashMap>>(); + try { + // Get the stored breakpoint list from the platform BreakpointManager + IBreakpoint[] bps = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints(); + // Single out the installable breakpoints... + for (IBreakpoint bp : bps) { + if (fAttributeTranslator.supportsBreakpoint(bp)) { + // Retrieve the breakpoint attributes + List> attrsArray = + fAttributeTranslator.getBreakpointAttributes(bp, fBreakpointManager.isEnabled()); + // Store it for now (will be installed on the dispatcher thread) + initialPlatformBPs.put(bp, attrsArray); + } + } + } catch (CoreException e) { + IStatus status = new Status( + IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, REQUEST_FAILED, "Unable to read initial breakpoint attributes", e); //$NON-NLS-1$ + rm.setStatus(status); + rm.done(); + return status; + } + + // Submit the runnable to plant the breakpoints on dispatch thread. + getExecutor().submit(new Runnable() { + public void run() { + installInitialBreakpoints(breakpointsDmc, initialPlatformBPs, rm); + } + }); + + return Status.OK_STATUS; + } + }.schedule(); + } + + /** + * Installs the breakpoints that existed prior to the activation of this + * breakpoints context. + */ + private void installInitialBreakpoints(final IBreakpointsTargetDMContext dmc, + Map>> initialPlatformBPs, + RequestMonitor rm) + { + // Retrieve the set of platform breakpoints for this context + Map>> platformBPs = fPlatformBPs.get(dmc); + if (platformBPs == null) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + // Install the individual breakpoints on the executor thread + // Requires a counting monitor to know when we're done + final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm); + countingRm.setDoneCount(platformBPs.size()); + + for (final IBreakpoint bp : initialPlatformBPs.keySet()) { + final List> attrs = initialPlatformBPs.get(bp); + // Upon determining the debuggerPath, the breakpoint is installed + installBreakpoint(dmc, bp, attrs, new RequestMonitor(getExecutor(), countingRm)); + } + } + + + public void stopTrackingBreakpoints(final IBreakpointsTargetDMContext dmc, final RequestMonitor rm) { + // - Remove the target breakpoints for the given execution context + // - Update the maps + + // Remove the breakpoints for given DMC from the internal maps. + Map>> platformBPs = fPlatformBPs.get(dmc); + if (platformBPs == null) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, INTERNAL_ERROR, "Breakpoints not installed for given context", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + // Uninstall the individual breakpoints on the executor thread + // Requires a counting monitor to know when we're done + final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm); + countingRm.setDoneCount(platformBPs.size()); + + for (final IBreakpoint bp : platformBPs.keySet()) { + uninstallBreakpoint(dmc, bp, + new RequestMonitor(getExecutor(), countingRm) { + @Override + protected void handleCompleted() { + // After the breakpoint is removed from target. Call the attribute + // translator to refresh breakpoint status based on the new target + // breakpoint status. + new Job("Breakpoint status update") { //$NON-NLS-1$ + { setSystem(true); } + @Override + protected IStatus run(IProgressMonitor monitor) { + fAttributeTranslator.updateBreakpointStatus(bp); + return Status.OK_STATUS; + }; + }.schedule(); + + countingRm.done(); + } + }); + } + } + + /////////////////////////////////////////////////////////////////////////// + // Back-end interface functions + /////////////////////////////////////////////////////////////////////////// + + /** + * Install a new platform breakpoint on the back-end. A platform breakpoint + * can resolve into multiple back-end breakpoints when threads are taken + * into account. + * + * @param dmc + * @param breakpoint + * @param attrsList + * @param rm + */ + private void installBreakpoint(IBreakpointsTargetDMContext dmc, final IBreakpoint breakpoint, + final List> attrsList, final RequestMonitor rm) + { + // Retrieve the set of breakpoints for this context + final Map>> platformBPs = fPlatformBPs.get(dmc); + assert platformBPs != null; + + final Map> breakpointIDs = fBreakpointDMContexts.get(dmc); + assert breakpointIDs != null; // fBreakpointIds should be updated in parallel with fPlatformBPs + + // Ensure the breakpoint is not already installed + if (platformBPs.containsKey(breakpoint)) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, INVALID_STATE, "Breakpoint already installed", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + // Update the breakpoint status when all back-end breakpoints have been installed + final CountingRequestMonitor installRM = new CountingRequestMonitor(getExecutor(), rm) { + @Override + protected void handleCompleted() { + // Store the platform breakpoint + platformBPs.put(breakpoint, attrsList); + new Job("Breakpoint status update") { //$NON-NLS-1$ + { setSystem(true); } + @Override + protected IStatus run(IProgressMonitor monitor) { + fAttributeTranslator.updateBreakpointStatus(breakpoint); + return Status.OK_STATUS; + }; + }.schedule(); + rm.done(); + } + }; + + // A back-end breakpoint needs to be installed for each specified attributes map. + installRM.setDoneCount(attrsList.size()); + + // Install the back-end breakpoint(s) + for (Map attrs : attrsList) { + fBreakpoints.insertBreakpoint( + dmc, attrs, + new DataRequestMonitor(getExecutor(), installRM) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + // Add the breakpoint back-end mapping + List list = breakpointIDs.get(breakpoint); + if (list == null) + list = new LinkedList(); + list.add(getData()); + breakpointIDs.put(breakpoint, list); + } + installRM.done(); + } + }); + } + } + + /** + * Un-install an individual breakpoint on the back-end. For one platform + * breakpoint, there could be multiple corresponding back-end breakpoints. + * + * @param dmc + * @param breakpoint + * @param rm + */ + private void uninstallBreakpoint(final IBreakpointsTargetDMContext dmc, final IBreakpoint breakpoint, + final RequestMonitor rm) + { + // Remove completion monitor + CountingRequestMonitor removeRM = new CountingRequestMonitor(getExecutor(), rm) { + @Override + protected void handleCompleted() { + // Remove the attributes mapping + Map>> platformBPs = fPlatformBPs.get(dmc); + if (platformBPs == null) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ + rm.done(); + return; + } + platformBPs.remove(breakpoint); + + // Remove the back-end mapping + Map> breakpointIDs = fBreakpointDMContexts.get(dmc); + if (breakpointIDs == null) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid breakpoint", null)); //$NON-NLS-1$ + rm.done(); + return; + } + breakpointIDs.get(breakpoint).clear(); + breakpointIDs.remove(breakpoint); + + // Update breakpoint status + new Job("Breakpoint status update") { //$NON-NLS-1$ + { setSystem(true); } + @Override + protected IStatus run(IProgressMonitor monitor) { + fAttributeTranslator.updateBreakpointStatus(breakpoint); + return Status.OK_STATUS; + }; + }.schedule(); + + rm.done(); + } + }; + + // Remove the back-end breakpoints + Map> breakpointIDs = fBreakpointDMContexts.get(dmc); + if (breakpointIDs == null) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid breakpoint", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + List list = breakpointIDs.get(breakpoint); + int count = 0; + if (list != null) { + for (IBreakpointDMContext bp : list) { + fBreakpoints.removeBreakpoint(bp, removeRM); + } + count = list.size(); + } + removeRM.setDoneCount(count); + } + + /** + * Modify an individual breakpoint + * + * @param context + * @param breakpoint + * @param attributes + * @param rm + * @throws CoreException + */ + private void modifyBreakpoint(final IBreakpointsTargetDMContext context, final IBreakpoint breakpoint, + final List> newAttrsList0, final IMarkerDelta oldValues, final RequestMonitor rm) + { + // Get the maps + final Map>> platformBPs = fPlatformBPs.get(context); + final Map> breakpointIDs = fBreakpointDMContexts.get(context); + if (platformBPs == null || breakpointIDs == null) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + // Get the original breakpoint attributes + final List> oldAttrsList0 = platformBPs.get(breakpoint); + if (oldAttrsList0 == null) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid breakpoint", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + // Get the list of corresponding back-end breakpoints + final List oldBpContexts = new ArrayList(breakpointIDs.get(breakpoint)); + if (oldBpContexts == null) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid breakpoint", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + List> commonAttrsList = getCommonAttributeMaps(newAttrsList0, oldAttrsList0); + final List newBpContexts = new ArrayList(commonAttrsList.size()); + + List> newAttrsList = new ArrayList>(newAttrsList0); + newAttrsList.removeAll(commonAttrsList); + + List> oldAttrsList = new ArrayList>(oldAttrsList0); + for (int i = 0; i < oldAttrsList.size(); i++) { + if (commonAttrsList.contains(oldAttrsList.get(i))) { + newBpContexts.add(oldBpContexts.remove(i)); + } + } + + final List> attrDeltasArray = getAttributesDeltas(oldAttrsList, newAttrsList); + + final CountingRequestMonitor countingRM = new CountingRequestMonitor(getExecutor(), rm) { + @Override + protected void handleCompleted() { + breakpointIDs.put(breakpoint, newBpContexts); + // Update breakpoint status + new Job("Breakpoint status update") { //$NON-NLS-1$ + { setSystem(true); } + @Override + protected IStatus run(IProgressMonitor monitor) { + fAttributeTranslator.updateBreakpointStatus(breakpoint); + return Status.OK_STATUS; + }; + }.schedule(); + + super.handleCompleted(); + } + }; + + countingRM.setDoneCount(attrDeltasArray.size()); + + for (int i = 0; i < attrDeltasArray.size(); i++) { + if (attrDeltasArray.get(i) == null) { + fBreakpoints.removeBreakpoint(oldBpContexts.get(i), countingRM); + } else if ( i >= oldBpContexts.size()) { + final Map attrs = newAttrsList.get(i); + fBreakpoints.insertBreakpoint( + context, attrs, + new DataRequestMonitor(getExecutor(), countingRM) { + @Override + protected void handleOK() { + newBpContexts.add(getData()); + countingRM.done(); + } + }); + } else if ( !fAttributeTranslator.canUpdateAttributes(oldBpContexts.get(i), attrDeltasArray.get(i)) ) { + final Map attrs = newAttrsList.get(i); + fBreakpoints.removeBreakpoint( + oldBpContexts.get(i), + new RequestMonitor(getExecutor(), countingRM) { + @Override + protected void handleOK() { + fBreakpoints.insertBreakpoint( + context, attrs, + new DataRequestMonitor(getExecutor(), countingRM) { + @Override + protected void handleOK() { + newBpContexts.add(getData()); + countingRM.done(); + } + }); + } + }); + } else { + final IBreakpointDMContext bpCtx = oldBpContexts.get(i); + fBreakpoints.updateBreakpoint( + oldBpContexts.get(i), attrDeltasArray.get(i), + new RequestMonitor(getExecutor(), countingRM) { + @Override + protected void handleOK() { + newBpContexts.add(bpCtx); + countingRM.done(); + } + }); + } + } + } + + private List> getCommonAttributeMaps(List> array1, List> array2) + { + List> intersection = new LinkedList>(); + List> list2 = new ArrayList>(array1); + for (Map array1Map : array1) { + if (list2.remove(array1Map)) { + intersection.add(array1Map); + } + } + return intersection; + } + + /** + * Determine the set of modified attributes + * + * @param oldAttributes + * @param newAttributes + * @return + */ + private List> getAttributesDeltas(List> oldAttributesList, List> newAttributesList) { + List> deltas = new ArrayList>(oldAttributesList.size()); + + // Go through the bp attributes common to the old and the new lists and calculate + // their deltas. + for (int i = 0; i < oldAttributesList.size() && i < newAttributesList.size(); i++) { + Map oldAttributes = oldAttributesList.get(i); + Map newAttributes = newAttributesList.get(i); + + Map delta = new HashMap(); + + Set oldKeySet = oldAttributes.keySet(); + Set newKeySet = newAttributes.keySet(); + + Set commonKeys = new HashSet(newKeySet); commonKeys.retainAll(oldKeySet); + Set addedKeys = new HashSet(newKeySet); addedKeys.removeAll(oldKeySet); + Set removedKeys = new HashSet(oldKeySet); removedKeys.removeAll(newKeySet); + + // Add the modified attributes + for (String key : commonKeys) { + if (!(oldAttributes.get(key).equals(newAttributes.get(key)))) + delta.put(key, newAttributes.get(key)); + } + + // Add the new attributes + for (String key : addedKeys) { + delta.put(key, newAttributes.get(key)); + } + + // Remove the deleted attributes + for (String key : removedKeys) { + delta.put(key, null); + } + deltas.add(delta); + } + + // Add all the new attributes as deltas + for (int i = deltas.size(); i < newAttributesList.size(); i++) { + deltas.add(newAttributesList.get(i)); + } + + // For any old attribute Maps that were removed, insert a null value in the deltas list. + for (int i = deltas.size(); i < oldAttributesList.size(); i++) { + deltas.add(null); + } + + return deltas; + } + + /////////////////////////////////////////////////////////////////////////// + // IBreakpointManagerListener implementation + /////////////////////////////////////////////////////////////////////////// + + public void breakpointManagerEnablementChanged(boolean enabled) { + for (IBreakpoint breakpoint : fBreakpointManager.getBreakpoints()) { + breakpointChanged(breakpoint, null); + } + } + + @ThreadSafe + public void breakpointAdded(final IBreakpoint breakpoint) { + if (fAttributeTranslator.supportsBreakpoint(breakpoint)) { + try { + // Retrieve the breakpoint attributes + final List> attrsArray = + fAttributeTranslator.getBreakpointAttributes(breakpoint, fBreakpointManager.isEnabled()); + + getExecutor().execute(new DsfRunnable() { + public void run() { + //TODO pp: need to track pending requests + + final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), null) { + @Override + protected void handleError() { + if (getStatus().getSeverity() == IStatus.ERROR) { + DsfDebugPlugin.getDefault().getLog().log(getStatus()); + } + } + }; + countingRm.setDoneCount(fPlatformBPs.size()); + + // Install the breakpoint in all the execution contexts + for (final IBreakpointsTargetDMContext dmc : fPlatformBPs.keySet()) { + installBreakpoint(dmc, breakpoint, attrsArray, new RequestMonitor(getExecutor(), countingRm)); + } + } + }); + } catch (CoreException e) { + DsfDebugPlugin.getDefault().getLog().log(e.getStatus()); + } catch (RejectedExecutionException e) { + } + } + + } + + /////////////////////////////////////////////////////////////////////////// + // IBreakpointListener implementation + /////////////////////////////////////////////////////////////////////////// + + public void breakpointChanged(final IBreakpoint breakpoint, final IMarkerDelta delta) { + if (fAttributeTranslator.supportsBreakpoint(breakpoint)) { + try { + // Retrieve the breakpoint attributes + final List> attrsArray = + fAttributeTranslator.getBreakpointAttributes(breakpoint, fBreakpointManager.isEnabled()); + + // Modify the breakpoint in all the target contexts + getExecutor().execute( new DsfRunnable() { + public void run() { + + // If the breakpoint is currently being updated, queue the request and exit + if (fPendingRequests.contains(breakpoint)) { + fPendingBreakpoints.add(breakpoint); + return; + } + + // Keep track of the updates + final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), null) { + @Override + protected void handleCompleted() { + + if (!getStatus().isOK()) { + if (getStatus().getSeverity() == IStatus.ERROR) { + DsfDebugPlugin.getDefault().getLog().log(getStatus()); + } + } + + // Indicate that the pending request has completed + fPendingRequests.remove(breakpoint); + + // Process the next pending update for this breakpoint + if (fPendingBreakpoints.contains(breakpoint)) { + fPendingBreakpoints.remove(breakpoint); + new Job("Deferred breakpoint changed job") { //$NON-NLS-1$ + { setSystem(true); } + @Override + protected IStatus run(IProgressMonitor monitor) { + breakpointChanged(breakpoint, delta); + return Status.OK_STATUS; + }; + }.schedule(); + } + } + }; + countingRm.setDoneCount(fPlatformBPs.size()); + + // Mark the breakpoint as being updated and go + fPendingRequests.add(breakpoint); + + // Modify the breakpoint in all the execution contexts + for (final IBreakpointsTargetDMContext dmc : fPlatformBPs.keySet()) { + modifyBreakpoint(dmc, breakpoint, attrsArray, delta, new RequestMonitor(getExecutor(), countingRm)); + } + } + }); + } catch (CoreException e) { + DsfDebugPlugin.getDefault().getLog().log(e.getStatus()); + } catch (RejectedExecutionException e) { + } + } + + } + + public void breakpointRemoved(final IBreakpoint breakpoint, IMarkerDelta delta) { + + if (fAttributeTranslator.supportsBreakpoint(breakpoint)) { + try { + getExecutor().execute(new DsfRunnable() { + public void run() { + //TODO pp: need to track pending requests + + CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), null) { + @Override + protected void handleError() { + if (getStatus().getSeverity() == IStatus.ERROR) { + DsfDebugPlugin.getDefault().getLog().log(getStatus()); + } + } + }; + countingRm.setDoneCount(fPlatformBPs.size()); + + // Remove the breakpoint in all the execution contexts + for (IBreakpointsTargetDMContext dmc : fPlatformBPs.keySet()) { + if (fPlatformBPs.get(dmc).remove(breakpoint) != null) { + uninstallBreakpoint(dmc, breakpoint, countingRm); + } else { + // Breakpoint not installed for given context, do nothing. + } + } + } + }); + } catch (RejectedExecutionException e) { + } + } + + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpointAttributeTranslator.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpointAttributeTranslator.java new file mode 100644 index 00000000000..067809fb82a --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpointAttributeTranslator.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.service; + +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.dd.dsf.concurrent.ThreadSafeAndProhibitedFromDsfExecutor; +import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointDMContext; +import org.eclipse.debug.core.model.IBreakpoint; + + +@ThreadSafeAndProhibitedFromDsfExecutor("") +public interface IBreakpointAttributeTranslator { + + public void initialize(BreakpointsMediator mediator); + + public void dispose(); + + public List> getBreakpointAttributes(IBreakpoint breakpoint, boolean bpManagerEnabled) throws CoreException; + + public boolean canUpdateAttributes(IBreakpointDMContext bp, Map delta); + + public boolean supportsBreakpoint(IBreakpoint bp); + + public void updateBreakpointStatus(IBreakpoint bp); +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpointsManager.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpointsManager.java deleted file mode 100644 index 79063e39a6c..00000000000 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpointsManager.java +++ /dev/null @@ -1,43 +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.service; - -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; -import org.eclipse.dd.dsf.service.IDsfService; - -/** - * Breakpoint service interface. The breakpoint service tracks platform breakpoint - * objects, and based on those, it manages breakpoints in the debugger back end. - * The purpose of the service model interface is to allow UI clients to display - * breakpoint status in more detail and more dynamically than it it possible with - * just the marker-based breakpoint object. - */ -public interface IBreakpointsManager extends IDsfService { - - /** - * Install and begin tracking breakpoints for given context. The service - * will keep installing new breakpoints that appear in the IDE for this - * context until {@link #uninstallBreakpoints(IDMContext)} is called for that - * context. - * @param dmc Context to start tracking breakpoints for. - * @param rm Completion callback. - */ - public void startTrackingBreakpoints(IBreakpointsTargetDMContext dmc, RequestMonitor rm); - - /** - * Uninstall and stop tracking breakpoints for the given context. - * @param dmc Context to start tracking breakpoints for. - * @param rm Completion callback. - */ - public void stopTrackingBreakpoints(IBreakpointsTargetDMContext dmc, RequestMonitor rm); -} From 17585c38f7aa1491a824b1603e590a320888f206 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 12 Feb 2008 22:52:53 +0000 Subject: [PATCH 235/834] [218577] Cleaned up IBreakpoints interface. --- .../dd/dsf/debug/service/IBreakpoints.java | 49 +++---------------- 1 file changed, 7 insertions(+), 42 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java index 759d44d1537..bd5011a297f 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IBreakpoints.java @@ -26,32 +26,6 @@ import org.eclipse.dd.dsf.service.IDsfService; */ public interface IBreakpoints extends IDsfService { - /** - * Breakpoint attributes markers used in the map parameters of insert/updateBreakpoint(). - * All are optional with the possible exception of TYPE. It is the responsibility of the - * service to ensure that the set of attributes provided is sufficient to create/update - * a valid breakpoint on the back-end. - */ - // General markers - public static final String DSFBREAKPOINT = "org.eclipse.dd.dsf.debug.breakpoint"; //$NON-NLS-1$ - public static final String BREAKPOINT_TYPE = DSFBREAKPOINT + ".type"; //$NON-NLS-1$ - public static final String BREAKPOINT = "breakpoint"; //$NON-NLS-1$ - public static final String WATCHPOINT = "watchpoint"; //$NON-NLS-1$ - public static final String CATCHPOINT = "catchpoint"; //$NON-NLS-1$ - - // Basic set of breakpoint attribute markers - public static final String FILE_NAME = DSFBREAKPOINT + ".fileName"; //$NON-NLS-1$ - public static final String LINE_NUMBER = DSFBREAKPOINT + ".lineNumber"; //$NON-NLS-1$ - public static final String FUNCTION = DSFBREAKPOINT + ".function"; //$NON-NLS-1$ - public static final String ADDRESS = DSFBREAKPOINT + ".address"; //$NON-NLS-1$ - public static final String CONDITION = DSFBREAKPOINT + ".condition"; //$NON-NLS-1$ - public static final String IGNORE_COUNT = DSFBREAKPOINT + ".ignoreCount"; //$NON-NLS-1$ - public static final String IS_ENABLED = DSFBREAKPOINT + ".isEnabled"; //$NON-NLS-1$ - - // Basic set of watchpoint attribute markers - public static final String EXPRESSION = DSFBREAKPOINT + ".expression"; //$NON-NLS-1$ - public static final String READ = DSFBREAKPOINT + ".read"; //$NON-NLS-1$ - public static final String WRITE = DSFBREAKPOINT + ".write"; //$NON-NLS-1$ /** * Marker interface for a context for which breakpoints can be installed @@ -62,27 +36,18 @@ public interface IBreakpoints extends IDsfService { * Specific breakpoint context */ @Immutable - public interface IBreakpointDMContext extends IDMContext { - - public IBreakpointsTargetDMContext getTargetContext(); - } + public interface IBreakpointDMContext extends IDMContext {} /** * Breakpoint events */ - public interface IBreakpointsChangedEvent extends IDMEvent {} + public interface IBreakpointsChangedEvent extends IDMEvent { + public IBreakpointDMContext[] getBreakpoints(); + } - public interface IBreakpointAddedEvent extends IBreakpointsChangedEvent { - public IBreakpointDMContext getAddedBreakpoint(); - } - - public interface IBreakpointUpdatedEvent extends IBreakpointsChangedEvent { - public IBreakpointDMContext getUpdatedBreakpoint(); - } - - public interface IBreakpointRemovedEvent extends IBreakpointsChangedEvent { - public IBreakpointDMContext getRemovedBreakpoint(); - } + public interface IBreakpointsAddedEvent extends IBreakpointsChangedEvent {} + public interface IBreakpointsUpdatedEvent extends IBreakpointsChangedEvent {} + public interface IBreakpointsRemovedEvent extends IBreakpointsChangedEvent {} /** * Effective breakpoint data as held by the back-end. From c61de9929cd903c180d406c796d52d381f58d2a5 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 12 Feb 2008 23:04:12 +0000 Subject: [PATCH 236/834] [218560] Replaced IStepQueueManager with a concrete generic implementation StepQueueManager. --- .../debug/ui/actions/DsfCommandRunnable.java | 6 +- .../sourcelookup/MISourceDisplayAdapter.java | 4 +- .../dsf/debug/service/IStepQueueManager.java | 73 ----- .../dsf/debug/service/StepQueueManager.java | 258 ++++++++++++++++++ 4 files changed, 263 insertions(+), 78 deletions(-) delete mode 100644 plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStepQueueManager.java create mode 100644 plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/StepQueueManager.java diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java index 42f870b9f1d..cd05575d3bc 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java @@ -16,7 +16,7 @@ import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.debug.service.IRunControl; -import org.eclipse.dd.dsf.debug.service.IStepQueueManager; +import org.eclipse.dd.dsf.debug.service.StepQueueManager; import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.service.DsfServicesTracker; @@ -33,8 +33,8 @@ public abstract class DsfCommandRunnable extends DsfRunnable { public IRunControl getRunControl() { return fTracker.getService(IRunControl.class); } - public IStepQueueManager getStepQueueMgr() { - return fTracker.getService(IStepQueueManager.class); + public StepQueueManager getStepQueueMgr() { + return fTracker.getService(StepQueueManager.class); } public DsfCommandRunnable(DsfServicesTracker servicesTracker, Object element, IDebugCommandRequest request) { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java index 3b51b20ed0f..b4689d6e5b6 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java @@ -31,7 +31,7 @@ import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; 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.StepQueueManager; 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; @@ -543,7 +543,7 @@ public class MISourceDisplayAdapter implements ISourceDisplay } @DsfServiceEventHandler - public void eventDispatched(IStepQueueManager.ISteppingTimedOutEvent e) { + public void eventDispatched(StepQueueManager.ISteppingTimedOutEvent e) { startAnnotationClearingJob(e.getDMContext()); } } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStepQueueManager.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStepQueueManager.java deleted file mode 100644 index 3a654c33e62..00000000000 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStepQueueManager.java +++ /dev/null @@ -1,73 +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.service; - -import org.eclipse.dd.dsf.datamodel.IDMEvent; -import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; -import org.eclipse.dd.dsf.service.IDsfService; - -/** - * This service builds on top of standard run control service to provide - * step queuing functionality. Step queuing essentially allows user to press - * and hold the step key and achieve maximum stepping speed. If this service - * is used, other service implementations, such as stack and expressions, can - * use it to avoid requesting data from debugger back end if another step is - * about to be executed. - */ -public interface IStepQueueManager extends IDsfService { - /** - * Amount of time in miliseconds, that it takes the ISteppingTimedOutEvent - * event to be issued after a step is started. - * @see ISteppingTimedOutEvent - */ - public final static int STEPPING_TIMEOUT = 500; - - /** - * 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 IDMEvent { - } - - - void setStepQueueDepth(int depth); - int getStepQueueDepth(); - - /** - * Returns the number of step commands that are queued for given execution - * context. - */ - int getPendingStepCount(IExecutionDMContext ctx); - - /** - * Checks whether a step command can be queued up for given context. - */ - boolean canEnqueueStep(IExecutionDMContext execCtx); - - boolean canEnqueueInstructionStep(IExecutionDMContext ctx); - - /** - * 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(IExecutionDMContext ctx, IRunControl.StepType stepType); - - /** - * Adds an instruction 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 enqueueInstructionStep(IExecutionDMContext ctx, IRunControl.StepType stepType); - - boolean isSteppingTimedOut(IExecutionDMContext context); -} diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/StepQueueManager.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/StepQueueManager.java new file mode 100644 index 00000000000..c46b28611f7 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/StepQueueManager.java @@ -0,0 +1,258 @@ +/******************************************************************************* + * 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 java.util.HashMap; +import java.util.Hashtable; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.IDMEvent; +import org.eclipse.dd.dsf.debug.DsfDebugPlugin; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason; +import org.eclipse.dd.dsf.debug.service.IRunControl.StepType; +import org.eclipse.dd.dsf.service.AbstractDsfService; +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; +import org.eclipse.dd.dsf.service.DsfSession; +import org.osgi.framework.BundleContext; + +/** + * This service builds on top of standard run control service to provide + * step queuing functionality. Step queuing essentially allows user to press + * and hold the step key and achieve maximum stepping speed. If this service + * is used, other service implementations, such as stack and expressions, can + * use it to avoid requesting data from debugger back end if another step is + * about to be executed. + */ +public class StepQueueManager extends AbstractDsfService +{ + /** + * Amount of time in miliseconds, that it takes the ISteppingTimedOutEvent + * event to be issued after a step is started. + * @see ISteppingTimedOutEvent + */ + public final static int STEPPING_TIMEOUT = 500; + + /** + * The depth of the step queue. In other words, the maximum number of steps + * that are queued before the step queue manager throwing them away. + */ + public final static int STEP_QUEUE_DEPTH = 3; + + /** + * 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 IDMEvent {} + + + private static class StepRequest { + StepType fStepType; + boolean fIsInstructionStep; + StepRequest(StepType type, boolean instruction) { + fStepType = type; + fIsInstructionStep = instruction; + } + } + + private IRunControl fRunControl; + private int fQueueDepth = STEP_QUEUE_DEPTH; + private Map> fStepQueues = new HashMap>(); + private Map fTimedOutFlags = new HashMap(); + private Map> fTimedOutFutures = new HashMap>(); + + public StepQueueManager(DsfSession session) { + super(session); + } + + /////////////////////////////////////////////////////////////////////////// + // IDsfService + @Override + public void initialize(final RequestMonitor requestMonitor) { + super.initialize( + new RequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleOK() { + doInitialize(requestMonitor); + }}); + } + + private void doInitialize(final RequestMonitor requestMonitor) { + fRunControl = getServicesTracker().getService(IRunControl.class); + + getSession().addServiceEventListener(this, null); + register(new String[]{ StepQueueManager.class.getName()}, new Hashtable()); + requestMonitor.done(); + } + + @Override + public void shutdown(final RequestMonitor requestMonitor) { + unregister(); + getSession().removeServiceEventListener(this); + super.shutdown(requestMonitor); + } + + @Override + protected BundleContext getBundleContext() { + return DsfDebugPlugin.getBundleContext(); + } + + /** + * Checks whether a step command can be queued up for given context. + */ + public boolean canEnqueueStep(IExecutionDMContext execCtx) { + return (fRunControl.isSuspended(execCtx) && fRunControl.canStep(execCtx)) || + (fRunControl.isStepping(execCtx) && !isSteppingTimedOut(execCtx)); + } + + /** + * Checks whether an instruction step command can be queued up for given context. + */ + public boolean canEnqueueInstructionStep(IExecutionDMContext execCtx) { + return (fRunControl.isSuspended(execCtx) && fRunControl.canInstructionStep(execCtx)) || + (fRunControl.isStepping(execCtx) && !isSteppingTimedOut(execCtx)); + } + + /** + * Returns the number of step commands that are queued for given execution + * context. + */ + public int getPendingStepCount(IExecutionDMContext execCtx) { + List stepQueue = fStepQueues.get(execCtx); + if (stepQueue == null) return 0; + return stepQueue.size(); + } + + /** + * 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. + */ + public void enqueueStep(IExecutionDMContext execCtx, StepType stepType) { + if (fRunControl.canStep(execCtx)) { + fRunControl.step(execCtx, stepType, new RequestMonitor(getExecutor(), null)); + } else if (canEnqueueStep(execCtx)) { + List stepQueue = fStepQueues.get(execCtx); + if (stepQueue == null) { + stepQueue = new LinkedList(); + fStepQueues.put(execCtx, stepQueue); + } + if (stepQueue.size() < fQueueDepth) { + stepQueue.add(new StepRequest(stepType, false)); + } + } + } + + /** + * Adds an instruction 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. + */ + public void enqueueInstructionStep(IExecutionDMContext execCtx, StepType stepType) { + if (fRunControl.canInstructionStep(execCtx)) { + fRunControl.instructionStep(execCtx, stepType, new RequestMonitor(getExecutor(), null)); + } else if (canEnqueueInstructionStep(execCtx)) { + List stepQueue = fStepQueues.get(execCtx); + if (stepQueue == null) { + stepQueue = new LinkedList(); + fStepQueues.put(execCtx, stepQueue); + } + if (stepQueue.size() < fQueueDepth) { + stepQueue.add(new StepRequest(stepType, true)); + } + } + } + + /** + * Returns whether the step instruction for the given context has timed out. + */ + public boolean isSteppingTimedOut(IExecutionDMContext execCtx) { + return fTimedOutFlags.containsKey(execCtx) ? fTimedOutFlags.get(execCtx) : false; + } + + + /////////////////////////////////////////////////////////////////////////// + + @DsfServiceEventHandler + public void eventDispatched(ISuspendedDMEvent e) { + // Take care of the stepping time out + fTimedOutFlags.remove(e.getDMContext()); + ScheduledFuture future = fTimedOutFutures.remove(e.getDMContext()); + if (future != null) future.cancel(false); + + // Check if there's a step pending, if so execute it + if (fStepQueues.containsKey(e.getDMContext())) { + List queue = fStepQueues.get(e.getDMContext()); + StepRequest request = queue.remove(queue.size() - 1); + if (queue.isEmpty()) fStepQueues.remove(e.getDMContext()); + if (request.fIsInstructionStep) { + if (fRunControl.canInstructionStep(e.getDMContext())) { + fRunControl.instructionStep( + e.getDMContext(), request.fStepType, new RequestMonitor(getExecutor(), null)); + } else { + // For whatever reason we can't step anymore, so clear out + // the step queue. + fStepQueues.remove(e.getDMContext()); + } + } else { + if (fRunControl.canStep(e.getDMContext())) { + fRunControl.step(e.getDMContext(), request.fStepType,new RequestMonitor(getExecutor(), null)); + } else { + // For whatever reason we can't step anymore, so clear out + // the step queue. + fStepQueues.remove(e.getDMContext()); + } + } + } + } + + @DsfServiceEventHandler + public void eventDispatched(final IResumedDMEvent e) { + if (e.getReason().equals(StateChangeReason.STEP)) { + fTimedOutFlags.put(e.getDMContext(), Boolean.FALSE); + // We shouldn't have a stepping timeout running unless we get two + // stepping events in a row without a suspended, which would be a + // protocol error. + assert !fTimedOutFutures.containsKey(e.getDMContext()); + fTimedOutFutures.put( + e.getDMContext(), + getExecutor().schedule( + new DsfRunnable() { public void run() { + fTimedOutFutures.remove(e.getDMContext()); + + // Issue the stepping time-out event. + getSession().dispatchEvent( + new ISteppingTimedOutEvent() { + public IExecutionDMContext getDMContext() { return e.getDMContext(); } + }, + getProperties()); + }}, + STEPPING_TIMEOUT, TimeUnit.MILLISECONDS) + ); + + } + } + + @DsfServiceEventHandler + public void eventDispatched(ISteppingTimedOutEvent e) { + fTimedOutFlags.put(e.getDMContext(), Boolean.TRUE); + } + +} From a12a4967e3670c700efb539f7698bdc137fc49cd Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 12 Feb 2008 23:13:12 +0000 Subject: [PATCH 237/834] [179102] Added logic to handle ModelProxyInstalledEvent. This logic now selects the top stack frame when the debug view is first opened. --- .../ui/viewmodel/launch/LaunchRootVMNode.java | 2 +- .../viewmodel/launch/StackFramesVMNode.java | 115 +++++++--- .../dd/dsf/ui/viewmodel/AbstractVMNode.java | 10 +- .../dsf/ui/viewmodel/AbstractVMProvider.java | 29 ++- .../DefaultVMContentProviderStrategy.java | 61 +++--- .../DefaultVMModelProxyStrategy.java | 205 ++++++++++-------- .../dd/dsf/ui/viewmodel/IVMModelProxy.java | 19 +- .../eclipse/dd/dsf/ui/viewmodel/IVMNode.java | 12 +- .../dd/dsf/ui/viewmodel/IVMProvider.java | 31 ++- .../viewmodel/ModelProxyInstalledEvent.java | 41 ++++ .../dd/dsf/ui/viewmodel/RootVMNode.java | 3 + .../dsf/ui/viewmodel/dm/AbstractDMVMNode.java | 12 +- .../update/AbstractCachingVMProvider.java | 29 +-- 13 files changed, 362 insertions(+), 207 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/ModelProxyInstalledEvent.java diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/LaunchRootVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/LaunchRootVMNode.java index 1c0af5b33b5..c6074e21142 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/LaunchRootVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/LaunchRootVMNode.java @@ -70,7 +70,7 @@ public class LaunchRootVMNode extends RootVMNode return false; } } - return true; + return super.isDeltaEvent(rootObject, e); } @Override diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java index 2e5f11b5c9e..317a2c584f1 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java @@ -19,7 +19,7 @@ import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.DMContexts; 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.StepQueueManager; import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerSuspendedDMEvent; import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent; @@ -30,6 +30,7 @@ import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMData; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.ModelProxyInstalledEvent; import org.eclipse.dd.dsf.ui.viewmodel.VMChildrenUpdate; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMNode; @@ -118,31 +119,39 @@ public class StackFramesVMNode extends AbstractDMVMNode return; } - getServicesTracker().getService(IStack.class).getTopFrame( - execDmc, - new DataRequestMonitor(getExecutor(), null) { - @Override - public void handleCompleted() { - if (!getStatus().isOK()) { - handleFailedUpdate(update); - return; - } - - IVMContext topFrameVmc = createVMContext(getData()); - - update.setChild(topFrameVmc, 0); - // 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 (fCachedOldFrameVMCs != null && fCachedOldFrameVMCs.length >= 1) { - fCachedOldFrameVMCs[0] = topFrameVmc; - for (int i = 0; i < fCachedOldFrameVMCs.length; i++) - update.setChild(fCachedOldFrameVMCs[i], i); - } else { - update.setChild(topFrameVmc, 0); - } - update.done(); + try { + getSession().getExecutor().execute(new DsfRunnable() { + public void run() { + getServicesTracker().getService(IStack.class).getTopFrame( + execDmc, + new DataRequestMonitor(getExecutor(), null) { + @Override + public void handleCompleted() { + if (!getStatus().isOK()) { + handleFailedUpdate(update); + return; + } + + IVMContext topFrameVmc = createVMContext(getData()); + + update.setChild(topFrameVmc, 0); + // 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 (fCachedOldFrameVMCs != null && fCachedOldFrameVMCs.length >= 1) { + fCachedOldFrameVMCs[0] = topFrameVmc; + for (int i = 0; i < fCachedOldFrameVMCs.length; i++) + update.setChild(fCachedOldFrameVMCs[i], i); + } else { + update.setChild(topFrameVmc, 0); + } + update.done(); + } + }); } }); + } catch (RejectedExecutionException e) { + update.done(); + } } @@ -209,7 +218,7 @@ public class StackFramesVMNode extends AbstractDMVMNode final IExecutionDMContext execDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IExecutionDMContext.class); IRunControl runControlService = getServicesTracker().getService(IRunControl.class); - IStepQueueManager stepQueueMgrService = getServicesTracker().getService(IStepQueueManager.class); + StepQueueManager stepQueueMgrService = getServicesTracker().getService(StepQueueManager.class); if (execDmc == null || runControlService == null || stepQueueMgrService == null) return; String imageKey = null; @@ -271,6 +280,31 @@ public class StackFramesVMNode extends AbstractDMVMNode } + @Override + public void getContextsForEvent(final VMDelta parentDelta, Object e, final DataRequestMonitor rm) { + if (e instanceof ModelProxyInstalledEvent) { + // Retrieve the list of stack frames, and mark the top frame to be selected. + getElementsTopStackFrameOnly( + new VMChildrenUpdate( + parentDelta, getVMProvider().getPresentationContext(), -1, -1, + new DataRequestMonitor>(getExecutor(), null) { + @Override + public void handleCompleted() { + if (getStatus().isOK() && getData().size() != 0) { + rm.setData(new IVMContext[] { (IVMContext)getData().get(0) }); + } else { + // In case of errors, return an empty set of frames. + rm.setData(new IVMContext[0]); + } + rm.done(); + } + }) + ); + return; + } + super.getContextsForEvent(parentDelta, e, rm); + } + public int getDeltaFlags(Object e) { // This node generates delta if the timers have changed, or if the // label has changed. @@ -282,9 +316,12 @@ public class StackFramesVMNode extends AbstractDMVMNode } else { return IModelDelta.CONTENT; } - } else if (e instanceof IStepQueueManager.ISteppingTimedOutEvent) { + } else if (e instanceof StepQueueManager.ISteppingTimedOutEvent) { return IModelDelta.CONTENT; + } else if (e instanceof ModelProxyInstalledEvent) { + return IModelDelta.SELECT | IModelDelta.EXPAND; } + return IModelDelta.NO_CHANGE; } @@ -300,8 +337,10 @@ public class StackFramesVMNode extends AbstractDMVMNode buildDeltaForSuspendedEvent((ISuspendedDMEvent)e, execDmc, execDmc, parent, nodeOffset, rm); } else if (e instanceof IResumedDMEvent) { buildDeltaForResumedEvent((IResumedDMEvent)e, parent, nodeOffset, rm); - } else if (e instanceof IStepQueueManager.ISteppingTimedOutEvent) { - buildDeltaForSteppingTimedOutEvent((IStepQueueManager.ISteppingTimedOutEvent)e, parent, nodeOffset, rm); + } else if (e instanceof StepQueueManager.ISteppingTimedOutEvent) { + buildDeltaForSteppingTimedOutEvent((StepQueueManager.ISteppingTimedOutEvent)e, parent, nodeOffset, rm); + } else if (e instanceof ModelProxyInstalledEvent) { + buildDeltaForModelProxyInstalledEvent(parent, nodeOffset, rm); } else { rm.done(); } @@ -372,9 +411,27 @@ public class StackFramesVMNode extends AbstractDMVMNode rm.done(); } - private void buildDeltaForSteppingTimedOutEvent(final IStepQueueManager.ISteppingTimedOutEvent e, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor rm) { + private void buildDeltaForSteppingTimedOutEvent(final StepQueueManager.ISteppingTimedOutEvent e, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor rm) { // Repaint the stack frame images to have the running symbol. parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); rm.done(); } + + private void buildDeltaForModelProxyInstalledEvent(final VMDelta parentDelta, final int nodeOffset, final RequestMonitor rm) { + // Retrieve the list of stack frames, and mark the top frame to be selected. + getElementsTopStackFrameOnly( + new VMChildrenUpdate( + parentDelta, getVMProvider().getPresentationContext(), -1, -1, + new DataRequestMonitor>(getExecutor(), null) { + @Override + public void handleCompleted() { + if (getStatus().isOK() && getData().size() != 0) { + parentDelta.addNode( getData().get(0), 0, IModelDelta.SELECT | IModelDelta.EXPAND); + } + rm.done(); + } + }) + ); + } + } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMNode.java index e91fc401214..436aec4aeca 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMNode.java @@ -10,7 +10,12 @@ *******************************************************************************/ package org.eclipse.dd.dsf.ui.viewmodel; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.dsf.ui.DsfUIPlugin; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; @@ -46,8 +51,9 @@ abstract public class AbstractVMNode implements IVMNode { fDisposed = true; } - public IVMContext getContextFromEvent(Object event) { - return null; + public void getContextsForEvent(VMDelta parentDelta, Object event, DataRequestMonitor rm) { + rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.NOT_SUPPORTED, "", null)); //$NON-NLS-1$ + rm.done(); } protected boolean isDisposed() { diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java index bfb34b0b151..495dc80c536 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java @@ -322,7 +322,7 @@ abstract public class AbstractVMProvider implements IVMProvider * overrides this method to optionally return the results for an update from * a cache. */ - protected void updateNode(final IVMNode node, IHasChildrenUpdate[] updates) { + public void updateNode(final IVMNode node, IHasChildrenUpdate[] updates) { IHasChildrenUpdate[] updateProxies = new IHasChildrenUpdate[updates.length]; for (int i = 0; i < updates.length; i++) { final IHasChildrenUpdate update = updates[i]; @@ -340,7 +340,7 @@ abstract public class AbstractVMProvider implements IVMProvider if (getStatus().getCode() == IDsfService.NOT_SUPPORTED) { updateNode( node, - new VMChildrenUpdate[] { new VMChildrenUpdate( + new VMChildrenUpdate( update, -1, -1, new ViewerDataRequestMonitor>(getExecutor(), update) { @Override @@ -349,7 +349,7 @@ abstract public class AbstractVMProvider implements IVMProvider update.done(); } }) - }); + ); } else { update.setStatus(getStatus()); @@ -370,13 +370,11 @@ abstract public class AbstractVMProvider implements IVMProvider * overrides this method to optionally return the results for an update from * a cache. */ - protected void updateNode(final IVMNode node, IChildrenCountUpdate[] updates) { - IChildrenCountUpdate[] updateProxies = new IChildrenCountUpdate[updates.length]; - for (int i = 0; i < updates.length; i++) { - final IChildrenCountUpdate update = updates[i]; - updateProxies[i] = new VMChildrenCountUpdate( + public void updateNode(final IVMNode node, final IChildrenCountUpdate update) { + node.update(new IChildrenCountUpdate[] { + new VMChildrenCountUpdate( update, - new ViewerDataRequestMonitor(getExecutor(), updates[i]) { + new ViewerDataRequestMonitor(getExecutor(), update) { @Override protected void handleOK() { update.setChildCount(getData()); @@ -388,7 +386,7 @@ abstract public class AbstractVMProvider implements IVMProvider if (getStatus().getCode() == IDsfService.NOT_SUPPORTED) { updateNode( node, - new VMChildrenUpdate[] { new VMChildrenUpdate( + new VMChildrenUpdate( update, -1, -1, new ViewerDataRequestMonitor>(getExecutor(), update) { @Override @@ -397,14 +395,13 @@ abstract public class AbstractVMProvider implements IVMProvider update.done(); } }) - }); + ); } } - }); - } - node.update(updateProxies); + }) + }); } /** @@ -415,8 +412,8 @@ abstract public class AbstractVMProvider implements IVMProvider * overrides this method to optionally return the results for an update from * a cache. */ - protected void updateNode(IVMNode node, IChildrenUpdate[] updates) { - node.update(updates); + public void updateNode(IVMNode node, IChildrenUpdate update) { + node.update(new IChildrenUpdate[] { update }); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMContentProviderStrategy.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMContentProviderStrategy.java index afff0d73f4c..6009f7b16c9 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMContentProviderStrategy.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMContentProviderStrategy.java @@ -170,7 +170,7 @@ public class DefaultVMContentProviderStrategy implements IElementContentProvider update.setChildCount(0); update.done(); } else if (childNodes.length == 1) { - getVMProvider().updateNode(childNodes[0], new IChildrenCountUpdate[] { update } ); + getVMProvider().updateNode(childNodes[0], update); } else { getChildrenCountsForNode( update, @@ -208,7 +208,7 @@ public class DefaultVMContentProviderStrategy implements IElementContentProvider // Invalid update, just mark done. update.done(); } else if (childNodes.length == 1) { - getVMProvider().updateNode(childNodes[0], new IChildrenUpdate[] { update }); + getVMProvider().updateNode(childNodes[0], update); } else { getChildrenCountsForNode( update, @@ -261,23 +261,22 @@ public class DefaultVMContentProviderStrategy implements IElementContentProvider final int nodeIndex = i; getVMProvider().updateNode( childNodes[i], - new IChildrenCountUpdate[] { - new VMChildrenCountUpdate( - update, - childrenCountMultiReqMon.add( - new DataRequestMonitor(getVMProvider().getExecutor(), null) { - @Override - protected void handleOK() { - counts[nodeIndex] = getData(); - } - - @Override - protected void handleCompleted() { - super.handleCompleted(); - childrenCountMultiReqMon.requestMonitorDone(this); - } - })) - }); + new VMChildrenCountUpdate( + update, + childrenCountMultiReqMon.add( + new DataRequestMonitor(getVMProvider().getExecutor(), null) { + @Override + protected void handleOK() { + counts[nodeIndex] = getData(); + } + + @Override + protected void handleCompleted() { + super.handleCompleted(); + childrenCountMultiReqMon.requestMonitorDone(this); + } + })) + ); } } @@ -315,21 +314,19 @@ public class DefaultVMContentProviderStrategy implements IElementContentProvider if (elementsLength > 0) { getVMProvider().updateNode( nodes[i], - new IChildrenUpdate[] { - new VMChildrenUpdate( - update, elementsStartIdx, elementsLength, - elementsMultiRequestMon.add(new DataRequestMonitor>(getVMProvider().getExecutor(), null) { - @Override - protected void handleCompleted() { - if (getStatus().isOK()) { - for (int i = 0; i < elementsLength; i++) { - update.setChild(getData().get(i), elementsStartIdx + nodeStartIdx + i); - } + new VMChildrenUpdate( + update, elementsStartIdx, elementsLength, + elementsMultiRequestMon.add(new DataRequestMonitor>(getVMProvider().getExecutor(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + for (int i = 0; i < elementsLength; i++) { + update.setChild(getData().get(i), elementsStartIdx + nodeStartIdx + i); } - elementsMultiRequestMon.requestMonitorDone(this); } - })) - } + elementsMultiRequestMon.requestMonitorDone(this); + } + })) ); } } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMModelProxyStrategy.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMModelProxyStrategy.java index 4a3739f5439..f51c807277a 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMModelProxyStrategy.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMModelProxyStrategy.java @@ -24,9 +24,8 @@ import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.MultiRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.debug.internal.ui.DebugUIPlugin; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelChangedListener; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy; @@ -182,6 +181,7 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy { */ public void installed(Viewer viewer) { fViewer = viewer; + fProvider.handleEvent(new ModelProxyInstalledEvent(this, viewer, fRootElement)); } /** @@ -262,8 +262,8 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy { // If no child nodes have deltas we can stop here. if (childNodesWithDeltaFlags.size() == 0) { - rm.done(); rm.setData(viewRootDelta); + rm.done(); return; } @@ -284,19 +284,26 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy { protected void buildChildDeltas(final IVMNode node, final Object event, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor rm) { - final IVMContext vmc = node.getContextFromEvent(event); - - if (vmc != null) { - buildChildDeltasForEventContext(vmc, node, event, parentDelta, nodeOffset, rm); - } else { - // The DMC for this node was not found in the event. Call the - // super-class to resort to the default behavior which may add a - // delta for every element in this node. - buildChildDeltasForAllContexts(node, event, parentDelta, nodeOffset, rm); - } + node.getContextsForEvent( + parentDelta, + event, + new DataRequestMonitor(getVMProvider().getExecutor(), rm) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + assert getData() != null; + buildChildDeltasForEventContext(getData(), node, event, parentDelta, nodeOffset, rm); + } else if (getStatus().getCode() == IDsfService.NOT_SUPPORTED) { + // The DMC for this node was not found in the event. Call the + // super-class to resort to the default behavior which may add a + // delta for every element in this node. + buildChildDeltasForAllContexts(node, event, parentDelta, nodeOffset, rm); + } + } + }); } - protected void buildChildDeltasForEventContext(final IVMContext vmc, final IVMNode node, final Object event, + protected void buildChildDeltasForEventContext(final IVMContext[] vmcs, final IVMNode node, final Object event, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) { final Map childNodeDeltas = getChildNodesWithDeltaFlags(node, parentDelta, event); @@ -324,31 +331,34 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy { // elements and then finding the DMC that the event is for. getVMProvider().updateNode( node, - new IChildrenUpdate[] { - new VMChildrenUpdate( - parentDelta, getVMProvider().getPresentationContext(), -1, -1, - new DataRequestMonitor>(getVMProvider().getExecutor(), null) { - @Override - protected void handleCompleted() { - if (isDisposed()) return; - - // Check for an empty list of elements. If it's empty then we - // don't have to call the children nodes, so return here. - // No need to propagate error, there's no means or need to display it. - if (!getStatus().isOK() || getData().isEmpty()) { - requestMonitor.done(); - return; - } - - // Find the index. + new VMChildrenUpdate( + parentDelta, getVMProvider().getPresentationContext(), -1, -1, + new DataRequestMonitor>(getVMProvider().getExecutor(), null) { + @Override + protected void handleCompleted() { + if (isDisposed()) return; + + // Check for an empty list of elements. If it's empty then we + // don't have to call the children nodes, so return here. + // No need to propagate error, there's no means or need to display it. + if (!getStatus().isOK() || getData().isEmpty()) { + requestMonitor.done(); + return; + } + + CountingRequestMonitor countingRm = + new CountingRequestMonitor(getVMProvider().getExecutor(), requestMonitor); + + int count = 0; + for (IVMContext vmc : vmcs) { + // Find the index of the vmc in the full list of elements. int i; for (i = 0; i < getData().size(); i++) { if (vmc.equals(getData().get(i))) break; } if (i == getData().size()) { // Element not found, no need to generate the delta. - requestMonitor.done(); - return; + continue; } // Optimization: Try to find a delta with a matching element, if found use it. @@ -359,18 +369,27 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy { delta = parentDelta.addNode(vmc, elementIndex, IModelDelta.NO_CHANGE); } - callChildNodesToBuildDelta(node, childNodeDeltas, delta, event, requestMonitor); + callChildNodesToBuildDelta(node, childNodeDeltas, delta, event, countingRm); + count++; } - }) - }); + countingRm.setDoneCount(count); + } + })); } else { - // Optimization: Try to find a delta with a matching element, if found use it. - // Otherwise create a new delta for the event element. - VMDelta delta = (VMDelta)parentDelta.getChildDelta(vmc); - if (delta == null) { - delta = parentDelta.addNode(vmc, IModelDelta.NO_CHANGE); + CountingRequestMonitor countingRm = + new CountingRequestMonitor(getVMProvider().getExecutor(), requestMonitor); + int count = 0; + for (IVMContext vmc : vmcs) { + // Optimization: Try to find a delta with a matching element, if found use it. + // Otherwise create a new delta for the event element. + VMDelta delta = (VMDelta)parentDelta.getChildDelta(vmc); + if (delta == null) { + delta = parentDelta.addNode(vmc, IModelDelta.NO_CHANGE); + } + callChildNodesToBuildDelta(node, childNodeDeltas, delta, event, requestMonitor); + count++; } - callChildNodesToBuildDelta(node, childNodeDeltas, delta, event, requestMonitor); + countingRm.setDoneCount(count); } } @@ -414,49 +433,48 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy { // each element as the parent of their delta. getVMProvider().updateNode( node, - new IChildrenUpdate[] { - new VMChildrenUpdate( - parentDelta, getVMProvider().getPresentationContext(), -1, -1, - new DataRequestMonitor>(getVMProvider().getExecutor(), null) { - @Override - protected void handleCompleted() { - if (fDisposed) return; - - // Check for an empty list of elements. If it's empty then we - // don't have to call the children nodes, so return here. - // No need to propagate error, there's no means or need to display it. - if (!getStatus().isOK() || getData().size() == 0) { - requestMonitor.done(); - return; - } - - final MultiRequestMonitor elementsDeltasMultiRequestMon = - new MultiRequestMonitor(getVMProvider().getExecutor(), null) { + new VMChildrenUpdate( + parentDelta, getVMProvider().getPresentationContext(), -1, -1, + new DataRequestMonitor>(getVMProvider().getExecutor(), null) { + @Override + protected void handleCompleted() { + if (fDisposed) return; + + // Check for an empty list of elements. If it's empty then we + // don't have to call the children nodes, so return here. + // No need to propagate error, there's no means or need to display it. + if (!getStatus().isOK() || getData().size() == 0) { + requestMonitor.done(); + return; + } + + final MultiRequestMonitor elementsDeltasMultiRequestMon = + new MultiRequestMonitor(getVMProvider().getExecutor(), null) { + @Override + protected void handleCompleted() { + if (isDisposed()) return; + requestMonitor.done(); + } + }; + + // For each element from this node, create a new delta, + // and then call all the child nodes to build their delta. + for (int i = 0; i < getData().size(); i++) { + int elementIndex = nodeOffset >= 0 ? nodeOffset + i : -1; + VMDelta delta = + parentDelta.addNode(getData().get(i), elementIndex, IModelDelta.NO_CHANGE); + callChildNodesToBuildDelta( + node, childNodesWithDeltaFlags, delta, event, + elementsDeltasMultiRequestMon.add(new RequestMonitor(getVMProvider().getExecutor(), null) { @Override protected void handleCompleted() { - if (isDisposed()) return; - requestMonitor.done(); + elementsDeltasMultiRequestMon.requestMonitorDone(this); } - }; - - // For each element from this node, create a new delta, - // and then call all the child nodes to build their delta. - for (int i = 0; i < getData().size(); i++) { - int elementIndex = nodeOffset >= 0 ? nodeOffset + i : -1; - VMDelta delta = - parentDelta.addNode(getData().get(i), elementIndex, IModelDelta.NO_CHANGE); - callChildNodesToBuildDelta( - node, childNodesWithDeltaFlags, delta, event, - elementsDeltasMultiRequestMon.add(new RequestMonitor(getVMProvider().getExecutor(), null) { - @Override - protected void handleCompleted() { - elementsDeltasMultiRequestMon.requestMonitorDone(this); - } - })); - } + })); } - }) - }); + } + }) + ); } } @@ -568,19 +586,18 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy { final int nodeIndex = i; getVMProvider().updateNode( childNodes[i], - new IChildrenCountUpdate[] { - new VMChildrenCountUpdate( - delta, getVMProvider().getPresentationContext(), - childrenCountMultiRequestMon.add( - new DataRequestMonitor(getVMProvider().getExecutor(), null) { - @Override - protected void handleCompleted() { - counts[nodeIndex] = getData(); - childrenCountMultiRequestMon.requestMonitorDone(this); - } - }) - ) - }); + new VMChildrenCountUpdate( + delta, getVMProvider().getPresentationContext(), + childrenCountMultiRequestMon.add( + new DataRequestMonitor(getVMProvider().getExecutor(), null) { + @Override + protected void handleCompleted() { + counts[nodeIndex] = getData(); + childrenCountMultiRequestMon.requestMonitorDone(this); + } + }) + ) + ); } } else { Map data = new HashMap(); diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMModelProxy.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMModelProxy.java index 07afe0dae52..ae2a808d020 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMModelProxy.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMModelProxy.java @@ -15,17 +15,32 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy; /** - * + * View Model extension to the platform IModelProxy interface. This extension + * allows the IVMProvider implementation to delegate the model proxy implementation + * into a separate object. */ @SuppressWarnings("restriction") public interface IVMModelProxy extends IModelProxy { - + + /** + * Returns the root element that this model proxy was created for. + */ public Object getRootElement(); + /** + * Returns whether the given event applies to the root element and the + * nodes in this model proxy. + */ public boolean isDeltaEvent(Object event); + /** + * Creates a model delta for the given event. + */ public void createDelta(final Object event, final DataRequestMonitor rm); + /** + * Sends the given delta to this model proxy's listeners. + */ public void fireModelChanged(IModelDelta delta); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMNode.java index 90036d72736..f3ea5927271 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMNode.java @@ -11,6 +11,7 @@ package org.eclipse.dd.dsf.ui.viewmodel; import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; @@ -92,20 +93,21 @@ public interface IVMNode extends IElementContentProvider public void buildDelta(Object event, VMDelta parent, int nodeOffset, RequestMonitor requestMonitor); /** - * Returns the view model element for the given data model event. This method + * Retireves the view model elements for the given data model event. This method * is optional and it allows the view model provider to optimize event processing * by avoiding the need to retrieve all possible elements for the given node. *

    * For example: If a threads node implementation is given a thread stopped event in - * for this method, and the stopped event included a reference to the thread. Then + * this method, and the stopped event included a reference to the thread. Then * the implementation should create a view model context for that thread and return it * here. * + * @param parentDelta The parent delta in the processing of this event. * @param event The event to check for the data model object. - * @return A view model object if it can be calculated, null - * if it cannot. + * @param Request monitor for the array of elements corresponding to the + * given event. */ - public IVMContext getContextFromEvent(Object event); + public void getContextsForEvent(VMDelta parentDelta, Object event, DataRequestMonitor rm); /** * Releases the resources held by this node. diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java index 2a924b2b09f..54331ac1b9b 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMProvider.java @@ -3,8 +3,11 @@ package org.eclipse.dd.dsf.ui.viewmodel; import java.util.concurrent.Executor; import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputProvider; @@ -39,6 +42,12 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputProvi public interface IVMProvider extends IElementContentProvider, IModelProxyFactory, IColumnPresentationFactory, IViewerInputProvider { + /** + * Returns the presentation context of the viewer that this provider + * is configured for. + */ + public IPresentationContext getPresentationContext(); + /** * Returns the VM Adapter associated with the provider. */ @@ -66,10 +75,26 @@ public interface IVMProvider public IVMNode[] getAllVMNodes(); /** - * Returns the presentation context of the viewer that this provider - * is configured for. + * Calls the given view model node to perform the given updates. This + * method is different than calling the IVMNode update method directly in that + * it allows the provider to do additional processing on the update such as caching. */ - public IPresentationContext getPresentationContext(); + public void updateNode(final IVMNode node, IHasChildrenUpdate[] updates); + + /** + * Calls the given view model node to perform the given updates. This + * method is different than calling the IVMNode update method directly in that + * it allows the provider to do additional processing on the update such as caching. + */ + public void updateNode(final IVMNode node, IChildrenCountUpdate updates); + + /** + * Calls the given view model node to perform the given updates. This + * method is different than calling the IVMNode update method directly in that + * it allows the provider to do additional processing on the update such as caching. + */ + public void updateNode(IVMNode node, IChildrenUpdate updates); + /** * Cleans up the resources associated with this provider. diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/ModelProxyInstalledEvent.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/ModelProxyInstalledEvent.java new file mode 100644 index 00000000000..68073af3ddb --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/ModelProxyInstalledEvent.java @@ -0,0 +1,41 @@ +package org.eclipse.dd.dsf.ui.viewmodel; + +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy; +import org.eclipse.jface.viewers.Viewer; + +/** + * Event generated by an IModelProxy implementation when it is installed + * into a viewer. + */ +public class ModelProxyInstalledEvent { + private final IModelProxy fProxy; + private final Viewer fViewer; + private final Object fRootElement; + + public ModelProxyInstalledEvent(IModelProxy proxy, Viewer viewer, Object rootElement) { + fProxy = proxy; + fViewer = viewer; + fRootElement = rootElement; + } + + /** + * Returns the IModelProxy that generated this event. + */ + public IModelProxy getModelProxy() { + return fProxy; + } + + /** + * Returns the element that this model proxy was registered for. + */ + public Object getRootElement() { + return fRootElement; + } + + /** + * Returns the viewer that installed this model proxy. + */ + public Viewer getViewer() { + return fViewer; + } +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/RootVMNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/RootVMNode.java index ae2895f8b39..5f34b2c05ad 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/RootVMNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/RootVMNode.java @@ -45,6 +45,9 @@ public class RootVMNode extends AbstractVMNode implements IRootVMNode { * event should be processed to generate a delta. */ public boolean isDeltaEvent(Object rootObject, Object event) { + if (event instanceof ModelProxyInstalledEvent) { + return rootObject.equals( ((ModelProxyInstalledEvent)event).getRootElement() ); + } return true; } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMNode.java index d265947d89b..d94b6f06f5b 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMNode.java @@ -15,6 +15,7 @@ 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.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.dsf.datamodel.DMContexts; @@ -28,6 +29,7 @@ import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMContext; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMNode; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.IVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; @@ -129,15 +131,17 @@ abstract public class AbstractDMVMNode extends AbstractVMNode implements IVMNode } @Override - public IVMContext getContextFromEvent(Object event) { + public void getContextsForEvent(VMDelta parentDelta, Object event, DataRequestMonitor rm) { if (event instanceof IDMEvent) { IDMEvent dmEvent = (IDMEvent)event; IDMContext dmc = DMContexts.getAncestorOfType(dmEvent.getDMContext(), fDMCClassType); if (dmc != null) { - return createVMContext(dmc); + rm.setData(new IVMContext[] { createVMContext(dmc) }); + rm.done(); + return; } - } - return null; + } + super.getContextsForEvent(parentDelta, event, rm); } protected AbstractDMVMProvider getDMVMProvider() { diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java index 98e7b4acc76..3851620e4db 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java @@ -285,7 +285,7 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa } @Override - protected void updateNode(IVMNode node, IHasChildrenUpdate[] updates) { + public void updateNode(IVMNode node, IHasChildrenUpdate[] updates) { LinkedList missUpdates = new LinkedList(); for(final IHasChildrenUpdate update : updates) { ElementDataKey key = makeEntryKey(node, update); @@ -316,20 +316,14 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa } @Override - protected void updateNode(IVMNode node, IChildrenCountUpdate[] updates) { - // Given our knowledge of DefaultVMContentProviderStragety, make an - // assumption about the updates argument: there should always be - // exactly one update in this array. - assert updates.length == 1; - final IChildrenCountUpdate update = updates[0]; - + public void updateNode(IVMNode node, final IChildrenCountUpdate update) { ElementDataKey key = makeEntryKey(node, update); final ElementDataEntry entry = getElementDataEntry(key); if(entry.fChildrenCount != null) { update.setChildCount(entry.fChildrenCount.intValue()); update.done(); } else { - updates[0] = new VMChildrenCountUpdate(update, new DataRequestMonitor(getExecutor(), null) { + IChildrenCountUpdate updateProxy = new VMChildrenCountUpdate(update, new DataRequestMonitor(getExecutor(), null) { @Override protected void handleCompleted() { if(getStatus().isOK()) { @@ -341,17 +335,12 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa update.done(); } }); - super.updateNode(node, updates); + super.updateNode(node, updateProxy); } } @Override - protected void updateNode(IVMNode node, IChildrenUpdate[] updates) { - // Given our knowledge of DefaultVMContentProviderStragety, make an - // assumption about the updates argument: there should always be - // exactly one update in this array. - assert updates.length == 1; - final IChildrenUpdate update = updates[0]; + public void updateNode(IVMNode node, final IChildrenUpdate update) { ElementDataKey key = makeEntryKey(node, update); @@ -360,7 +349,7 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa // We need to retrieve all the children if we don't have any children information. // Or if the client requested all children (offset = -1, length -1) and we have not // retrieved that before. - updates[0] = new VMChildrenUpdate( + IChildrenUpdate updateProxy = new VMChildrenUpdate( update, update.getOffset(), update.getLength(), new DataRequestMonitor>(getExecutor(), null) { @@ -396,7 +385,7 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa update.done(); } }); - super.updateNode(node, updates); + super.updateNode(node, updateProxy); } else if (update.getOffset() < 0 ) { // The update requested all children. Fill in all children assuming that // the children array is complete. @@ -450,7 +439,9 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa })); } - super.updateNode( node, partialUpdates.toArray(new IChildrenUpdate[partialUpdates.size()]) ); + for (IChildrenUpdate partialUpdate : partialUpdates) { + super.updateNode(node, partialUpdate); + } multiRm.setDoneCount(partialUpdates.size()); } else { // we have all of the children in cache; return from cache From 65ce6ccf3772082b3abedae1b7738430dc1c7f92 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 13 Feb 2008 20:14:03 +0000 Subject: [PATCH 238/834] [179102] Re-aligned plugin and package names to confirm with Eclipse policy. --- plugins/org.eclipse.dd.doc.dsf/.cvsignore | 7 + plugins/org.eclipse.dd.doc.dsf/.project | 22 + .../META-INF/MANIFEST.MF | 8 + plugins/org.eclipse.dd.doc.dsf/about.html | 28 ++ plugins/org.eclipse.dd.doc.dsf/book.css | 1 + .../org.eclipse.dd.doc.dsf/build.properties | 21 + plugins/org.eclipse.dd.doc.dsf/buildDoc.xml | 141 ++++++ .../customBuildCallbacks.xml | 157 +++++++ .../docs/dsf_concurrency_model-1.png | Bin 0 -> 6256 bytes .../docs/dsf_concurrency_model.html | 432 ++++++++++++++++++ .../docs/dsf_data_model.html | 286 ++++++++++++ .../docs/dsf_mi_instructions.html | 135 ++++++ .../docs/dsf_services_model-1.png | Bin 0 -> 2224 bytes .../docs/dsf_services_model-2.png | Bin 0 -> 1761 bytes .../docs/dsf_services_model.html | 363 +++++++++++++++ .../docs/dsf_white_paper.html | 315 +++++++++++++ plugins/org.eclipse.dd.doc.dsf/notices.html | 22 + plugins/org.eclipse.dd.doc.dsf/options.txt | 35 ++ .../org.eclipse.dd.doc.dsf/plugin.properties | 13 + plugins/org.eclipse.dd.doc.dsf/plugin.xml | 32 ++ plugins/org.eclipse.dd.doc.dsf/schema.css | 66 +++ plugins/org.eclipse.dd.doc.dsf/toc.xml | 15 + 22 files changed, 2099 insertions(+) create mode 100644 plugins/org.eclipse.dd.doc.dsf/.cvsignore create mode 100644 plugins/org.eclipse.dd.doc.dsf/.project create mode 100644 plugins/org.eclipse.dd.doc.dsf/META-INF/MANIFEST.MF create mode 100644 plugins/org.eclipse.dd.doc.dsf/about.html create mode 100644 plugins/org.eclipse.dd.doc.dsf/book.css create mode 100644 plugins/org.eclipse.dd.doc.dsf/build.properties create mode 100644 plugins/org.eclipse.dd.doc.dsf/buildDoc.xml create mode 100644 plugins/org.eclipse.dd.doc.dsf/customBuildCallbacks.xml create mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/dsf_concurrency_model-1.png create mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/dsf_concurrency_model.html create mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/dsf_data_model.html create mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/dsf_mi_instructions.html create mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/dsf_services_model-1.png create mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/dsf_services_model-2.png create mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/dsf_services_model.html create mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/dsf_white_paper.html create mode 100644 plugins/org.eclipse.dd.doc.dsf/notices.html create mode 100644 plugins/org.eclipse.dd.doc.dsf/options.txt create mode 100644 plugins/org.eclipse.dd.doc.dsf/plugin.properties create mode 100644 plugins/org.eclipse.dd.doc.dsf/plugin.xml create mode 100644 plugins/org.eclipse.dd.doc.dsf/schema.css create mode 100644 plugins/org.eclipse.dd.doc.dsf/toc.xml diff --git a/plugins/org.eclipse.dd.doc.dsf/.cvsignore b/plugins/org.eclipse.dd.doc.dsf/.cvsignore new file mode 100644 index 00000000000..2bb5b7b6fde --- /dev/null +++ b/plugins/org.eclipse.dd.doc.dsf/.cvsignore @@ -0,0 +1,7 @@ ++index ++javadoc.link.location ++reference ++build.xml ++org.eclipse.dd.dsf.doc_1.0.0.jar ++temp.convert.txt ++temp.options.txt \ No newline at end of file diff --git a/plugins/org.eclipse.dd.doc.dsf/.project b/plugins/org.eclipse.dd.doc.dsf/.project new file mode 100644 index 00000000000..3e85a3a2094 --- /dev/null +++ b/plugins/org.eclipse.dd.doc.dsf/.project @@ -0,0 +1,22 @@ + + + org.eclipse.dd.doc.dsf + + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + + diff --git a/plugins/org.eclipse.dd.doc.dsf/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.doc.dsf/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..595efe4e773 --- /dev/null +++ b/plugins/org.eclipse.dd.doc.dsf/META-INF/MANIFEST.MF @@ -0,0 +1,8 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Debug Services Framework Documentation +Bundle-Vendor: Eclipse.org +Bundle-SymbolicName: org.eclipse.dd.doc.dsf;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Localization: plugin +Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/plugins/org.eclipse.dd.doc.dsf/about.html b/plugins/org.eclipse.dd.doc.dsf/about.html new file mode 100644 index 00000000000..d4cc693f9f0 --- /dev/null +++ b/plugins/org.eclipse.dd.doc.dsf/about.html @@ -0,0 +1,28 @@ + + + + +About + + +

    About This Content

    + +

    June 5, 2007

    +

    License

    + +

    The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at http://www.eclipse.org/legal/epl-v10.html. +For purposes of the EPL, "Program" will mean the Content.

    + +

    If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at http://www.eclipse.org.

    + + + \ No newline at end of file diff --git a/plugins/org.eclipse.dd.doc.dsf/book.css b/plugins/org.eclipse.dd.doc.dsf/book.css new file mode 100644 index 00000000000..157414c6c66 --- /dev/null +++ b/plugins/org.eclipse.dd.doc.dsf/book.css @@ -0,0 +1 @@ +@import "../PRODUCT_PLUGIN/book.css"; diff --git a/plugins/org.eclipse.dd.doc.dsf/build.properties b/plugins/org.eclipse.dd.doc.dsf/build.properties new file mode 100644 index 00000000000..4ae11288b7b --- /dev/null +++ b/plugins/org.eclipse.dd.doc.dsf/build.properties @@ -0,0 +1,21 @@ +############################################################################### +# Copyright (c) 2000, 2006 IBM Corporation and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Wind River Systems, Inc. - initial API and implementation +############################################################################### +bin.includes = META-INF/,\ + about.html,\ + notices.html,\ + plugin.properties,\ + plugin.xml,\ + toc.xml,\ + docs/,\ + book.css,\ + schema.css +customBuildCallbacks = customBuildCallbacks.xml + diff --git a/plugins/org.eclipse.dd.doc.dsf/buildDoc.xml b/plugins/org.eclipse.dd.doc.dsf/buildDoc.xml new file mode 100644 index 00000000000..765a01ce184 --- /dev/null +++ b/plugins/org.eclipse.dd.doc.dsf/buildDoc.xml @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/org.eclipse.dd.doc.dsf/customBuildCallbacks.xml b/plugins/org.eclipse.dd.doc.dsf/customBuildCallbacks.xml new file mode 100644 index 00000000000..7e14739e639 --- /dev/null +++ b/plugins/org.eclipse.dd.doc.dsf/customBuildCallbacks.xml @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/dsf_concurrency_model-1.png b/plugins/org.eclipse.dd.doc.dsf/docs/dsf_concurrency_model-1.png new file mode 100644 index 0000000000000000000000000000000000000000..1bb373447d7bd0f17cd54f8298fc6f65658c8420 GIT binary patch literal 6256 zcmb7IXH-*Nvra<5D1dv zrDzaB2SJe=-}hVJk9&XJv(_nlpPAWn=FB{MX5x(vb)nZ-t^oi5s2=RL2><{JBR)q! zK*TG%I*&f_26odh&;S7HQ^J1TODB%6`ogRN0045@zb6p4_~kZU?c` z%=YG5e(+_`D3-r6fDIHE_W)^gCW$PQFC;a=@elm|^<$>?@g6w@0OSOKBLLKv5nWXH zuZ+|HkUHS+WE~*#F~iRY@_*kFXID-uUE1vI_LNpR85OSoOC&)Rc?+XF1{C3l?i$-z zDSAL7^jE-&0$3gUG1Jqri*qr4rAOxPTv3}H8NK?-nFfh3aYS4qG8ke%@iKNNI7E5M)_@JV>mW2sXncXP&W*nXvO^PVoj0 z+-Ks*L|JKDTDj2NVY?GM?wTIzQ7!D*nS`0@aDnFAB}Q(f|B#N#}f z{RaI?y}2?TknigAm8Q42&nfojJASl~d7;k45sY_`sai_+a48AbX4N`j-{B~olEKj% zx5{7JxgX+?Z`#)TiG?T)>8plI)WCj_5IwAsYnwESad$}*duu9867zDg$RTW!y=Y|Z zCc-J$B~99-EZpUnm)#0e)7y5%jp$fE!+lB~BsBnE(|raL--4{Ly}pqA+-+bXCfPK% zb0cHKYMLJQ=05ZJ!Jy;peY!7jTxMt)RwTsRU8mpbi^R$Ck!X`~D+|l}B>4f#CiXE9 z1J;o4&mc9+<}L7V3{s?HYp?joiH?7ff3iAG^u};Q`qDIoGQR(SLO2Vj;fcFC*^*(!7tR1a`o;)cS$F(@l`552e3Gj*|)pUeJ>#AGsSJPHqeYg3vLGa73 zjbM1t$GLayiDTQ_C-t3V-@*^trD;F(*MIr8CeEjpgao)6j!f!0#d zS=VKFEN3Cy02~w)6g98PV{cH(juXA*0-ssd?A@Z``F6a{61Lg@IKgElOut0uD;S?r zbn3Sls?+u2ZXTwxLupgD@!S3DqaNe3Kb^HhYuHx8ymx-5MWHS%5&Xe_SADZp()_t% z3<@fke~H}7ebGbnA@Y#Mg@u9^qYPQep4w#wBBe6z3R?O$O8ngU*4_(Ax027SNGm5^ z?2vrBK+3Rl!Gdn|j#94&QvR%+>=_#P6N$zVZaSWlWv zCD0%heIfOn&z%MBmY@{a*#X^%wTclFPb#$H**i5&`J`uvR-9%OCsQ&@N|*#D=iKV^ z2mfdW7^AAOw*3{HSIR5hB0;&(xpOq@)76p$SssVAgP1Zk=9bQ?cUPWbDbjZpLHI|t zrS8nK@^^F|qJD@LP9e%vFs3Hq<$S$25HM_FS->n?q4@f)Zf5QGD`%+;+0*T9E)G;v zuBizw1B8PdbfZvAkHQ!w#R(k|boic}$(kZCLowNsL+dA|Ut+hJZwo&5wT4zqTotRO zqlR@C%`S5J(Km+HCt} z00qwFSFEja>2on&IXMoe2Qhk2vB;D^mYx;n`dxn>_7FTU!oo0{avf|%)=h2Zo!0_- zGjf(4(6U|K9E3v1b*{(MM1YJ+Xi}QA!xqN?2^0K6 zMiMdtS0vyif}7rTfjvJzZO!Q0-kiH~W?PKVGUDB(jR@f?e?tNK4yRh%ZltPbBZfS| z_^E+YonAJLTY%}Si7am>m*IifrrPxc3;CzYMXcfEQohL_6+L=#yDF$nMe8U zm{m2W&$U|Xi&dGr%^ux|@#|b;Q1Npe$iMDoKHV}0#4nler-TvxTrd}>swY--&<_YL zuBZ#QsDPCTzTZ~ITE*9ex2yp~7)SJjgI9cKBLT1$lBzGaZz+N%8Dj)J{<}@un11nTO5e@UL@Lw&!u>2oI+p3pC-?#_h9%DmTl>*A9y&arSCc=Bw-b)MI z%!gQ$C^s%mt&!yRaUvLP3g-zWmgnaYCa_yyw3*}AtE?O3 zM?3aKHTQ!$iJIg>NK-_BxFi2yp+0s?*)G-Fn|$dnD#=W9b@9j8)H3)Iw6|}ciKh|{ z=d=C*%>KX{)&)8wj`Rlsj!88{d?kC>%UZay4?_lvGQ=moHgP`g)aT0dMuckvD-u~60Gedr}qAH z0TQZEHt8L}w9K_=Yy4d*&Ezd(GR)b(eoKExdj{c`LOwRym@TD&U6WP)+_S9)mvpGr z%a>H>ALM=BzM}WWP&B4y)`S}`b-;(G)O4a~5QF6G*~6QW)5|8adRVw8Ev3sc3-FMB zaiN%1`-m~6aJchw436S*%^Vzgs;E>_6#GH(HQGR6678jfqc3`d99c*bWZdKS4I=n4n;9w}*-|e0x@= ztrosDie|dPdFe^dlC7%!BlB@hHgOtsQjZk#k!^LQRVPz}t@w%ns{?bdFnK+T4frvE zCoiI&X5u;5)a)H@ZRDF5)tQAf)o&v`1n$j{ZEA~9qoIu!A*jd+iq7VD-isId;wng45%l9U*cAACz)7wq&(u)=I*n7O znU!wl(d-+^;xySGJzq;s7B~?MXurW(xU0ON=R9|9QiO$J4-rCENdJKlyKbvMp>I^J zag}#%TdU-Q7hekqo(y4rc)qm!*w-lc{;fiqB3#7w#oEEnVB?*K!U8>MvDaJlA79!N zIhD+^^Zj?T!GhUPvZi#@&c^N0uwz$yaOYK|gberPiPRTJsIv03n`HIUtXOvE6=!AB zlk->P45gLm49Vv@l-WvmokSNi{f9{#mx{sj#ToVb+7IaTABp~O{d_E6FmItV7Jxnf zb$R%TtgC8geBdf3apJ%XjD9dKJIj)L&JRmBhWbN)pjYX{9$3~3t3XJ;v4#LJp<0h?7HDK4k_cR{N9w0+$>4) z*e%pIhj;u)x6+J856qDBPaxf8YQcKHX7tl-XmRHHNc5CKiOVl0g?+!5ypSmxz^FXx z3T(z~Lz${q)k;~qNw1~tlMBbJn!eSvWg0WHseg62c{MZZ`z=sj4U&79#{XpX#)#KL0;D|-3mgI>EH!bA3Qw^28AAgJD zkCLC?DloJRY)0KO%zx>)yV)?dQ_Waocg8X*t89@jw#a0{@C4c#b`w*z$r|sFOdvYO z9{3-}NRl)V*F$XVc~Tm7uHhAUPW!gYl)eZaAH$TQJd1%iGtP?R`e?OEiV-C*USFf> zQ)d>W#6KI@oqj8|ZJ}6OerGs)$anuOx4unH6~c^Dca({~Ebkk)gD{`C#0~O6*@Tz( zV)_*+v4=80iV_VbcL!w16!zj*rz@xKU{PL06Zw?#uBI1T^@q2I)UxTn=R5a|&{%)X zu)~PG=EY~bik3Adjlh!Y0ov+cjkPlM831!y^HP7r;QNkD%<;G-j)md@HNkWEmBXrlHxU=oVx5f*#(hmb5OS zDsvE63(?+pGF+_Q;cQJbWGSABMWpe6Y0cjwwP=JZvbKhd3yI(ey!*SD*9_b2$9 zM2EDnsI}~%qMku1l~jVTE*@SsLgVY<7{?0nj8{MGo5S2;RLCRq2z^yAKByfWeJK!o zChwEUHkaTo-q*ZrokEr=C-0d`$kO$iDSE+UKhs6SNUcB%JnoxAa)cjRt=(+Sz3%Y} zo1p^l$%=+6bbQdmmF`E+XDdiBj#RmO7EEr_TdI60tvq*W|5RPyz&7_DqI4CQ>P?#} zK?1ggtn|INSF#mIM~&^|1n|^0-PhL<)S9m=_M? zj=|Pfc)Fr!og>s4Kni|VFoLIB9BL;p-772OZ2hQgyO`E4;H`5v?7$UVYLbB!96S$9 z6HBxuO)*hUsZ|s*Kf|c9ggv)s)() zH+D;3zj9U^8^aw4xA}3Q$DCIq^Y#C7D&Se}a4qgojHWuGR-F=>!ta&P83CF$a4Cat z)0BC3v3fA)$-GEw`s0zvGC@g@ihu?g#F;CCF8k^FDEcd=HNZShloXg0LC@p>hA7Z< z#Rq@_8<}9I-w#Hh>^$~j9d(r8KRN(@LQD#=J7m0JpTY#xSSca{YZ8@zYOj3vDkjvj z+dL+brjFL@Cx~bi`6B@AG)Cx3KpzAGx+2R-tqI^41AlSQ=UnW))+}Y46p{I$myx_+|SdY)$LjthE7D?%jw&8y?fW_p&*9!`(hL+Ye|bK!84^s?`jQZi{@VXhxh8v>2V6F=WL=l+t> zJu&`ceqOu}Go>;!&Uc~kxJl~3+}W3GUEW`HE}QhWSUT{yMW{`v6SsZswxRP)jK_I= zhG6JHUit>1$};ot{?|q5?%W)I3Lw+xdxrDjOQ@7wHnKIYVq;$uYO-{oA})0|ZOV@C zdoVXiIj|%~D6&GaX}=aY^zlk?C*qerR9&;IB51=fR7cc6`lmHN)3(~f6*{8@`}@_1{;i*QPQ zyHjVNec=`GxQThO(@}p{bWM^_p7&n(*H9gd34mN70Q8;)Wm@1nx!-a z;n~gWGFKhJRkv9?A^?U9P*nh~{ncRi4N1_GE)6Ioni$aJ-RK-z*lFF9Y6?akd*1my z(!XneCw~3kGAfRS8cgY-&KV6bw1qVHW~gIhuY0<@V*(0)juGdKpbOHXia`04`%CC1 zMR58WlYqF0+?sW4rC^+DmA!CpKg2R#E(}P-?*C?Lj$m+P6bm(kh-ZvXb|iRH2@a$- z%wjrS`i-mPM0{EtC*fRVt++8v!@~)=F&Uu_A#ziD#tPywzYgg;BLF&G4rR=%>?r`( zQC`Tn+Qr4?M8Eid+wk^4BHWO2_LBamQy;lZbc)Yc{_V#DzzoEHfdI=a0D%8;{N!*+ W(|ar%1~vi^4?S(e+clc@PyPove1psY literal 0 HcmV?d00001 diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/dsf_concurrency_model.html b/plugins/org.eclipse.dd.doc.dsf/docs/dsf_concurrency_model.html new file mode 100644 index 00000000000..9ef49c39f64 --- /dev/null +++ b/plugins/org.eclipse.dd.doc.dsf/docs/dsf_concurrency_model.html @@ -0,0 +1,432 @@ + + + + + DSF Concurrency Model + + +

    DSF Concurrency Model

    +

    +

    +

    Version +1.0
    +Pawel Piech
    +© 2006, Wind River Systems.  Release +under EPL version 1.0.

    +

    Introduction

    +Providing a solution to concurrency problems is the primary design goal +of DSF.  To that end DSF imposes a rather draconian +restriction on services that use it: 1) +All service interface methods must be called using a single designated +dispatch thread, unless explicitly stated otherwise, 2) The dispatch +thread should never be used to make a blocking call (a call that waits +on I/O or a call that makes a long-running computation).  What +the first restriction effectively means, is that the dispatch thread +becomes a global "lock" that all DSF services in a given session +share with each other, and which controls access to most of services' +shared data.  It's important to note that multi-threading is still allowed +within individual service implementation. but when crossing the service +interface boundaries, only the dispatch thread can be used.  The +second restriction just ensures that the performance of the whole +system is not killed by one service that needs to read a huge file over +the network.  Another way of looking at it is that the +service implementations practice co-operative multi-threading using the +single dispatch thread.
    +
    +There are a couple of obvious side effects that result from this rule:
    +
      +
    1. When executing within the dispatch thread, the state of the +services is guaranteed not to change.  This means that +thread-defensive programming techniques, such as making duplicates of +lists before iterating over them, are not necessary.  Also it's +possible to implement much more complicated logic which polls the state +of many objects, without the worry about dead-locks.
    2. +
    3. Whenever a blocking operation needs to be performed, it must be +done using an asynchronous method.  By the time the operation is +completed, and the caller regains the dispatch thread, this caller may +need to retest the relevant state of the system, because it could +change completely while the asynchronous operation was executing.
    4. +
    +

    The Mechanics

    +

    java.util.concurrent.ExecutorService
    +

    +DSF builds on the vast array of tools added in Java 5.0's +java.util.concurrent package (see http://java.sun.com/j2se/1.5.0/docs/guide/concurrency/index.html +for details), where the most important is the ExecutorService +interface.  ExecutorService +is a formal interface for submitting Runnable objects that will be +executed according to executor's rules, which could be to execute the +Runnable immediately, +within a thread pool, using a display thread, +etc.  For DSF, the main rule for executors is that they have +to use a single thread to execute the runnable and that the runnables +be executed in the order that they were submitted.  To give the +DSF clients and services a method for checking whether they are +being called on the dispatch thread, we extended the ExecutorService +interface as such:
    +
    public interface DsfExecutor extends ScheduledExecutorService
    {
    /**
    * Checks if the thread that this method is called in is the same as the
    * executor's dispatch thread.
    * @return true if in DSF executor's dispatch thread
    */
    public boolean isInExecutorThread();
    }
    +

    java.lang.concurrent.Future +vs org.eclipse.dd.dsf.concurrent.Done

    +The Done object +encapsulates the return value of an asynchronous call in DSF.  It +is actually merely a Runnable with +an attached org.eclipse.core.runtime.IStatus +object , but it can be extended by the services or clients to hold +whatever additional data is needed.   Typical pattern in how +the Done object is used, +is as follows:
    +
    Service:
    public class Service {
    void asyncMethod(Done done) {
    new Job() {
    public void run() {
    // perform calculation
    ...
    done.setStatus(new Status(IStatus.ERROR, ...));
    fExecutor.execute(done);
    }
    }.schedule();
    }
    }

    Client:
    ...
    Service service = new Service();
    final String clientData = "xyz";
    ...
    service.asynMethod(new Done() {
    public void run() {
    if (getStatus().isOK()) {
    // Handle return data
    ...
    } else {
    // Handle error
    ...
    }
    }
    }
    +The service performs the asynchronous operation a background thread, +but +it can still submit the Done runnable +with the executor.  In other words, the Done and other runnables can be +submitted from any thread, but will always execute in the single +dispatch thread.  Also if the implementation of the asyncMethod() is non-blocking, +it does not need to start a job, it could just perform the operation in +the dispatch thread.  On the client side, care has to be taken to +save appropriate state before the asynchronous method is called, +because by the time the Done is +executed, the client state may change.
    +
    +The java.lang.concurrent +package +doesn't already have a Done, +because the generic concurrent +package is geared more towards large thread pools, where clients submit +tasks to be run in a style similar to Eclipse's Jobs, rather than using +the single dispatch thread model of DSF.  To this end, the +concurrent package does have an equivalent object, Future.  +Future has methods that +allows the client to call the get() +method, and block while waiting for a result, and for this reason it +cannot +be used from the dispatch thread.  But it can be used, in a +limited way, by clients which are running on background thread that +still +need to retrieve data from synchronous +DSF methods.  In this case the code might look like the +following:
    +
    Service:
    public class Service {
    int syncMethod() {
    // perform calculation
    ...
    return result;
    }
    }

    Client:
    ...
    DsfExecutor executor = new DsfExecutor();
    final Service service = new Service(executor);
    Future<Integer> future = executor.submit(new Callable<Integer>() {
    Integer call() {
    return service.syncMethod();
    }
    });
    int result = future.get();
    +The biggest drawback to using Future +with DSF services, is that it does not work with +asynchronous methods.  This is because the Callable.call() +implementation +has to return a value within a single dispatch cycle.  To get +around this, DSF has an additional object called DsfQuery, which works like a Future combined with a Callable, but allows the +implementation to make multiple dispatches before setting the return +value to the client.  The DsfQuery object works as follows:
    +
    +
      +
    1. Client creates the query object with its own implementation of DsfQuery.execute().
      +
    2. +
    3. Client calls the DsfQuery.get() +method on non-dispatch thread, and blocks.
    4. +
    5. The query is queued with the executor, and eventually the DsfQuery.execute() method is +called on the dispatch thread.
    6. +
    7. The query DsfQuery.execute() +calls synchronous and asynchronous methods that are needed to do its +job.
    8. +
    9. The query code calls DsfQuery.done() +method with the result.
    10. +
    11. The DsfQuery.get() +method un-blocks and returns the result to the client.
      +
    12. +
    +

    Slow +Data Provider Example

    +The point of DSF concurrency can be most easily explained through +a practical example.  Suppose there is a viewer which needs to +show data that originates from a remote "provider".  There is a +considerable delay in transmitting the data to and from the provider, +and some delay in processing the data.  The viewer is a +lazy-loading table, which means that it request information only about +items that are visible on the screen, and as the table is scrolled, new +requests for data are generated.  The diagram below illustrates +the +logical relationship between components:
    +
    +.
    +

    In detail, these components look like this:

    +

    +Table Viewer
    +

    The table viewer is the standard +org.eclipse.jface.viewers.TableViewer, +created with SWT.VIRTUAL +flag.  It has an associated content +provider, SlowDataProviderContentProvider) which handles all the +interactions with the data provider.  The lazy content provider +operates in a very simple cycle:

    +
      +
    1. Table viewer tells content provider that the input has changed by +calling IContentProvider.inputChanged().  +This means that the content provider has to query initial state of the +data.
    2. +
    3. Next the content provider tells the viewer how many elements +there are, by calling TableViewer.setItemCount().
    4. +
    5. At this point, the table resizes, and it requests data values for +items that are visible.  So for each visible item it calls: ILazyContentProvider.updateElement().
    6. +
    7. After calculating the value, the content provider tells the table +what the value is, by calling TableViewer.replace().
    8. +
    9. If the data ever changes, the content provider tells the table to +rerequest the data, by calling TableViewer.clear().
    10. +
    +Table viewer operates in the +SWT display thread, which means that the content provider must switch +from the display thread to the DSF dispatch thread, whenever it is +called by the table viewer, as in the example below:
    +
        public void updateElement(final int index) {
    assert fTableViewer != null;
    if (fDataProvider == null) return;

    fDataProvider.getExecutor().execute(
    new Runnable() { public void run() {
    // Must check again, in case disposed while redispatching.
    if (fDataProvider == null) return;

    queryItemData(index);
    }});
    }
    +Likewise, when the content provider calls the table viewer, it also has +to switch back into the display thread as in following example, when +the content provider receives an event from the data provider, that an +item value has changed.
    +
        public void dataChanged(final Set<Integer> indexes) {
    // Check for dispose.
    if (fDataProvider == null) return;

    // Clear changed items in table viewer.
    if (fTableViewer != null) {
    final TableViewer tableViewer = fTableViewer;
    tableViewer.getTable().getDisplay().asyncExec(
    new Runnable() { public void run() {
    // Check again if table wasn't disposed when
    // switching to the display thread.
    if (tableViewer.getTable().isDisposed()) return; // disposed
    for (Integer index : indexes) {
    tableViewer.clear(index);
    }
    }});
    }
    }
    +All of this switching back and forth between threads makes the code +look a lot more complicated than it really is, and it takes some +getting used to, but this is the price to be paid for multi-threading. +Whether the participants use semaphores or the dispatch thread, the +logic is equally complicated, and we believe that using a single +dispatch thread, makes the synchronization very explicit and thus less +error-prone.
    +

    Data Provider Service

    +

    The data provider service interface, DataProvider, is very similar +to that of the lazy content provider.  It has methods to:

    +
      +
    • get item count
    • +
    • get a value for given item
    • +
    • register as listener for changes in data count and data values
    • +
    +But this is a DSF interface, and all methods must be called on the +service's dispatch thread.  For this reason, the DataProvider interface returns +an instance of DsfExecutor, +which must be used with the interface.
    +

    Slow Data Provider

    +

    The data provider is actually implemented as a thread which is an +inner class of SlowDataProvider +service.  The provider thread +communicates with the service by reading Request objects from a shared +queue, and by posting Runnable objects directly to the DsfExecutor but +with a simulated transmission delay.  Separately, an additional +flag is also used to control the shutdown of the provider thread.

    +To simulate a real back end, the data provider randomly invalidates a +set of items and notifies the listeners to update themselves.  It +also periodically invalidates the whole table and forces the clients to +requery all items.
    +

    Data and Control Flow
    +

    +This can be described in following steps:
    +
      +
    1. The table viewer requests data for an item at a given index (SlowDataProviderContentProvider.updateElement).
      +
    2. +
    3. The table viewer's content provider executes a Runnable in the DSF +dispatch thread and calls the data provider interface (SlowDataProviderContentProvider.queryItemData).
    4. +
    5. Data provider service creates a Request object, and files it in a +queue (SlowDataProvider.getItem).
    6. +
    7. Data provider thread de-queues the Request object and acts on it, +calculating the value (ProviderThread.processItemRequest).
    8. +
    9. Data provider thread schedules the calculation result to be +posted with DSF executor (SlowDataProvider.java:185).
    10. +
    11. The Done callback sets the result data in the table viewer (SlowDataProviderContentProvider.java:167).
      +
    12. +
    +

    Running the example and full sources

    +This example is implemented in the org.eclipse.dd.dsf.examples +plugin, in the org.eclipse.dd.dsf.examples.concurrent +package. 
    +
    +To run the example:
    +
      +
    1. Build the test plugin (along with the org.eclipse.dsdp.DSF plugin) +and launch the PDE. 
      +
    2. +
    3. Make sure to add the DSF +Tests action set to your current perspective.
    4. +
    5. From the main menu, select DSF +Tests -> Slow Data Provider.
    6. +
    7. A dialog will open and after a delay it will populate with data.
    8. +
    9. Scroll and resize dialog and observe the update behavior.
    10. +
    +

    Initial Notes
    +

    +This example is supposed to be representative of a typical embedded +debugger design problem.  Embedded debuggers are often slow in +retrieving and processing data, and can sometimes be accessed through a +relatively slow data channel, such as serial port or JTAG +connection.  But as such, this basic example presents a couple +of major usability problems
    +
      +
    1. The data provider service interface mirrors the table's content +provider interface, in that it has a method to retrieve a single piece +of data at a time.  The result of this is visible to the user as +lines of data are filled in one-by-one in the table.  However, +most debugger back ends are in fact capable of retrieving data in +batches and are much more efficient at it than retrieving data items +one-by-one.
    2. +
    3. When scrolling quickly through the table, the requests are +generated by the table viewer for items which are quickly scrolled out +of view, but the service still queues them up and calculates them in +the order they were received.  As a result, it takes a very long +time for the table to be populated with data at the location where the +user is looking. 
      +
    4. +
    +These two problems are very common in creating UI for embedded +debugging, and there are common patterns which can be used to solve +these problems in DSF services.
    +

    Coalescing

    +Coalescing many single-item requests into fewer multi-item requests is +the surest way to improve performance in communication with a remote +debugger, although it's not necessarily the simplest.  There are +two basic patterns in which coalescing is achieved:
    +
      +
    1. The back end provides an interface for retrieving data in large +chunks.  So when the service implementation receives a request for +a single item, it retrieves a whole chunk of data, returns the single +item, and stores the rest of the data in a local cache.
    2. +
    3. The back end providers an interface for retrieving data in +variable size chunks.  When the service implementation receives a +request for a single item, it buffers the request, and waits for other +requests to come in.  After a delay, the service clears the buffer +and submits a request for the combined items to the data provider.
    4. +
    +In practice, a combination of the two patterns is needed, but for +purpose of an example, we implemented the second pattern in the +"Input-Coalescing Slow Data Provider" (InputCoalescingSlowDataProvider.java).  +
    +

    Input Buffer

    +

    The main feature of this pattern is a buffer for holding the +requests before sending them to the data provider.  In this +example the user requests are buffered in two arrays: fGetItemIndexesBuffer and fGetItemDonesBuffer.  The +DataProvider.getItem() +implementation is changed as follows:

    +
        public void getItem(final int index, final GetDataDone<String> done) {
    // Schedule a buffer-servicing call, if one is needed.
    if (fGetItemIndexesBuffer.isEmpty()) {
    fExecutor.schedule(
    new Runnable() { public void run() {
    fileBufferedRequests();
    }},
    COALESCING_DELAY_TIME,
    TimeUnit.MILLISECONDS);
    }

    // Add the call data to the buffer.
    // Note: it doesn't matter that the items were added to the buffer
    // after the buffer-servicing request was scheduled. This is because
    // the buffers are guaranteed not to be modified until this dispatch
    // cycle is over.
    fGetItemIndexesBuffer.add(index);
    fGetItemDonesBuffer.add(done);
    }

    +And method that services the buffer looks like this:
    +
        public void fileBufferedRequests() { 
    // Remove a number of getItem() calls from the buffer, and combine them
    // into a request.
    int numToCoalesce = Math.min(fGetItemIndexesBuffer.size(), COALESCING_COUNT_LIMIT);
    final ItemRequest request = new ItemRequest(new Integer[numToCoalesce], new GetDataDone[numToCoalesce]);
    for (int i = 0; i < numToCoalesce; i++) {
    request.fIndexes[i] = fGetItemIndexesBuffer.remove(0);
    request.fDones[i] = fGetItemDonesBuffer.remove(0);
    }

    // Queue the coalesced request, with the appropriate transmission delay.
    fQueue.add(request);

    // If there are still calls left in the buffer, execute another
    // buffer-servicing call, but without any delay.
    if (!fGetItemIndexesBuffer.isEmpty()) {
    fExecutor.execute(new Runnable() { public void run() {
    fileBufferedRequests();
    }});
    }
    }
    +The most interesting feature of this implementation is the fact that +there are no semaphores anywhere to control access to the input +buffers.  Even though the buffers are serviced with a delay and +multiple clients can call the getItem() +method, the use of a single +dispatch thread prevents any race conditions that could corrupt the +buffer data.  In real-world implementations, the buffers and +caches that need to be used are far more sophisticated with much more +complicated logic, and this is where managing access to them using the +dispatch thread is ever more important.
    +

    Cancellability

    +

    Table Viewer

    +

    +Unlike coalescing, which can be implemented entirely within the +service, cancellability requires that the client be modified as well +to take advantage of this capability.  For the table viewer +content provider, this means that additional features have to be +added.  In CancellingSlowDataProviderContentProvider.java +ILazyContentProvider.updateElement() +was changes as follows:
    +
        public void updateElement(final int index) {
    assert fTableViewer != null;
    if (fDataProvider == null) return;

    // Calculate the visible index range.
    final int topIdx = fTableViewer.getTable().getTopIndex();
    final int botIdx = topIdx + getVisibleItemCount(topIdx);

    fCancelCallsPending.incrementAndGet();
    fDataProvider.getExecutor().execute(
    new Runnable() { public void run() {
    // Must check again, in case disposed while redispatching.
    if (fDataProvider == null || fTableViewer.getTable().isDisposed()) return;
    if (index >= topIdx && index <= botIdx) {
    queryItemData(index);
    }
    cancelStaleRequests(topIdx, botIdx);
    }});
    }
    +Now the client keeps track of the requests it made to the service in fItemDataDones, and above, cancelStaleRequests() iterates +through all the outstanding requests and cancels the ones that are no +longer in the visible range.
    +

    Data Provider Service

    +

    +

    The data provider implementation +(CancellableInputCoalescingSlowDataProvider.java), +builds on top of the +coalescing data provider.  To make the canceling feature useful, +the data provider service has to limit the size of the request +queue.  This is because in this example which simulates +communication with a target and once requests are filed into the +request +queue, they cannot be canceled, just like a client can't cancel +request once it sends them over a socket.  So instead, if a flood +of getItem() +calls comes in, the service has to hold most of them in the coalescing +buffer in case the client decides to cancel them.  Therefore the +fileBufferedRequests() +method includes a simple check before servicing +the buffer, and if the request queue is full, the buffer servicing call +is delayed.

    +
            if (fQueue.size() >= REQUEST_QUEUE_SIZE_LIMIT) {
    if (fGetItemIndexesBuffer.isEmpty()) {
    fExecutor.schedule(
    new Runnable() { public void run() {
    fileBufferedRequests();
    }},
    REQUEST_BUFFER_FULL_RETRY_DELAY,
    TimeUnit.MILLISECONDS);
    }
    return;
    }
    +Beyond this change, the only other significant change is that before +the requests are queued, they are checked for cancellation.
    +

    Final Notes
    +

    +The example given here is fairly simplistic, and chances are that the +same example could be implemented using semaphores and free threading +with perhaps fewer lines of code.  But what we have found is that +as the problem gets bigger, the amount of +features in the data provider increases, the state of the +communication protocol gets more complicated, and the number of modules +needed in the service layer increases, using free threading and +semaphores does not safely scale.  Using a dispatch thread for +synchronization certainly doesn't make the inherent problems of the +system less complicated, but it does help eliminate the race conditions +and deadlocks from the overall system.
    +

    Coalescing and Cancellability are both optimizations.  Neither +of these optimizations affected the original interface of the service, +and one of them only needed a service-side modification.  But as +with all optimizations, it is often better to first make sure that the +whole system is working correctly and then add optimizations where they +can make the biggest difference in user experience. 

    +

    The above examples of optimizations can take many forms, and as +mentioned with coalescing, caching data that is retrieved from the data +provider is the most common form of data coalescing.  For +cancellation, many services in DSF build on top of other services, +which means that even a low-level service can cause a higher +level service to retrieve data, while another event might cause it to +cancel those requests.  The perfect example of this is a Variables +service, which is responsible for calculating the value of expressions +shown in the Variables view.  The Variables service reacts to the +Run Control service, which issues a suspended event and then requests a +set of variables to be evaluated by the debugger back end.  But as +soon as a resumed event is issued by Run Control, the Variables service +needs to cancel  the pending evaluation requests.
    +

    +
    +
    + + diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/dsf_data_model.html b/plugins/org.eclipse.dd.doc.dsf/docs/dsf_data_model.html new file mode 100644 index 00000000000..bd1b40112e6 --- /dev/null +++ b/plugins/org.eclipse.dd.doc.dsf/docs/dsf_data_model.html @@ -0,0 +1,286 @@ + + + + + DSF Data Model + + +

    DSF Data Model

    +Version +1.0
    +Pawel Piech
    +© 2006, Wind River Systems.  Release +under EPL version 1.0.
    +

    Overview

    +

    The data model aspect of DSF is only partially complete as compared +to the Concurrency and Services Models.  The goals for its design +are:
    +

    +
      +
    1. Separate the structure of the +data in the services from the model used for presentation in views.  +This seems like a basic model-viewer separation, which is something +that we theoretically have already.  But in reality the current +platform debug model APIs closely correspond to how the data is +laid out in debug views, and even with the flexible hierarchy views it +is +difficult to provide alternative layouts.
    2. +
    3. Allow for a modular +implementation of services that contribute to the data model.   +
      +
    4. +
    5. Perform well with large +data sets.
    6. +
    7. Make the data model interfaces +convenient to use by other services as well as by views.  +Some interim designs of DSF data model APIs were very well suited for +populating views (though asynchronous) content and label provider, but +were very difficult to use for other purposes, such as by another +service, or a client that creates a dialog.  This led to services +implementing two sets of interfaces for the same data, which was more +expensive to develop and maintain.
      +
    8. +
    9. Allow for easy changes to the +layout of data in views.  This is from the point of view of +a debugger implementer that would like to modify the standard layout of +debugger data.
      +
    10. +
    11. Allow the users to modify the +layout of data in views.  And this is a logical extension +of the previous goal.
    12. +
    +

    +That's a pretty ambitious set of goals to keep in mind, which partly +explains why the design is not fully complete yet.  In particular, +the last goal doesn't have any implementation at this point.  But +other than that the, we believe that our current design mostly +meets the other goals.  It remains to be seen how well it will +hold up +beyond a prototype implementation.
    +

    The DSF data model is divided into two parts: a non-UI part that +helps services expose data in a consistent form, and a UI part that +helps viewers present the data.  They are described separately in +the two sections below.
    +

    +

    Timers Example

    +

    A "timers +example" is included with the DSF plugins which +demonstrates the use of data model and view model +APIs.   It is probably much easier to digest this document +when referring to this example for usage.
    +

    +

    Data Model API (org.eclipse.dd.dsf.model)
    +

    +As stated before, the aim of this API is to allow services to provide +data with just enough common information, so that it can be easily +presented in the view, but with a simple enough design, so that the +data can be accessed by non-viewer clients.  The type of data in +services can vary greatly from service to service, some data for +example:
    +
      +
    • service data might be extremely large and thus may only be +retrieved from a back end process in small chunks, while some service +data might be always stored locally in the service
      +
    • +
    • data might take a very long time to retrieve, or it could be +instantaneous
      +
    • +
    • some services might support canceling of the request while it is +being processed, while other services might not
      +
    • +
    • some data may change very frequently, other data may not change +at all
      +
    • +
    +The data model API tries to find a common denominator for these +divergent properties and imposes the following restrictions:
    +
      +
    1. Each "chunk" of data that comes from a service has a +corresponding IDataModelContext (Data Model Context) +object.
      +
    2. +
    3. The DM-Context objects are to be generated by the data model services (IDataModelService) with either +synchronous or asynchronous methods, and taking whatever arguments are +needed.  Put differently, how DM-Contexts are created is up to the +service.
    4. +
    5. The service will provide a method for retrieving each "chunk" of +model data (IDataModelData) +using a method that requires no other arguments besides the DM-Contexts.
    6. +
    +

    DM-Context (IMContext)
    +

    +The DM-Contexts are the most +important part of this design, so they warrant a closer look.  The +interface is listed below:
    +
        public interface IDataModelContext<V extends IDataModelData> extends IAdaptable {
    public String getSessionId();
    public String getServiceFilter();
    public IDataModelContext[] getParents();
    }
    +First of all the object extends IAdaptable, +which allows clients to use these objects as handles that are stored +with UI components.  However the implementation of IDataModelData.getAdapter()  +presents a particular challenge.  If the standard platform method +of retrieving an adapter is used (PlatformObject.getAdapter()), +then there can only be one adapter registered for a given DM-Context class, +which has to be shared by all the DSF sessions that are running +concurrently.  Thus one debugger that implements a IStack.IFrameDMContext, would have to +have the same instance of +IAsynchronousLabelAdapter as another debugger implementation +that is running at the same time.  To overcome this problem, DSF +provides a method for registering adapters with a session using DsfSession.registerModelAdapter(), +instead of with the platform (Platform.getAdapterManager().registerAdapters()).  +
    +

    The getSessionId() +method serves two purposes.  First, it allows the +IAdapter.getAdapter() +implementation to work as described above. Second, it allows clients to +access the correct dispatch thread (DsfSession.getSession(id).getExecutor()) +for calling the service that the DM-Context originated from. 
    +

    +

    The getServiceFilter() +method is actually included to allow future development.  It is +intended to allow the client to precisely identify the service that +the DM-Context originated from, without having to examine the exact class type +of the DM-Context.  But this functionality will not really be needed +until we start writing generic/data-driven clients.
    +

    +

    The getParents() +method allows the DM-Context to be connected together into something that can +be considered a "model".  Of course, most debugger data objects, +require the context of other objects in order to make sense: stack +frame is meaningless without the thread, debug symbols belong to a +module, which belongs to a process, etc.  In other words, there is +some natural hierarchy to the data in debug services which needs to be +accessible through the data model APIs.  This hierarchy may be the +same hierarchy that is to be shown in some debug views, but it doesn't +have to be.  More importantly, this hierarchy should allow for a +clean separation of debug services, and for a clear dependency graph +between these services.

    +

    View Model API (org.eclipse.dd.dsf.ui.model)
    +

    +This is the component which allows the DSF data model to be presented +in +the views with different/configurable layouts.  It is tightly +integrated with the recently added (and still provisional) +flexible-hierarchy viewers in the org.eclipse.debug.ui +plugin (see EclipseCon 2006 presentation +for more details).  Actually, the platform flexible hierarchy +framework already provides all the adapter interfaces needed to present +the DSF data model in the viewers, and it is possible to do +that.  However the flexible hierarchy views were not specifically +designed for DSF, and there are a few ugly patterns that emerge when +using them with DSF data model interfaces directly:
    +
      +
    • Because of the nature of IAdaptable pattern, the flexible +hierarchy label and content adapters have to have a single instance +that works for all views that the objects appear in.  This leads +to a lot of if-else statements, which make the implementation difficult +to follow.
      +
    • +
    • There is a single adapter for all DSF data model elements in the +tree (from the same session), so the adapters have even more if-else +statements to handle the different elements in the viewer.
    • +
    • Most of DSF adapter work needs to be performed in the dispatch +thread, so each handler starts with a re-dispatch call.
    • +
    • In all of this, the logic which determines the hierarchy of +elements in the viewer is very hard to follow.
    • +
    +The view model API tries to address these issues in the following way:
    +
      +
    1. It divides the adapter work for different views in separate ViewModelProvider objects.
    2. +
    3. It defines the view layout in an object-oriented manner using the + IViewModelLayoutNode +objects.
    4. +
    5. It consolidates the logic of switching to dispatch thread in one +place, and allows the ViewModelProvider +objects to work only in dispatch thread.
      +
    6. +
    +

    IViewModelLayoutNode

    +The core of the logic in this design lies in the implementation of the IViewModelLayoutNode objects. +This interface is listed below:
    +
    public interface IViewModelLayoutNode {
    public IViewModelLayoutNode[] getChildNodes();
    public void hasElements(IViewModelContext parentVmc, GetDataDone<Boolean> done);
    public void getElements(final IViewModelContext parentVmc, GetDataDone<IViewModelContext[]> done);
    public void retrieveLabel(IViewModelContext vmc, final ILabelRequestMonitor result);
    public boolean hasDeltaFlags(IDataModelEvent e);
    public void buildDelta(IDataModelEvent e, ViewModelDelta parent, Done done);
    public void sessionDispose();
    }
    +The getChildNodes() +method allows these layout nodes to be combined into a tree structure, +which mimics the layout of elements in the view.  What the +children are depends on the implementation, some may be configurable +and +some may be fixed.
    +
    +The hasElements() +and getElements() +methods generate the actual elements that will appear in the +view.  The methods are analogous to the flexible hierarchy API +methods: IAsynchronousContentAdapter.isContainer() +and IAsynchronousContentAdapter.retrieveChildren() +and are pretty straightforward to implement. Also retrieveLabel() +is directly analogous to +IAsynchronousLabelAdapter.retrieveLabel(). 
    +
    +The hasDeltaFlags() +and buildDelta() +are used to generate model deltas in response to service events. These +are discussed in the next section.
    +
    +Finally, in most cases the elements in the views correspond +directly to an IDataModelContext +(DM-Context) objects of a specific type.  In those cases, the DMContextVMLayoutNode +abstract class implements the common functionality in that pattern.
    +

    Model deltas

    +The hasDeltaFlags() and buildDelta() methods are used +to implement the IModelProxy adapter, +and are the most tricky aspect of this design.  The difficulty is +that the flexible hierarchy views require that the IModelProxy translate data +model-specific events, into generic model deltas that can be +interpreted by the viewer.  The deltas (IModelDelta) are tree +structures which are supposed to mirror the structure of nodes in the +tree, and which contain flags that tell the viewer what has changed in +the view and how.*  This means that if the +model proxy receives an event for some IDataModelContext (DM-Context) object, +it needs to know if this object is in the viewer's tree, and what is +the full path (or paths) that leads to this object. 
    +

    The model delta is generated by first calling the top layout node's hasDeltaFlags() with the +received event, which then can either return true or ask any of its +children if they have deltas (which in turn returns true or calls its +children, etc).  If a node returns true for hasDeltaFlags(), then the +asynchronous buildDelta() +is called with the event and a parent delta node, to generate the delta +elements and flags for its node.  Once the layout node generates +its delta objects, it still needs to call its children, which in turn +add their delta information, and so on.
    +

    +

    * It's not strictly true that a full path to +an element always has to be present for model delta's to work.  If +the full path is not present, the viewer will try to find the element +using an internal map that it keeps of all of the elements it +knows.  +But since the viewer is lazy loading, it is possible (and likely) that +the element affected by an event is not even known to the viewer at +time of the event, and for some delta actions, IModelDelta.SELECT and IModelDelta.EXPAND, this is not +acceptable.
    +

    + + diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/dsf_mi_instructions.html b/plugins/org.eclipse.dd.doc.dsf/docs/dsf_mi_instructions.html new file mode 100644 index 00000000000..7d6e2b51153 --- /dev/null +++ b/plugins/org.eclipse.dd.doc.dsf/docs/dsf_mi_instructions.html @@ -0,0 +1,135 @@ + + + + + GDB/MI Debugger on top of DSF - Instructions + + +

    GDB/MI Debugger implementation based on DSF

    +
    +
    +

    Buiding and Running Instructions
    +

    +

    To build:

    +
      +
    1. Install the latest milestone of Eclipse 3.3 SDK
    2. +
    3. Install the latest milestone of CDT 4.0
    4. +
    5. Install and configure gdb (cygwin on windows)
    6. +
    7. Check out following projects from + /cvsroot/dsdp/org.eclipse.dd.dsf/plugins +
    8. +
        +
      • org.eclipse.dd.dsf
      • +
      • org.eclipse.dd.dsf.ui
      • +
      • org.eclipse.dd.dsf.debug
      • +
      • org.eclipse.dd.dsf.debug.ui
      • +
      • org.eclipse.dd.dsf.mi.core
      • +
      • org.eclipse.dd.dsf.mi.ui.
      • +
      +
    +

    To run:

    +
      +
    1. Create a new "Managed make build project" called "hello".
    2. +
    3. Create a simple hello.c source file:
    4. +
    +
    +
    #include <stdio.h>
    int main(void) {
    printf("Hello world");
    }
    +
    +
      +
    1. Build the project.
      +
    2. +
    3. Create a new "DSF C/C++ Local Application"  launch +configuration (one with the pink icon) and set the executable and entry +point to "main"
      +
    4. +
    5. Launch and step through.
    6. +
    7. If the "source not found" page appears, the a path mapping needs +to be created.  This is an issue with latest cygwin gdb.
      +
    8. +
        +
      1. Click on the "Edit source lookup" button in the editor, or +right click on the launch node in Debug View and select "Edit source +lookup"
      2. +
      3. Click on the "Add..." button
      4. +
      5. Select "Path Mapping" and click OK.
        +
      6. +
      7. Select the new "Path Mapping" source container and click the +"Edit..." button.
      8. +
      9. Once again, click the "Add..." button to create a mapping.
      10. +
      11. Enter the path to map from.  Look at the stack frame label +in Debug view, if the filename is something like +"/cygdrive/c/workspace/hello/hello.c", enter the path to the first real +directory "/cygdrive/c/workspace".
      12. +
      13. Enter the correct path to the directory entered above, in the +file system.  In example above, it would be "C:\workspace".
      14. +
      15. Click OK three times and you'll be back in Kansas.... ehm Debug +view that is.
      16. +
      17. If the source doesn't show up right away, try stepping once.
      18. +
      +
    +
    +

    Supported Platforms
    +

    +Currently only Windows with cygwin GDB is supported. +
    +
    +
    +

    Current Features
    +

    +
      +
    • Launching
    • +
        +
      • The "DSF C/C++Local Application" is the standard CDT launch +configuration minus some of the features. 
        +
      • +
      • What is NOT working here is
        +
      • +
          +
        • Debugger tab: the selection of debugger back ends (gdb/mi, +Cygwin gdb debugger, etc.), tThe implementation is currently hard-wired +for Cygwin,
        • +
        • Debugger tab: Debugger Options section
        • +
        +
      +
    • Debug view
    • +
        +
      • Single thread debugging only.
      • +
      • Terminating
        +
      • +
      • Stepping
        +
      • +
      • Resume/Suspend
        +
      • +
      +
    • Console support
      +
    • +
        +
      • GDB process output
      • +
      • NO user process console support
        +
      • +
      +
    • Breakpoints
    • +
        +
      • Basic CDT breakpoint support implemented
      • +
          +
        • no filtering support,
          +
        • +
        • no advanced options (hardware, temporary, etc)
        • +
        • no watchpoints
          +
        • +
        +
      +
    • Variables
    • +
        +
      • not yet
        +
      • +
      +
    +
    +
    Updated Aug 25th, 2006
    +
    + + diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/dsf_services_model-1.png b/plugins/org.eclipse.dd.doc.dsf/docs/dsf_services_model-1.png new file mode 100644 index 0000000000000000000000000000000000000000..b593371ee805527e885bd02a05399a15d30ac5a0 GIT binary patch literal 2224 zcma)8eK^x=A0O%{VqH#NuF211tK@hqHpkoYHb&M&N%Bq^c}rWgmA4!=!dgXC^7c?V zNwkPfIu#QSerpO7t7leQ4vyJjdC9ZhuIK8X=X(D5e!lnpxv%@Wzu)WnUZ2mMw;zwy zP=l#KAP@~NPmCV~q6{ixtFnrMss1_nu_7rE{jjde&X3c&6q}9vaR=QMd3=0)ZEcOV z14jQ$p70DLLLllte-0(c)$4i?$OdOGjLX5({OR#O@Iw17KZQrt`%V5my(dz;{ARe$ zeM^LNkMALbQx4~Mgp=q&h#C`QW+CUiGU)4Qq>Io+na@tUJT+yiGAyPt>!%+9$Ubxo zx}?>Sa2{}0(LjRVfw@68^Jfx#>?Aj1;L{D&ZwCU8`yX(joqdKK1!XPiP*JNnV*@Fv zy|Qhp5Ydk^ebrS{o}2}Xo@GDSqgRbw>>6Z3^S9_%a52w3)?FfQP==3L%S|^k zD2H2qLindPJ@i5q=Y{o*ww=y9^GuVK{H;Qr-*i6Sm2l;&m)17@x2hjjjp`k~YxUz# zc}FX3h?T8c1WJxrH_sANIm>oDMAIn);9O6-1GaG&dNbJ>fzI@pG*SQsQrL6pD&X*- zn3`?^K|gYgcJV0(Zfn!hFO~wG+o~(BV8i^oRD@LrWgPSJqKw)Sjvyc!ULZF@olH7A$|?_6B_Ik!idZoJ7hOMCRc zajdhx(5`OA;IQ#-QO#4JJT!+~XD64&@q>EBZsfnr`=XkAtUa34dTaa6?tlM*e;FW? zFFZy^ri&teEvjKZ;mQr>2Dqj;CZ=ME==FU8ko-Q***I`;yf71yB zOfjv_f>bgM2W5!06g>4fUuh9xaH-QG__HBy)j zS3BZLxv)K-=WWzaTH#oMHZ@UXIZekGz{eS?KZ_-dkP0Ksjil1>JS-W8CENC@ET#9> zglq|MoqVesgqipS?COZi?;I)FLRPPIFX5Zt!6{p2hxj7S@6us3c<4et3+A}TMOnJhw)~Lf;`vmBz9@mf4x9kbH4uxwTt;Qzh)|J5?Pi#zx}5yvul=y+qh#{@>aPz1vJR2Tu2 zNiQ?S6L2Vl+T%89B;8D=v1cnQa<2iM_Nx&WP~Pqnu4cz*Nz=GSg;%rw`5U#I z1(7nv8isbGu;X(Hkw{7jFs3e^K1@C()1NGa7 zwND;Pya*f>3}5^BiH8fSNWbvf+MytQ_6|C}xmv%>BMaZ&7@yZHN zRsLRuuUSnbBzUlBHm$A>t5;sE2Aw+lK+k`Zr+X9q-a;Cjx<}AZ0X1~^>S8BYW8Q6;Of-* zg-i~TCB9i{;-((8U3^o|&G>0xNIz{>-F`m&tBuTRj{Dc2X%VDO05#=@VzciETAm>b zqF00hj%AfP z_@VnAmyi18)Vt6k$AEg~ld~Hk$qu@CF@$Xc$Rc#+7Y8rN{_KxtDnB^-4Ol}j5LUBZ g;|H5xS{7y)nhbBn-kA^o{=cytjBXo<(sU`1*Z&!C~In}D#Xz%h1_Eh=N(NU#R`Mx~McrJL% z8<`9M=o-zL8ld>bG5|mm?c)Ip#_}YBXNlMSjGsu=OxEl(*>Mnb;J`CP^qM1sCP8{r znGMuBosPqg5t9qcuZRp5n*$$RSC)gEFt3KC$@&4tebmTTyNIw%O+7O(iu2QpG^9A} zS>mrC5^iZV5c=b~5h+2#417+jc)Nx_1(tV+6Ke)0X!=h9zCmv;zA}Td=;xt{f7`L7aM~3ftJ{P#Hg2^e7l(@P3`vd6YQJ}+KQjf#q7(C0 z@yzzi&l3}*wx!@Fm6-dr56xeK$f3gzgb{j@j|~M@I(#x$|EAC3kk(5B3*x`@BI&<5 z=f_SQ?G?BfP5BO$9FqSzwlS6=4euMX@F7idJU3`cf<9Q#D6qJ()3>baeD=6aI3wJ} zjec<jPkCso2Oh*iAF{p{fRBrPESNcBKwwm4#?Z^cPU{rGE#gnI*z1~7!dROHCjn7*c^ z36)sWs0BVNdco2{DR`m~4fGB|AekLFEl6No{RLT43=n7x=@ZWBIbPY#Z2ZpFumS+2(aQ z`bYUhC=VGY;|7$V$&GnXl(F1oq4XCj12b*x;S#A?U%jD|sCE|M3s&ZXtFp?VxrVZI1v$X!FS!(eIH3KrXoRQ3fa#UH2C<+LtiOO%e`9Id}5w1ZKb^omvKU-5(PD>H1kLN)o_(xRep z3fG$S(UU~BUh>AWt6jaT6^z=vEyFNJd9l=J)-sHdDVoxvTg+a|XsTN5hD%qyoTeaD zJgQ2Uo75C!FO#>ercC$k`IAqd)cK{$ zJP5tbYiVyQDR-&9ZO^CmraQeHy~rs}rp$L;u6bb`n$T80X4ys-(AP<#4upLYuOFK5 z-a>Y8F=b}gfR2j26uDUXGpy{O1A=wQT0cb`<-QzZeQsIbeH`r`Rn%q2meg5h>|K(! zflHk3m=9Lf0kdVvbR^gP1$>rl@4w*GYb5M{ny6}-@f#Y)(RcWxu55s#D(1h+49iL}0{dHIXiJYrM)Vp$7$k;>~} zAZMN2)bo}xt2EQ%Z#eg6rD zUtnN>=8yAgUC)N>+&KegmZsX%<3V&>A-dnmYs>gZr|%SZJWF4YY+hgcPCw~PD*6s< zvMhXJ9ws!TX7JMv*Ud90M8%PaX@>K0xH!sRB%FVGc;L0~>>)M+!3Yy-3$XO=*BhDo zF3gGd!MKYd76N*Y3uneYjM27EQd|p%f=Kf8zT@I3iGY)PNTSK9uNKd^+Sy~MgLw2q z?VRvIo8YqGJ5@PhC2J8hRvqDe>n%t+nqbd67uS`|a{5;HQwwC4&G8U9;2(l7v+JrU m7HB~|*r(6@=O9qB#n7yhy{R`8i3O^O1n}_;@Tk}xo$(jIq)#UR literal 0 HcmV?d00001 diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/dsf_services_model.html b/plugins/org.eclipse.dd.doc.dsf/docs/dsf_services_model.html new file mode 100644 index 00000000000..8380a0e4ae3 --- /dev/null +++ b/plugins/org.eclipse.dd.doc.dsf/docs/dsf_services_model.html @@ -0,0 +1,363 @@ + + + + + DSF Services Model + + +

    DSF Services Model

    +
    +Version +1.0
    +Pawel Piech
    +
    © 2006, +Wind River Systems.  Release under EPL +version 1.0.
    +
    +

    Debugger Services Framework (DSF) is primarily a service framework +defining rules for how +services should be registered, discovered, organized into functional +groups, communicated with, and started/ended.  These rules help to +organize the services into a functional system that efficiently +abstracts various debugger back end capabilities. 

    +

    DSF services build on top of the OSGI services framework, so +it's important to understand OSGI services before looking at DSF +itself.  For an overview of OSGI including services, see the presentation +on OSGI from EclipseCon 2006.  For detailed information, see +OSGI javadocs, primarily: org.osgi.frameworkServiceRegistration, +BundleContext, ServiceReference, Filter, and ServiceTracker. +

    +

    Services
    +

    +In OSGI any class can be registered as a service.  In DSF, +Services must implement the IDsfService  +interface, which requires that the service +provide:
    +
      +
    1. Access to the DsfExecutor that +has to be used to access service methods.
    2. +
    3. Full list of properties used to uniquely identify the service in +OSGI.
    4. +
    5. Startup and shutdown methods.
    6. +
    +For the first two items, a service must use the data it received from +its constructor.  For the third item, a service must register and +unregister itself with OSGI.  But beyond that, this is all that +services have in common, everything else is up to the specific service +interface.
    +

    Sessions (org.eclipse.dd.dsf.service.DsfSession)
    +

    +DSF services are organized into logical groups, called +sessions.  Sessions are only necessary because we want multiple +instances of systems built with DSF services to run at the same +time  This is because there is only a single OSGI service +registry, so if multiple services are registered with a given class +name, OSGI will not be able to distinguish between the two based on the +class name alone.  So there is an additional property which is +used by every DSF service when registering with OSGI, IDsfService.PROP_SESSION_ID.  +
    +

    A Session object +(TODO: link javadoc) has the following data associated with it:
    +

    +
      +
    • Session ID - A String object that is unique +among all other sessions.  Its ID is used by services as the IDsfService.PROP_SESSION_ID +property, and it is used by the client to obtain the Session object instance.
    • +
    • DsfExecutor +- Each session has a single executor.  This means that all the +services in a single session share the same executor and dispatch +thread, and conversely it means that when operating in the dispatch +thread, the state of all the services in a session will remain the same +until the end of a dispatch.  Note: multiple sessions could share the same DsfExecutor.
    • +
    • Service startup counter +- An integer counter which is read and incremented by every service +that is started in a session.  This counter is used to determine +the dependency order among services, which is used by events.
    • +
    • Event listener list +- This will be covered in the "Events" section.
    • +
    • Adapter list - A +list of adapters, providing functionality analogous to runtime's org.eclipse.core.internal.runtime.AdapterManager.  +Sessions need to manage their own lists of adapters, so that IAdapter objects which +originate from DSF services can provider different adapters, based +on the session that they originate from.  This feature is covered +in detail in the "DSF Data Model" document.
      +
    • +
    +

    The Session class also has a number of static features used to +manage Session objects:

    +
      +
    • Session ID counter +- Used to generate new session IDs.
    • +
    • Methods for starting +and ending sessions
      +
    • +
    • Session started/ended +event listener list - This allows clients to be notified when +sessions are created or terminated, which is used mostly for clean-up +purposes.
      +
    • +
    +

    Startup/Shutdown

    +Managing the startup and shutdown process is often the most complicated +aspect of modular systems.  The details of how the startup and +shutdown processes should be performed are also highly dependent on the +specifics of the system and service implementations.  To help +with this, DSF provides two simple guidelines:
    +
      +
    1. There should be a clear +dependency tree of all services within a session - When the +dependencies between services are clearly defined, it is possible to +bring-up and bring-down the services in an order that guarantees each +running service can access all of the services that it depends on.
    2. +
    3. There needs to be a +single point of control, which brings up and shuts down all the +services. - In other words, services should not initialize or +shut-down themselves, based on some global event that they are all +listening to.  But rather an external piece of logic needs to be +in charge of performing this operation.
    4. +
    +The main implication of the first guideline, is that each service can +get and hold onto references to other services, without having to +repeatedly check, whether the service references are still valid.  +This is because if a given service is to be shut-down, all services +that depend on this service will already have been shut down.  The +second guideline, simply ensures that startup and shutdown procedures +are clear and easy to follow.
    +

    org.eclipse.dd.dsf.service.DsfServicesTracker +vs org.osgi.util.tracker.ServiceTracker

    +OSGI methods for obtaining and tracking services can be rather +complicated.  To obtain a reference to a service, the client has +to:
    +
      +
    1. Get a reference to a BundleContext + object, which can be retrieved from the plugin class.
    2. +
    3. Obtain a service reference object by calling BundleContext.getServiceReference();
    4. +
    5. Obtain an instance of the service by calling BundleContext.getService(ServiceReference).
    6. +
    +But worst of all, when the client is finished using the service, it has +to call BundleContext.ungetService(ServiceReference), +because the bundle context counts the used references to a given +service.  All this paperwork is useful for services which manage +their own life-cycle, and could be un-registered at any time.  To +make managing references to these kinds of services, OSGI provides a +utility class, called ServiceTracker.  +
    +

    For DSF services, the life cycle of the services is much more +predictable, but the process of obtaining a reference to a service is +just as onerous.  DSF provides its own utility, which is +separate from the ServiceTracker, +named DsfServicesTracker.  +The differences between the two are listed in table below:
    +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Property
    +
    OSGI + ServiceTracker
    +
    DSF + DsfServicesTracker
    +
    Number +of services tracked
    +
    While +not strictly limited, it is optimized for tracking services of a single +class type, or more typically to track a single service reference.
    +
    Designed +to track services within a single DSF session. 
    +
    When +are service references obtained
    +
    Obtain +references automatically as the services register themselves.
    +
    Service +references are obtained as requested by the client, and cached.
    Synchronization
    +
    Multi-thread +accessible. 
    +
    Can +be accessed only on the session's dispatch thread.
    +
    Clean-up
    +
    Automatically +un-gets references for services that are shut down.
    +
    Client +must listen to session events, and clean up as needed.
    +
    +

    Both trackers are useful.  Service implementations that depend +on a number of other services are most likely to use DSF ServicesTracker, while some +clients, which use a single service may find OSGI ServiceTracker more suitable.
    +

    +

    Events

    +Events are the most un-conventional component of the services package +and probably most likely to need modifications to the design by the +community.  The design goal of +the event system is to allow a hierarchy of event classes, where a +listener could register itself for a specific event class or for all +events which derive from a base class.  The use case for this +behavior is in the data model, where we would like to have the ability +to capture all model-related events with a generic listener while at +the same time allowing for services to fully use class types. 
    +

    The event model is made up of the following components:
    +

    +
      +
    • DsfServiceEventHandler annotation +- This is the only indicator that a given method is an event +listener.  The class with the event handler doesn't have to +implement any interfaces, but it must be public, which is a big +drawback.
    • +
    • Session.addServiceEventListener, + Session.removeServiceEventListener +methods - These methods allow clients to register for an event +based on an event class and a service filter, where the filter can be +used to uniquely identify a service in case of services with multiple +instances of same class.
    • +
    • Session.dispatchEvent method - +This is the method that actually dispatches the event to the +listeners.  +The method must be called by a service that generates the event.
    • +
    +There are only a few more notes about the events mechanism:
    +
      +
    1. The event is always dispatched in its own Runnable submitted to +the session's DsfExecutor.
    2. +
    3. There is a slight convenience for clients not to have to register +for each type of event separately.
    4. +
    5. There is a slight inconvenience for clients, because anonymous +classes cannot be used as listeners, due to the public class +requirement.
    6. +
    +

    Debugger Services (org.eclipse.dd.dsf.debug)
    +

    +DSF framework includes a set of service interfaces for a typical +debugger implementation.  Functionally, they are pretty much +equivalent to the platform debug interfaces, but they are structured in +a way that allows a debugger to implement only some of them.  In +order for the startup and shutdown process to work effectively, the +dependencies between services need to be clearly defined.  The +dependencies between the main service interfaces are shown in the graph +below:
    +
    +

    It's also important to realize that it's unlikely that a single +hierarchy of interfaces will adequately fit all the various debugger +use cases, and it is likely that some interfaces will be needed which +partially duplicate functionality found in other interfaces.  +An example of this in the proposed interface set are the interfaces +which are used to initiate a debugging session.  The INativeProcesses service is +intended as the simple abstraction for native debuggers, where a +debugger only needs an existing host process ID or an executable image +name.  Based on this a INativeProcess +debugger implementation should be able to initiate a debugging session, +and return run-control, memory, and symbol contexts that are required +to carry out debugging operations.  By comparison, IOS and ITarget are generic interfaces +which allow clients to manage multiple target definitions, to +examine a wide array of OS objects, and to attach a debugger to a +process or some other debuggable entity. 
    +
    +

    +

    Disclaimer

    +Drafting large APIs that are intended to have many implementations and +by clients is a notoriously difficult task.  It is +impossible to expect that a first draft of such interfaces will not +require changes, and only time and multiple successful implementation +can validate them.  While we can draw upon many examples of +debugger +APIs in Eclipse in and our commercial debugger, this is a new API with +a +prototype that exercises only a small portion of its interfaces.
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/dsf_white_paper.html b/plugins/org.eclipse.dd.doc.dsf/docs/dsf_white_paper.html new file mode 100644 index 00000000000..7b41f5c87d2 --- /dev/null +++ b/plugins/org.eclipse.dd.doc.dsf/docs/dsf_white_paper.html @@ -0,0 +1,315 @@ + + + + + DSF White Paper + + +

    Debugger Services Framework (DSF)  White Paper

    +Version 1.0
    +Pawel Piech
    +© 2006, Wind River Systems.  Release under EPL version 1.0.
    +

    Overview

    +DSF is a service framework for implementing the model and communication +layers of Eclipse debuggers.  The framework itself is actually +very small in terms of lines of code, because it mostly builds on top +of existing standard frameworks of OSGI services and Java 5.0 +concurrency features.  The value of DSF is the set of utilities, +patterns, and guidelines that together help solve some of the more +difficult problems we have with existing Eclipse debugger +implementations.
    +

    Design goals

    +The +primary design goal is to overcome the problems with +existing Eclipse debuggers.  These problems are: +
      +
    1. Poor performance when debugging a remote +target (over a slow connection).
    2. +
        +
      • Synchronous debugger communication, which +results in poor throughput of data.
      • +
      • Amount of data that is retrieved from target +is based on the data model, rather than on what's visible to the user +on the screen.
      • +
      • No ability to filter, or to choose update +policies, which could allow user to control what is retrieved from the +target.
      • +
      +
    3. No modularity in APIs or debugger +implementations.
    4. +
        +
      • Specialized debuggers must use forking and +duplication of common code to provide unique features.
      • +
      • Degenerate debuggers (with a subset of +functionality of conventional debuggers)  must implement a lot of +interfaces that are meaningless to their users. 
      • +
      • It's difficult to modify or selectively +replace interfaces, because all interfaces have references to each +other. 
      • +
      +
    5. Difficulty in +customizing data presentation for different types of debugging.
    6. +
    +

    Features

    +The DSF features described below, more-or-less correspond one-to-one to +the problems in the Design Goals section. 
    +

    Concurrency Model

    +It may be a surprise that simply adopting a threading model would solve +performance problems with debugger communication, but indirectly, it +actually does.  The primary reason for poor performance with +remote targets in debuggers such as CDT is the synchronous nature of +target communication.  When a request is made at the UI level that +results in a command being sent to the target, then the client thread +is blocked while the command is being processed.  After the result +if finally retrieved, the client makes the next request for data and is +blocked again.  In this pattern the responsiveness of the UI is +slow, yet the majority of this performance hit is due to the latency of +the communication channel to the debugger back end. 
    +

    There is one major improvement to this pattern implemented in the +platform already.  The platform debugger views have been +re-written so that they spin off a separate thread for each separable +call to the debug model.  The multiple threads each result in +individual requests being sent to the target, and each thread is +blocked waiting for the result.  Overall the responsiveness of the +view is improved because all the request threads execute in +parallel.  However, there is one obvious limitation of this +approach: creating a lot of new threads, even when using a thread pool, +is an expensive operation and can in itself degrade performance, +therefore this solution doesn't scale well to programs that for example +have thousands of threads, or threads, or variables.
    +

    +

    There is also a more subtle limitation of using jobs.  Most +debuggers have a very lopsided performance characteristic, where it +takes a long time to initiate a query for the target, but once a query +is run, it takes relatively little extra time to retrieve larger +amounts of data.  Therefore, to better optimize the performance of +communicating with a remote target, it is important to coalesce +individual requests into queries for larger chunks of data.  This +is a rather complicated problem, mostly because the commands available +in debugger back ends vary depending on the type of data being +retrieved.  Also different types of data require different types +of coalescing.  For example, where it might be possible to +retrieve memory in arbitrarily sized chunks, registers may be +retrievable only in groups.  There is one thing all coalescing +solutions will have in common, though: they need to convert the calls +that are made to the service into objects, which can be compared, +sorted, and pooled together.  Management of such objects requires +a lot of state information to be tracked by the service, and managing +the cache of the request results requires even more state +information. 

    +

    Managing a lot of state information, which coalescing optimization +requires, is exceedingly difficult in a free multi-threaded +environment.  This is because the more state information there is +in the system, the more semaphores are needed to avoid race conditions. +The more semaphores are used, the greater the chance that deadlocks +will occur.  There are many methods for managing concurrency in +systems with a lot of state information, and they all have some +drawbacks.  One such example is the Eclipse resource system use of +ISchedulingRule and +jobs.  Unfortunately this this concurrency model would not work +well for the debugger because the resource system has a clearly defined +hierarchy to its data: Workspace/Projects/File, so it’s easy to lock a +portion of the tree and still allow other clients to interact with +it.  For debugger services, the relationship between state data is +not clearly defined and often very complicated, so if scheduling rules +were applied in a debugger implementation they would likely degrade +performance, because each request would probably need to lock the +entire system.
    +

    +

    For its concurrency model, DSF imposes a strict threading +model.  All services that make +up a debugger implementation must talk to each other using a single +dispatch thread, and no service can make a blocking call while in the +dispatch thread.  Conceptually this rule can be interpreted +as: all communication between services is accomplished by runnables in +a thread pool, where the thread pool size is just one.  The effect +of this policy is that the dispatch thread acts as a single global +semaphore, and when executing on the dispatch thread, a client or a +service can perform arbitrarily complex operations, and can poll the +sate of as many services as necessary without worrying about the state +of the system changing concurrently.  The single threading rule +only applies to the service interfaces, and does not preclude +multi-threading in the service implementations.  In fact +multi-threading is utilized more in this architecture because many +blocking operations that would normally be performed on shared threads, +possibly slowing the UI responsiveness, now need to be performed using +background threads.
    +

    +

    In summary, a restrictive threading model combined with asynchronous +interfaces, is the DSF solution to communication performance problems +because it allows debugger implementations to have highly complex logic +that handles coalescing and cancelling of requests, intelligent caching +of debugger requests, and other advanced features such as filtering and +configurable update policies.

    +

    Services Model
    +

    +

    Fortunately +it's easier to see the connection between a +services model and addressing modularity problems. 

    +

    Most current +debugger +implementations don't make an effort to separate out different +components that make +up the data model and communication layers.  It is true that UI +components +usually interact with clearly defined data model interfaces, and in +case of CDT +the data model is somewhat separated from the communication layer using +the CDI +interface.  However within the CDT data model and communication +layer +interfaces, there are enough references between the various objects to +make all +of them essentially inter-dependent.  Furthermore, in the +implementation +of these layers, components use internal knowledge of other +components.  +This is perfectly acceptable if we assume that the debugger +implementation is +going to be used as a single module, and any extensions can be built on +top of +it.  But, it is important that vendors be able to selectively pick +and +choose components which they would like to reuse "as is" and which +components they would like to extend, modify, replace, or not use at +all.  +In order to achieve that kind of modularity, a lot of design work has +to go +into interfaces not just between the major layers of implementation, +but also +between various components that make up these layers.
    +

    +

    +

    To help build +a modular +architecture, DSF builds on the OSGI services framework, by providing +additional functionality of:

    +
      +
    • organizing services into sessions,
    • +
    • managing start-up and shut-down processes,
    • +
    • managing events between services.
    • +
    +

    Additionally, +DSF includes an +initial draft of service interfaces designed to build a modular +debugger +implementation.  These interfaces must be validated, and this can +only be +realistically accomplished by implementing several full-featured and +diverse +debuggers.  We are seeking additional debug tool vendors from the +community to port to these interfaces in addition to Wind River.

    +

    Data Model

    +

    The problems +of the data model are perhaps less severe than +problems of performance and modularity, but this is an area with a lot +of room +for innovation.  We are used to thinking of the debug data model +in a +rather rigid terms, where there is a defined hierarchy of debug +targets, +threads, stack frames, variables, sub-expressions, etc.  We are +also used +to seeing standard debug views of threads, stack frames, locals, and +watch.  These expectations seem to be pretty accurately reflected +in the +platform debug model, on top of which all of the current Eclipse +debuggers are +based.  This is a problem for two reasons:

    +
      +
    1. The direct +references between different types of objects prevent the debug model +implementation from being modular.
    2. +
    3. Extensions to +the debug model are limited to additions in functionality of the basic +platform objects and some additional object types.
    4. +
    +

    Fortunately +in release 3.2, the Eclipse platform introduced +a way to circumvent the standard platform model and to drive the +content of +most of the standard debugger views using a completely custom data +model and a +set of viewer adapters.  DSF aims to take advantage of this new +capability +to address the above problems, as well as to provide the additional +benefits +of:

    +
      +
    1. Improving +performance by using the DSF dispatch thread model and asynchronous +methods.
    2. +
    3. Giving the +user ability to fully customize at runtime the content and layout of +debugger views.
    4. +
    +

    Points 1, 2, +and 3 are a side effect of DSF's Threading +Model and Services Model used in conjunction with the platform's +flexible +hierarchy interfaces.  Point 4 is an innovative and exciting +feature that +naturally builds on top of the service model and flexible hierarchy.  In the first release of DSF to open source, +we have not yet implemented the capability described in point 4.  +The +design for this feature calls for data driven, configurable views, +where the +configuration data drives the content and label providers to retrieve +appropriate information from the data model.  +On the service side, there needs to be a published data model +schema and +a query language interpreter, which will retrieve the data for clients.  We expect community discussion and design +work to help solve this problem, and we intend to present +implementations from +our commercial product as one possible solution.

    +

    One final +point is that although the +DSF data model is fundamentally different than the platform debug model +and the +CDT extensions, a DSF debugger could easily be adapted to provide any +of these +API’s.  This may require considerable effort, especially for +extensive +API’s like CDI, but is desirable and necessary to support the existing +CDT +community.

    +
    + + diff --git a/plugins/org.eclipse.dd.doc.dsf/notices.html b/plugins/org.eclipse.dd.doc.dsf/notices.html new file mode 100644 index 00000000000..829b3379436 --- /dev/null +++ b/plugins/org.eclipse.dd.doc.dsf/notices.html @@ -0,0 +1,22 @@ + + + + + + + + + Legal Notices + + + +

    +Notices

    +

    +The material in this guide is Copyright (c) Wind River Systems, Inc. and others 2000, 2006. +

    +

    +Terms and conditions regarding the use of this guide. +

    + + diff --git a/plugins/org.eclipse.dd.doc.dsf/options.txt b/plugins/org.eclipse.dd.doc.dsf/options.txt new file mode 100644 index 00000000000..ba6356d4617 --- /dev/null +++ b/plugins/org.eclipse.dd.doc.dsf/options.txt @@ -0,0 +1,35 @@ +-quiet +-encoding "iso-8859-1" +-charset "iso-8859-1" +-sourcepath "../org.eclipse.dd.dsf/src +;../org.eclipse.dd.dsf.ui/src +;../org.eclipse.dd.dsf.examples/src +-d reference/api +-classpath @rt@ +-breakiterator +-tag generated:X +-tag lastgen:X +-tag model:X +-tag ordered:X +-use +-splitIndex +-windowtitle "DSF API Specification" +-doctitle "DSF API Specification" +-header "DSF" +-bottom "Copyright (c) Wind River Systems, Inc. and others 2000, 2006. All Rights Reserved." +-group "DSF Core Packages" "org.eclipse.dd.dsf" +-group "DSF UI Packages" "org.eclipse.dd.dsf.ui" +-group "DSF Examples Packages" "org.eclipse.dd.dsf.examples" +-link http://java.sun.com/j2se/1.5/docs/api +-link http://bundles.osgi.org/javadoc/r4 + +org.eclipse.dd.dsf +org.eclipse.dd.dsf.concurrent +org.eclipse.dd.dsf.debug +org.eclipse.dd.dsf.model +org.eclipse.dd.dsf.service +org.eclipse.dd.dsf.ui +org.eclipse.dd.dsf.ui.model +org.eclipse.dd.dsf.examples +org.eclipse.dd.dsf.examples.concurrent +org.eclipse.dd.dsf.examples.timers diff --git a/plugins/org.eclipse.dd.doc.dsf/plugin.properties b/plugins/org.eclipse.dd.doc.dsf/plugin.properties new file mode 100644 index 00000000000..e0c1cadf344 --- /dev/null +++ b/plugins/org.eclipse.dd.doc.dsf/plugin.properties @@ -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) Documentation +providerName=Eclipse.org + diff --git a/plugins/org.eclipse.dd.doc.dsf/plugin.xml b/plugins/org.eclipse.dd.doc.dsf/plugin.xml new file mode 100644 index 00000000000..dd4a89cc70f --- /dev/null +++ b/plugins/org.eclipse.dd.doc.dsf/plugin.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/org.eclipse.dd.doc.dsf/schema.css b/plugins/org.eclipse.dd.doc.dsf/schema.css new file mode 100644 index 00000000000..4efbf267284 --- /dev/null +++ b/plugins/org.eclipse.dd.doc.dsf/schema.css @@ -0,0 +1,66 @@ +H6.CaptionFigColumn#header { + font-size:16px; + display:inline +} + +P.Note#copyright { + font-size: smaller; + font-style: normal; + color: #336699; + display:inline; + margin-top: 3.000000pt; + margin-bottom: 11.000000pt; + margin-right: 0.000000pt; + margin-left: 0.000000pt; +} + +P.Code#dtd { + color: #800000; + margin-top: 0.000000pt; + margin-bottom: 0.000000pt; + margin-right: 0.000000pt; + margin-left: 10.000000pt; +} + +P.Code#dtdAttlist { + color: #800000; + margin-top: 0.000000pt; + margin-bottom: 0.000000pt; + margin-right: 0.000000pt; + margin-left: 20.000000pt; +} + +P.Code#tag { + color: #000080; + display:inline; + margin-top: 0.000000pt; + margin-bottom: 0.000000pt; + margin-right: 0.000000pt; + margin-left: 0.000000pt; +} + +P.Code#cstring { + color: #008000; + display:inline; + margin-top: 0.000000pt; + margin-bottom: 0.000000pt; + margin-right: 0.000000pt; + margin-left: 0.000000pt; +} + +.ConfigMarkup#elementDesc { + color: black; + margin-top: 0.000000pt; + margin-bottom: 0.000000pt; + margin-right: 0.000000pt; + margin-left: 10.000000pt; +} + +.ConfigMarkup#attlistDesc { + color: black; + margin-top: 0.000000pt; + margin-bottom: 0.000000pt; + margin-right: 0.000000pt; + margin-left: 32.000000pt; +} + diff --git a/plugins/org.eclipse.dd.doc.dsf/toc.xml b/plugins/org.eclipse.dd.doc.dsf/toc.xml new file mode 100644 index 00000000000..cdda79bb01c --- /dev/null +++ b/plugins/org.eclipse.dd.doc.dsf/toc.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + From 6d5de9c3193943c5ec2465d33960c2d987e6baea Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 13 Feb 2008 20:26:10 +0000 Subject: [PATCH 239/834] [216854] Checked in initial version of PDA example debugger. --- .../org.eclipse.dd.examples.pda.ui/.classpath | 7 + .../org.eclipse.dd.examples.pda.ui/.cvsignore | 1 + .../org.eclipse.dd.examples.pda.ui/.project | 28 + .../.settings/org.eclipse.jdt.core.prefs | 37 + .../META-INF/MANIFEST.MF | 26 + .../org.eclipse.dd.examples.pda.ui/about.html | 28 + .../build.properties | 12 + .../icons/full/dlcl16/pop.gif | Bin 0 -> 159 bytes .../icons/full/dlcl16/push.gif | Bin 0 -> 361 bytes .../icons/full/elcl16/pop.gif | Bin 0 -> 163 bytes .../icons/full/elcl16/push.gif | Bin 0 -> 590 bytes .../icons/full/obj16/pda.gif | Bin 0 -> 182 bytes .../org.eclipse.dd.examples.pda.ui/plugin.xml | 139 ++++ .../dd/examples/pda/ui/PDAAdapterFactory.java | 205 ++++++ .../dd/examples/pda/ui/PDAUIPlugin.java | 191 +++++ .../pda/ui/actions/DsfTerminateCommand.java | 95 +++ .../ui/breakpoints/PDABreakpointAdapter.java | 220 ++++++ .../breakpoints/PDAEditorAdapterFactory.java | 57 ++ .../ui/breakpoints/PDARunToLineAdapter.java | 76 ++ .../pda/ui/editor/AnnotationHover.java | 45 ++ .../ui/editor/PDAContentAssistProcessor.java | 102 +++ .../pda/ui/editor/PDAContentAssistant.java | 42 ++ .../dd/examples/pda/ui/editor/PDAEditor.java | 48 ++ .../ui/editor/PDAEditorMessages.properties | 15 + .../dd/examples/pda/ui/editor/PDAScanner.java | 92 +++ .../editor/PDASourceViewerConfiguration.java | 63 ++ .../pda/ui/editor/PopFrameActionDelegate.java | 90 +++ .../dd/examples/pda/ui/editor/TextHover.java | 88 +++ .../dd/examples/pda/ui/editor/WordFinder.java | 79 ++ .../pda/ui/launcher/PDALaunchShortcut.java | 75 ++ .../examples/pda/ui/launcher/PDAMainTab.java | 185 +++++ .../examples/pda/ui/launcher/PDATabGroup.java | 39 + .../pda/ui/viewmodel/PDAVMAdapter.java | 57 ++ .../ui/viewmodel/launch/LaunchVMProvider.java | 126 ++++ .../pda/ui/viewmodel/launch/ThreadVMNode.java | 247 +++++++ .../org.eclipse.dd.examples.pda/.classpath | 7 + .../org.eclipse.dd.examples.pda/.cvsignore | 1 + plugins/org.eclipse.dd.examples.pda/.options | 1 + plugins/org.eclipse.dd.examples.pda/.project | 28 + .../.settings/org.eclipse.jdt.core.prefs | 69 ++ .../META-INF/MANIFEST.MF | 20 + .../org.eclipse.dd.examples.pda/about.html | 28 + .../build.properties | 21 + .../pdavm/docs/protocol.html | 198 ++++++ .../org.eclipse.dd.examples.pda/pdavm/pda.pl | 673 ++++++++++++++++++ .../pdavm/tests/vmtest2.pda | 48 ++ .../pdavm/tests/vmtest3.pda | 11 + .../pdavm/tests/vmtest6.pda | 31 + .../pdavm/tests/vmtest8.pda | 14 + .../pdavm/tests/vmtests.pl | 448 ++++++++++++ .../org.eclipse.dd.examples.pda/plugin.xml | 72 ++ .../org.eclipse.dd.examples.pda/readme.html | 11 + .../samples/counter.pda | 11 + .../samples/drop.pda | 12 + .../samples/example.pda | 35 + .../samples/fibonacci.pda | 32 + .../samples/structures.pda | 8 + .../eclipse/dd/examples/pda/PDAPlugin.java | 208 ++++++ .../pda/breakpoints/PDALineBreakpoint.java | 78 ++ .../breakpoints/PDARunToLineBreakpoint.java | 70 ++ .../pda/breakpoints/PDAWatchpoint.java | 168 +++++ .../dd/examples/pda/launch/PDALaunch.java | 181 +++++ .../pda/launch/PDALaunchDelegate.java | 198 ++++++ .../pda/launch/PDAServicesInitSequence.java | 138 ++++ .../launch/PDAServicesShutdownSequence.java | 156 ++++ .../breakpoints/BreakpointDMContext.java | 48 ++ .../PDABreakpointAttributeTranslator.java | 117 +++ .../service/breakpoints/PDABreakpoints.java | 264 +++++++ .../breakpoints/WatchpointDMContext.java | 54 ++ .../pda/service/command/PDACommand.java | 28 + .../service/command/PDACommandControl.java | 477 +++++++++++++ .../command/PDACommandControlDMContext.java | 45 ++ .../pda/service/command/PDACommandResult.java | 23 + .../pda/service/command/PDAStartedEvent.java | 22 + .../service/command/PDATerminatedEvent.java | 22 + .../commands/PDAClearBreakpointCommand.java | 34 + .../command/commands/PDACommandBase.java | 58 ++ .../commands/PDACommandBaseResult.java | 44 ++ .../command/commands/PDADataCommand.java | 33 + .../commands/PDADataCommandResult.java | 42 ++ .../command/commands/PDADropFrameCommand.java | 36 + .../command/commands/PDAEvalCommand.java | 38 + .../command/commands/PDAEventStopCommand.java | 42 ++ .../command/commands/PDAExitCommand.java | 33 + .../command/commands/PDAPopDataCommand.java | 33 + .../command/commands/PDAPushDataCommand.java | 33 + .../command/commands/PDAResumeCommand.java | 34 + .../commands/PDASetBreakpointCommand.java | 36 + .../command/commands/PDASetDataCommand.java | 33 + .../command/commands/PDASetVarCommand.java | 33 + .../command/commands/PDAStackCommand.java | 33 + .../commands/PDAStackCommandResult.java | 57 ++ .../command/commands/PDAStepCommand.java | 35 + .../commands/PDAStepReturnCommand.java | 35 + .../command/commands/PDASuspendCommand.java | 34 + .../command/commands/PDAVarCommand.java | 33 + .../command/commands/PDAVarCommandResult.java | 25 + .../command/commands/PDAWatchCommand.java | 51 ++ .../pda/service/runcontrol/ExecutionData.java | 24 + .../pda/service/runcontrol/PDARunControl.java | 270 +++++++ .../pda/service/runcontrol/ResumedEvent.java | 41 ++ .../service/runcontrol/SuspendedEvent.java | 34 + .../tests/pda/service/command/BasicTests.java | 134 ++++ .../command/CommandControlTestsBase.java | 140 ++++ .../pda/service/command/PDATestEvent.java | 21 + .../dd/tests/pda/service/command/Test1.java | 46 ++ .../dd/tests/pda/service/command/Test2.java | 109 +++ .../dd/tests/pda/service/command/Test3.java | 74 ++ .../dd/tests/pda/service/command/Test6.java | 79 ++ .../dd/tests/pda/service/command/Test8.java | 70 ++ .../eclipse/dd/tests/pda/util/Launching.java | 94 +++ .../sourcelookup/PDASourceLookupDirector.java | 32 + .../PDASourceLookupParticipant.java | 29 + .../PDASourcePathComputerDelegate.java | 65 ++ 114 files changed, 8718 insertions(+) create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/.classpath create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/.cvsignore create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/.project create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/.settings/org.eclipse.jdt.core.prefs create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/META-INF/MANIFEST.MF create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/about.html create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/build.properties create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/icons/full/dlcl16/pop.gif create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/icons/full/dlcl16/push.gif create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/icons/full/elcl16/pop.gif create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/icons/full/elcl16/push.gif create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/icons/full/obj16/pda.gif create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/plugin.xml create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAUIPlugin.java create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/actions/DsfTerminateCommand.java create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/breakpoints/PDABreakpointAdapter.java create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/breakpoints/PDAEditorAdapterFactory.java create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/breakpoints/PDARunToLineAdapter.java create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/AnnotationHover.java create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAContentAssistProcessor.java create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAContentAssistant.java create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAEditor.java create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAEditorMessages.properties create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAScanner.java create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDASourceViewerConfiguration.java create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PopFrameActionDelegate.java create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/TextHover.java create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/WordFinder.java create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/launcher/PDALaunchShortcut.java create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/launcher/PDAMainTab.java create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/launcher/PDATabGroup.java create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/LaunchVMProvider.java create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/ThreadVMNode.java create mode 100644 plugins/org.eclipse.dd.examples.pda/.classpath create mode 100644 plugins/org.eclipse.dd.examples.pda/.cvsignore create mode 100755 plugins/org.eclipse.dd.examples.pda/.options create mode 100644 plugins/org.eclipse.dd.examples.pda/.project create mode 100644 plugins/org.eclipse.dd.examples.pda/.settings/org.eclipse.jdt.core.prefs create mode 100644 plugins/org.eclipse.dd.examples.pda/META-INF/MANIFEST.MF create mode 100644 plugins/org.eclipse.dd.examples.pda/about.html create mode 100644 plugins/org.eclipse.dd.examples.pda/build.properties create mode 100644 plugins/org.eclipse.dd.examples.pda/pdavm/docs/protocol.html create mode 100644 plugins/org.eclipse.dd.examples.pda/pdavm/pda.pl create mode 100644 plugins/org.eclipse.dd.examples.pda/pdavm/tests/vmtest2.pda create mode 100644 plugins/org.eclipse.dd.examples.pda/pdavm/tests/vmtest3.pda create mode 100644 plugins/org.eclipse.dd.examples.pda/pdavm/tests/vmtest6.pda create mode 100644 plugins/org.eclipse.dd.examples.pda/pdavm/tests/vmtest8.pda create mode 100644 plugins/org.eclipse.dd.examples.pda/pdavm/tests/vmtests.pl create mode 100644 plugins/org.eclipse.dd.examples.pda/plugin.xml create mode 100644 plugins/org.eclipse.dd.examples.pda/readme.html create mode 100644 plugins/org.eclipse.dd.examples.pda/samples/counter.pda create mode 100644 plugins/org.eclipse.dd.examples.pda/samples/drop.pda create mode 100644 plugins/org.eclipse.dd.examples.pda/samples/example.pda create mode 100644 plugins/org.eclipse.dd.examples.pda/samples/fibonacci.pda create mode 100644 plugins/org.eclipse.dd.examples.pda/samples/structures.pda create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/PDAPlugin.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/breakpoints/PDALineBreakpoint.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/breakpoints/PDARunToLineBreakpoint.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/breakpoints/PDAWatchpoint.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunch.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunchDelegate.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/breakpoints/BreakpointDMContext.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/breakpoints/PDABreakpointAttributeTranslator.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/breakpoints/PDABreakpoints.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/breakpoints/WatchpointDMContext.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommand.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommandControl.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommandControlDMContext.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommandResult.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDAStartedEvent.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDATerminatedEvent.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAClearBreakpointCommand.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDACommandBase.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDACommandBaseResult.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDADataCommand.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDADataCommandResult.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDADropFrameCommand.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAEvalCommand.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAEventStopCommand.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAExitCommand.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAPopDataCommand.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAPushDataCommand.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAResumeCommand.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASetBreakpointCommand.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASetDataCommand.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASetVarCommand.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStackCommand.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStackCommandResult.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStepCommand.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStepReturnCommand.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASuspendCommand.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAVarCommand.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAVarCommandResult.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAWatchCommand.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/ExecutionData.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/PDARunControl.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/ResumedEvent.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/SuspendedEvent.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/BasicTests.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/CommandControlTestsBase.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/PDATestEvent.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/Test1.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/Test2.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/Test3.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/Test6.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/Test8.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/util/Launching.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourceLookupDirector.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourceLookupParticipant.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourcePathComputerDelegate.java diff --git a/plugins/org.eclipse.dd.examples.pda.ui/.classpath b/plugins/org.eclipse.dd.examples.pda.ui/.classpath new file mode 100644 index 00000000000..b7464f3ca24 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/plugins/org.eclipse.dd.examples.pda.ui/.cvsignore b/plugins/org.eclipse.dd.examples.pda.ui/.cvsignore new file mode 100644 index 00000000000..ba077a4031a --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/.cvsignore @@ -0,0 +1 @@ +bin diff --git a/plugins/org.eclipse.dd.examples.pda.ui/.project b/plugins/org.eclipse.dd.examples.pda.ui/.project new file mode 100644 index 00000000000..656deb7648b --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/.project @@ -0,0 +1,28 @@ + + + org.eclipse.dd.examples.pda.ui + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/plugins/org.eclipse.dd.examples.pda.ui/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.dd.examples.pda.ui/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000000..14a59416048 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,37 @@ +#Mon Jan 24 20:23:44 CST 2005 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.emptyStatement=warning +org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore +org.eclipse.jdt.core.compiler.problem.finalParameterBound=ignore +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning diff --git a/plugins/org.eclipse.dd.examples.pda.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.examples.pda.ui/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..db3421c8f05 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/META-INF/MANIFEST.MF @@ -0,0 +1,26 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: PDA Example Device Debugging UI Plug-in +Bundle-SymbolicName: org.eclipse.dd.examples.pda.ui;singleton:=true +Bundle-Version: 1.0.0 +Bundle-Activator: org.eclipse.dd.examples.pda.ui.PDAUIPlugin +Require-Bundle: org.eclipse.core.runtime, + org.eclipse.core.resources, + org.eclipse.debug.core, + org.eclipse.ui, + org.eclipse.debug.ui, + org.eclipse.jface.text, + org.eclipse.ui.editors, + org.eclipse.ui.workbench.texteditor, + org.eclipse.ui.ide, + org.eclipse.dd.examples.pda;bundle-version="1.0.0", + org.eclipse.dd.dsf;bundle-version="1.0.0", + org.eclipse.dd.dsf.ui;bundle-version="1.0.0", + org.eclipse.dd.dsf.debug;bundle-version="1.0.0", + org.eclipse.dd.dsf.debug.ui;bundle-version="1.0.0" +Eclipse-LazyStart: true +Export-Package: org.eclipse.dd.examples.pda.ui, + org.eclipse.dd.examples.pda.ui.breakpoints, + org.eclipse.dd.examples.pda.ui.editor, + org.eclipse.dd.examples.pda.ui.launcher +Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/plugins/org.eclipse.dd.examples.pda.ui/about.html b/plugins/org.eclipse.dd.examples.pda.ui/about.html new file mode 100644 index 00000000000..460233046ee --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/about.html @@ -0,0 +1,28 @@ + + + + +About + + +

    About This Content

    + +

    June 2, 2006

    +

    License

    + +

    The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at http://www.eclipse.org/legal/epl-v10.html. +For purposes of the EPL, "Program" will mean the Content.

    + +

    If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at http://www.eclipse.org.

    + + + \ No newline at end of file diff --git a/plugins/org.eclipse.dd.examples.pda.ui/build.properties b/plugins/org.eclipse.dd.examples.pda.ui/build.properties new file mode 100644 index 00000000000..0fb5122be93 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/build.properties @@ -0,0 +1,12 @@ +source.. = src/ +output.. = bin/ +bin.includes = plugin.xml,\ + bin/,\ + about.html,\ + META-INF/,\ + .,\ + icons/ +src.includes = src/,\ + about.html,\ + icons/,\ + plugin.xml diff --git a/plugins/org.eclipse.dd.examples.pda.ui/icons/full/dlcl16/pop.gif b/plugins/org.eclipse.dd.examples.pda.ui/icons/full/dlcl16/pop.gif new file mode 100644 index 0000000000000000000000000000000000000000..559e462985f439553de36c89f65392eae3e9a44e GIT binary patch literal 159 zcmZ?wbhEHb6krfw*v!Ci=-|O)$BrF5cyQ02Jv(;n*t~i3x^?STu3Wif$&v*N7X1JJ zp8*vp{$ycfVBliV0SSZ5U|{hHIO(~1uSCNtU5#UEjBbj3ZUQY)yXJ8fa4;1Ld|~WA z@!)sI-4+*(HUmTFi3NKYgjzF96l>i0I}eMb=?0hv=!;iZy|UTOS9Ern3j>2S03Llh A4*&oF literal 0 HcmV?d00001 diff --git a/plugins/org.eclipse.dd.examples.pda.ui/icons/full/dlcl16/push.gif b/plugins/org.eclipse.dd.examples.pda.ui/icons/full/dlcl16/push.gif new file mode 100644 index 0000000000000000000000000000000000000000..f7e6cc089c226721a198a3ed515fd0626761db3a GIT binary patch literal 361 zcmZ?wbhEHb6krfwxXQrr`}dz;zkdJx`Rn`l9|sQ|UAJ-j*6q93uHU@>;L*=tzJ2=q z_0i*}*RJ2(wsYU9Gv^N+I=W{4=Jy{zU%h_w>$mUEp1(MJ9{K#~?WvPTH>{brY2AXgE9b0UKI_!+y^kMUdvNFCq5a#A9NhWh>D{-l zpDtTCb;aW8ySJ@AdSL6`9qYb-`*PvT(L)Ch{{8#+&!0d4|Nmzo1QdU=FfuThFzA33 zg8an5*5)v)z(Yr>ePhZSj~-7Io|BhWm{_diYu?0Zt*|eFBS)(zHSLATEa$#N2cyzi zv37g?K141)Fu!t|p_;O+vYNaRV`rzhr)FQjrXqI@E0a`%p00+jo)QD|f(6pShB_)b u+6=5!U(~$qz@e@b9PM>yUum%9b4zw!( literal 0 HcmV?d00001 diff --git a/plugins/org.eclipse.dd.examples.pda.ui/icons/full/elcl16/pop.gif b/plugins/org.eclipse.dd.examples.pda.ui/icons/full/elcl16/pop.gif new file mode 100644 index 0000000000000000000000000000000000000000..2cd9c544436c47a57f20b348b3fb024bb50701a7 GIT binary patch literal 163 zcmZ?wbhEHb6krfw*v!DNV#SID3l_|nF=N7n2^}3B4Gj$y6%_>q1sNF`2?+`R|Nmz| z1&Tje7#SG27<53wATtBYuHJj2L#xNM)vQ#JRl<>hDKU#-N&yE`p}?0M(Gw4T zcQCOfDoF5h^e6?|s2Q}nBw9^h7K$KQ28^82qz zvzLAT{^!PvAHV{+c)*@-qQ8==c6YNFZ_AC z^Y7>LoB9+t_A73mth#Hu+P2B6f1WM=`*!ENO0h+?5({f2mNiN(Ym#2mA$Mg*>hHVF zhgYTjc{t(nx`4yW;ttJnJT%wq!kUUJ8>)}aN<6o+?D(RhQ%g%Oud8}@|J1?RIY;K@ z@0*eR{8d*Rb6z9wC>*1tMmg_~C<+Ym>RXjlG!!%dz7u3SMkiFE}CVZ!|R^VhCj`@j9` ze + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + --> + diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java new file mode 100644 index 00000000000..46243cb2619 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java @@ -0,0 +1,205 @@ +/******************************************************************************* + * 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.examples.pda.ui; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.runtime.IAdapterFactory; +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.dd.dsf.debug.ui.actions.DsfResumeCommand; +import org.eclipse.dd.dsf.debug.ui.actions.DsfStepIntoCommand; +import org.eclipse.dd.dsf.debug.ui.actions.DsfStepOverCommand; +import org.eclipse.dd.dsf.debug.ui.actions.DsfStepReturnCommand; +import org.eclipse.dd.dsf.debug.ui.actions.DsfSuspendCommand; +import org.eclipse.dd.dsf.debug.ui.sourcelookup.MISourceDisplayAdapter; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.examples.pda.PDAPlugin; +import org.eclipse.dd.examples.pda.launch.PDALaunch; +import org.eclipse.dd.examples.pda.ui.actions.DsfTerminateCommand; +import org.eclipse.dd.examples.pda.ui.viewmodel.PDAVMAdapter; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.ILaunchesListener2; +import org.eclipse.debug.core.commands.IResumeHandler; +import org.eclipse.debug.core.commands.IStepIntoHandler; +import org.eclipse.debug.core.commands.IStepOverHandler; +import org.eclipse.debug.core.commands.IStepReturnHandler; +import org.eclipse.debug.core.commands.ISuspendHandler; +import org.eclipse.debug.core.commands.ITerminateHandler; +import org.eclipse.debug.core.model.IDebugModelProvider; +import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory; +import org.eclipse.debug.ui.sourcelookup.ISourceDisplay; + +/** + * This implementation of platform adapter factory only retrieves the adapters + * for the launch object. It also manages the creation and destruction + * of the session-based adapters which are returned by the + * IDMContext.getAdapter() methods. + */ +@ThreadSafe +@SuppressWarnings({"restriction"}) +public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2 +{ + @Immutable + class LaunchAdapterSet { + final PDAVMAdapter fViewModelAdapter; + final MISourceDisplayAdapter fSourceDisplayAdapter; + final DsfStepIntoCommand fStepIntoCommand; + final DsfStepOverCommand fStepOverCommand; + final DsfStepReturnCommand fStepReturnCommand; + final DsfSuspendCommand fSuspendCommand; + final DsfResumeCommand fResumeCommand; + final DsfTerminateCommand fTerminateCommand; + final IDebugModelProvider fDebugModelProvider; + final PDALaunch fLaunch; + + LaunchAdapterSet(PDALaunch launch) { + fLaunch = launch; + DsfSession session = launch.getSession(); + + fViewModelAdapter = new PDAVMAdapter(session); + + if (launch.getSourceLocator() instanceof ISourceLookupDirector) { + fSourceDisplayAdapter = new MISourceDisplayAdapter(session, (ISourceLookupDirector)launch.getSourceLocator()); + } else { + fSourceDisplayAdapter = null; + } + session.registerModelAdapter(ISourceDisplay.class, fSourceDisplayAdapter); + + fStepIntoCommand = new DsfStepIntoCommand(session); + fStepOverCommand = new DsfStepOverCommand(session); + fStepReturnCommand = new DsfStepReturnCommand(session); + fSuspendCommand = new DsfSuspendCommand(session); + fResumeCommand = new DsfResumeCommand(session); + fTerminateCommand = new DsfTerminateCommand(session); + session.registerModelAdapter(IStepIntoHandler.class, fStepIntoCommand); + session.registerModelAdapter(IStepOverHandler.class, fStepOverCommand); + session.registerModelAdapter(IStepReturnHandler.class, fStepReturnCommand); + session.registerModelAdapter(ISuspendHandler.class, fSuspendCommand); + session.registerModelAdapter(IResumeHandler.class, fResumeCommand); + session.registerModelAdapter(ITerminateHandler.class, fTerminateCommand); + + fDebugModelProvider = new IDebugModelProvider() { + // @see org.eclipse.debug.core.model.IDebugModelProvider#getModelIdentifiers() + public String[] getModelIdentifiers() { + return new String[] { PDAPlugin.ID_PDA_DEBUG_MODEL }; + } + }; + session.registerModelAdapter(IDebugModelProvider.class, fDebugModelProvider); + + /* + * Registering the launch as an adapter, ensures that this launch, + * and debug model ID will be associated with all DMContexts from this + * session. + */ + session.registerModelAdapter(ILaunch.class, fLaunch); + } + + void dispose() { + DsfSession session = fLaunch.getSession(); + + fViewModelAdapter.dispose(); + + session.unregisterModelAdapter(ISourceDisplay.class); + if (fSourceDisplayAdapter != null) fSourceDisplayAdapter.dispose(); + + session.unregisterModelAdapter(IStepIntoHandler.class); + session.unregisterModelAdapter(IStepOverHandler.class); + session.unregisterModelAdapter(IStepReturnHandler.class); + session.unregisterModelAdapter(ISuspendHandler.class); + session.unregisterModelAdapter(IResumeHandler.class); + session.unregisterModelAdapter(ITerminateHandler.class); + fStepIntoCommand.dispose(); + fStepOverCommand.dispose(); + fStepReturnCommand.dispose(); + fSuspendCommand.dispose(); + fResumeCommand.dispose(); + fTerminateCommand.dispose(); + } + } + + private Map fLaunchAdapterSets = + Collections.synchronizedMap(new HashMap()); + + public PDAAdapterFactory() { + DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this); + } + + /** + * This method only actually returns adapters for the launch object. + */ + @SuppressWarnings("unchecked") + public Object getAdapter(Object adaptableObject, Class adapterType) { + if (!(adaptableObject instanceof PDALaunch)) return null; + + PDALaunch launch = (PDALaunch)adaptableObject; + + // Find the correct set of adapters based on the launch. If not found + // it means that we have a new launch, and we have to create a + // new set of adapters. + LaunchAdapterSet adapterSet; + synchronized(fLaunchAdapterSets) { + adapterSet = fLaunchAdapterSets.get(launch); + if (adapterSet == null) { + adapterSet = new LaunchAdapterSet(launch); + fLaunchAdapterSets.put(launch, adapterSet); + } + } + + // Returns the adapter type for the launch object. + if (adapterType.equals(IElementContentProvider.class)) return adapterSet.fViewModelAdapter; + else if (adapterType.equals(IModelProxyFactory.class)) return adapterSet.fViewModelAdapter; + else if (adapterType.equals(IColumnPresentationFactory.class)) return adapterSet.fViewModelAdapter; + else return null; + } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.IAdapterFactory#getAdapterList() + */ + @SuppressWarnings("unchecked") + public Class[] getAdapterList() { + return new Class[] { IElementContentProvider.class, IModelProxyFactory.class, IColumnPresentationFactory.class }; + } + + public void sessionEnded(DsfSession session) { + } + + public void launchesRemoved(ILaunch[] launches) { + // Dispose the set of adapters for a launch only after the launch is + // removed. + for (ILaunch launch : launches) { + if (launch instanceof PDALaunch) { + PDALaunch pdaLaunch = (PDALaunch)launch; + synchronized(fLaunchAdapterSets) { + if ( fLaunchAdapterSets.containsKey(pdaLaunch) ) { + fLaunchAdapterSets.remove(pdaLaunch).dispose(); + } + } + } + } + } + + public void launchesTerminated(ILaunch[] launches) { + } + + public void launchesAdded(ILaunch[] launches) { + } + + public void launchesChanged(ILaunch[] launches) { + } + +} diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAUIPlugin.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAUIPlugin.java new file mode 100644 index 00000000000..f44fc65f030 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAUIPlugin.java @@ -0,0 +1,191 @@ +/******************************************************************************* + * Copyright (c) 2005, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Bjorn Freeman-Benson - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.ui; + +import java.net.URL; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.MissingResourceException; +import java.util.ResourceBundle; +import java.util.Map.Entry; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.ImageRegistry; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.internal.util.BundleUtility; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The main plugin class to be used in the desktop. + */ +public class PDAUIPlugin extends AbstractUIPlugin { + //The shared instance. + private static PDAUIPlugin plugin; + //Resource bundle. + private ResourceBundle resourceBundle; + + private static BundleContext fContext; + + private final static String ICONS_PATH = "icons/full/";//$NON-NLS-1$ + private final static String PATH_OBJECT = ICONS_PATH + "obj16/"; //Model object icons //$NON-NLS-1$ + private final static String PATH_ELOCALTOOL = ICONS_PATH + "elcl16/"; //Enabled local toolbar icons //$NON-NLS-1$ + private final static String PATH_DLOCALTOOL = ICONS_PATH + "dlcl16/"; //Disabled local toolbar icons //$NON-NLS-1$ + + /** + * Toolbar action to pop data stack + */ + public final static String IMG_ELCL_POP = "IMG_ELCL_POP"; + public final static String IMG_DLCL_POP = "IMG_DLCL_POP"; + + /** + * Toolbar action to push onto data stack + */ + public final static String IMG_ELCL_PUSH = "IMG_ELCL_PUSH"; + public final static String IMG_DLCL_PUSH = "IMG_DLCL_PUSH"; + + /** + * PDA program image + */ + public final static String IMG_OBJ_PDA = "IMB_OBJ_PDA"; + + /** + * Keyword color + */ + public final static RGB KEYWORD = new RGB(0,0,255); + public final static RGB LABEL = new RGB(128, 128, 0); + + /** + * Managed colors + */ + private Map fColors = new HashMap(); + + /** + * The constructor. + */ + public PDAUIPlugin() { + super(); + plugin = this; + } + + /** + * This method is called upon plug-in activation + */ + public void start(BundleContext context) throws Exception { + fContext = context; + super.start(context); +// Toggles single threaded adapter example +// IAdapterManager adapterManager = Platform.getAdapterManager(); +// IAdapterFactory factory = new AdapterFactory(); +// adapterManager.registerAdapters(factory, PDADebugTarget.class); + } + + /** + * This method is called when the plug-in is stopped + */ + public void stop(BundleContext context) throws Exception { + super.stop(context); + plugin = null; + resourceBundle = null; + fContext = null; + Iterator colors = fColors.entrySet().iterator(); + while (colors.hasNext()) { + Map.Entry entry = (Entry) colors.next(); + ((Color)entry.getValue()).dispose(); + } + } + + /** + * Returns the shared instance. + */ + public static PDAUIPlugin getDefault() { + return plugin; + } + + public static BundleContext getBundleContext() { + return fContext; + } + + + /** + * Returns the string from the plugin's resource bundle, + * or 'key' if not found. + */ + public static String getResourceString(String key) { + ResourceBundle bundle = PDAUIPlugin.getDefault().getResourceBundle(); + try { + return (bundle != null) ? bundle.getString(key) : key; + } catch (MissingResourceException e) { + return key; + } + } + + /** + * Returns the plugin's resource bundle, + */ + public ResourceBundle getResourceBundle() { + try { + if (resourceBundle == null) + resourceBundle = ResourceBundle.getBundle("org.eclipse.debug.examples.ui.pda.DebugUIPluginResources"); + } catch (MissingResourceException x) { + resourceBundle = null; + } + return resourceBundle; + } + + + /* (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#initializeImageRegistry(org.eclipse.jface.resource.ImageRegistry) + */ + protected void initializeImageRegistry(ImageRegistry reg) { + declareImage(IMG_OBJ_PDA, PATH_OBJECT + "pda.gif"); + declareImage(IMG_ELCL_POP, PATH_ELOCALTOOL + "pop.gif"); + declareImage(IMG_DLCL_POP, PATH_DLOCALTOOL + "pop.gif"); + declareImage(IMG_ELCL_PUSH, PATH_ELOCALTOOL + "push.gif"); + declareImage(IMG_DLCL_PUSH, PATH_DLOCALTOOL + "push.gif"); + } + + /** + * Declares a workbench image given the path of the image file (relative to + * the workbench plug-in). This is a helper method that creates the image + * descriptor and passes it to the main declareImage method. + * + * @param symbolicName the symbolic name of the image + * @param path the path of the image file relative to the base of the workbench + * plug-ins install directory + * false if this is not a shared image + */ + private void declareImage(String key, String path) { + URL url = BundleUtility.find("org.eclipse.debug.examples.ui", path); + ImageDescriptor desc = ImageDescriptor.createFromURL(url); + getImageRegistry().put(key, desc); + } + + /** + * Returns the color described by the given RGB. + * + * @param rgb + * @return color + */ + public Color getColor(RGB rgb) { + Color color = (Color) fColors.get(rgb); + if (color == null) { + color= new Color(Display.getCurrent(), rgb); + fColors.put(rgb, color); + } + return color; + } + + } diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/actions/DsfTerminateCommand.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/actions/DsfTerminateCommand.java new file mode 100644 index 00000000000..720c4ec6fc4 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/actions/DsfTerminateCommand.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * 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.examples.pda.ui.actions; + +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandControl; +import org.eclipse.dd.examples.pda.ui.PDAUIPlugin; +import org.eclipse.debug.core.commands.IDebugCommandRequest; +import org.eclipse.debug.core.commands.IEnabledStateRequest; +import org.eclipse.debug.core.commands.ITerminateHandler; + +public class DsfTerminateCommand implements ITerminateHandler { + private final DsfExecutor fExecutor; + private final DsfServicesTracker fTracker; + + public DsfTerminateCommand(DsfSession session) { + fExecutor = session.getExecutor(); + fTracker = new DsfServicesTracker(PDAUIPlugin.getBundleContext(), session.getId()); + } + + public void dispose() { + fTracker.dispose(); + } + + // Run control may not be avilable after a connection is terminated and shut down. + public void canExecute(final IEnabledStateRequest request) { + if (request.getElements().length != 1 || + !(request.getElements()[0] instanceof IDMVMContext) ) + { + request.setEnabled(false); + request.done(); + return; + } + + // Javac doesn't like the cast to "(AbstractDMVMLayoutNode.DMVMContext)" need to use the + // construct below and suppress warnings. + IDMVMContext vmc = (IDMVMContext)request.getElements()[0]; + final IExecutionDMContext dmc = DMContexts.getAncestorOfType(vmc.getDMContext(), IExecutionDMContext.class); + if (dmc == null) { + request.setEnabled(false); + request.done(); + return; + } + + fExecutor.execute( + new DsfRunnable() { + public void run() { + // Get the processes service and the exec context. + PDACommandControl commandControl = fTracker.getService(PDACommandControl.class); + if (commandControl == null || dmc == null) { + // Context or service already invalid. + request.setEnabled(false); + request.done(); + } else { + // Check the terminate. + request.setEnabled(!commandControl.isTerminated()); + request.done(); + } + } + }); + } + + public boolean execute(final IDebugCommandRequest request) { + if (request.getElements().length != 1) { + request.done(); + return false; + } + + fExecutor.submit(new DsfRunnable() { + public void run() { + PDACommandControl commandControl = fTracker.getService(PDACommandControl.class); + if (commandControl != null) { + commandControl.shutdown(new RequestMonitor(fExecutor, null)); + } + } + }); + return false; + } + +} diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/breakpoints/PDABreakpointAdapter.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/breakpoints/PDABreakpointAdapter.java new file mode 100644 index 00000000000..006fbe1d6aa --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/breakpoints/PDABreakpointAdapter.java @@ -0,0 +1,220 @@ +/******************************************************************************* + * Copyright (c) 2005, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Bjorn Freeman-Benson - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.ui.breakpoints; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.dd.examples.pda.PDAPlugin; +import org.eclipse.dd.examples.pda.breakpoints.PDALineBreakpoint; +import org.eclipse.dd.examples.pda.breakpoints.PDAWatchpoint; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.model.IBreakpoint; +import org.eclipse.debug.core.model.ILineBreakpoint; +import org.eclipse.debug.ui.actions.IToggleBreakpointsTargetExtension; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.texteditor.IDocumentProvider; +import org.eclipse.ui.texteditor.ITextEditor; + + +/** + * Adapter to create breakpoints in PDA files. + */ +public class PDABreakpointAdapter implements IToggleBreakpointsTargetExtension { + /* (non-Javadoc) + * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#toggleLineBreakpoints(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection) + */ + public void toggleLineBreakpoints(IWorkbenchPart part, ISelection selection) throws CoreException { + ITextEditor textEditor = getEditor(part); + if (textEditor != null) { + IResource resource = (IResource) textEditor.getEditorInput().getAdapter(IResource.class); + ITextSelection textSelection = (ITextSelection) selection; + int lineNumber = textSelection.getStartLine(); + IBreakpoint[] breakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints(PDAPlugin.ID_PDA_DEBUG_MODEL); + for (int i = 0; i < breakpoints.length; i++) { + IBreakpoint breakpoint = breakpoints[i]; + if (breakpoint instanceof ILineBreakpoint && resource.equals(breakpoint.getMarker().getResource())) { + if (((ILineBreakpoint)breakpoint).getLineNumber() == (lineNumber + 1)) { + // remove + breakpoint.delete(); + return; + } + } + } + // create line breakpoint (doc line numbers start at 0) + PDALineBreakpoint lineBreakpoint = new PDALineBreakpoint(resource, lineNumber + 1); + DebugPlugin.getDefault().getBreakpointManager().addBreakpoint(lineBreakpoint); + } + } + /* (non-Javadoc) + * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#canToggleLineBreakpoints(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection) + */ + public boolean canToggleLineBreakpoints(IWorkbenchPart part, ISelection selection) { + return getEditor(part) != null; + } + + /** + * Returns the editor being used to edit a PDA file, associated with the + * given part, or null if none. + * + * @param part workbench part + * @return the editor being used to edit a PDA file, associated with the + * given part, or null if none + */ + private ITextEditor getEditor(IWorkbenchPart part) { + if (part instanceof ITextEditor) { + ITextEditor editorPart = (ITextEditor) part; + IResource resource = (IResource) editorPart.getEditorInput().getAdapter(IResource.class); + if (resource != null) { + String extension = resource.getFileExtension(); + if (extension != null && extension.equals("pda")) { + return editorPart; + } + } + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#toggleMethodBreakpoints(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection) + */ + public void toggleMethodBreakpoints(IWorkbenchPart part, ISelection selection) throws CoreException { + } + /* (non-Javadoc) + * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#canToggleMethodBreakpoints(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection) + */ + public boolean canToggleMethodBreakpoints(IWorkbenchPart part, ISelection selection) { + return false; + } + /* (non-Javadoc) + * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#toggleWatchpoints(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection) + */ + public void toggleWatchpoints(IWorkbenchPart part, ISelection selection) throws CoreException { + String[] variableAndFunctionName = getVariableAndFunctionName(part, selection); + if (variableAndFunctionName != null && part instanceof ITextEditor && selection instanceof ITextSelection) { + ITextEditor editorPart = (ITextEditor)part; + int lineNumber = ((ITextSelection)selection).getStartLine(); + IResource resource = (IResource) editorPart.getEditorInput().getAdapter(IResource.class); + String var = variableAndFunctionName[0]; + String fcn = variableAndFunctionName[1]; + // look for existing watchpoint to delete + IBreakpoint[] breakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints(PDAPlugin.ID_PDA_DEBUG_MODEL); + for (int i = 0; i < breakpoints.length; i++) { + IBreakpoint breakpoint = breakpoints[i]; + if (breakpoint instanceof PDAWatchpoint && resource.equals(breakpoint.getMarker().getResource())) { + PDAWatchpoint watchpoint = (PDAWatchpoint)breakpoint; + String otherVar = watchpoint.getVariableName(); + String otherFcn = watchpoint.getFunctionName(); + if (otherVar.equals(var) && otherFcn.equals(fcn)) { + breakpoint.delete(); + return; + } + } + } + // create watchpoint + PDAWatchpoint watchpoint = new PDAWatchpoint(resource, lineNumber + 1, fcn, var, true, true); + DebugPlugin.getDefault().getBreakpointManager().addBreakpoint(watchpoint); + } + } + /* (non-Javadoc) + * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#canToggleWatchpoints(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection) + */ + public boolean canToggleWatchpoints(IWorkbenchPart part, ISelection selection) { + return getVariableAndFunctionName(part, selection) != null; + } + + /** + * Returns the variable and function names at the current line, or null if none. + * + * @param part text editor + * @param selection text selection + * @return the variable and function names at the current line, or null if none. + * The array has two elements, the first is the variable name, the second is the function name. + */ + private String[] getVariableAndFunctionName(IWorkbenchPart part, ISelection selection) { + ITextEditor editor = getEditor(part); + if (editor != null && selection instanceof ITextSelection) { + ITextSelection textSelection = (ITextSelection) selection; + IDocumentProvider documentProvider = editor.getDocumentProvider(); + try { + documentProvider.connect(this); + IDocument document = documentProvider.getDocument(editor.getEditorInput()); + IRegion region = document.getLineInformationOfOffset(textSelection.getOffset()); + String string = document.get(region.getOffset(), region.getLength()).trim(); + if (string.startsWith("var ")) { + String varName = string.substring(4).trim(); + String fcnName = getFunctionName(document, varName, document.getLineOfOffset(textSelection.getOffset())); + return new String[] {varName, fcnName}; + } + } catch (CoreException e) { + } catch (BadLocationException e) { + } finally { + documentProvider.disconnect(this); + } + } + return null; + } + + /** + * Returns the name of the function containing the given variable defined at the given + * line number in the specified document. + * + * @param document PDA source file + * @param varName variable name + * @param line line numbner at which the variable is defined + * @return name of function defining the variable + */ + private String getFunctionName(IDocument document, String varName, int line) { + // This is a simple guess at the function name - look for the labels preceeding + // the variable definition, and then see if there are any 'calls' to that + // label. If none, assumet the variable is in the "_main_" function + String source = document.get(); + int lineIndex = line - 1; + while (lineIndex >= 0) { + try { + IRegion information = document.getLineInformation(lineIndex); + String lineText = document.get(information.getOffset(), information.getLength()); + if (lineText.startsWith(":")) { + String label = lineText.substring(1); + if (source.indexOf("call " + label) >= 0) { + return label; + } + } + lineIndex--; + } catch (BadLocationException e) { + } + } + return "_main_"; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTargetExtension#toggleBreakpoints(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection) + */ + public void toggleBreakpoints(IWorkbenchPart part, ISelection selection) throws CoreException { + if (canToggleWatchpoints(part, selection)) { + toggleWatchpoints(part, selection); + } else { + toggleLineBreakpoints(part, selection); + } + } + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTargetExtension#canToggleBreakpoints(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection) + */ + public boolean canToggleBreakpoints(IWorkbenchPart part, ISelection selection) { + return canToggleLineBreakpoints(part, selection) || canToggleWatchpoints(part, selection); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/breakpoints/PDAEditorAdapterFactory.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/breakpoints/PDAEditorAdapterFactory.java new file mode 100644 index 00000000000..30d8c770a39 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/breakpoints/PDAEditorAdapterFactory.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2005, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Bjorn Freeman-Benson - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.ui.breakpoints; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IAdapterFactory; +import org.eclipse.dd.examples.pda.ui.editor.PDAEditor; +import org.eclipse.debug.ui.actions.IRunToLineTarget; +import org.eclipse.debug.ui.actions.IToggleBreakpointsTarget; +import org.eclipse.ui.texteditor.ITextEditor; + + +/** + * Creates a toggle breakpoint adapter + */ +public class PDAEditorAdapterFactory implements IAdapterFactory { + /* (non-Javadoc) + * @see org.eclipse.core.runtime.IAdapterFactory#getAdapter(java.lang.Object, java.lang.Class) + */ + public Object getAdapter(Object adaptableObject, Class adapterType) { + if (adaptableObject instanceof PDAEditor) { + ITextEditor editorPart = (ITextEditor) adaptableObject; + IResource resource = (IResource) editorPart.getEditorInput().getAdapter(IResource.class); + if (resource != null) { + String extension = resource.getFileExtension(); + if (extension != null && extension.equals("pda")) { + if (adapterType.equals(IToggleBreakpointsTarget.class)) { + return new PDABreakpointAdapter(); + } + //#ifdef ex7 +//# // TODO: Exercise 7 - create run to line adapter + //#else + if (adapterType.equals(IRunToLineTarget.class)) { + return new PDARunToLineAdapter(); + } + //#endif + } + } + } + return null; + } + /* (non-Javadoc) + * @see org.eclipse.core.runtime.IAdapterFactory#getAdapterList() + */ + public Class[] getAdapterList() { + return new Class[]{IToggleBreakpointsTarget.class}; + } +} diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/breakpoints/PDARunToLineAdapter.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/breakpoints/PDARunToLineAdapter.java new file mode 100644 index 00000000000..e73fbeeedab --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/breakpoints/PDARunToLineAdapter.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (c) 2005, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Bjorn Freeman-Benson - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.ui.breakpoints; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.dd.examples.pda.PDAPlugin; +import org.eclipse.dd.examples.pda.breakpoints.PDARunToLineBreakpoint; +import org.eclipse.debug.core.model.IBreakpoint; +import org.eclipse.debug.core.model.IDebugElement; +import org.eclipse.debug.core.model.IDebugTarget; +import org.eclipse.debug.core.model.ISuspendResume; +import org.eclipse.debug.ui.actions.IRunToLineTarget; +import org.eclipse.debug.ui.actions.RunToLineHandler; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.texteditor.ITextEditor; + + +/** + * Run to line target for the Java debugger + */ +public class PDARunToLineAdapter implements IRunToLineTarget { + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.actions.IRunToLineTarget#runToLine(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection, org.eclipse.debug.core.model.ISuspendResume) + */ + public void runToLine(IWorkbenchPart part, ISelection selection, ISuspendResume target) throws CoreException { + IEditorPart editorPart = (IEditorPart)part; + ITextEditor textEditor = (ITextEditor)editorPart; + ITextSelection textSelection = (ITextSelection) selection; + int lineNumber = textSelection.getStartLine() + 1; + if (lineNumber > 0) { + if (target instanceof IAdaptable) { + IDebugTarget debugTarget = (IDebugTarget) ((IAdaptable)target).getAdapter(IDebugTarget.class); + if (debugTarget != null) { + //#ifdef ex7 +//# // TODO: Exercise 7 - perform the run-to-line with a run-to-line breakpoint and handler + //#else + IFile resource = (IFile) textEditor.getEditorInput().getAdapter(IResource.class); + IBreakpoint breakpoint= new PDARunToLineBreakpoint(resource, lineNumber); + RunToLineHandler handler = new RunToLineHandler(debugTarget, target, breakpoint); + handler.run(new NullProgressMonitor()); + //#endif + } + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.actions.IRunToLineTarget#canRunToLine(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection, org.eclipse.debug.core.model.ISuspendResume) + */ + public boolean canRunToLine(IWorkbenchPart part, ISelection selection, ISuspendResume target) { + //#ifdef ex7 +//# // TODO: Exercise 7 - ensure the target is a PDA target +//# return false; + //#else + return target instanceof IDebugElement && + ((IDebugElement)target).getModelIdentifier().equals(PDAPlugin.ID_PDA_DEBUG_MODEL); + //#endif + } +} diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/AnnotationHover.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/AnnotationHover.java new file mode 100644 index 00000000000..0e76a9ca3f7 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/AnnotationHover.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2005, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Bjorn Freeman-Benson - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.ui.editor; + +import java.util.Iterator; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.source.Annotation; +import org.eclipse.jface.text.source.IAnnotationHover; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.jface.text.source.ISourceViewer; + +/** + * Returns hover for breakpoints. + */ +public class AnnotationHover implements IAnnotationHover { + + public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) { + IAnnotationModel annotationModel = sourceViewer.getAnnotationModel(); + Iterator iterator = annotationModel.getAnnotationIterator(); + while (iterator.hasNext()) { + Annotation annotation = (Annotation) iterator.next(); + Position position = annotationModel.getPosition(annotation); + try { + int lineOfAnnotation = sourceViewer.getDocument().getLineOfOffset(position.getOffset()); + if (lineNumber == lineOfAnnotation) { + return annotation.getText(); + } + } catch (BadLocationException e) { + } + } + return null; + } + +} diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAContentAssistProcessor.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAContentAssistProcessor.java new file mode 100644 index 00000000000..93519ba4680 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAContentAssistProcessor.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright (c) 2005, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Bjorn Freeman-Benson - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.ui.editor; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.contentassist.CompletionProposal; +import org.eclipse.jface.text.contentassist.ICompletionProposal; +import org.eclipse.jface.text.contentassist.IContentAssistProcessor; +import org.eclipse.jface.text.contentassist.IContextInformation; +import org.eclipse.jface.text.contentassist.IContextInformationValidator; + +public class PDAContentAssistProcessor implements IContentAssistProcessor { + + public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) { + int index = offset - 1; + StringBuffer prefix = new StringBuffer(); + IDocument document = viewer.getDocument(); + while (index > 0) { + try { + char prev = document.getChar(index); + if (Character.isWhitespace(prev)) { + break; + } + prefix.insert(0, prev); + index--; + } catch (BadLocationException e) { + } + } + + List proposals = new ArrayList(); + String[] keywords = PDAScanner.fgKeywords; + if (prefix.length() > 0) { + String word = prefix.toString(); + for (int i = 0; i < keywords.length; i++) { + String keyword = keywords[i]; + if (keyword.startsWith(word) && word.length() < keyword.length()) { + proposals.add(new CompletionProposal(keyword + " ", index + 1, offset - (index + 1), keyword.length() + 1)); + } + } + } else { + // propose all keywords + for (int i = 0; i < keywords.length; i++) { + String keyword = keywords[i]; + proposals.add(new CompletionProposal(keyword + " ", offset, 0, keyword.length() + 1)); + } + } + if (!proposals.isEmpty()) { + return (ICompletionProposal[]) proposals.toArray(new ICompletionProposal[proposals.size()]); + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeContextInformation(org.eclipse.jface.text.ITextViewer, int) + */ + public IContextInformation[] computeContextInformation(ITextViewer viewer, int offset) { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getCompletionProposalAutoActivationCharacters() + */ + public char[] getCompletionProposalAutoActivationCharacters() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getContextInformationAutoActivationCharacters() + */ + public char[] getContextInformationAutoActivationCharacters() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getErrorMessage() + */ + public String getErrorMessage() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getContextInformationValidator() + */ + public IContextInformationValidator getContextInformationValidator() { + return null; + } + +} diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAContentAssistant.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAContentAssistant.java new file mode 100644 index 00000000000..00d991204b5 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAContentAssistant.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2005, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Bjorn Freeman-Benson - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.ui.editor; + +import org.eclipse.jface.text.DefaultInformationControl; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IInformationControl; +import org.eclipse.jface.text.IInformationControlCreator; +import org.eclipse.jface.text.contentassist.ContentAssistant; +import org.eclipse.swt.widgets.Shell; + +public class PDAContentAssistant extends ContentAssistant { + + public PDAContentAssistant() { + super(); + + PDAContentAssistProcessor processor= new PDAContentAssistProcessor(); + setContentAssistProcessor(processor, IDocument.DEFAULT_CONTENT_TYPE); + + enableAutoActivation(false); + enableAutoInsert(false); + + setInformationControlCreator(getInformationControlCreator()); + } + + private IInformationControlCreator getInformationControlCreator() { + return new IInformationControlCreator() { + public IInformationControl createInformationControl(Shell parent) { + return new DefaultInformationControl(parent); + } + }; + } +} diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAEditor.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAEditor.java new file mode 100644 index 00000000000..c40a80b516c --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAEditor.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2005, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Bjorn Freeman-Benson - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.ui.editor; + +import java.util.ResourceBundle; + +import org.eclipse.jface.action.IAction; +import org.eclipse.ui.texteditor.AbstractDecoratedTextEditor; +import org.eclipse.ui.texteditor.ContentAssistAction; +import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds; + +/** + * PDA editor + */ +public class PDAEditor extends AbstractDecoratedTextEditor { + + /** + * Creates a PDE editor + */ + public PDAEditor() { + super(); + setSourceViewerConfiguration(new PDASourceViewerConfiguration()); + setRulerContextMenuId("pda.editor.rulerMenu"); + setEditorContextMenuId("pda.editor.editorMenu"); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.AbstractTextEditor#createActions() + */ + protected void createActions() { + super.createActions(); + ResourceBundle bundle = ResourceBundle.getBundle("org.eclipse.dd.examples.pda.ui.editor.PDAEditorMessages"); //$NON-NLS-1$ + IAction action = new ContentAssistAction(bundle, "ContentAssistProposal.", this); //$NON-NLS-1$ + action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS); + setAction("ContentAssistProposal", action); //$NON-NLS-1$ + } + + +} diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAEditorMessages.properties b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAEditorMessages.properties new file mode 100644 index 00000000000..3215e8892de --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAEditorMessages.properties @@ -0,0 +1,15 @@ +############################################################################### +# Copyright (c) 2000, 2007 IBM Corporation and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# IBM Corporation - initial API and implementation +############################################################################### + +ContentAssistProposal.label=Content &Assist +ContentAssistProposal.tooltip=Content Assist +ContentAssistProposal.image= +ContentAssistProposal.description=Content Assist \ No newline at end of file diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAScanner.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAScanner.java new file mode 100644 index 00000000000..b1b1e067893 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAScanner.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 2005, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Bjorn Freeman-Benson - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.ui.editor; + +import org.eclipse.dd.examples.pda.ui.PDAUIPlugin; +import org.eclipse.jface.text.TextAttribute; +import org.eclipse.jface.text.rules.BufferedRuleBasedScanner; +import org.eclipse.jface.text.rules.IRule; +import org.eclipse.jface.text.rules.IWordDetector; +import org.eclipse.jface.text.rules.Token; +import org.eclipse.jface.text.rules.WordRule; + + +/** + * PDA editor keyword scanner. + */ +public class PDAScanner extends BufferedRuleBasedScanner { + + /** + * PDA keywods + */ + public static final String[] fgKeywords = new String[] { + "add", "branch_not_zero", "call", "dec", "dup", + "halt", "output", "pop", "push", "return", "var" + }; + + /** + * Detects potential keywords + */ + class PDAWordDetector implements IWordDetector { + + /* (non-Javadoc) + * @see org.eclipse.jface.text.rules.IWordDetector#isWordStart(char) + */ + public boolean isWordStart(char c) { + return Character.isLetter(c); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.rules.IWordDetector#isWordPart(char) + */ + public boolean isWordPart(char c) { + return Character.isLetter(c) || c == '_'; + } + } + + /** + * Detects PDA branch labels + */ + class PDALabelDetector extends PDAWordDetector { + + /* (non-Javadoc) + * @see org.eclipse.jface.text.rules.IWordDetector#isWordStart(char) + */ + public boolean isWordStart(char c) { + return c == ':'; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.rules.IWordDetector#isWordPart(char) + */ + public boolean isWordPart(char c) { + return super.isWordPart(c) || Character.isDigit(c); + } + } + + /** + * Constructs a scanner that identifies PDA keywords. + */ + public PDAScanner() { + // keywords + Token token = new Token(new TextAttribute(PDAUIPlugin.getDefault().getColor(PDAUIPlugin.KEYWORD))); + WordRule keywords = new WordRule(new PDAWordDetector()); + for (int i = 0; i < fgKeywords.length; i++) { + String keyword = fgKeywords[i]; + keywords.addWord(keyword, token); + } + // labels + token = new Token(new TextAttribute(PDAUIPlugin.getDefault().getColor(PDAUIPlugin.LABEL))); + WordRule labels = new WordRule(new PDALabelDetector(), token); + setRules(new IRule[]{keywords, labels}); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDASourceViewerConfiguration.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDASourceViewerConfiguration.java new file mode 100644 index 00000000000..f0b873eac44 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDASourceViewerConfiguration.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (c) 2005, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Bjorn Freeman-Benson - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.ui.editor; + +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITextHover; +import org.eclipse.jface.text.contentassist.IContentAssistant; +import org.eclipse.jface.text.presentation.IPresentationReconciler; +import org.eclipse.jface.text.presentation.PresentationReconciler; +import org.eclipse.jface.text.rules.DefaultDamagerRepairer; +import org.eclipse.jface.text.source.IAnnotationHover; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.ui.editors.text.TextSourceViewerConfiguration; + +/** + * Source view configuration for the PDA editor + */ +public class PDASourceViewerConfiguration extends TextSourceViewerConfiguration { + + /* (non-Javadoc) + * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getTextHover(org.eclipse.jface.text.source.ISourceViewer, java.lang.String) + */ + public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) { + return new TextHover(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getAnnotationHover(org.eclipse.jface.text.source.ISourceViewer) + */ + public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) { + return new AnnotationHover(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getPresentationReconciler(org.eclipse.jface.text.source.ISourceViewer) + */ + public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) { + PresentationReconciler reconciler = new PresentationReconciler(); + reconciler.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer)); + DefaultDamagerRepairer dr = new DefaultDamagerRepairer(new PDAScanner()); + reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE); + reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE); + return reconciler; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getContentAssistant(org.eclipse.jface.text.source.ISourceViewer) + */ + public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) { + return new PDAContentAssistant(); + } + + +} diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PopFrameActionDelegate.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PopFrameActionDelegate.java new file mode 100644 index 00000000000..d9250db2bb4 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PopFrameActionDelegate.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2005, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Bjorn Freeman-Benson - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.ui.editor; + +import org.eclipse.debug.core.DebugException; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.widgets.Event; +import org.eclipse.ui.IActionDelegate2; +import org.eclipse.ui.IObjectActionDelegate; +import org.eclipse.ui.IWorkbenchPart; + + +public class PopFrameActionDelegate implements IObjectActionDelegate, IActionDelegate2 { + + //private PDAThread fThread = null; + + /* (non-Javadoc) + * @see org.eclipse.ui.IObjectActionDelegate#setActivePart(org.eclipse.jface.action.IAction, org.eclipse.ui.IWorkbenchPart) + */ + public void setActivePart(IAction action, IWorkbenchPart targetPart) { + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction) + */ + public void run(IAction action) { + /* + try { + fThread.pop(); + } catch (DebugException e) { + }*/ + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection) + */ + public void selectionChanged(IAction action, ISelection selection) { + /* if (selection instanceof IStructuredSelection) { + IStructuredSelection ss = (IStructuredSelection) selection; + Object element = ss.getFirstElement(); + if (element instanceof PDAStackFrame) { + PDAStackFrame frame = (PDAStackFrame) element; + //#ifdef ex5 +//# // TODO: Exercise 5 - enable the action if the frame's thread supports it + //#else + fThread = (PDAThread) frame.getThread(); + try { + action.setEnabled(fThread.canPop() && fThread.getTopStackFrame().equals(frame)); + } catch (DebugException e) { + } + return; + //#endif + } + + } + action.setEnabled(false); + */ + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IActionDelegate2#init(org.eclipse.jface.action.IAction) + */ + public void init(IAction action) { + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IActionDelegate2#dispose() + */ + public void dispose() { + //fThread = null; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IActionDelegate2#runWithEvent(org.eclipse.jface.action.IAction, org.eclipse.swt.widgets.Event) + */ + public void runWithEvent(IAction action, Event event) { + run(action); + } + +} diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/TextHover.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/TextHover.java new file mode 100644 index 00000000000..5874463e207 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/TextHover.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (c) 2005, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Bjorn Freeman-Benson - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.ui.editor; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.model.IThread; +import org.eclipse.debug.core.model.IVariable; +import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextHover; +import org.eclipse.jface.text.ITextViewer; + + +/** + * Produces debug hover for the PDA debugger. + */ +public class TextHover implements ITextHover { + + /* (non-Javadoc) + * @see org.eclipse.jface.text.ITextHover#getHoverInfo(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion) + */ + public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) { + /*String varName = null; + try { + varName = textViewer.getDocument().get(hoverRegion.getOffset(), hoverRegion.getLength()); + } catch (BadLocationException e) { + return null; + } + if (varName.startsWith("$") && varName.length() > 1) { + varName = varName.substring(1); + } + + PDAStackFrame frame = null; + IAdaptable debugContext = DebugUITools.getDebugContext(); + if (debugContext instanceof PDAStackFrame) { + frame = (PDAStackFrame) debugContext; + } else if (debugContext instanceof PDAThread) { + PDAThread thread = (PDAThread) debugContext; + try { + frame = (PDAStackFrame) thread.getTopStackFrame(); + } catch (DebugException e) { + return null; + } + } else if (debugContext instanceof PDADebugTarget) { + PDADebugTarget target = (PDADebugTarget) debugContext; + try { + IThread[] threads = target.getThreads(); + if (threads.length > 0) { + frame = (PDAStackFrame) threads[0].getTopStackFrame(); + } + } catch (DebugException e) { + return null; + } + } + if (frame != null) { + try { + IVariable[] variables = frame.getVariables(); + for (int i = 0; i < variables.length; i++) { + IVariable variable = variables[i]; + if (variable.getName().equals(varName)) { + return varName + " = " + variable.getValue().getValueString(); + } + } + } catch (DebugException e) { + } + }*/ + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.ITextHover#getHoverRegion(org.eclipse.jface.text.ITextViewer, int) + */ + public IRegion getHoverRegion(ITextViewer textViewer, int offset) { + return WordFinder.findWord(textViewer.getDocument(), offset); + } + +} diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/WordFinder.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/WordFinder.java new file mode 100644 index 00000000000..12cd611be11 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/WordFinder.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2005, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Bjorn Freeman-Benson - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.ui.editor; + + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.Region; + +/** + * Looks for an identifier in a source file + */ +public class WordFinder { + + /** + * Returns the region in the given document that contains an identifier, or + * null if none. + * + * @param document document to search + * @param offset offset at which to look for an identifier + * @return region containing an identifier, or null + */ + public static IRegion findWord(IDocument document, int offset) { + + int start= -1; + int end= -1; + + + try { + + int pos= offset; + char c; + + while (pos >= 0) { + c= document.getChar(pos); + if (!Character.isJavaIdentifierPart(c)) + break; + --pos; + } + + start= pos; + + pos= offset; + int length= document.getLength(); + + while (pos < length) { + c= document.getChar(pos); + if (!Character.isJavaIdentifierPart(c)) + break; + ++pos; + } + + end= pos; + + } catch (BadLocationException x) { + } + + if (start > -1 && end > -1) { + if (start == offset && end == offset) + return new Region(offset, 0); + else if (start == offset) + return new Region(start, end - start); + else + return new Region(start + 1, end - start - 1); + } + + return null; + } +} diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/launcher/PDALaunchShortcut.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/launcher/PDALaunchShortcut.java new file mode 100644 index 00000000000..2e295858be8 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/launcher/PDALaunchShortcut.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2005, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Bjorn Freeman-Benson - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.ui.launcher; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.dd.examples.pda.PDAPlugin; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchConfigurationType; +import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; +import org.eclipse.debug.core.ILaunchManager; +import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.debug.ui.ILaunchShortcut; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IEditorPart; + + +/** + * Launches a PDA file + */ +public class PDALaunchShortcut implements ILaunchShortcut { + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.ILaunchShortcut#launch(org.eclipse.jface.viewers.ISelection, java.lang.String) + */ + public void launch(ISelection selection, String mode) { + // must be a structured selection with one file selected + IFile file = (IFile) ((IStructuredSelection)selection).getFirstElement(); + + // check for an existing launch config for the pda file + String path = file.getFullPath().toString(); + ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager(); + ILaunchConfigurationType type = launchManager.getLaunchConfigurationType(PDAPlugin.ID_PDA_LAUNCH_CONFIGURATION_TYPE); + try { + ILaunchConfiguration[] configurations = launchManager.getLaunchConfigurations(type); + for (int i = 0; i < configurations.length; i++) { + ILaunchConfiguration configuration = configurations[i]; + String attribute = configuration.getAttribute(PDAPlugin.ATTR_PDA_PROGRAM, (String)null); + if (path.equals(attribute)) { + DebugUITools.launch(configuration, mode); + return; + } + } + } catch (CoreException e) { + return; + } + + try { + // create a new configuration for the pda file + ILaunchConfigurationWorkingCopy workingCopy = type.newInstance(null, file.getName()); + workingCopy.setAttribute(PDAPlugin.ATTR_PDA_PROGRAM, path); + ILaunchConfiguration configuration = workingCopy.doSave(); + DebugUITools.launch(configuration, mode); + } catch (CoreException e1) { + } + } + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.ILaunchShortcut#launch(org.eclipse.ui.IEditorPart, java.lang.String) + */ + public void launch(IEditorPart editor, String mode) { + } + +} diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/launcher/PDAMainTab.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/launcher/PDAMainTab.java new file mode 100644 index 00000000000..2770df962da --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/launcher/PDAMainTab.java @@ -0,0 +1,185 @@ +/******************************************************************************* + * Copyright (c) 2005, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Bjorn Freeman-Benson - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.ui.launcher; + + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.dd.examples.pda.PDAPlugin; +import org.eclipse.dd.examples.pda.ui.PDAUIPlugin; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; +import org.eclipse.debug.ui.AbstractLaunchConfigurationTab; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.dialogs.ResourceListSelectionDialog; + + +/** + * Tab to specify the PDA program to run/debug. + */ +public class PDAMainTab extends AbstractLaunchConfigurationTab { + + private Text fProgramText; + private Button fProgramButton; + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.ILaunchConfigurationTab#createControl(org.eclipse.swt.widgets.Composite) + */ + public void createControl(Composite parent) { + Font font = parent.getFont(); + + Composite comp = new Composite(parent, SWT.NONE); + setControl(comp); + GridLayout topLayout = new GridLayout(); + topLayout.verticalSpacing = 0; + topLayout.numColumns = 3; + comp.setLayout(topLayout); + comp.setFont(font); + + createVerticalSpacer(comp, 3); + + Label programLabel = new Label(comp, SWT.NONE); + programLabel.setText("&Program:"); + GridData gd = new GridData(GridData.BEGINNING); + programLabel.setLayoutData(gd); + programLabel.setFont(font); + + fProgramText = new Text(comp, SWT.SINGLE | SWT.BORDER); + gd = new GridData(GridData.FILL_HORIZONTAL); + fProgramText.setLayoutData(gd); + fProgramText.setFont(font); + fProgramText.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + updateLaunchConfigurationDialog(); + } + }); + + fProgramButton = createPushButton(comp, "&Browse...", null); //$NON-NLS-1$ + fProgramButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + browsePDAFiles(); + } + }); + } + + /** + * Open a resource chooser to select a PDA program + */ + protected void browsePDAFiles() { + ResourceListSelectionDialog dialog = new ResourceListSelectionDialog(getShell(), ResourcesPlugin.getWorkspace().getRoot(), IResource.FILE); + dialog.setTitle("PDA Program"); + dialog.setMessage("Select PDA Program"); + if (dialog.open() == Window.OK) { + Object[] files = dialog.getResult(); + IFile file = (IFile) files[0]; + fProgramText.setText(file.getFullPath().toString()); + } + + } + /* (non-Javadoc) + * @see org.eclipse.debug.ui.ILaunchConfigurationTab#setDefaults(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy) + */ + public void setDefaults(ILaunchConfigurationWorkingCopy configuration) { + } + /* (non-Javadoc) + * @see org.eclipse.debug.ui.ILaunchConfigurationTab#initializeFrom(org.eclipse.debug.core.ILaunchConfiguration) + */ + public void initializeFrom(ILaunchConfiguration configuration) { + //#ifdef ex1 +//# // TODO: Exercise 1 - retrieve the program path attribute from the launch configuration +//# String program = null; +//# if (program != null) { +//# fProgramText.setText(program); +//# } + //#else + try { + String program = null; + program = configuration.getAttribute(PDAPlugin.ATTR_PDA_PROGRAM, (String)null); + if (program != null) { + fProgramText.setText(program); + } + } catch (CoreException e) { + setErrorMessage(e.getMessage()); + } + //#endif + } + /* (non-Javadoc) + * @see org.eclipse.debug.ui.ILaunchConfigurationTab#performApply(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy) + */ + public void performApply(ILaunchConfigurationWorkingCopy configuration) { + String program = fProgramText.getText().trim(); + if (program.length() == 0) { + program = null; + } + //#ifdef ex1 +//# // TODO: Exercise 1 - update the launch configuration with the path to +//# // currently specified program + //#else + configuration.setAttribute(PDAPlugin.ATTR_PDA_PROGRAM, program); + //#endif + } + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getName() + */ + public String getName() { + return "Main"; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.ILaunchConfigurationTab#isValid(org.eclipse.debug.core.ILaunchConfiguration) + */ + public boolean isValid(ILaunchConfiguration launchConfig) { + setErrorMessage(null); + setMessage(null); + String text = fProgramText.getText(); + //#ifdef ex1 +//# // TODO: Exercise 1 - validate the currently specified program exists and is not +//# // empty, providing the user with feedback. + //#else + if (text.length() > 0) { + IPath path = new Path(text); + if (ResourcesPlugin.getWorkspace().getRoot().findMember(path) == null) { + setErrorMessage("Specified program does not exist"); + return false; + } + } else { + setMessage("Specify a program"); + } + //#endif + return true; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getImage() + */ + public Image getImage() { + return PDAUIPlugin.getDefault().getImageRegistry().get(PDAUIPlugin.IMG_OBJ_PDA); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/launcher/PDATabGroup.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/launcher/PDATabGroup.java new file mode 100644 index 00000000000..5df54b6f66d --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/launcher/PDATabGroup.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2005, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Bjorn Freeman-Benson - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.ui.launcher; + +import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup; +import org.eclipse.debug.ui.CommonTab; +import org.eclipse.debug.ui.ILaunchConfigurationDialog; +import org.eclipse.debug.ui.ILaunchConfigurationTab; +import org.eclipse.debug.ui.sourcelookup.SourceLookupTab; + +/** + * Tab group for a PDA application + */ +public class PDATabGroup extends AbstractLaunchConfigurationTabGroup { + /* (non-Javadoc) + * @see org.eclipse.debug.ui.ILaunchConfigurationTabGroup#createTabs(org.eclipse.debug.ui.ILaunchConfigurationDialog, java.lang.String) + */ + public void createTabs(ILaunchConfigurationDialog dialog, String mode) { + //#ifdef ex1 +//# // TODO: Exercise 1 - add the PDA main tab, source lookup tab and common +//# // tab to the tab group + //#else + setTabs(new ILaunchConfigurationTab[] { + new PDAMainTab(), + new SourceLookupTab(), + new CommonTab() + }); + //#endif + } +} diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java new file mode 100644 index 00000000000..ac1adb19cc3 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * 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.examples.pda.ui.viewmodel; + +import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.ExpressionVMProvider; +import org.eclipse.dd.dsf.debug.ui.viewmodel.modules.ModulesVMProvider; +import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterVMProvider; +import org.eclipse.dd.dsf.debug.ui.viewmodel.variable.VariableVMProvider; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMAdapter; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; +import org.eclipse.dd.examples.pda.ui.viewmodel.launch.LaunchVMProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.ui.IDebugUIConstants; + +/* + * + */ +@ThreadSafe +@SuppressWarnings("restriction") +public class PDAVMAdapter extends AbstractDMVMAdapter +{ + public PDAVMAdapter(DsfSession session) { + super(session); + getSession().registerModelAdapter(IColumnPresentationFactory.class, this); + } + + @Override + public void dispose() { + getSession().unregisterModelAdapter(IColumnPresentationFactory.class); + super.dispose(); + } + + @Override + protected AbstractDMVMProvider createViewModelProvider(IPresentationContext context) { + if ( IDebugUIConstants.ID_DEBUG_VIEW.equals(context.getId()) ) { + return new LaunchVMProvider(this, context, getSession()); + } else if (IDebugUIConstants.ID_VARIABLE_VIEW.equals(context.getId()) ) { + return new VariableVMProvider(this, context, getSession()); + } else if (IDebugUIConstants.ID_REGISTER_VIEW.equals(context.getId()) ) { + return new RegisterVMProvider(this, context, getSession()); + } else if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(context.getId()) ) { + return new ExpressionVMProvider(this, context, getSession()); + } + return null; + } +} diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/LaunchVMProvider.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/LaunchVMProvider.java new file mode 100644 index 00000000000..2990aa9d968 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/LaunchVMProvider.java @@ -0,0 +1,126 @@ +/******************************************************************************* + * 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 + * Ericsson - Modified for new functionality + *******************************************************************************/ +package org.eclipse.dd.examples.pda.ui.viewmodel.launch; + +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.LaunchRootVMNode; +import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.StackFramesVMNode; +import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.StandardProcessVMNode; +import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.LaunchRootVMNode.LaunchesEvent; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; +import org.eclipse.dd.dsf.ui.viewmodel.IRootVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.IVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; +import org.eclipse.debug.core.DebugEvent; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.IDebugEventSetListener; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.ILaunchesListener2; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; + + +/** + * + */ +@SuppressWarnings("restriction") +public class LaunchVMProvider extends AbstractDMVMProvider + implements IDebugEventSetListener, ILaunchesListener2 +{ + @ThreadSafe + public LaunchVMProvider(AbstractVMAdapter adapter, IPresentationContext presentationContext, DsfSession session) + { + super(adapter, presentationContext, session); + + IRootVMNode launchNode = new LaunchRootVMNode(this); + setRootNode(launchNode); + + // Container node to contain all processes and threads + IVMNode threadsNode = new ThreadVMNode(this, getSession()); + IVMNode processesNode = new StandardProcessVMNode(this); + addChildNodes(launchNode, new IVMNode[] { threadsNode, processesNode}); + + IVMNode stackFramesNode = new StackFramesVMNode(this, getSession()); + addChildNodes(threadsNode, new IVMNode[] { stackFramesNode }); + + + DebugPlugin.getDefault().addDebugEventListener(this); + DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this); + } + + + public void handleDebugEvents(final DebugEvent[] events) { + if (isDisposed()) return; + + // We're in session's executor thread. Re-dispach to VM Adapter + // executor thread and then call root layout node. + try { + getExecutor().execute(new Runnable() { + public void run() { + if (isDisposed()) return; + + for (final DebugEvent event : events) { + handleEvent(event); + } + }}); + } catch (RejectedExecutionException e) { + // Ignore. This exception could be thrown if the provider is being + // shut down. + } + } + + @Override + public void dispose() { + DebugPlugin.getDefault().removeDebugEventListener(this); + DebugPlugin.getDefault().getLaunchManager().removeLaunchListener(this); + super.dispose(); + } + + public void launchesAdded(ILaunch[] launches) { + handleLaunchesEvent(new LaunchesEvent(launches, LaunchesEvent.Type.ADDED)); + } + + public void launchesRemoved(ILaunch[] launches) { + handleLaunchesEvent(new LaunchesEvent(launches, LaunchesEvent.Type.REMOVED)); + } + + public void launchesChanged(ILaunch[] launches) { + handleLaunchesEvent(new LaunchesEvent(launches, LaunchesEvent.Type.CHANGED)); + } + + public void launchesTerminated(ILaunch[] launches) { + handleLaunchesEvent(new LaunchesEvent(launches, LaunchesEvent.Type.TERMINATED)); + } + + private void handleLaunchesEvent(final LaunchesEvent event) { + if (isDisposed()) return; + + // We're in session's executor thread. Re-dispach to VM Adapter + // executor thread and then call root layout node. + try { + getExecutor().execute(new Runnable() { + public void run() { + if (isDisposed()) return; + + IRootVMNode rootLayoutNode = getRootVMNode(); + if (rootLayoutNode != null && rootLayoutNode.getDeltaFlags(event) != 0) { + handleEvent(event); + } + }}); + } catch (RejectedExecutionException e) { + // Ignore. This exception could be thrown if the provider is being + // shut down. + } + } +} diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/ThreadVMNode.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/ThreadVMNode.java new file mode 100644 index 00000000000..a044c1e09a6 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/ThreadVMNode.java @@ -0,0 +1,247 @@ +/******************************************************************************* + * 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 + * Ericsson - Modified for multi threaded functionality + *******************************************************************************/ +package org.eclipse.dd.examples.pda.ui.viewmodel.launch; + +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.datamodel.IDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerResumedDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerSuspendedDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMData; +import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.IVMAdapter; +import org.eclipse.dd.dsf.ui.viewmodel.IVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; +import org.eclipse.dd.examples.pda.PDAPlugin; +import org.eclipse.dd.examples.pda.launch.PDALaunch; +import org.eclipse.dd.examples.pda.service.command.PDACommandControl; +import org.eclipse.dd.examples.pda.service.command.PDAStartedEvent; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; +import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.debug.ui.IDebugUIConstants; +import org.eclipse.jface.viewers.TreePath; + + +@SuppressWarnings("restriction") +public class ThreadVMNode extends AbstractDMVMNode + implements IElementLabelProvider +{ + private class TerminatedThreadVMContext extends AbstractVMContext { + TerminatedThreadVMContext(IVMAdapter adapter, IVMNode node) { + super(adapter, node); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof TerminatedThreadVMContext) { + TerminatedThreadVMContext context = (TerminatedThreadVMContext)obj; + return getVMNode().equals(context.getVMNode()); + } + return false; + } + + @Override + public int hashCode() { + return getVMNode().hashCode(); + } + } + + public ThreadVMNode(AbstractDMVMProvider provider, DsfSession session) { + super(provider, session, IExecutionDMContext.class); + } + + @Override + public void update(IHasChildrenUpdate[] updates) { + for (IHasChildrenUpdate update : updates) { + update.setHasChilren(true); + update.done(); + } + } + + @Override + public void update(IChildrenCountUpdate[] updates) { + for (IChildrenCountUpdate update : updates) { + update.setChildCount(1); + update.done(); + } + } + + @Override + public void update(IChildrenUpdate[] updates) { + for (IChildrenUpdate update : updates) { + PDALaunch launch = findLaunchInPath(update.getElementPath()); + if (launch != null && launch.isInitialized() && launch.isShutDown()) { + // If the debug session has been shut down. We cannot retrieve the + // DM context representing the thread. Instead add a dummy + // "terminated" PDA thread. + update.setChild(new TerminatedThreadVMContext(getVMProvider().getVMAdapter(), this), 0); + update.done(); + } else { + super.update(new IChildrenUpdate[] { update }); + } + } + } + + @Override + protected void updateElementsInSessionThread(final IChildrenUpdate update) { + if (!checkService(PDACommandControl.class, null, update)) return; + final PDACommandControl commandControl = getServicesTracker().getService(PDACommandControl.class); + + update.setChild(createVMContext(commandControl.getDMContext()), 0); + update.done(); + } + + public void update(final ILabelUpdate[] updates) { + for (final ILabelUpdate update : updates) { + if (update.getElement() instanceof TerminatedThreadVMContext) { + updateTerminatedThreadLabel(update); + } else { + try { + getSession().getExecutor().execute(new DsfRunnable() { + public void run() { + updateActiveThreadLabelInSessionThread(update); + }}); + } catch (RejectedExecutionException e) { + handleFailedUpdate(update); + } + } + } + } + + @ConfinedToDsfExecutor("getSession().getExecutor()") + private void updateActiveThreadLabelInSessionThread(final ILabelUpdate update) { + if (!checkService(IRunControl.class, null, update)) return; + final IRunControl runControl = getServicesTracker().getService(IRunControl.class); + + final IExecutionDMContext dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IExecutionDMContext.class); + + String imageKey = null; + if (getServicesTracker().getService(IRunControl.class).isSuspended(dmc)) { + imageKey = IDebugUIConstants.IMG_OBJS_THREAD_SUSPENDED; + } else { + imageKey = IDebugUIConstants.IMG_OBJS_THREAD_RUNNING; + } + update.setImageDescriptor(DebugUITools.getImageDescriptor(imageKey), 0); + + final boolean isSuspended = runControl.isSuspended(dmc); + + // Find the Reason for the State + runControl.getExecutionData(dmc, + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + public void handleCompleted(){ + if (!getStatus().isOK()) { + handleFailedUpdate(update); + return; + } + + final StringBuilder builder = new StringBuilder(); + + builder.append("PDA ["); + builder.append(getProgramName(update)); + builder.append("]"); + + if(isSuspended) { + builder.append(" (Suspended"); + } else { + builder.append(" (Running"); + } + // Reason will be null before ContainerSuspendEvent is fired + if(getData().getStateChangeReason() != null) { + builder.append(" : "); + builder.append(getData().getStateChangeReason()); + } + builder.append(")"); + update.setLabel(builder.toString(), 0); + update.done(); + } + }); + } + + private void updateTerminatedThreadLabel(ILabelUpdate update) { + update.setLabel(" PDA [" + getProgramName(update) + "]", 0); + update.setImageDescriptor(DebugUITools.getImageDescriptor(IDebugUIConstants.IMG_OBJS_DEBUG_TARGET_TERMINATED), 0); + update.done(); + } + + private String getProgramName(IViewerUpdate update) { + String program = "unknown program"; + ILaunch launch = findLaunchInPath(update.getElementPath()); + if (launch != null) { + try { + program = launch.getLaunchConfiguration().getAttribute(PDAPlugin.ATTR_PDA_PROGRAM, program); + } catch (CoreException e) { + // Ignore, label will revert to default. + } + } + return program; + } + + private PDALaunch findLaunchInPath(TreePath path) { + for (int i = 0; i < path.getSegmentCount(); i++) { + if (path.getSegment(i) instanceof PDALaunch) { + return (PDALaunch)path.getSegment(i); + } + } + return null; + } + + public int getDeltaFlags(Object e) { + if(e instanceof IResumedDMEvent || e instanceof ISuspendedDMEvent) { + return IModelDelta.CONTENT; + } + if (e instanceof PDAStartedEvent) { + return IModelDelta.EXPAND; + } + return IModelDelta.NO_CHANGE; + } + + public void buildDelta(Object e, VMDelta parentDelta, int nodeOffset, RequestMonitor rm) { + if(e instanceof IContainerResumedDMEvent) { + IDMContext triggeringContext = ((IContainerResumedDMEvent)e).getTriggeringContext(); + if (triggeringContext != null) { + parentDelta.addNode(createVMContext(triggeringContext), IModelDelta.CONTENT); + } + } else if (e instanceof IContainerSuspendedDMEvent) { + IDMContext triggeringContext = ((IContainerSuspendedDMEvent)e).getTriggeringContext(); + if (triggeringContext != null) { + parentDelta.addNode(createVMContext(triggeringContext), IModelDelta.CONTENT); + } + } else if(e instanceof IResumedDMEvent || e instanceof ISuspendedDMEvent) { + parentDelta.addNode(createVMContext(((IDMEvent)e).getDMContext()), IModelDelta.CONTENT); + } + if (e instanceof PDAStartedEvent) { + parentDelta.addNode(createVMContext(((PDAStartedEvent)e).getDMContext()), IModelDelta.EXPAND); + } + rm.done(); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/.classpath b/plugins/org.eclipse.dd.examples.pda/.classpath new file mode 100644 index 00000000000..b7464f3ca24 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/plugins/org.eclipse.dd.examples.pda/.cvsignore b/plugins/org.eclipse.dd.examples.pda/.cvsignore new file mode 100644 index 00000000000..ba077a4031a --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/.cvsignore @@ -0,0 +1 @@ +bin diff --git a/plugins/org.eclipse.dd.examples.pda/.options b/plugins/org.eclipse.dd.examples.pda/.options new file mode 100755 index 00000000000..247d1d7bcff --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/.options @@ -0,0 +1 @@ +org.eclipse.dd.examples.pda/debug = false diff --git a/plugins/org.eclipse.dd.examples.pda/.project b/plugins/org.eclipse.dd.examples.pda/.project new file mode 100644 index 00000000000..203e92857d8 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/.project @@ -0,0 +1,28 @@ + + + org.eclipse.dd.examples.pda + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/plugins/org.eclipse.dd.examples.pda/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.dd.examples.pda/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000000..d43d1a3d99c --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,69 @@ +#Mon Jan 21 09:21:02 PST 2008 +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.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=warning +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore +org.eclipse.jdt.core.compiler.problem.nullReference=ignore +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning +org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore +org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=error +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/plugins/org.eclipse.dd.examples.pda/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.examples.pda/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..9be4b200732 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/META-INF/MANIFEST.MF @@ -0,0 +1,20 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: PDA Example Device Debugging Core Plug-in +Bundle-SymbolicName: org.eclipse.dd.examples.pda;singleton:=true +Bundle-Version: 1.0.0 +Bundle-Activator: org.eclipse.dd.examples.pda.PDAPlugin +Require-Bundle: org.eclipse.core.runtime, + org.eclipse.core.resources, + org.eclipse.core.variables, + org.eclipse.debug.core, + org.eclipse.dd.dsf;bundle-version="1.0.0", + org.eclipse.dd.dsf.debug;bundle-version="1.0.0", + org.junit4;bundle-version="4.3.1" +Eclipse-LazyStart: true +Export-Package: org.eclipse.dd.examples.pda, + org.eclipse.dd.examples.pda.breakpoints, + org.eclipse.dd.examples.pda.launch, + org.eclipse.dd.examples.pda.service.command, + org.eclipse.debug.examples.core.pda.sourcelookup +Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/plugins/org.eclipse.dd.examples.pda/about.html b/plugins/org.eclipse.dd.examples.pda/about.html new file mode 100644 index 00000000000..460233046ee --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/about.html @@ -0,0 +1,28 @@ + + + + +About + + +

    About This Content

    + +

    June 2, 2006

    +

    License

    + +

    The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at http://www.eclipse.org/legal/epl-v10.html. +For purposes of the EPL, "Program" will mean the Content.

    + +

    If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at http://www.eclipse.org.

    + + + \ No newline at end of file diff --git a/plugins/org.eclipse.dd.examples.pda/build.properties b/plugins/org.eclipse.dd.examples.pda/build.properties new file mode 100644 index 00000000000..f50444bad7c --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/build.properties @@ -0,0 +1,21 @@ +############################################################################### +# Copyright (c) 2005, 2007 IBM Corporation and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# IBM Corporation - initial API and implementation +############################################################################### +source.. = src/ +output.. = bin/ +bin.includes = plugin.xml,\ + pdavm/,\ + META-INF/,\ + about.html,\ + .,\ + readme.html,\ + samples/ +src.includes = about.html,\ + src/ diff --git a/plugins/org.eclipse.dd.examples.pda/pdavm/docs/protocol.html b/plugins/org.eclipse.dd.examples.pda/pdavm/docs/protocol.html new file mode 100644 index 00000000000..8717a8dbf61 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/pdavm/docs/protocol.html @@ -0,0 +1,198 @@ + + + + + PDA Debugger Protocol Reference + + + +

    PDA Debugger Protocol Reference

    + +

    clear

    +Clears any breakpoint set on given line +
    +   C: clear {line}
    +   R: ok
    +
    + + +

    data

    +Retrieves data stack information +
    +   C: data
    +   R: {value 1}|{value 2}|{value 3}|...|
    +
    + + +

    drop

    +Returns from the current frame without executing the rest of instructions. + +
    +   C: drop
    +   R: ok
    +   E: resumed drop
    +   E: suspended drop
    +
    + + +

    eval

    +Sets what events cause the execution to stop. + +
    +   C: eval {instruction}%20{parameter}|{instruction}%20{parameter}|...
    +   R: ok
    +   E: resume client
    +   E: evalresult result
    +   E: suspended eval
    +
    + + +

    eventstop

    +Sets what events cause the execution to stop. + +
    +   C: eventstop {event_name} {0|1}
    +   R: ok
    +   ...
    +   E: suspended event {event_name}
    +
    + + +

    exit

    +Instructs the debugger to exit. + +
    +   C: exit
    +   R: ok
    +
    + + +

    popdata

    +Pops the top value from the data stack + +
    +   C: popdata
    +   R: ok
    +
    + + +

    pushdata

    +Pushes the given value on top of the data stack. + +
    +   C: pushdata {value}
    +   R: ok
    +
    + + +

    resume

    +Resumes the execution + +
    +   C: resume
    +   R: ok
    +   E: resumed client
    +
    + + +

    set

    +Sets a breakpoint at given line + +
    +   C: set {line_number}
    +   R: ok
    +   C: resume
    +   E: resumed client
    +   E: suspended breakpoint line_number
    +
    + + +

    setdata

    +Sets a data value in the data stack at the given location + +
    +   C: setdata {index} {value}
    +   R: ok
    +
    + + +

    setvar

    +Sets a variable value + +
    +   C: setvar {variable} {value}
    +   R: ok
    +
    + + +

    stack

    +Retrieves command stack information + +
    +   C: stack
    +   R: {file}|{line}|{function}|{var_1}|{var_2}|...{file}|{line}|{function}|{var_1}|{var_2}|......
    +
    + + +

    step

    +Executes next instruction + +
    +   C: step
    +   R: ok
    +   E: resumed step
    +   E: suspended step
    +
    + + +

    stepreturn

    +Executes instructions until the current subroutine is finished + +
    +   C: stepreturn
    +   R: ok
    +   E: resumed step
    +   E: suspended step
    +
    + + +

    suspend

    +Suspends execution + +
    +   C: suspend
    +   R: ok
    +   E: suspended client
    +
    + + +

    var

    +Retrieves variable value + +
    +   C: var {frame_number} {variable_name}
    +   R: {variable_value}
    +
    + + +

    watch

    +Sets a watchpoint on a given variable + +
    +   C: watch {function}::{variable_name} {watch_operation}
    +   R: ok
    +   C: resume
    +   R: resumed client
    +   E: suspended watch {watch_operation} {function}::{variable_name}
    +
    + +The watch_operation value can be: +
      +
    • 0 - no watch
    • +
    • 1 - read watch
    • +
    • 2 - write watch
    • +
    • 3 - both, etc.
    • +
    + + diff --git a/plugins/org.eclipse.dd.examples.pda/pdavm/pda.pl b/plugins/org.eclipse.dd.examples.pda/pdavm/pda.pl new file mode 100644 index 00000000000..897ff650fba --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/pdavm/pda.pl @@ -0,0 +1,673 @@ +#!perl.exe + +use strict; +use warnings; +use IO::Socket; + +##################################################################### +# Copyright (c) 2005 IBM Corporation and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Bjorn Freeman-Benson - initial API and implementation +##################################################################### + +##################################################################### +# # +# I N I T I A L I Z A T I O N A N D V A R I A B L E S # +# # +##################################################################### +# +# The push down automata stack (the data stack) +# +my @stack; +# +# Load all the code into memory +# The code is stored as an array of strings, each line of +# the source file being one entry in the array. +# +my $filename = shift; +open INFILE, $filename or die $!; +my @code = ; +close INFILE; + +my %labels; +sub map_labels { + # + # A mapping of labels to indicies in the code array + # + %labels = ( ); + my $idx = 0; + while( $idx <= $#code ) { + if( length $code[$idx] > 0 ) { + $code[$idx] =~ /^\s*(.+?)\s*$/; + $code[$idx] = $1; + $labels{$1} = $idx if( $code[$idx] =~ /^:(\S+)/ ); + } else { + $code[$idx] = "\n"; + } + $idx ++; + } +} +map_labels(); +# +# The stack of stack frames (the control stack) +# Each stack frame is a mapping of variable names to values. +# There are a number of special variable names: +# _pc_ is the current program counter in the frame +# the pc points to the next instruction to be executed +# _func_ is the name of the function in this frame +# +my @frames; +my $currentframe; +$currentframe = { + _pc_ => 0, + _func_ => 'main' + }; + +# +# The command line argument to start a debug session. +# +my $debugflag = shift; +# +# The port to listen for debug commands on +# and the port to send debug events to +# +my $debugport; +my $debugport2; +# +# The socket to listen for debug commands on +# and the socket to send debug events on +# +my $debugsock; +my $debugsock2; +# +# An input buffer +# +my $debugbuf; +# +# Breakpoint array +# breakpoints are stored as a boolean for each line of code +# if the boolean is true, there is a breakpoint on that line +# +my @breakpoints; +# +# Mapping of debugger commands to functions that evaluate them +# +my %debug_commands = ( + clear => \&debug_clear_breakpoint, + data => \&debug_data, + drop => \&debug_drop_frame, + eval => \&debug_eval, + eventstop => \&debug_event_stop, + exit => \&debug_exit, + popdata => \&debug_pop, + pushdata => \&debug_push, + resume => \&debug_resume, + set => \&debug_set_breakpoint, + setdata => \&debug_set_data, + setvar => \&debug_set_variable, + stack => \&debug_stack, + step => \&debug_step, + stepreturn => \&debug_step_return, + suspend => \&debug_suspend, + var => \&debug_var, + watch => \&debug_watch +); + +# +# The run flag is true if the VM is running. +# If the run flag is false, the VM exits the +# next time the main instruction loop runs. +# +my $run = 1; +# +# The suspend flag is true if the VM should suspend +# running the program and just listen for debug commands. +# +my $suspend = 0; +my $started = 1; +$suspend = "client" if( $debugflag ); +# +# The step flag is used to control single-stepping. +# See the implementation of the "step" debug command. +# The stepreturn flag is used to control step-return. +# The eventstops table holds which events cause suspends and which do not. +# The watchpoints table holds watchpoint information. +# variablename_stackframedepth => N +# N = 0 is no watch +# N = 1 is read watch +# N = 2 is write watch +# N = 3 is both, etc. +# +my $step = 0; +my $stepreturn = 0; +my %eventstops = ( "unimpinstr" => 0, + "nosuchlabel" => 0, + ); +my %watchpoints = ( ); + +# +# Mapping of the names of the instructions to the functions that evaluate them +# +my %instructions = ( + add => \&add, + branch_not_zero => \&branch_not_zero, + call => \&call, + dec => \&dec, + dup => \&dup, + halt => \&halt, + output => \&output, + pop => \&ipop, + push => \&ipush, + return => \&ireturn, + var => \&var, + xyzzy => \&internal_end_eval, +); + +##################################################################### +# # +# M A I N I N T E R P R E T E R # +# # +##################################################################### +# +# Open a debug session if the command line argument is given. +# +start_debugger(); +send_debug_event( "started", 0 ); +debug_ui() if( $suspend ); +# +# The main run loop +# +while( $run ) { + check_for_breakpoint(); + debug_ui() if( $suspend ); + yield_to_debug(); + my $instruction = fetch_instruction(); + increment_pc(); + do_one_instruction($instruction); + if( $$currentframe{_pc_} > $#code ) { + $run = 0; + } elsif( $stepreturn ) { + $instruction = fetch_instruction(); + $suspend = "step" if( is_return_instruction($instruction) ); + } +} +send_debug_event( "terminated", 0 ); + +sub fetch_instruction { + my $pc = $$currentframe{_pc_}; + my $theinstruction = $code[$pc]; + return $theinstruction; +} +sub is_return_instruction { + my $theinstruction = shift; + if( $theinstruction =~ /^:/ ) { + return 0; + } elsif( $theinstruction =~ /^#/ ) { + return 0; + } else { + $theinstruction =~ /^(\S+)\s*(.*)/; + return $1 eq "return"; + } +} +sub increment_pc { + my $pc = $$currentframe{_pc_}; + $pc++; + $$currentframe{_pc_} = $pc; +} +sub decrement_pc { + my $pc = $$currentframe{_pc_}; + $pc--; + $$currentframe{_pc_} = $pc; +} +sub do_one_instruction { + my $theinstruction = shift; + if( $theinstruction =~ /^:/ ) { + # label + $suspend = "step" if( $step ); + } elsif( $theinstruction =~ /^#/ ) { + # comment + } else { + $theinstruction =~ /^(\S+)\s*(.*)/; + my $op = $1; + my $instr = $instructions{$op}; + if( $instr ) { + &$instr( $theinstruction, $2 ); + $suspend = "step" if( $step ); + } else { + send_debug_event( "unimplemented instruction $op", 1 ); + if( $eventstops{"unimpinstr"} ) { + $suspend = "event unimpinstr"; + decrement_pc(); + } + } + } +} + +##################################################################### +# # +# I N S T R U C T I O N S # +# # +##################################################################### +sub add { + my $val1 = pop @stack; + my $val2 = pop @stack; + my $val = $val1 + $val2; + push @stack, $val; +} + +sub branch_not_zero { + my $val = pop @stack; + if( $val ) { + shift; + my $label = shift; + my $dest = $labels{$label}; + if( !defined $dest ) { + send_debug_event( "no such label $label", 1 ); + if( $eventstops{"nosuchlabel"} ) { + $suspend = "event nosuchlabel"; + push @stack, $val; + decrement_pc(); + } + } else { + $$currentframe{_pc_} = $dest; + } + } +} + +sub call { + shift; + my $label = shift; + my $dest = $labels{$label}; + if( !defined $dest ) { + send_debug_event( "no such label $label", 1 ); + if( $eventstops{"nosuchlabel"} ) { + $suspend = "event nosuchlabel"; + decrement_pc(); + } + } else { + push @frames, $currentframe; + $currentframe = { + _pc_ => $dest, + _func_ => $label + }; + } +} + +sub dec { + my $val = pop @stack; + $val--; + push @stack, $val; +} + +sub dup { + my $val = pop @stack; + push @stack, $val; + push @stack, $val; +} + +sub halt { + $run = 0; +} + +sub output { + my $val = pop @stack; + print "$val\n"; +} + +sub ipop { + shift; + my $arg = shift; + if( $arg =~ /^\$(.*)/ ) { + $$currentframe{$1} = pop @stack; + my $key = "$$currentframe{_func_}\:\:$1"; + if( defined $watchpoints{$key} ) { + if( $watchpoints{$key} & 2 ) { + $suspend = "watch write $key"; + } + } + } else { + pop @stack; + } +} + +sub ipush { + shift; + my $arg = shift; + if( $arg =~ /^\$(.*)/ ) { + my $val = $$currentframe{$1}; + push @stack, $val; + my $key = "$$currentframe{_func_}\:\:$1"; + if( defined $watchpoints{$key} ) { + if( $watchpoints{$key} & 1 ) { + $suspend = "watch read $key"; + } + } + } else { + push @stack, $arg; + } +} + +sub ireturn { + $currentframe = pop @frames; +} + +sub var { + shift; + my $name = shift; + $$currentframe{$name} = 0; +} + +##################################################################### +# # +# D E B U G G E R I N T E R F A C E # +# # +##################################################################### + +sub check_for_breakpoint { + if( $debugflag ) { + my $pc = $$currentframe{_pc_}; + if( $breakpoints[$pc] ) { + $suspend = "breakpoint $pc" unless $suspend eq "eval"; + } + } +} +# +# For each instruction, we check the debug co-routine for +# control input. If there is input, we process it. +# +sub yield_to_debug { + if( $debugflag ) { + my $bytes_to_read = 1024; + my $bytes_read = sysread($debugsock, $debugbuf, $bytes_to_read); + if( defined($bytes_read) ) { + #print "read $bytes_to_read\n"; + my $rin = ''; + my $win = ''; + my $ein = ''; + vec($rin,fileno($debugsock),1) = 1; + $ein = $rin | $win; + my $debugline = $debugbuf; + while( !($debugline =~ /\n/) ) { + select($rin, undef, undef, undef); + my $bytes_to_read = 1024; + my $bytes_read = sysread($debugsock, $debugbuf, $bytes_to_read); + $debugline .= $debugbuf; + } + #print "read: $debugline"; + process_debug_command($debugline); + $debugline = ''; + } else { + # no bytes read + } + } +} + +# +# If the execution is suspended, then we go into the debug +# ui loop, reading and processing instructions. +# +sub debug_ui { + return unless( $suspend ); + my $pc = $$currentframe{_pc_}; + if (!$started) { + send_debug_event( "suspended $suspend", 0 ); + } else { + $started = 0; + } + $step = 0; + $stepreturn = 0; + my $rin = ''; + my $win = ''; + my $ein = ''; + vec($rin,fileno($debugsock),1) = 1; + $ein = $rin | $win; + my $debugline = ''; + while( $suspend ) { + select($rin, undef, undef, undef); + my $bytes_to_read = 1024; + my $bytes_read = sysread($debugsock, $debugbuf, $bytes_to_read); + $debugline .= $debugbuf; + if( $debugline =~ /\n/ ) { + #print "read: $debugline"; + process_debug_command($debugline); + $debugline = ''; + } + } + send_debug_event( "resumed step", 0 ) if( $step ); + send_debug_event( "resumed client", 0 ) unless( $step ); +} + +sub process_debug_command { + my $line = shift; + return if( length $line < 2 ); + my @words = split /\s/, $line; + my $command = lc($words[0]); + my $dfunc = $debug_commands{$words[0]}; + if( $dfunc ) { + &$dfunc( @words ); + } +} + +sub debug_clear_breakpoint { + shift; + my $line = shift; + $breakpoints[$line] = 0; + print $debugsock "ok\n"; +} +my @saved_code; +my %saved_labels; +my $saved_pc; +sub debug_eval { + shift; + my $code = shift; + my @lines = split /\|/, $code; + my $newpc = scalar @code; + @saved_code = @code; + %saved_labels = %labels; + foreach my $line ( @lines ) { + $line =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; + push @code, $line; + } + push @code, "xyzzy"; + map_labels(); + $saved_pc = $$currentframe{_pc_}; + $$currentframe{_pc_} = $newpc; + print $debugsock "ok\n"; + $suspend = 0; +} +sub internal_end_eval { + my $result = pop @stack; + @code = @saved_code; + %labels = %saved_labels; + $$currentframe{_pc_} = $saved_pc; + send_debug_event( "evalresult $result", 0 ); + $suspend = "eval"; +} + +sub debug_data { + my $result = ''; + foreach my $d ( @stack ) { + $result .= $d . '|'; + } + print $debugsock "$result\n"; +} +sub debug_drop_frame { + ireturn(); + decrement_pc(); + print $debugsock "ok\n"; + send_debug_event( "resumed drop", 0 ); + send_debug_event( "suspended drop", 0 ); +} +sub debug_event_stop { + shift; + my $event = shift; + my $bool = shift; + $eventstops{$event} = $bool; + print $debugsock "ok\n"; +} +sub debug_exit { + print $debugsock "ok\n"; + send_debug_event( "terminated", 0 ); + exit 0; +} +sub debug_pop { + pop @stack; + print $debugsock "ok\n"; +} +sub debug_push { + shift; + my $value = shift; + push @stack, $value; + print $debugsock "ok\n"; +} +sub debug_resume { + $suspend = 0; + print $debugsock "ok\n"; +} +sub debug_set_breakpoint { + shift; + my $line = shift; + $breakpoints[$line] = 1; + print $debugsock "ok\n"; +} +sub debug_set_data { + shift; + my $offset = shift; + my $value = shift; + $stack[$offset] = $value; + print $debugsock "ok\n"; +} +sub debug_set_variable { + shift; + my $sfnumber = shift; + my $var = shift; + my $value = shift; + if( $sfnumber > $#frames ) { + $$currentframe{$var} = $value; + } else { + my $theframe = $frames[$sfnumber]; + $$theframe{$var} = $value; + } + print $debugsock "ok\n"; +} +sub debug_stack { + my $result = ''; + foreach my $frame ( @frames ) { + $result .= print_frame($frame); + $result .= '#'; + } + $result .= print_frame($currentframe); + print $debugsock "$result\n"; +} +sub debug_step { + # set suspend to 0 to allow the debug loop to exit back to + # the instruction loop and thus run an instruction. However, + # we want to come back to the debug loop right away, so the + # step flag is set to true which will cause the suspend flag + # to get set to true when we get to the next instruction. + $step = 1; + $suspend = 0; + print $debugsock "ok\n"; +} +sub debug_step_return { + $stepreturn = 1; + $suspend = 0; + print $debugsock "ok\n"; +} +sub debug_suspend { + $suspend = "client"; + print $debugsock "ok\n"; +} +sub debug_var { + shift; + my $sfnumber = shift; + my $var = shift; + if( $sfnumber > $#frames ) { + print $debugsock "$$currentframe{$var}\n"; + } else { + my $theframe = $frames[$sfnumber]; + print $debugsock "$$theframe{$var}\n"; + } +} +sub debug_watch { + shift; + my $key = shift; + my $value = shift; + $watchpoints{$key} = $value; + print $debugsock "ok\n"; +} +# +# Some event has happened so notify the debugger. +# If there is no debugger, we may still want to report the +# event (such as if it is an error). +# +sub send_debug_event { + my $event = shift; + if( $debugflag ) { + print $debugsock2 "$event\n"; + } else { + my $use_stderr = shift; + print "Error: $event\n" if $use_stderr; + } +} +# +# The stack frame output is: +# frame # frame # frame ... +# where each frame is: +# filename | line number | function name | var | var | var | var ... +# +sub print_frame { + my $frame = shift; + my $result = $filename; + $result .= '|' . $$frame{_pc_}; + $result .= '|' . $$frame{_func_}; + for my $var ( keys %$frame ) { + $result .= '|' . $var unless( substr($var,0,1) eq '_'); + } + return $result; +} + +sub start_debugger { + if( defined($debugflag) ) { + if( $debugflag eq "-debug" ) { + { # make STDOUT unbuffered + my $ofh = select STDOUT; + $| = 1; + select $ofh; + } + $debugflag = 1; + $debugport = shift @ARGV; + $debugport2 = shift @ARGV; + print "-debug $debugport $debugport2\n"; + + my $mainsock = new IO::Socket::INET (LocalHost => '127.0.0.1', + LocalPort => $debugport, + Listen => 1, + Proto => 'tcp', + Reuse => 1, + ); + $debugsock = $mainsock->accept(); + my $set_it = "1"; + my $ioctl_val = 0x80000000 | (4 << 16) | (ord('f') << 8) | 126; + ioctl($debugsock, $ioctl_val, $set_it); #or die "couldn't set nonblocking: $^E"; + $debugsock->blocking(0); + + my $mainsock2 = new IO::Socket::INET (LocalHost => '127.0.0.1', + LocalPort => $debugport2, + Listen => 1, + Proto => 'tcp', + Reuse => 1, + ); + $debugsock2 = $mainsock2->accept(); + + print "debug connection accepted\n"; + } else { + $debugflag = 0; + } + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/pdavm/tests/vmtest2.pda b/plugins/org.eclipse.dd.examples.pda/pdavm/tests/vmtest2.pda new file mode 100644 index 00000000000..95a35f04ffb --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/pdavm/tests/vmtest2.pda @@ -0,0 +1,48 @@ +push 6 +push 7 +push 8 +push 9 +push 10 +call sub1 +output +call sub3 +call sub5 +push 3 +halt +:sub2 +push 27 +return +:sub1 +var m +var n +call sub2 +pop $n +pop $m +push $n +push $m +return +# zero-based line 23 +:sub3 +push 1 +call sub4 +push 2 +call sub4 +push 3 +return +:sub4 +push 4 +return +# zero-based line 34 +:sub5 +var a +var b +var c +pop $c +pop $b +call sub6 +push $a +return +:sub6 +var b +pop $b +return diff --git a/plugins/org.eclipse.dd.examples.pda/pdavm/tests/vmtest3.pda b/plugins/org.eclipse.dd.examples.pda/pdavm/tests/vmtest3.pda new file mode 100644 index 00000000000..a9fcfc2a853 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/pdavm/tests/vmtest3.pda @@ -0,0 +1,11 @@ +push 1 +push 2 +push 3 +foobar swish +push 4 +add +add +call zippy +add +output +halt diff --git a/plugins/org.eclipse.dd.examples.pda/pdavm/tests/vmtest6.pda b/plugins/org.eclipse.dd.examples.pda/pdavm/tests/vmtest6.pda new file mode 100644 index 00000000000..d90a960cf38 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/pdavm/tests/vmtest6.pda @@ -0,0 +1,31 @@ +var a +var b +push 1 +pop $a +push 2 +pop $b +push 3 +push 4 +# +call inner +# +push $a +push 2 +add +pop $b +output +# +halt +# +:inner +var a +var c +pop $a +pop $c +push $a +push $a +add +return +:other +push 15 +return \ No newline at end of file diff --git a/plugins/org.eclipse.dd.examples.pda/pdavm/tests/vmtest8.pda b/plugins/org.eclipse.dd.examples.pda/pdavm/tests/vmtest8.pda new file mode 100644 index 00000000000..7729409c279 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/pdavm/tests/vmtest8.pda @@ -0,0 +1,14 @@ +var a +call inner +push 1 +output +halt +:inner +var b +call inner2 +push 2 +return +:inner2 +var c +push 3 +return diff --git a/plugins/org.eclipse.dd.examples.pda/pdavm/tests/vmtests.pl b/plugins/org.eclipse.dd.examples.pda/pdavm/tests/vmtests.pl new file mode 100644 index 00000000000..5eff5c103e5 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/pdavm/tests/vmtests.pl @@ -0,0 +1,448 @@ +#!perl.exe + +use strict; +use warnings; +use IO::Socket; + +##################################################################### +# Copyright (c) 2004-2005 IBM Corporation and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Bjorn Freeman-Benson - initial API and implementation +##################################################################### +# +# This test is designed to run on Windows: +# +# cd c:\eclipse\workspace\org.eclipse.debug.examples.core +# perl pdavm\tests\vmtests.pl +# +# If the tests fail, they often indicate that by hanging in an +# infinite loop. Additionally, the vm under test often becomes +# a 100% CPU usage zombie. Use the task manager to kill them. +# +my $socket1; +my $socket2; + +sub expect_output { + my $expect = shift; + my $line = ; + chomp($line); + return if( $line eq $expect ); + die "expected output: $expect\nSaw output: $line"; +} +sub expect_output_eof { + my $line = ; + return if( !defined $line ); + die "expected: EOF on output"; +} +sub send_command { + my $string = shift; + my $expect = shift; + $expect = "ok" if( !defined $expect ); + #print STDERR "SEND: $string\n"; + print $socket1 "$string\n"; + my $result = <$socket1>; + chomp($result); + #print STDERR "RESULT: $result\n"; + die "sent: $string\nexpected: $expect\nsaw: $result" if( !($result eq $expect) ); +} +sub expect_event { + my $string = shift; + my $event = <$socket2>; + chomp($event); + #print STDERR "EVENT: $event\n"; + die "expected event: $string\nsaw event: $event" if( !($string eq $event) ); +} +sub setup_sockets { + #print STDERR "calling socket 12345\n"; + $socket1 = IO::Socket::INET->new( + Proto => "tcp", + PeerAddr => "localhost", + PeerPort => "12345", + Timeout => 10, + ) + or die "cannot connect to debug socket 12345"; + #print STDERR "calling socket 12346\n"; + $socket2 = IO::Socket::INET->new( + Proto => "tcp", + PeerAddr => "localhost", + PeerPort => "12346", + Timeout => 10, + ) + or die "cannot connect to debug socket 12346"; + #print STDERR "done calling sockets\n"; +} + +sub test2 { + print "test2 (common debug commands)..\n"; + + my $kidpid; + die "can't fork: $!" unless defined($kidpid = fork()); + if( $kidpid ) { + #print STDERR "starting program\n"; + open PROGRAM_OUTPUT, "perl pdavm/pda.pl pdavm/tests/vmtest2.pda -debug 12345 12346 |"; + #print STDERR "done starting program\n"; + expect_output("-debug 12345 12346"); + expect_output("debug connection accepted"); + expect_output("10"); + expect_output_eof(); + exit 0; + } else { + setup_sockets(); + expect_event("started"); + # test step + send_command("step"); + expect_event("resumed step"); + expect_event("suspended step"); + # test breakpoint + send_command("set 4"); + send_command("data", "6|"); + send_command("resume"); + expect_event("resumed client"); + expect_event("suspended breakpoint 4"); + # test data stack + send_command("data", "6|7|8|9|"); + send_command("popdata"); + send_command("data", "6|7|8|"); + send_command("pushdata 11"); + send_command("data", "6|7|8|11|"); + send_command("setdata 1 2"); + send_command("data", "6|2|8|11|"); + # test call stack + send_command("set 12"); + send_command("set 19"); + send_command("stepreturn"); + expect_event("resumed client"); + expect_event("suspended breakpoint 12"); + send_command("clear 19"); + send_command("stack", "pdavm\\tests\\vmtest2.pda|6|main#pdavm\\tests\\vmtest2.pda|18|sub1|m|n#pdavm\\tests\\vmtest2.pda|12|sub2" ); + send_command("stepreturn"); + expect_event("resumed client"); + expect_event("suspended step"); + send_command("stack", "pdavm\\tests\\vmtest2.pda|6|main#pdavm\\tests\\vmtest2.pda|18|sub1|m|n#pdavm\\tests\\vmtest2.pda|13|sub2" ); + send_command("stepreturn"); + expect_event("resumed client"); + expect_event("suspended step"); + send_command("stack", "pdavm\\tests\\vmtest2.pda|6|main#pdavm\\tests\\vmtest2.pda|22|sub1|m|n" ); + send_command("set 6"); + send_command("stepreturn"); + expect_event("resumed client"); + expect_event("suspended breakpoint 6"); + # test set and clear + send_command("set 27"); + send_command("set 29"); + send_command("set 33"); + send_command("resume"); + expect_event("resumed client"); + expect_event("suspended breakpoint 33"); + send_command("resume"); + expect_event("resumed client"); + expect_event("suspended breakpoint 27"); + send_command("clear 33"); + send_command("resume"); + expect_event("resumed client"); + expect_event("suspended breakpoint 29"); + # test var and setvar + send_command("set 47"); + send_command("resume"); + expect_event("resumed client"); + expect_event("suspended breakpoint 47"); + send_command("var 1 b", "4"); + send_command("var 2 b", "2"); + send_command("var 1 a", "0"); + send_command("setvar 1 a 99"); + send_command("data", "6|2|8|11|27|1|4|"); + send_command("step"); + expect_event("resumed step"); + expect_event("suspended step"); + send_command("var 1 a", "99"); + send_command("step"); + expect_event("resumed step"); + expect_event("suspended step"); + send_command("data", "6|2|8|11|27|1|4|99|"); + # test exit + send_command("exit"); + expect_event("terminated"); + } + #print STDERR "waiting for child\n"; + wait(); + #print STDERR "child joined\n"; + close PROGRAM_OUTPUT; + print "test2..SUCCESS\n"; +} + +sub test3 { + print "test3 (uncaught events)..\n"; + + my $kidpid; + die "can't fork: $!" unless defined($kidpid = fork()); + if( $kidpid ) { + #print STDERR "starting program\n"; + open PROGRAM_OUTPUT, "perl pdavm\\pda.pl pdavm\\tests\\vmtest3.pda -debug 12345 12346 |"; + #print STDERR "done starting program\n"; + expect_output("-debug 12345 12346"); + expect_output("debug connection accepted"); + expect_output("10"); + expect_output_eof(); + exit 0; + } else { + setup_sockets(); + expect_event("started"); + send_command("resume"); + expect_event("resumed client"); + expect_event("unimplemented instruction foobar"); + expect_event("no such label zippy"); + expect_event("terminated"); + } + #print STDERR "waiting for child\n"; + wait(); + #print STDERR "child joined\n"; + close PROGRAM_OUTPUT; + print "test3..SUCCESS\n"; +} +sub test4 { + print "test4 (caught events)..\n"; + + my $kidpid; + die "can't fork: $!" unless defined($kidpid = fork()); + if( $kidpid ) { + #print STDERR "starting program\n"; + open PROGRAM_OUTPUT, "perl pdavm\\pda.pl pdavm\\tests\\vmtest3.pda -debug 12345 12346 |"; + #print STDERR "done starting program\n"; + expect_output("-debug 12345 12346"); + expect_output("debug connection accepted"); + expect_output("10"); + expect_output_eof(); + exit 0; + } else { + setup_sockets(); + expect_event("started"); + send_command("eventstop unimpinstr 1"); + send_command("resume"); + expect_event("resumed client"); + expect_event("unimplemented instruction foobar"); + expect_event("suspended event unimpinstr"); + send_command("eventstop unimpinstr 0"); + send_command("resume"); + expect_event("resumed client"); + expect_event("unimplemented instruction foobar"); + expect_event("no such label zippy"); + expect_event("terminated"); + } + #print STDERR "waiting for child\n"; + wait(); + #print STDERR "child joined\n"; + close PROGRAM_OUTPUT; + print "test4..SUCCESS\n"; +} +sub test5 { + print "test5 (caught events)..\n"; + + my $kidpid; + die "can't fork: $!" unless defined($kidpid = fork()); + if( $kidpid ) { + #print STDERR "starting program\n"; + open PROGRAM_OUTPUT, "perl pdavm\\pda.pl pdavm\\tests\\vmtest3.pda -debug 12345 12346 |"; + #print STDERR "done starting program\n"; + expect_output("-debug 12345 12346"); + expect_output("debug connection accepted"); + expect_output("10"); + expect_output_eof(); + exit 0; + } else { + setup_sockets(); + expect_event("started"); + send_command("eventstop nosuchlabel 1"); + send_command("resume"); + expect_event("resumed client"); + expect_event("unimplemented instruction foobar"); + expect_event("no such label zippy"); + expect_event("suspended event nosuchlabel"); + send_command("eventstop nosuchlabel 0"); + send_command("resume"); + expect_event("resumed client"); + expect_event("no such label zippy"); + expect_event("terminated"); + } + #print STDERR "waiting for child\n"; + wait(); + #print STDERR "child joined\n"; + close PROGRAM_OUTPUT; + print "test5..SUCCESS\n"; +} +sub test6 { + print "test6 (watch points)..\n"; + + my $kidpid; + die "can't fork: $!" unless defined($kidpid = fork()); + if( $kidpid ) { + #print STDERR "starting program\n"; + open PROGRAM_OUTPUT, "perl pdavm\\pda.pl pdavm\\tests\\vmtest6.pda -debug 12345 12346 |"; + #print STDERR "done starting program\n"; + expect_output("-debug 12345 12346"); + expect_output("debug connection accepted"); + expect_output("8"); + expect_output_eof(); + exit 0; + } else { + setup_sockets(); + expect_event("started"); + send_command("watch inner::a 1"); + send_command("watch main::a 2"); + send_command("resume"); + expect_event("resumed client"); + expect_event("suspended watch write main::a"); + send_command("stack", "pdavm\\tests\\vmtest6.pda|4|main|a|b"); + send_command("resume"); + expect_event("resumed client"); + expect_event("suspended watch read inner::a"); + send_command("stack", "pdavm\\tests\\vmtest6.pda|10|main|a|b#pdavm\\tests\\vmtest6.pda|25|inner|a|c"); + send_command("watch inner::a 0"); + send_command("resume"); + expect_event("resumed client"); + expect_event("terminated"); + } + #print STDERR "waiting for child\n"; + wait(); + #print STDERR "child joined\n"; + close PROGRAM_OUTPUT; + print "test6..SUCCESS\n"; +} +sub test7 { + print "test7 (eval)..\n"; + + my $kidpid; + die "can't fork: $!" unless defined($kidpid = fork()); + if( $kidpid ) { + #print STDERR "starting program\n"; + open PROGRAM_OUTPUT, "perl pdavm\\pda.pl pdavm\\tests\\vmtest6.pda -debug 12345 12346 |"; + #print STDERR "done starting program\n"; + expect_output("-debug 12345 12346"); + expect_output("debug connection accepted"); + expect_output("8"); + expect_output_eof(); + exit 0; + } else { + setup_sockets(); + expect_event("started"); + send_command("set 25"); + send_command("resume"); + expect_event("resumed client"); + expect_event("suspended breakpoint 25"); + # + send_command("eval push%204|push%205|add"); + expect_event("resumed client"); + expect_event("evalresult 9"); + expect_event("suspended eval"); + # + send_command("step"); + expect_event("resumed step"); + expect_event("suspended step"); + send_command("stack", "pdavm\\tests\\vmtest6.pda|10|main|a|b#pdavm\\tests\\vmtest6.pda|26|inner|a|c"); + send_command("data", "4|4|"); + send_command("eval call%20other"); + expect_event("resumed client"); + expect_event("evalresult 15"); + expect_event("suspended eval"); + send_command("stack", "pdavm\\tests\\vmtest6.pda|10|main|a|b#pdavm\\tests\\vmtest6.pda|26|inner|a|c"); + send_command("data", "4|4|"); + send_command("resume"); + expect_event("resumed client"); + expect_event("terminated"); + } + #print STDERR "waiting for child\n"; + wait(); + #print STDERR "child joined\n"; + close PROGRAM_OUTPUT; + print "test7..SUCCESS\n"; +} +sub test1 { + print "test1 (normal run mode)..\n"; + open PROGRAM_OUTPUT, "perl pdavm/pda.pl samples/example.pda |" or die $!; + expect_output("\"hello\""); + expect_output("\"barfoo\""); + expect_output("\"first\""); + expect_output("\"second\""); + expect_output("12"); + expect_output("11"); + expect_output("10"); + expect_output("\"barfoo\""); + expect_output("\"first\""); + expect_output("\"second\""); + expect_output("\"end\""); + expect_output_eof(); + print "test1..SUCCESS\n"; +} +sub test8 { + print "test8 (drop to frame)..\n"; + + my $kidpid; + die "can't fork: $!" unless defined($kidpid = fork()); + if( $kidpid ) { + #print STDERR "starting program\n"; + open PROGRAM_OUTPUT, "perl pdavm\\pda.pl pdavm\\tests\\vmtest8.pda -debug 12345 12346 |"; + #print STDERR "done starting program\n"; + expect_output("-debug 12345 12346"); + expect_output("debug connection accepted"); + expect_output("1"); + expect_output_eof(); + exit 0; + } else { + setup_sockets(); + expect_event("started"); + send_command("step"); + expect_event("resumed step"); + expect_event("suspended step"); + send_command("step"); + expect_event("resumed step"); + expect_event("suspended step"); + send_command("step"); + expect_event("resumed step"); + expect_event("suspended step"); + send_command("step"); + expect_event("resumed step"); + expect_event("suspended step"); + send_command("step"); + expect_event("resumed step"); + expect_event("suspended step"); + send_command("step"); + expect_event("resumed step"); + expect_event("suspended step"); + send_command("step"); + expect_event("resumed step"); + expect_event("suspended step"); + send_command("stack", "pdavm\\tests\\vmtest8.pda|2|main|a#pdavm\\tests\\vmtest8.pda|8|inner|b#pdavm\\tests\\vmtest8.pda|12|inner2|c"); + send_command("drop"); + expect_event("suspended drop"); + send_command("stack", "pdavm\\tests\\vmtest8.pda|2|main|a#pdavm\\tests\\vmtest8.pda|7|inner|b"); + send_command("step"); + expect_event("resumed step"); + expect_event("suspended step"); + send_command("stack", "pdavm\\tests\\vmtest8.pda|2|main|a#pdavm\\tests\\vmtest8.pda|8|inner|b#pdavm\\tests\\vmtest8.pda|10|inner2"); + send_command("resume"); + expect_event("resumed client"); + expect_event("terminated"); + } + #print STDERR "waiting for child\n"; + wait(); + #print STDERR "child joined\n"; + close PROGRAM_OUTPUT; + print "test8..SUCCESS\n"; +} + +# +# Run the tests +# +test1(); +test2(); +test3(); +test4(); +test5(); +test6(); +test7(); +test8(); +print "All tests complete\n"; diff --git a/plugins/org.eclipse.dd.examples.pda/plugin.xml b/plugins/org.eclipse.dd.examples.pda/plugin.xml new file mode 100644 index 00000000000..053f2625f91 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/plugin.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/org.eclipse.dd.examples.pda/readme.html b/plugins/org.eclipse.dd.examples.pda/readme.html new file mode 100644 index 00000000000..2a7cb9df3bc --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/readme.html @@ -0,0 +1,11 @@ +

    Debug Examples ReadMe Notes

    +

    PDA Debugger Example

    +

    In order to actually run the PDA debugger example, you will need a Perl interpreter. + Linux®™ comes with Perl. For Microsoft® Windows®, we use either + ActivePerl (http://www.activeperl.com/) or Indigo Perl + (http://www.indigostar.com/). You also + have to set the string substitution variable named “perlExecutable” + to the complete path to your Perl interpreter. (For example, ours was C:\perl\bin\perl.exe) + To set a string substitution variable, use the Windows > Preferences > + Run/Debug > String Substitution preferences page.
    +

    diff --git a/plugins/org.eclipse.dd.examples.pda/samples/counter.pda b/plugins/org.eclipse.dd.examples.pda/samples/counter.pda new file mode 100644 index 00000000000..9b2b731006b --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/samples/counter.pda @@ -0,0 +1,11 @@ +push 0 +:main +var n +pop $n +push $n +push 1 +add +dup +push $n +output +branch_not_zero main \ No newline at end of file diff --git a/plugins/org.eclipse.dd.examples.pda/samples/drop.pda b/plugins/org.eclipse.dd.examples.pda/samples/drop.pda new file mode 100644 index 00000000000..84f60fee035 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/samples/drop.pda @@ -0,0 +1,12 @@ +call one +:one +call two +:two +call three +:three +call four +:four +push DONE +output + + diff --git a/plugins/org.eclipse.dd.examples.pda/samples/example.pda b/plugins/org.eclipse.dd.examples.pda/samples/example.pda new file mode 100644 index 00000000000..a95886358c2 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/samples/example.pda @@ -0,0 +1,35 @@ +push "hello" +output +call foobar +push 3 +:label +dup +push 4 +push 5 +add +add +output +dec +dup +branch_not_zero label +call foobar +push "end" +output +halt +:foobar +var a +var b +call barfoo +push "first" +push "second" +pop $a +pop $b +push $a +push $b +output +output +return +:barfoo +push "barfoo" +output +return diff --git a/plugins/org.eclipse.dd.examples.pda/samples/fibonacci.pda b/plugins/org.eclipse.dd.examples.pda/samples/fibonacci.pda new file mode 100644 index 00000000000..e39595a9811 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/samples/fibonacci.pda @@ -0,0 +1,32 @@ +push 6 +call fibonacci +output +halt +# +# f(n) = f(n-1) + f(n-2) +# f(0) = 1 +# f(1) = 1 +# +:fibonacci +var n +pop $n +push $n +branch_not_zero gt0 +push 1 +return +:gt0 +push $n +dec +branch_not_zero gt1 +push 1 +return +:gt1 +push $n +dec +call fibonacci +push $n +dec +dec +call fibonacci +add +return diff --git a/plugins/org.eclipse.dd.examples.pda/samples/structures.pda b/plugins/org.eclipse.dd.examples.pda/samples/structures.pda new file mode 100644 index 00000000000..97858b0791d --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/samples/structures.pda @@ -0,0 +1,8 @@ +push one two three +push 1 2 3 +var x +var y +pop $x +pop $y +push Done +output \ No newline at end of file diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/PDAPlugin.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/PDAPlugin.java new file mode 100644 index 00000000000..d910c04dd5d --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/PDAPlugin.java @@ -0,0 +1,208 @@ +/******************************************************************************* + * Copyright (c) 2005, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Bjorn Freeman-Benson - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.MissingResourceException; +import java.util.ResourceBundle; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Plugin; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.Query; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.examples.pda.launch.PDALaunch; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunch; +import org.osgi.framework.BundleContext; + +/** + * The main plugin class to be used in the desktop. + */ +public class PDAPlugin extends Plugin { + + public static String PLUGIN_ID = "org.eclipse.dd.examples.pda"; + + // Debugging flag + public static boolean DEBUG = false; + + //The shared instance. + private static PDAPlugin plugin; + //Resource bundle. + private ResourceBundle resourceBundle; + + private static BundleContext fContext; + + /** + * Unique identifier for the PDA debug model (value + * pda.debugModel). + */ + public static final String ID_PDA_DEBUG_MODEL = "org.eclipse.dd.examples.pda.debugModel"; + + /** + * Name of the string substitution variable that resolves to the + * location of a local Perl executable (value perlExecutable). + */ + public static final String VARIALBE_PERL_EXECUTABLE = "dsfPerlExecutable"; + /** + * Launch configuration attribute key. Value is a path to a perl + * program. The path is a string representing a full path + * to a perl program in the workspace. + */ + public static final String ATTR_PDA_PROGRAM = ID_PDA_DEBUG_MODEL + ".ATTR_PDA_PROGRAM"; + + /** + * Identifier for the PDA launch configuration type + * (value pda.launchType) + */ + public static final String ID_PDA_LAUNCH_CONFIGURATION_TYPE = "org.eclipse.dd.examples.pda.launchType"; + + /** + * The constructor. + */ + public PDAPlugin() { + super(); + plugin = this; + } + + /** + * This method is called upon plug-in activation + */ + @Override + public void start(BundleContext context) throws Exception { + fContext = context; + DEBUG = "true".equals(Platform.getDebugOption(PLUGIN_ID + "/debug")); //$NON-NLS-1$//$NON-NLS-2$ + super.start(context); + } + + /** + * This method is called when the plug-in is stopped + */ + @Override + public void stop(BundleContext context) throws Exception { + shutdownActiveLaunches(); + super.stop(context); + plugin = null; + resourceBundle = null; + fContext = context; + } + + /** + * Returns the shared instance. + */ + public static PDAPlugin getDefault() { + return plugin; + } + + /** + * Returns the string from the plugin's resource bundle, + * or 'key' if not found. + */ + public static String getResourceString(String key) { + ResourceBundle bundle = PDAPlugin.getDefault().getResourceBundle(); + try { + return (bundle != null) ? bundle.getString(key) : key; + } catch (MissingResourceException e) { + return key; + } + } + + /** + * Returns the plugin's resource bundle, + */ + public ResourceBundle getResourceBundle() { + try { + if (resourceBundle == null) + resourceBundle = ResourceBundle.getBundle("org.eclipse.debug.examples.core.pda.DebugCorePluginResources"); + } catch (MissingResourceException x) { + resourceBundle = null; + } + return resourceBundle; + } + + public static BundleContext getBundleContext() { + return fContext; + } + + /** + * Return a java.io.File object that corresponds to the specified + * IPath in the plugin directory, or null if none. + */ + public static File getFileInPlugin(IPath path) { + try { + URL installURL = + new URL(getDefault().getDescriptor().getInstallURL(), path.toString()); + URL localURL = Platform.asLocalURL(installURL); + return new File(localURL.getFile()); + } catch (IOException ioe) { + return null; + } + } + + /** + * Shuts down any active launches. We must shutdown any active sessions + * and services associated with this plugin before this plugin is stopped. + * Any attempts to use the plugins {@link BundleContext} after the plugin + * is shut down will result in exceptions. + */ + private void shutdownActiveLaunches() { + for (ILaunch launch : DebugPlugin.getDefault().getLaunchManager().getLaunches()) { + if (launch instanceof PDALaunch && !((PDALaunch)launch).isShutDown()) { + final PDALaunch pdaLaunch = (PDALaunch)launch; + + Query launchShutdownQuery = new Query() { + @Override + protected void execute(DataRequestMonitor rm) { + pdaLaunch.shutdownSession(rm); + } + }; + + try { + pdaLaunch.getSession().getExecutor().execute(launchShutdownQuery); + } catch (RejectedExecutionException e) { + // We can get this exception if the session is shutdown concurrently + // to this method running. + break; + } + + // The Query.get() method is a synchronous call which blocks until the + // query completes. + try { + launchShutdownQuery.get(); + } catch (InterruptedException e) { + getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, "InterruptedException while shutting down PDA debugger launch " + pdaLaunch, e.getCause())); + } catch (ExecutionException e) { + getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, "Exception while shutting down PDA debugger launch " + pdaLaunch, e.getCause())); + } + } + } + } + + + public static void failRequest(RequestMonitor rm, int code, String message) { + rm.setStatus(new Status(IStatus.ERROR, PLUGIN_ID, code, message, null)); + rm.done(); + } + + public static void debug(String debugString) { + if (DEBUG) { + System.out.println(debugString); + } + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/breakpoints/PDALineBreakpoint.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/breakpoints/PDALineBreakpoint.java new file mode 100644 index 00000000000..cf93ba6b6d4 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/breakpoints/PDALineBreakpoint.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2005, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Bjorn Freeman-Benson - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.breakpoints; + +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspaceRunnable; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.dd.examples.pda.PDAPlugin; +import org.eclipse.debug.core.model.IBreakpoint; +import org.eclipse.debug.core.model.LineBreakpoint; + + +/** + * PDA line breakpoint + */ +public class PDALineBreakpoint extends LineBreakpoint { + + /** + * Default constructor is required for the breakpoint manager + * to re-create persisted breakpoints. After instantiating a breakpoint, + * the setMarker(...) method is called to restore + * this breakpoint's attributes. + */ + public PDALineBreakpoint() { + } + + /** + * Constructs a line breakpoint on the given resource at the given + * line number. The line number is 1-based (i.e. the first line of a + * file is line number 1). The PDA VM uses 0-based line numbers, + * so this line number translation is done at breakpoint install time. + * + * @param resource file on which to set the breakpoint + * @param lineNumber 1-based line number of the breakpoint + * @throws CoreException if unable to create the breakpoint + */ + public PDALineBreakpoint(final IResource resource, final int lineNumber) throws CoreException { + IWorkspaceRunnable runnable = new IWorkspaceRunnable() { + public void run(IProgressMonitor monitor) throws CoreException { + IMarker marker = resource.createMarker("org.eclipse.debug.examples.core.pda.markerType.lineBreakpoint"); + setMarker(marker); + marker.setAttribute(IBreakpoint.ENABLED, Boolean.TRUE); + marker.setAttribute(IMarker.LINE_NUMBER, lineNumber); + marker.setAttribute(IBreakpoint.ID, getModelIdentifier()); + marker.setAttribute(IMarker.MESSAGE, "Line Breakpoint: " + resource.getName() + " [line: " + lineNumber + "]"); + } + }; + run(getMarkerRule(resource), runnable); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IBreakpoint#getModelIdentifier() + */ + public String getModelIdentifier() { + return PDAPlugin.ID_PDA_DEBUG_MODEL; + } + + /** + * Returns whether this breakpoint is a run-to-line breakpoint + * + * @return whether this breakpoint is a run-to-line breakpoint + */ + public boolean isRunToLineBreakpoint() { + return false; + } + +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/breakpoints/PDARunToLineBreakpoint.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/breakpoints/PDARunToLineBreakpoint.java new file mode 100644 index 00000000000..eda5308d957 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/breakpoints/PDARunToLineBreakpoint.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (c) 2005, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Bjorn Freeman-Benson - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.breakpoints; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IWorkspaceRunnable; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.model.IBreakpoint; + +/** + * A run to line breakpoint. + */ +public class PDARunToLineBreakpoint extends PDALineBreakpoint { + + private IFile fSourceFile; + + /** + * Constructs a run-to-line breakpoint in the given PDA program. + * + * @param resource PDA source file + * @param lineNumber line to run to + * @exception DebugException if unable to create the breakpoint + */ + public PDARunToLineBreakpoint(final IFile resource, final int lineNumber) throws DebugException { + IWorkspaceRunnable runnable = new IWorkspaceRunnable() { + public void run(IProgressMonitor monitor) throws CoreException { + // associate with workspace root to avoid drawing in editor ruler + IMarker marker = ResourcesPlugin.getWorkspace().getRoot().createMarker("org.eclipse.debug.examples.core.pda.markerType.lineBreakpoint"); + setMarker(marker); + marker.setAttribute(IBreakpoint.ENABLED, Boolean.TRUE); + marker.setAttribute(IMarker.LINE_NUMBER, lineNumber); + marker.setAttribute(IBreakpoint.ID, getModelIdentifier()); + setRegistered(false); + fSourceFile = resource; + } + }; + run(getMarkerRule(resource), runnable); + } + + /** + * Returns whether this breakpoint is a run-to-line breakpoint + * + * @return whether this breakpoint is a run-to-line breakpoint + */ + public boolean isRunToLineBreakpoint() { + return true; + } + + /** + * Returns the source file this breakpoint is contained in. + * + * @return the source file this breakpoint is contained in + */ + public IFile getSourceFile() { + return fSourceFile; + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/breakpoints/PDAWatchpoint.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/breakpoints/PDAWatchpoint.java new file mode 100644 index 00000000000..809d149e6f4 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/breakpoints/PDAWatchpoint.java @@ -0,0 +1,168 @@ +/******************************************************************************* + * Copyright (c) 2005, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Bjorn Freeman-Benson - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.breakpoints; + +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspaceRunnable; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.debug.core.model.IBreakpoint; +import org.eclipse.debug.core.model.IWatchpoint; + + +/** + * A watchpoint. + */ +public class PDAWatchpoint extends PDALineBreakpoint implements IWatchpoint { + + // 'read' or 'write' depending on what caused the last suspend for this watchpoint + private String fLastSuspendType; + + // marker attributes + public static final String ACCESS = "ACCESS"; + public static final String MODIFICATION = "MODIFICATION"; + public static final String FUNCTION_NAME = "FUNCTION_NAME"; + public static final String VAR_NAME = "VAR_NAME"; + + /** + * Default constructor is required for the breakpoint manager + * to re-create persisted breakpoints. After instantiating a breakpoint, + * the setMarker(...) method is called to restore + * this breakpoint's attributes. + */ + public PDAWatchpoint() { + } + /** + * Constructs a line breakpoint on the given resource at the given + * line number. The line number is 1-based (i.e. the first line of a + * file is line number 1). The PDA VM uses 0-based line numbers, + * so this line number translation is done at breakpoint install time. + * + * @param resource file on which to set the breakpoint + * @param lineNumber 1-based line number of the breakpoint + * @param functionName function name the variable is defined in + * @param varName variable name that watchpoint is set on + * @param access whether this is an access watchpoint + * @param modification whether this in a modification watchpoint + * @throws CoreException if unable to create the watchpoint + */ + public PDAWatchpoint(final IResource resource, final int lineNumber, final String functionName, final String varName, final boolean access, final boolean modification) throws CoreException { + IWorkspaceRunnable runnable = new IWorkspaceRunnable() { + public void run(IProgressMonitor monitor) throws CoreException { + IMarker marker = resource.createMarker("org.eclipse.debug.examples.core.pda.markerType.watchpoint"); + setMarker(marker); + setEnabled(true); + ensureMarker().setAttribute(IMarker.LINE_NUMBER, lineNumber); + ensureMarker().setAttribute(IBreakpoint.ID, getModelIdentifier()); + setAccess(access); + setModification(modification); + setVariable(functionName, varName); + marker.setAttribute(IMarker.MESSAGE, "Watchpoint: " + resource.getName() + " [line: " + lineNumber + "]"); + } + }; + run(getMarkerRule(resource), runnable); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IWatchpoint#isAccess() + */ + public boolean isAccess() throws CoreException { + return getMarker().getAttribute(ACCESS, true); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IWatchpoint#setAccess(boolean) + */ + public void setAccess(boolean access) throws CoreException { + setAttribute(ACCESS, access); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IWatchpoint#isModification() + */ + public boolean isModification() throws CoreException { + return getMarker().getAttribute(MODIFICATION, true); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IWatchpoint#setModification(boolean) + */ + public void setModification(boolean modification) throws CoreException { + setAttribute(MODIFICATION, modification); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IWatchpoint#supportsAccess() + */ + public boolean supportsAccess() { + return true; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IWatchpoint#supportsModification() + */ + public boolean supportsModification() { + return true; + } + + /** + * Sets the variable and function names the watchpoint is set on. + * + * @param functionName function name + * @param variableName variable name + * @throws CoreException if an exception occurrs setting marker attribtues + */ + protected void setVariable(String functionName, String variableName) throws CoreException { + setAttribute(VAR_NAME, variableName); + setAttribute(FUNCTION_NAME, functionName); + } + + /** + * Returns the name of the variable this watchpoint is set on. + * + * @return the name of the variable this watchpoint is set on + * @throws CoreException if unable to access the attribute + */ + public String getVariableName() throws CoreException { + return getMarker().getAttribute(VAR_NAME, (String)null); + } + + /** + * Returns the name of the function the variable associted with this watchpoint is defined in. + * + * @return the name of the function the variable associted with this watchpoint is defined in + * @throws CoreException if unable to access the attribute + */ + public String getFunctionName() throws CoreException { + return getMarker().getAttribute(FUNCTION_NAME, (String)null); + } + + /** + * Sets the type of event that causes the last suspend event. + * + * @param description one of 'read' or 'write' + */ + public void setSuspendType(String description) { + fLastSuspendType = description; + } + + /** + * Returns the type of event that caused the last suspend. + * + * @return 'read', 'write', or null if undefined + */ + public String getSuspendType() { + return fLastSuspendType; + } + +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunch.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunch.java new file mode 100644 index 00000000000..8b5020cf440 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunch.java @@ -0,0 +1,181 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.launch; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; +import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.concurrent.Sequence; +import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.examples.pda.PDAPlugin; +import org.eclipse.dd.examples.pda.service.command.PDATerminatedEvent; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.Launch; +import org.eclipse.debug.core.model.ISourceLocator; +import org.eclipse.debug.core.model.ITerminate; + +/** + * A DSF-based debugger has to override the base launch class in order to + * supply its own content providers for the debug view. + */ +@ThreadSafe +public class PDALaunch extends Launch + implements ITerminate +{ + private final DefaultDsfExecutor fExecutor; + private final DsfSession fSession; + + @ConfinedToDsfExecutor("getSession().getExecutor()") + private DsfServicesTracker fTracker; + + private AtomicBoolean fInitialized = new AtomicBoolean(false); + private AtomicBoolean fShutDown = new AtomicBoolean(false); + + public PDALaunch(ILaunchConfiguration launchConfiguration, String mode, ISourceLocator locator) { + super(launchConfiguration, mode, locator); + + // Create the dispatch queue to be used by debugger control and services + // that belong to this launch + final DefaultDsfExecutor dsfExecutor = new DefaultDsfExecutor(PDAPlugin.ID_PDA_DEBUG_MODEL); + dsfExecutor.prestartCoreThread(); + fExecutor = dsfExecutor; + fSession = DsfSession.startSession(fExecutor, PDAPlugin.ID_PDA_DEBUG_MODEL); + } + + public DsfExecutor getDsfExecutor() { return fExecutor; } + + public DsfSession getSession() { return fSession; } + + @ConfinedToDsfExecutor("getExecutor") + public void initializeControl() + throws CoreException + { + + Runnable initRunnable = new DsfRunnable() { + public void run() { + fTracker = new DsfServicesTracker(PDAPlugin.getBundleContext(), fSession.getId()); + fSession.addServiceEventListener(PDALaunch.this, null); + fInitialized.set(true); + fireChanged(); + } + }; + + // Invoke the execution code and block waiting for the result. + try { + fExecutor.submit(initRunnable).get(); + } catch (InterruptedException e) { + throw new CoreException(new Status( + IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Error initializing launch", e)); //$NON-NLS-1$ + } catch (ExecutionException e) { + throw new CoreException(new Status( + IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Error initializing launch", e.getCause())); //$NON-NLS-1$ + } + } + + @DsfServiceEventHandler public void eventDispatched(PDATerminatedEvent event) { + shutdownSession(new RequestMonitor(ImmediateExecutor.getInstance(), null)); + } + + public boolean isInitialized() { + return fInitialized.get(); + } + + public boolean isShutDown() { + return fShutDown.get(); + } + + @Override + public boolean canTerminate() { + return super.canTerminate() && isInitialized() && !isShutDown(); + } + + @Override + public boolean isTerminated() { + return super.isTerminated() || isShutDown(); + } + + + @Override + public void terminate() throws DebugException { + if (isShutDown()) return; + super.terminate(); + } + + /** + * Shuts down the services, the session and the executor associated with + * this launch. + *

    + * Note: The argument request monitor to this method should NOT use the + * executor that belongs to this launch. By the time the shutdown is + * complete, this executor will not be dispatching anymore and the + * request monitor will never be invoked. Instead callers should use + * the {@link ImmediateExecutor}. + *

    + * @param rm The request monitor invoked when the shutdown is complete. + */ + @ConfinedToDsfExecutor("getSession().getExecutor()") + public void shutdownSession(final RequestMonitor rm) { + if (fShutDown.getAndSet(true)) { + rm.done(); + return; + } + + Sequence shutdownSeq = new PDAServicesShutdownSequence( + getDsfExecutor(), fSession.getId(), + new RequestMonitor(fSession.getExecutor(), rm) { + @Override + public void handleCompleted() { + fSession.removeServiceEventListener(PDALaunch.this); + if (!getStatus().isOK()) { + PDAPlugin.getDefault().getLog().log(new MultiStatus( + PDAPlugin.PLUGIN_ID, -1, new IStatus[]{getStatus()}, "Session shutdown failed", null)); //$NON-NLS-1$ + } + // Last order of business, shutdown the dispatch queue. + fTracker.dispose(); + fTracker = null; + DsfSession.endSession(fSession); + // endSession takes a full dispatch to distribute the + // session-ended event, finish step only after the dispatch. + fExecutor.shutdown(); + fireTerminate(); + + rm.setStatus(getStatus()); + rm.done(); + } + }); + fExecutor.execute(shutdownSeq); + } + + @SuppressWarnings("unchecked") + @Override + public Object getAdapter(Class adapter) { + // Force adapters to be loaded. Otherwise the adapter manager may not find + // the model proxy adapter for DSF-based debug elements. + Platform.getAdapterManager().loadAdapter(this, adapter.getName()); + return super.getAdapter(adapter); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunchDelegate.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunchDelegate.java new file mode 100644 index 00000000000..8a6c57ee116 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunchDelegate.java @@ -0,0 +1,198 @@ +/******************************************************************************* + * Copyright (c) 2005, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Bjorn Freeman-Benson - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.launch; + +import java.io.File; +import java.io.IOException; +import java.net.ServerSocket; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutionException; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.variables.IValueVariable; +import org.eclipse.core.variables.VariablesPlugin; +import org.eclipse.dd.examples.pda.PDAPlugin; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.model.IPersistableSourceLocator; +import org.eclipse.debug.core.model.ISourceLocator; +import org.eclipse.debug.core.model.LaunchConfigurationDelegate; +import org.eclipse.debug.core.sourcelookup.IPersistableSourceLocator2; + + +/** + * Launches PDA program on a PDA interpretter written in Perl + */ +public class PDALaunchDelegate extends LaunchConfigurationDelegate { + + @Override + public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) throws CoreException { + // Need to configure the source locator before creating the launch + // because once the launch is created and added to launch manager, + // the adapters will be created for the whole session, including + // the source lookup adapter. + ISourceLocator locator = getSourceLocator(configuration); + + return new PDALaunch(configuration, mode, locator); + } + + @Override + public boolean buildForLaunch(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException { + return false; + } + + private ISourceLocator getSourceLocator(ILaunchConfiguration configuration) throws CoreException { + String type = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_ID, (String)null); + if (type == null) { + type = configuration.getType().getSourceLocatorId(); + } + if (type != null) { + IPersistableSourceLocator locator = DebugPlugin.getDefault().getLaunchManager().newSourceLocator(type); + String memento = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_MEMENTO, (String)null); + if (memento == null) { + locator.initializeDefaults(configuration); + } else { + if(locator instanceof IPersistableSourceLocator2) + ((IPersistableSourceLocator2)locator).initializeFromMemento(memento, configuration); + else + locator.initializeFromMemento(memento); + } + return locator; + } + return null; + } + + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.ILaunchConfigurationDelegate#launch(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.debug.core.ILaunch, org.eclipse.core.runtime.IProgressMonitor) + */ + public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException { + + String program = configuration.getAttribute(PDAPlugin.ATTR_PDA_PROGRAM, (String)null); + if (program == null) { + abort("Perl program unspecified.", null); + } + + int requestPort = findFreePort(); + int eventPort = findFreePort(); + if (requestPort == -1 || eventPort == -1) { + abort("Unable to find free port", null); + } + + launchProcess(launch, program, requestPort, eventPort); + + PDALaunch pdaLaunch = (PDALaunch)launch; + + initServices(pdaLaunch, program, requestPort, eventPort); + + pdaLaunch.initializeControl(); + } + + private void launchProcess(ILaunch launch, String program, int requestPort, int eventPort) throws CoreException { + List commandList = new ArrayList(); + + // Perl executable + IValueVariable perl = VariablesPlugin.getDefault().getStringVariableManager().getValueVariable(PDAPlugin.VARIALBE_PERL_EXECUTABLE); + if (perl == null) { + abort("Perl executable location undefined. Check value of ${dsfPerlExecutable}.", null); + } + String path = perl.getValue(); + if (path == null) { + abort("Perl executable location unspecified. Check value of ${dsfPerlExecutable}.", null); + } + File exe = new File(path); + if (!exe.exists()) { + abort(MessageFormat.format("Specified Perl executable {0} does not exist. Check value of $dsfPerlExecutable.", new Object[]{path}), null); + } + commandList.add(path); + + // Add PDA VM + File vm = PDAPlugin.getFileInPlugin(new Path("pdavm/pda.pl")); + if (vm == null) { + abort("Missing PDA VM", null); + } + commandList.add(vm.getAbsolutePath()); + + IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(program)); + if (!file.exists()) { + abort(MessageFormat.format("Perl program {0} does not exist.", new Object[] {file.getFullPath().toString()}), null); + } + + commandList.add(file.getLocation().toOSString()); + + // add debug arguments - i.e. '-debug requestPort eventPort' + commandList.add("-debug"); + commandList.add("" + requestPort); + commandList.add("" + eventPort); + + String[] commandLine = commandList.toArray(new String[commandList.size()]); + Process process = DebugPlugin.exec(commandLine, null); + DebugPlugin.newProcess(launch, process, path); + } + + private void initServices(PDALaunch pdaLaunch, String program, int requestPort, int eventPort) throws CoreException { + final PDAServicesInitSequence initSequence = + new PDAServicesInitSequence(pdaLaunch.getSession(), pdaLaunch, program, requestPort, eventPort); + pdaLaunch.getSession().getExecutor().execute(initSequence); + try { + initSequence.get(); + } catch (InterruptedException e1) { + throw new DebugException(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, "Interrupted Exception in dispatch thread", e1)); //$NON-NLS-1$ + } catch (ExecutionException e1) { + throw new DebugException(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Error in launch sequence", e1.getCause())); //$NON-NLS-1$ + } + } + + /** + * Throws an exception with a new status containing the given + * message and optional exception. + * + * @param message error message + * @param e underlying exception + * @throws CoreException + */ + private void abort(String message, Throwable e) throws CoreException { + throw new CoreException(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, 0, message, e)); + } + + /** + * Returns a free port number on localhost, or -1 if unable to find a free port. + * + * @return a free port number on localhost, or -1 if unable to find a free port + */ + public static int findFreePort() { + ServerSocket socket= null; + try { + socket= new ServerSocket(0); + return socket.getLocalPort(); + } catch (IOException e) { + } finally { + if (socket != null) { + try { + socket.close(); + } catch (IOException e) { + } + } + } + return -1; + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java new file mode 100644 index 00000000000..56b09b8c673 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java @@ -0,0 +1,138 @@ +/******************************************************************************* + * 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.examples.pda.launch; + +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.concurrent.Sequence; +import org.eclipse.dd.dsf.debug.service.BreakpointsMediator; +import org.eclipse.dd.dsf.debug.service.StepQueueManager; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.examples.pda.service.breakpoints.PDABreakpointAttributeTranslator; +import org.eclipse.dd.examples.pda.service.breakpoints.PDABreakpoints; +import org.eclipse.dd.examples.pda.service.command.PDACommandControl; +import org.eclipse.dd.examples.pda.service.runcontrol.PDARunControl; +import org.eclipse.debug.examples.core.pda.sourcelookup.PDASourceLookupDirector; + +public class PDAServicesInitSequence extends Sequence { + + Step[] fSteps = new Step[] { + // Create and initialize the Connection service. + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + // Create the connection. + fCommandControl = new PDACommandControl(fSession, fRequestPort, fEventPort); + fCommandControl.initialize(requestMonitor); + } + }, + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + new PDARunControl(fSession).initialize(requestMonitor); + } + }, + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + new StepQueueManager(fSession).initialize(requestMonitor); + } + }, + new Step() { + @Override + public void execute(final RequestMonitor requestMonitor) { + // Create the low-level breakpoint service + new PDABreakpoints(fSession, fProgram).initialize(new RequestMonitor(getExecutor(), requestMonitor)); + } + }, + new Step() { + @Override + public void execute(final RequestMonitor requestMonitor) { + final BreakpointsMediator bpmService = new BreakpointsMediator( + fSession, new PDABreakpointAttributeTranslator()); + bpmService.initialize(new RequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleOK() { + bpmService.startTrackingBreakpoints(fCommandControl.getDMContext(), requestMonitor); + } + }); + } + }, + /*new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new MIMemory(fSession).initialize(requestMonitor); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new MIModules(fSession).initialize(requestMonitor); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new MIStack(fSession).initialize(requestMonitor); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new ExpressionService(fSession).initialize(requestMonitor); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + fSourceLookup = new CSourceLookup(fSession); + fSourceLookup.initialize(requestMonitor); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + fSourceLookup.setSourceLookupDirector( + fCommandControl.getGDBDMContext(), + ((CSourceLookupDirector)fLaunch.getSourceLocator())); + requestMonitor.done(); + }}, + new Step() { @Override + public void execute(final RequestMonitor requestMonitor) { + // Create high-level breakpoint service and install breakpoints + // for the GDB debug context. + final MIBreakpointsManager bpmService = new MIBreakpointsManager(fSession, CDebugCorePlugin.PLUGIN_ID); + bpmService.initialize(new RequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleOK() { + bpmService.startTrackingBreakpoints(fCommandControl.getGDBDMContext(), requestMonitor); + } + }); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new MIRegisters(fSession).initialize(requestMonitor); + }},*/ + }; + + private DsfSession fSession; + private PDALaunch fLaunch; + private String fProgram; + private int fRequestPort; + private int fEventPort; + + PDACommandControl fCommandControl; + PDASourceLookupDirector fSourceLookup; + + public PDAServicesInitSequence(DsfSession session, PDALaunch launch, String program, int requestPort, + int eventPort) + { + super(session.getExecutor()); + fSession = session; + fLaunch = launch; + fProgram = program; + fRequestPort = requestPort; + fEventPort = eventPort; + } + + @Override + public Step[] getSteps() { + return fSteps; + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java new file mode 100644 index 00000000000..9ad48dd1320 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java @@ -0,0 +1,156 @@ +/******************************************************************************* + * 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.examples.pda.launch; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.concurrent.Sequence; +import org.eclipse.dd.dsf.debug.service.BreakpointsMediator; +import org.eclipse.dd.dsf.debug.service.StepQueueManager; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.examples.pda.PDAPlugin; +import org.eclipse.dd.examples.pda.service.breakpoints.PDABreakpoints; +import org.eclipse.dd.examples.pda.service.command.PDACommandControl; +import org.eclipse.dd.examples.pda.service.runcontrol.PDARunControl; + +public class PDAServicesShutdownSequence extends Sequence { + + String fSessionId; + DsfServicesTracker fTracker; + + public PDAServicesShutdownSequence(DsfExecutor executor, String sessionId, RequestMonitor requestMonitor) { + super(executor, requestMonitor); + fSessionId = sessionId; + } + + @Override + public Step[] getSteps() { + return fSteps; + } + + private final Step[] fSteps = new Step[] { new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + assert PDAPlugin.getBundleContext() != null; + fTracker = new DsfServicesTracker(PDAPlugin.getBundleContext(), fSessionId); + requestMonitor.done(); + } + + @Override + public void rollBack(RequestMonitor requestMonitor) { + fTracker.dispose(); + fTracker = null; + requestMonitor.done(); + } + }, +/* new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(MIRegisters.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(MIBreakpointsManager.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(MIBreakpoints.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(CSourceLookup.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(ExpressionService.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(MIStack.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(MIModules.class, requestMonitor); + } + }, + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(MIMemory.class, requestMonitor); + } + }, */ + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(BreakpointsMediator.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(PDABreakpoints.class, requestMonitor); + } + }, + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(StepQueueManager.class, requestMonitor); + } + }, + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(PDARunControl.class, requestMonitor); + } + }, + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(PDACommandControl.class, requestMonitor); + } + }, + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + fTracker.dispose(); + fTracker = null; + requestMonitor.done(); + } + } }; + + @SuppressWarnings("unchecked") + private void shutdownService(Class clazz, final RequestMonitor requestMonitor) { + IDsfService service = fTracker.getService(clazz); + if (service != null) { + service.shutdown(new RequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + PDAPlugin.getDefault().getLog().log(getStatus()); + } + requestMonitor.done(); + } + }); + } else { + requestMonitor.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, + "Service '" + clazz.getName() + "' not found.", null)); //$NON-NLS-1$//$NON-NLS-2$ + requestMonitor.done(); + } + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/breakpoints/BreakpointDMContext.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/breakpoints/BreakpointDMContext.java new file mode 100644 index 00000000000..0802693ccae --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/breakpoints/BreakpointDMContext.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.breakpoints; + +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.datamodel.AbstractDMContext; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; + +/** + * Context representing a PDA line breakpoint. In PDA debugger, since there is only + * one file being debugged at a time, a breakpoint is uniquely identified using the + * line number only. + */ +@Immutable +class BreakpointDMContext extends AbstractDMContext implements IBreakpointDMContext { + + final Integer fLine; + + public BreakpointDMContext(String sessionId, PDACommandControlDMContext commandControlCtx, Integer line) { + super(sessionId, new IDMContext[] { commandControlCtx }); + fLine = line; + } + + @Override + public boolean equals(Object obj) { + return baseEquals(obj) && (fLine.equals(((BreakpointDMContext) obj).fLine)); + } + + @Override + public int hashCode() { + return baseHashCode() + fLine.hashCode(); + } + + @Override + public String toString() { + return baseToString() + ".breakpoint(" + fLine + ")"; //$NON-NLS-1$//$NON-NLS-2$*/ + } +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/breakpoints/PDABreakpointAttributeTranslator.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/breakpoints/PDABreakpointAttributeTranslator.java new file mode 100644 index 00000000000..0e342716357 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/breakpoints/PDABreakpointAttributeTranslator.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.breakpoints; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.debug.service.BreakpointsMediator; +import org.eclipse.dd.dsf.debug.service.IBreakpointAttributeTranslator; +import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointDMContext; +import org.eclipse.dd.examples.pda.PDAPlugin; +import org.eclipse.dd.examples.pda.breakpoints.PDALineBreakpoint; +import org.eclipse.dd.examples.pda.breakpoints.PDAWatchpoint; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.model.IBreakpoint; + +/** + * + */ +public class PDABreakpointAttributeTranslator implements IBreakpointAttributeTranslator { + + private static final String[] fgPDALineBreakpointAttributes = { + IMarker.LINE_NUMBER, + }; + + private static final String[] fgPDAWatchpointAttributes = { + PDAWatchpoint.FUNCTION_NAME, + PDAWatchpoint.VAR_NAME, + PDAWatchpoint.ACCESS, + PDAWatchpoint.MODIFICATION + }; + + + public void initialize(BreakpointsMediator mediator) { + } + + public void dispose() { + } + + public List> getBreakpointAttributes(IBreakpoint bp, boolean bpManagerEnabled) + throws CoreException + { + Map attrs = new HashMap(); + + IMarker marker = bp.getMarker(); + if (marker == null || !marker.exists()) { + throw new DebugException(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Breakpoint marker does not exist", null)); + } + + // Suppress cast warning: platform is still on Java 1.3 + @SuppressWarnings("unchecked") + Map platformBpAttrs = marker.getAttributes(); + + if (bp instanceof PDAWatchpoint) { + attrs.put(PDABreakpoints.ATTR_BREAKPOINT_TYPE, PDABreakpoints.PDA_WATCHPOINT); + + copyAttributes(platformBpAttrs, attrs, fgPDAWatchpointAttributes); + } else if (bp instanceof PDALineBreakpoint) { + attrs.put(PDABreakpoints.ATTR_BREAKPOINT_TYPE, PDABreakpoints.PDA_LINE_BREAKPOINT); + attrs.put(PDABreakpoints.ATTR_PROGRAM_PATH, marker.getResource().getFullPath().toString()); + + copyAttributes(platformBpAttrs, attrs, fgPDALineBreakpointAttributes); + } + + // If the breakpoint manager is disabled, override the enabled attribute. + if (!bpManagerEnabled) { + attrs.put(IBreakpoint.ENABLED, false); + } + + List> retVal = new ArrayList>(1); + retVal.add(attrs); + return retVal; + } + + private void copyAttributes(Map srcMap, Map destMap, String[] attrs) { + for (String attr : attrs) { + if (srcMap.containsKey(attr)) { + destMap.put(attr, srcMap.get(attr)); + } + } + } + + public boolean canUpdateAttributes(IBreakpointDMContext bp, Map delta) { + // PDA debugger only allows updating of the action property of the watchpoint. + // All other breakpoint updates will require a reinstallation. + if (bp instanceof PDAWatchpoint) { + Map deltaCopy = new HashMap(delta); + deltaCopy.remove(PDAWatchpoint.ACCESS); + deltaCopy.remove(PDAWatchpoint.MODIFICATION); + return !deltaCopy.isEmpty(); + } + return false; + } + + public boolean supportsBreakpoint(IBreakpoint bp) { + return bp.getModelIdentifier().equals(PDAPlugin.ID_PDA_DEBUG_MODEL); + } + + public void updateBreakpointStatus(IBreakpoint bp) { + // PDA breakpoints do not support status reporting + } + +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/breakpoints/PDABreakpoints.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/breakpoints/PDABreakpoints.java new file mode 100644 index 00000000000..4f9625ba0f0 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/breakpoints/PDABreakpoints.java @@ -0,0 +1,264 @@ +/******************************************************************************* + * Copyright (c) 2007 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.examples.pda.service.breakpoints; + +import java.util.HashSet; +import java.util.Hashtable; +import java.util.Map; +import java.util.Set; + +import org.eclipse.core.resources.IMarker; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.debug.service.IBreakpoints; +import org.eclipse.dd.dsf.service.AbstractDsfService; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.examples.pda.PDAPlugin; +import org.eclipse.dd.examples.pda.breakpoints.PDAWatchpoint; +import org.eclipse.dd.examples.pda.service.command.PDACommand; +import org.eclipse.dd.examples.pda.service.command.PDACommandControl; +import org.eclipse.dd.examples.pda.service.command.PDACommandResult; +import org.osgi.framework.BundleContext; + +/** + * Initial breakpoint service implementation. + * Implements the IBreakpoints interface. + */ +public class PDABreakpoints extends AbstractDsfService implements IBreakpoints +{ + public static final String ATTR_BREAKPOINT_TYPE = PDAPlugin.PLUGIN_ID + ".pdaBreakpointType"; //$NON-NLS-1$ + public static final String PDA_LINE_BREAKPOINT = "breakpoint"; //$NON-NLS-1$ + public static final String PDA_WATCHPOINT = "watchpoint"; //$NON-NLS-1$ + public static final String ATTR_PROGRAM_PATH = PDAPlugin.PLUGIN_ID + ".pdaProgramPath"; //$NON-NLS-1$ + + private final String fProgram; + + // Services + private PDACommandControl fCommandControl; + + // Service breakpoints tracking + // The breakpoints are stored per context and keyed on the back-end breakpoint reference + private Set fBreakpoints = new HashSet(); + + /** + * The service constructor + * + * @param session The debugging session this service belongs to. + * @param program The name of the program of this PDA debugger. + */ + public PDABreakpoints(DsfSession session, String program) { + super(session); + fProgram = program; + } + + @Override + public void initialize(final RequestMonitor rm) { + super.initialize(new RequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + doInitialize(rm); + } + }); + } + + private void doInitialize(final RequestMonitor rm) { + + // Get the services references + fCommandControl = getServicesTracker().getService(PDACommandControl.class); + + // Register this service + register(new String[] { IBreakpoints.class.getName(), PDABreakpoints.class.getName() }, + new Hashtable()); + + rm.done(); + } + + @Override + public void shutdown(final RequestMonitor rm) { + unregister(); + rm.done(); + } + + @Override + protected BundleContext getBundleContext() { + return PDAPlugin.getBundleContext(); + } + + public void getBreakpoints(final IBreakpointsTargetDMContext context, final DataRequestMonitor rm) { + // Validate the context + if (!fCommandControl.getDMContext().equals(context)) { + PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid breakpoints target context"); + return; + } + + rm.setData(fBreakpoints.toArray(new IBreakpointDMContext[fBreakpoints.size()])); + rm.done(); + } + + public void getBreakpointDMData(IBreakpointDMContext dmc, DataRequestMonitor rm) { + PDAPlugin.failRequest(rm, IDsfService.NOT_SUPPORTED, "Retrieving breakpoint data is not supported"); + } + + public void insertBreakpoint(IBreakpointsTargetDMContext context, Map attributes, + DataRequestMonitor rm) + { + String type = (String) attributes.get(ATTR_BREAKPOINT_TYPE); + + if (PDA_LINE_BREAKPOINT.equals(type)) { + doInsertBreakpoint(attributes, rm); + } + else if (PDA_WATCHPOINT.equals(type)) { + doInsertWatchpoint(attributes, rm); + } + else { + PDAPlugin.failRequest(rm, IDsfService.REQUEST_FAILED, "Unknown breakpoint type"); + } + } + + private void doInsertBreakpoint(final Map attributes, final DataRequestMonitor rm) + { + String program = (String)attributes.get(ATTR_PROGRAM_PATH); + if (!fProgram.equals(program)) { + PDAPlugin.failRequest(rm, IDsfService.REQUEST_FAILED, "Invalid file name"); + return; + } + + Integer line = (Integer)attributes.get(IMarker.LINE_NUMBER); + if (line == null) { + PDAPlugin.failRequest(rm, IDsfService.REQUEST_FAILED, "No breakpoint line specified"); + return; + } + + final BreakpointDMContext breakpointCtx = + new BreakpointDMContext(getSession().getId(), fCommandControl.getDMContext(), line); + if (fBreakpoints.contains(breakpointCtx)) { + PDAPlugin.failRequest(rm, IDsfService.REQUEST_FAILED, "Breakpoint already set"); + return; + } + + fBreakpoints.add(breakpointCtx); + fCommandControl.queueCommand( + new PDACommand(fCommandControl.getDMContext(), "set " + line), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + rm.setData(breakpointCtx); + rm.done(); + } + + @Override + protected void handleErrorOrCancel() { + fBreakpoints.remove(breakpointCtx); + super.handleErrorOrCancel(); + } + }); + } + + private void doInsertWatchpoint(final Map attributes, final DataRequestMonitor rm) + { + String function = (String)attributes.get(PDAWatchpoint.FUNCTION_NAME); + if (function == null) { + PDAPlugin.failRequest(rm, IDsfService.REQUEST_FAILED, "No function specified"); + return; + } + + String variable = (String)attributes.get(PDAWatchpoint.VAR_NAME); + if (variable == null) { + PDAPlugin.failRequest(rm, IDsfService.REQUEST_FAILED, "No variable specified"); + return; + } + + Boolean isAccess = (Boolean)attributes.get(PDAWatchpoint.ACCESS); + isAccess = isAccess != null ? isAccess : Boolean.FALSE; + + Boolean isModification = (Boolean)attributes.get(PDAWatchpoint.MODIFICATION); + isModification = isModification != null ? isModification : Boolean.FALSE; + + final WatchpointDMContext watchpointCtx = + new WatchpointDMContext(getSession().getId(), fCommandControl.getDMContext(), function, variable); + if (fBreakpoints.contains(watchpointCtx)) { + PDAPlugin.failRequest(rm, IDsfService.REQUEST_FAILED, "Watchpoint already set"); + return; + } + + int watchOperation = 0; + if (isAccess && isModification) { + watchOperation = 3; + } else if (isAccess) { + watchOperation = 1; + } else if (isModification) { + watchOperation = 2; + } + + String watchCommand = "watch " + function + "::" + variable + " " + watchOperation; + + fBreakpoints.add(watchpointCtx); + fCommandControl.queueCommand( + new PDACommand(fCommandControl.getDMContext(), watchCommand), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + rm.setData(watchpointCtx); + rm.done(); + } + + @Override + protected void handleErrorOrCancel() { + // Since the command failed, we need to remove the breakpoint from + // the existing breakpoint set. + fBreakpoints.remove(watchpointCtx); + super.handleErrorOrCancel(); + } + }); + } + + public void removeBreakpoint(IBreakpointDMContext bpCtx, RequestMonitor rm) { + if (!fBreakpoints.contains(bpCtx)) { + PDAPlugin.failRequest(rm, IDsfService.REQUEST_FAILED, "Breakpoint already removed"); + return; + } + + if (bpCtx instanceof BreakpointDMContext) { + doRemoveBreakpoint((BreakpointDMContext)bpCtx, rm); + } else if (bpCtx instanceof WatchpointDMContext) { + doRemoveWatchpoint((WatchpointDMContext)bpCtx, rm); + } else { + PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid breakpoint"); + } + } + + private void doRemoveBreakpoint(BreakpointDMContext bpCtx, RequestMonitor rm) { + // Remove the breakpoint from the table right away, so that even when + // the remove is being processed, a new breakpoint can be created at the same + // location. + fBreakpoints.remove(bpCtx); + + fCommandControl.queueCommand( + new PDACommand(fCommandControl.getDMContext(), "clear " + bpCtx.fLine), + new DataRequestMonitor(getExecutor(), rm)); + } + + private void doRemoveWatchpoint(WatchpointDMContext bpCtx, RequestMonitor rm) { + fBreakpoints.remove(bpCtx); + + // Watchpoints are cleared using the same command, but with a "no watch" operation + String command = "watch " + bpCtx.fFunction + "::" + bpCtx.fVariable + " 0"; + fCommandControl.queueCommand( + new PDACommand(fCommandControl.getDMContext(), command), + new DataRequestMonitor(getExecutor(), rm)); + } + + public void updateBreakpoint(IBreakpointDMContext dmc, Map properties, RequestMonitor rm) { + PDAPlugin.failRequest(rm, IDsfService.NOT_SUPPORTED, "Modifying PDA breakpoints is not supported"); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/breakpoints/WatchpointDMContext.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/breakpoints/WatchpointDMContext.java new file mode 100644 index 00000000000..6e0e7252a87 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/breakpoints/WatchpointDMContext.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.breakpoints; + +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.datamodel.AbstractDMContext; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; + +/** + * Context representing a watch point. In PDA debugger, a watchpoint is + * uniquely identified using the function and variable. + */ +@Immutable +class WatchpointDMContext extends AbstractDMContext implements IBreakpointDMContext { + final String fFunction; + final String fVariable; + + public WatchpointDMContext(String sessionId, PDACommandControlDMContext commandControlCtx, String function, + String variable) + { + super(sessionId, new IDMContext[] { commandControlCtx }); + fFunction = function; + fVariable = variable; + } + + @Override + public boolean equals(Object obj) { + if (baseEquals(obj)) { + WatchpointDMContext watchpointCtx = (WatchpointDMContext)obj; + return fFunction.equals(watchpointCtx.fFunction) && fVariable.equals(watchpointCtx.fVariable); + } + return false; + } + + @Override + public int hashCode() { + return baseHashCode() + fFunction.hashCode() + fVariable.hashCode(); + } + + @Override + public String toString() { + return baseToString() + ".watchpoint(" + fFunction + "::" + fVariable + ")"; + } +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommand.java new file mode 100644 index 00000000000..cb6215a4136 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommand.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.command; + +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.examples.pda.service.command.commands.PDACommandBase; + +/** + * + */ +public class PDACommand extends PDACommandBase { + public PDACommand(IDMContext context, String command) { + super(context, command); + } + + @Override + public PDACommandResult createResult(String resultText) { + return new PDACommandResult(resultText); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommandControl.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommandControl.java new file mode 100644 index 00000000000..c2e6b5675f4 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommandControl.java @@ -0,0 +1,477 @@ +package org.eclipse.dd.examples.pda.service.command; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.net.Socket; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.dd.dsf.debug.service.command.ICommand; +import org.eclipse.dd.dsf.debug.service.command.ICommandControl; +import org.eclipse.dd.dsf.debug.service.command.ICommandListener; +import org.eclipse.dd.dsf.debug.service.command.ICommandResult; +import org.eclipse.dd.dsf.debug.service.command.IEventListener; +import org.eclipse.dd.dsf.service.AbstractDsfService; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.examples.pda.PDAPlugin; +import org.eclipse.dd.examples.pda.service.command.commands.PDACommandBase; +import org.eclipse.dd.examples.pda.service.command.commands.PDACommandBaseResult; +import org.eclipse.dd.examples.pda.service.command.commands.PDAExitCommand; +import org.osgi.framework.BundleContext; + + +/** + * Service that handles communication with a PDA debugger back end. + */ +public class PDACommandControl extends AbstractDsfService implements ICommandControl { + + // Structure used to store command information in services internal queues. + private static class CommandHandle { + final private PDACommandBase fCommand; + final private DataRequestMonitor fRequestMonitor; + + CommandHandle(PDACommandBase c, DataRequestMonitor rm) { + fCommand = c; + fRequestMonitor = rm; + } + } + + // Queue of commands waiting to be sent to the debugger. As long as commands + // are in this queue, they can still be removed by clients. + private final List fCommandQueue = new LinkedList(); + + // Queue of commands that are being sent to the debugger. This queue is read + // by the send job, so as soon as commands are inserted into this queue, they can + // be considered as sent. + @ThreadSafe + private final BlockingQueue fTxCommands = new LinkedBlockingQueue(); + + // Flag indicating that the PDA debugger started + private boolean fStarted = false; + + // Flag indicating that the PDA debugger has been disconnected + @ThreadSafe + private boolean fTerminated = false; + + // Data Model context of this command control. + private PDACommandControlDMContext fDMContext; + + // Synchronous listeners for commands and events. + private final List fCommandListeners = new ArrayList(); + private final List fEventListeners = new ArrayList(); + + // Sockets for communicating with PDA debugger + final private int fRequestPort; + final private int fEventPort; + private Socket fRequestSocket; + private PrintWriter fRequestWriter; + private BufferedReader fRequestReader; + private Socket fEventSocket; + private BufferedReader fEventReader; + + // Jobs servicing the sockets. + private EventDispatchJob fEventDispatchJob; + private CommandSendJob fRequestJob; + + /** + * Command control constructor. + * @param session The DSF session that this service is a part of. + * @param requestPort Port number for sending PDA commands. + * @param eventPort Port for listening to PDA events. + */ + public PDACommandControl(DsfSession session, int requestPort, int eventPort) { + super(session); + fRequestPort = requestPort; + fEventPort = eventPort; + } + + @Override + public void initialize(final RequestMonitor rm) { + super.initialize( new RequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + doInitialize(rm); + } + }); + } + + public void doInitialize(final RequestMonitor rm) { + // Create the control's data model context. + fDMContext = new PDACommandControlDMContext(getSession().getId()); + + addEventListener(new IEventListener() { + public void eventReceived(Object output) { + if ("started".equals(output)) { + setStarted(); + } else if ("terminated".equals(output)) { + setTerminated(); + } + } + }); + + // Request monitor that will be invoked when the socket initialization is + // completed. + final RequestMonitor socketsInitializeRm = new RequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + // Register the service with OSGi as the last step in initialization of + // the service. + register( + new String[]{ ICommandControl.class.getName(), PDACommandControl.class.getName() }, + new Hashtable()); + rm.done(); + } + }; + + // To avoid blocking the DSF dispatch thread use a job to initialize communication sockets. + new Job("PDA Initialize") { + @Override + protected IStatus run(IProgressMonitor monitor) { + try { + // give interpreter a chance to start + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + } + fRequestSocket = new Socket("localhost", fRequestPort); + fRequestWriter = new PrintWriter(fRequestSocket.getOutputStream()); + fRequestReader = new BufferedReader(new InputStreamReader(fRequestSocket.getInputStream())); + // give interpreter a chance to open next socket + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + } + fEventSocket = new Socket("localhost", fEventPort); + fEventReader = new BufferedReader(new InputStreamReader(fEventSocket.getInputStream())); + + fEventDispatchJob = new EventDispatchJob(); + fEventDispatchJob.schedule(); + + fRequestJob = new CommandSendJob(); + fRequestJob.schedule(); + + socketsInitializeRm.done(); + } catch (UnknownHostException e) { + socketsInitializeRm.setStatus(new Status( + IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, "Unable to connect to PDA VM", e)); + socketsInitializeRm.done(); + } catch (IOException e) { + socketsInitializeRm.setStatus(new Status( + IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, "Unable to connect to PDA VM", e)); + socketsInitializeRm.done(); + } + return Status.OK_STATUS; + } + }.schedule(); + } + + @Override + public void shutdown(final RequestMonitor requestMonitor) { + // Unregister the service first, so that clients may no longer gain access to it. + unregister(); + + if (!isTerminated()) { + // If the debugger is still connected, send it the exit command. + terminate(new RequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleCompleted() { + // Mark the command control as terminated. + setTerminated(); + + // Ignore any error resulting from the exit command. + // Errors will most likely result if the PDA process is + // already terminated. + requestMonitor.done(); + } + }); + } else { + requestMonitor.done(); + } + } + + @Override + protected BundleContext getBundleContext() { + return PDAPlugin.getBundleContext(); + } + + class CommandSendJob extends Job { + public CommandSendJob() { + super("PDA Command Send"); + setSystem(true); + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + while (!isTerminated()) { + synchronized(fTxCommands) { + try { + final CommandHandle commandHandle = fTxCommands.take(); + fRequestWriter.println(commandHandle.fCommand.getRequest()); + fRequestWriter.flush(); + + try { + // wait for reply + final String response = fRequestReader.readLine(); + getExecutor().execute(new DsfRunnable() { + public void run() { + processCommandDone(commandHandle, response); + } + }); + + + } catch (final IOException e) { + getExecutor().execute(new DsfRunnable() { + public void run() { + processCommandException(commandHandle, e); + } + }); + } + } catch (InterruptedException e) { + break; // Shutting down. + } + } + } + return Status.OK_STATUS; + } + + } + + /** + * Listens to events from the PDA VM and fires corresponding + * debug events. + */ + class EventDispatchJob extends Job { + + public EventDispatchJob() { + super("PDA Event Dispatch"); + setSystem(true); + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + while (!isTerminated()) { + try { + final String event = fEventReader.readLine(); + if (event != null) { + try { + getExecutor().execute(new DsfRunnable() { + public void run() { + processEventReceived(event); + } + }); + } catch (RejectedExecutionException e) {} + } else { + break; + } + } catch (IOException e) { + break; + } + } + if (!isTerminated()) { + try { + getExecutor().execute(new DsfRunnable() { + public void run() { + setTerminated(); + } + }); + } catch (RejectedExecutionException e) {} + } + return Status.OK_STATUS; + } + + } + + public void queueCommand(ICommand command, DataRequestMonitor rm) { + if (command instanceof PDACommandBase) { + // Cast from command with "" to a more concrete + // type to use internally in the command control. + @SuppressWarnings("unchecked") + PDACommandBase pdaCommand = (PDACommandBase)command; + + // Similarly, cast the request monitor to a more concrete type. + @SuppressWarnings("unchecked") + DataRequestMonitor pdaRM = (DataRequestMonitor)rm; + + fCommandQueue.add( new CommandHandle(pdaCommand, pdaRM) ); + for (ICommandListener listener : fCommandListeners) { + listener.commandQueued(command); + } + + getExecutor().execute(new DsfRunnable() { + public void run() { + processQueues(); + } + }); + + } else { + rm.setStatus(new Status( + IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Unrecognized command: " + command, null)); + rm.done(); + } + } + + public void cancelCommand(ICommand command) { + // This debugger is unable of canceling commands once they have + // been sent. + } + + public void removeCommand(ICommand command) { + for (Iterator itr = fCommandQueue.iterator(); itr.hasNext();) { + CommandHandle handle = itr.next(); + if (command.equals(handle.fCommand)) { + itr.remove(); + for (ICommandListener listener : fCommandListeners) { + listener.commandRemoved(command); + } + } + } + } + + public void addCommandListener(ICommandListener processor) { + fCommandListeners.add(processor); + } + + public void removeCommandListener(ICommandListener processor) { + fCommandListeners.remove(processor); + } + + public void addEventListener(IEventListener processor) { + fEventListeners.add(processor); + } + + public void removeEventListener(IEventListener processor) { + fEventListeners.remove(processor); + } + + private void processCommandDone(CommandHandle handle, String response) { + PDAPlugin.debug(response); + + PDACommandBaseResult result = handle.fCommand.createResult(response); + handle.fRequestMonitor.setData(result); + handle.fRequestMonitor.done(); + + for (ICommandListener listener : fCommandListeners) { + listener.commandDone(handle.fCommand, result); + } + processQueues(); + } + + private void processCommandException(CommandHandle handle, Throwable exception) { + handle.fRequestMonitor.setStatus(new Status( + IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, "Exception reading request response", exception)); + handle.fRequestMonitor.done(); + + for (ICommandListener listener : fCommandListeners) { + listener.commandDone(handle.fCommand, null); + } + } + + private void processEventReceived(String event) { + PDAPlugin.debug(event); + for (IEventListener listener : fEventListeners) { + listener.eventReceived(event); + } + } + + private synchronized void processQueues() { + if (isTerminated()) { + // If the PDA debugger is terminated. Return all submitted commands + // with an error. + for (CommandHandle handle : fCommandQueue) { + handle.fRequestMonitor.setStatus(new Status( + IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Command control is terminated", null)); + handle.fRequestMonitor.done(); + } + fCommandQueue.clear(); + } else if (fStarted && fTxCommands.isEmpty() && !fCommandQueue.isEmpty()) { + // Process the queues if: + // - the PDA debugger has started, + // - there are no pending commands in the send queue, + // - and there are commands waiting to be sent. + CommandHandle handle = fCommandQueue.remove(0); + fTxCommands.add(handle); + PDAPlugin.debug(handle.fCommand.getRequest()); + for (ICommandListener listener : fCommandListeners) { + listener.commandSent(handle.fCommand); + } + } + } + + @ThreadSafe + public PDACommandControlDMContext getDMContext() { + return fDMContext; + } + + private void setStarted() { + fStarted = true; + + // Process any waiting commands. + processQueues(); + + // Issue a data model event. + getSession().dispatchEvent(new PDAStartedEvent(getDMContext()), getProperties()); + } + + /** + * Returns whether the PDA debugger has started and is processing commands. + */ + public boolean isStarted() { + return fStarted; + } + + @ThreadSafe + private synchronized void setTerminated() { + // Set terminated may be called more than once: by event listener thread, + // by the terminate command, etc, so protect against sending events multiple + // times. + if (!fTerminated) { + fTerminated = true; + + // Process any waiting commands, they all should return with an error. + processQueues(); + + // Issue a data model event. + getSession().dispatchEvent(new PDATerminatedEvent(getDMContext()), getProperties()); + } + } + + /** + * Returns whether the PDA debugger has been terminated. + */ + @ThreadSafe + public synchronized boolean isTerminated() { + return fTerminated; + } + + /** + * Sends a command to PDA debugger to terminate. + */ + public void terminate(RequestMonitor rm) { + if (!isTerminated()) { + queueCommand( + new PDAExitCommand(fDMContext), + new DataRequestMonitor(getExecutor(), rm)); + } else { + // If already terminated, indicate success. + rm.done(); + } + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommandControlDMContext.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommandControlDMContext.java new file mode 100644 index 00000000000..2b34baf4477 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommandControlDMContext.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.command; + +import org.eclipse.dd.dsf.datamodel.AbstractDMContext; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; + +/** + * + */ +public class PDACommandControlDMContext extends AbstractDMContext + implements IExecutionDMContext, IBreakpointsTargetDMContext +{ + + private Object fHashObject = new Object(); + + public PDACommandControlDMContext(String sessionId) { + super(sessionId, new IDMContext[0]); + } + + @Override + public boolean equals(Object obj) { + return obj == this; + } + + @Override + public int hashCode() { + return fHashObject.hashCode(); + } + + @Override + public String toString() { + return "PDA(" + getSessionId() + ")"; + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommandResult.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommandResult.java new file mode 100644 index 00000000000..1d81993739a --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommandResult.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.command; + +import org.eclipse.dd.examples.pda.service.command.commands.PDACommandBaseResult; + + +/** + * @see PDACommand + */ +public class PDACommandResult extends PDACommandBaseResult { + PDACommandResult(String response) { + super(response); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDAStartedEvent.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDAStartedEvent.java new file mode 100644 index 00000000000..0c9f16ab8d1 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDAStartedEvent.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.command; + +import org.eclipse.dd.dsf.datamodel.AbstractDMEvent; + +/** + * + */ +public class PDAStartedEvent extends AbstractDMEvent { + PDAStartedEvent(PDACommandControlDMContext context) { + super(context); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDATerminatedEvent.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDATerminatedEvent.java new file mode 100644 index 00000000000..ebc43b642c5 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDATerminatedEvent.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.command; + +import org.eclipse.dd.dsf.datamodel.AbstractDMEvent; + +/** + * + */ +public class PDATerminatedEvent extends AbstractDMEvent { + PDATerminatedEvent(PDACommandControlDMContext context) { + super(context); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAClearBreakpointCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAClearBreakpointCommand.java new file mode 100644 index 00000000000..c513d49362d --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAClearBreakpointCommand.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; + +/** + * Clears any breakpoint set on given line + * + *
    + *    C: clear {line}
    + *    R: ok
    + * 
    + + */ +public class PDAClearBreakpointCommand extends PDACommandBase { + + public PDAClearBreakpointCommand(IDMContext context, int line) { + super(context, "clear " + line); + } + + @Override + public PDACommandBaseResult createResult(String resultText) { + return new PDACommandBaseResult(resultText); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDACommandBase.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDACommandBase.java new file mode 100644 index 00000000000..1c0c8e82c3c --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDACommandBase.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.command.ICommand; +import org.eclipse.dd.dsf.debug.service.command.ICommandResult; + +/** + * + */ +abstract public class PDACommandBase implements ICommand { + + final private IDMContext fContext; + final private String fRequest; + + public PDACommandBase(IDMContext context, String request) { + fContext = context; + fRequest = request; + } + + public IDMContext getContext() { + return fContext; + } + + public ICommand coalesceWith(ICommand command) { + return null; + } + + public String getRequest() { + return fRequest; + } + + abstract public V createResult(String resultText); + + @Override + public boolean equals(Object obj) { + if (obj instanceof PDACommandBase) { + PDACommandBase cmd = (PDACommandBase)obj; + return fContext.equals(cmd.fContext) && fRequest.equals(cmd.fRequest); + } + return false; + } + + @Override + public int hashCode() { + return fContext.hashCode() + fRequest.hashCode(); + } + +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDACommandBaseResult.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDACommandBaseResult.java new file mode 100644 index 00000000000..c700ea339a1 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDACommandBaseResult.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.command.commands; + +import org.eclipse.dd.dsf.debug.service.command.ICommand; +import org.eclipse.dd.dsf.debug.service.command.ICommandResult; + +/** + * + */ +public class PDACommandBaseResult implements ICommandResult { + + final public String fResponseText; + + protected PDACommandBaseResult(String response) { + fResponseText = response; + } + + public V getSubsetResult(ICommand command) { + return null; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof PDACommandBaseResult) { + PDACommandBaseResult result = (PDACommandBaseResult)obj; + return fResponseText.equals(result.fResponseText); + } + return false; + } + + @Override + public int hashCode() { + return fResponseText.hashCode(); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDADataCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDADataCommand.java new file mode 100644 index 00000000000..26614c26653 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDADataCommand.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; + +/** + * Retrieves data stack information + * + *
    + *    C: data
    + *    R: {value 1}|{value 2}|{value 3}|...|
    + * 
    + */ +public class PDADataCommand extends PDACommandBase { + + public PDADataCommand(IDMContext context) { + super(context, "data"); + } + + @Override + public PDACommandBaseResult createResult(String resultText) { + return new PDACommandBaseResult(resultText); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDADataCommandResult.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDADataCommandResult.java new file mode 100644 index 00000000000..322cb3fe1c6 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDADataCommandResult.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.command.commands; + +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; + +/** + * @see PDADataCommand + */ +public class PDADataCommandResult extends PDACommandBaseResult { + + final public int[] fValues; + + PDADataCommandResult(String response) { + super(response); + StringTokenizer st = new StringTokenizer(response, "|"); + List valuesList = new ArrayList(); + + while (st.hasMoreTokens()) { + String token = st.nextToken(); + if (token.length() != 0) { + valuesList.add(new Integer(st.nextToken())); + } + } + + + fValues = new int[valuesList.size()]; + for (int i = 0; i < valuesList.size(); i++) { + fValues[i] = valuesList.get(i); + } + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDADropFrameCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDADropFrameCommand.java new file mode 100644 index 00000000000..dbd705bb7d0 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDADropFrameCommand.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; + +/** + * Returns from the current frame without executing the rest of instructions. + * + *
    + *    C: drop
    + *    R: ok
    + *    E: resumed drop
    + *    E: suspended drop
    + * 
    + + */ +public class PDADropFrameCommand extends PDACommandBase { + + public PDADropFrameCommand(IDMContext context) { + super(context, "drop"); + } + + @Override + public PDACommandBaseResult createResult(String resultText) { + return new PDACommandBaseResult(resultText); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAEvalCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAEvalCommand.java new file mode 100644 index 00000000000..7978a3f8485 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAEvalCommand.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; + +/** + * Sets what events cause the execution to stop. + * + *
    + *    C: eval {instruction}%20{parameter}|{instruction}%20{parameter}|...
    + *    R: ok
    + *    E: resume client
    + *    E: evalresult result
    + *    E: suspended eval
    + * 
    + * + * Where event_name could be unimpinstr or nosuchlabel. + */ +public class PDAEvalCommand extends PDACommandBase { + + public PDAEvalCommand(IDMContext context, String operation) { + super(context, "eval " + operation); + } + + @Override + public PDACommandBaseResult createResult(String resultText) { + return new PDACommandBaseResult(resultText); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAEventStopCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAEventStopCommand.java new file mode 100644 index 00000000000..d6ed8d23f97 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAEventStopCommand.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; + +/** + * Sets what events cause the execution to stop. + * + *
    + *    C: eventstop {event_name} {0|1}
    + *    R: ok
    + *    ...
    + *    E: suspended event {event_name}
    + * 
    + * + * Where event_name could be unimpinstr or nosuchlabel. + */ +public class PDAEventStopCommand extends PDACommandBase { + + public enum Event { UNIMPINSTR, NOSUCHLABEL }; + + public PDAEventStopCommand(IDMContext context, Event event, boolean enable) { + super(context, + "eventstop " + + (event == Event.UNIMPINSTR ? "unimpinstr " : "nosuchlabel ") + + (enable ? "1" : "0")); + } + + @Override + public PDACommandBaseResult createResult(String resultText) { + return new PDACommandBaseResult(resultText); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAExitCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAExitCommand.java new file mode 100644 index 00000000000..f1a78b77cf3 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAExitCommand.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; + +/** + * Instructs the debugger to exit. + * + *
    + *    C: exit
    + *    R: ok
    + * 
    + */ +public class PDAExitCommand extends PDACommandBase { + + public PDAExitCommand(IDMContext context) { + super(context, "exit"); + } + + @Override + public PDACommandBaseResult createResult(String resultText) { + return new PDACommandBaseResult(resultText); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAPopDataCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAPopDataCommand.java new file mode 100644 index 00000000000..3a27d46f5ed --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAPopDataCommand.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; + +/** + * Pops the top value from the data stack + * + *
    + *    C: popdata
    + *    R: ok
    + * 
    + */ +public class PDAPopDataCommand extends PDACommandBase { + + public PDAPopDataCommand(IDMContext context) { + super(context, "popdata"); + } + + @Override + public PDACommandBaseResult createResult(String resultText) { + return new PDACommandBaseResult(resultText); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAPushDataCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAPushDataCommand.java new file mode 100644 index 00000000000..73e902b5f65 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAPushDataCommand.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; + +/** + * Pushes the given value on top of the data stack. + * + *
    + *    C: pushdata {value}
    + *    R: ok
    + * 
    + */ +public class PDAPushDataCommand extends PDACommandBase { + + public PDAPushDataCommand(IDMContext context, int value) { + super(context, "pushdata " + value); + } + + @Override + public PDACommandBaseResult createResult(String resultText) { + return new PDACommandBaseResult(resultText); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAResumeCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAResumeCommand.java new file mode 100644 index 00000000000..c0a29a958e5 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAResumeCommand.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; + +/** + * Resumes the execution + * + *
    + *    C: resume
    + *    R: ok
    + *    E: resumed client
    + * 
    + */ +public class PDAResumeCommand extends PDACommandBase { + + public PDAResumeCommand(IDMContext context) { + super(context, "resume"); + } + + @Override + public PDACommandBaseResult createResult(String resultText) { + return new PDACommandBaseResult(resultText); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASetBreakpointCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASetBreakpointCommand.java new file mode 100644 index 00000000000..30844bac9be --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASetBreakpointCommand.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; + +/** + * Sets a breakpoint at given line + * + *
    + *    C: set {line_number}
    + *    R: ok
    + *    C: resume
    + *    E: resumed client
    + *    E: suspended breakpoint line_number
    + * 
    + */ +public class PDASetBreakpointCommand extends PDACommandBase { + + public PDASetBreakpointCommand(IDMContext context, int line) { + super(context, "set " + line); + } + + @Override + public PDACommandBaseResult createResult(String resultText) { + return new PDACommandBaseResult(resultText); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASetDataCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASetDataCommand.java new file mode 100644 index 00000000000..7a7c1fa5b0e --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASetDataCommand.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; + +/** + * Sets a data value in the data stack at the given location + * + *
    + *    C: setdata {index} {value}
    + *    R: ok
    + * 
    + */ +public class PDASetDataCommand extends PDACommandBase { + + public PDASetDataCommand(IDMContext context, int index, int value) { + super(context, "setdata " + index + " " + value); + } + + @Override + public PDACommandBaseResult createResult(String resultText) { + return new PDACommandBaseResult(resultText); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASetVarCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASetVarCommand.java new file mode 100644 index 00000000000..8a0cb9eaa99 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASetVarCommand.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; + +/** + * Sets a variable value + * + *
    + *    C: setvar {variable} {value}
    + *    R: ok
    + * 
    + */ +public class PDASetVarCommand extends PDACommandBase { + + public PDASetVarCommand(IDMContext context, String variable, int value) { + super(context, "setvar " + variable + " " + value); + } + + @Override + public PDACommandBaseResult createResult(String resultText) { + return new PDACommandBaseResult(resultText); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStackCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStackCommand.java new file mode 100644 index 00000000000..5ca5a30eb05 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStackCommand.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; + +/** + * Retrieves command stack information + * + *
    + *    C: stack
    + *    R: {file}|{line}|{function}|{var_1}|{var_2}|...#{file}|{line}|{function}|{var_1}|{var_2}|...#...
    + * 
    + */ +public class PDAStackCommand extends PDACommandBase { + + public PDAStackCommand(IDMContext context) { + super(context, "stack"); + } + + @Override + public PDACommandBaseResult createResult(String resultText) { + return new PDACommandBaseResult(resultText); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStackCommandResult.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStackCommandResult.java new file mode 100644 index 00000000000..41cc81a9f29 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStackCommandResult.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.command.commands; + +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + +/** + * @see PDAStackCommand + */ +public class PDAStackCommandResult extends PDACommandBaseResult { + + public static class Frame { + Frame(String frameString) { + StringTokenizer st = new StringTokenizer(frameString, "|"); + + fFilePath = new Path(st.nextToken()); + fLine = Integer.parseInt(st.nextToken()); + fFunction = st.nextToken(); + + List variablesList = new ArrayList(); + while (st.hasMoreTokens()) { + variablesList.add(st.nextToken()); + } + fVariables = variablesList.toArray(new String[variablesList.size()]); + } + final public IPath fFilePath; + final public int fLine; + final public String fFunction; + final public String[] fVariables; + } + + final public Frame[] fFrames; + + PDAStackCommandResult(String response) { + super(response); + StringTokenizer st = new StringTokenizer(response, "#"); + List framesList = new ArrayList(); + + while (st.hasMoreTokens()) { + framesList.add(new Frame(st.nextToken())); + } + fFrames = framesList.toArray(new Frame[framesList.size()]); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStepCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStepCommand.java new file mode 100644 index 00000000000..97d0311f831 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStepCommand.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; + +/** + * Executes next instruciton + * + *
    + *    C: step
    + *    R: ok
    + *    E: resumed client
    + *    E: suspended step
    + * 
    + */ +public class PDAStepCommand extends PDACommandBase { + + public PDAStepCommand(IDMContext context) { + super(context, "step"); + } + + @Override + public PDACommandBaseResult createResult(String resultText) { + return new PDACommandBaseResult(resultText); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStepReturnCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStepReturnCommand.java new file mode 100644 index 00000000000..e8be6d5ec06 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStepReturnCommand.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; + +/** + * Executes instructions until the current subroutine is finished + * + *
    + *    C: stepreturn
    + *    R: ok
    + *    E: resumed step
    + *    E: suspended step
    + * 
    + */ +public class PDAStepReturnCommand extends PDACommandBase { + + public PDAStepReturnCommand(IDMContext context) { + super(context, "stepreturn"); + } + + @Override + public PDACommandBaseResult createResult(String resultText) { + return new PDACommandBaseResult(resultText); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASuspendCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASuspendCommand.java new file mode 100644 index 00000000000..4b07d0a066b --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASuspendCommand.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; + +/** + * Suspends execution + * + *
    + *    C: suspend
    + *    R: ok
    + *    E: suspended client
    + * 
    + */ +public class PDASuspendCommand extends PDACommandBase { + + public PDASuspendCommand(IDMContext context) { + super(context, "suspend"); + } + + @Override + public PDACommandBaseResult createResult(String resultText) { + return new PDACommandBaseResult(resultText); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAVarCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAVarCommand.java new file mode 100644 index 00000000000..d4b52df8cd6 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAVarCommand.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; + +/** + * Retrieves variable value + * + *
    + *    C: var {frame_number} {variable_name}
    + *    R: {variable_value}
    + * 
    + */ +public class PDAVarCommand extends PDACommandBase { + + public PDAVarCommand(IDMContext context, int frame, String name) { + super(context, "var " + frame + " " + name); + } + + @Override + public PDACommandBaseResult createResult(String resultText) { + return new PDACommandBaseResult(resultText); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAVarCommandResult.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAVarCommandResult.java new file mode 100644 index 00000000000..0b583335661 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAVarCommandResult.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.command.commands; + + +/** + * @see PDAVarCommand + */ +public class PDAVarCommandResult extends PDACommandBaseResult { + + final public int fValue; + + PDAVarCommandResult(String response) { + super(response); + fValue = Integer.parseInt(response); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAWatchCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAWatchCommand.java new file mode 100644 index 00000000000..48a959ed53d --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAWatchCommand.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; + +/** + * Sets a watchpoint on a given variable + * + *
    + *    C: watch {function}::{variable_name} {watch_operation}
    + *    R: ok
    + *    C: resume
    + *    R: resume client
    + *    E: suspended watch {watch_operation} {function}::{variable_name}
    + * 
    + */ +public class PDAWatchCommand extends PDACommandBase { + + public enum WatchOperation { READ, WRITE, BOTH, NONE }; + + private static int getWatchOperationCode(WatchOperation operation) { + switch (operation) { + case READ: + return 1; + case WRITE: + return 2; + case BOTH: + return 3; + default: + return 0; + } + } + + public PDAWatchCommand(IDMContext context, String function, String variable, WatchOperation operation) { + super(context, "watch " + function+ "::" + variable + " " + getWatchOperationCode(operation)); + } + + @Override + public PDACommandBaseResult createResult(String resultText) { + return new PDACommandBaseResult(resultText); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/ExecutionData.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/ExecutionData.java new file mode 100644 index 00000000000..8591e79c690 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/ExecutionData.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.runcontrol; + +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMData; +import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason; + +@Immutable +class ExecutionData implements IExecutionDMData { + private final StateChangeReason fReason; + ExecutionData(StateChangeReason reason) { + fReason = reason; + } + public StateChangeReason getStateChangeReason() { return fReason; } +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/PDARunControl.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/PDARunControl.java new file mode 100644 index 00000000000..3d075bbfc95 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/PDARunControl.java @@ -0,0 +1,270 @@ +/******************************************************************************* + * 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 + * Ericsson AB - Modified for handling of multiple threads + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.runcontrol; + +import java.util.Hashtable; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.datamodel.IDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.command.CommandCache; +import org.eclipse.dd.dsf.debug.service.command.IEventListener; +import org.eclipse.dd.dsf.service.AbstractDsfService; +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.examples.pda.PDAPlugin; +import org.eclipse.dd.examples.pda.service.command.PDACommand; +import org.eclipse.dd.examples.pda.service.command.PDACommandControl; +import org.eclipse.dd.examples.pda.service.command.PDACommandResult; +import org.osgi.framework.BundleContext; + + +/** + * + *

    + * Implementation note: + * This class implements event handlers for the events that are generated by + * this service itself. When the event is dispatched, these handlers will + * be called first, before any of the clients. These handlers update the + * service's internal state information to make them consistent with the + * events being issued. Doing this in the handlers as opposed to when + * the events are generated, guarantees that the state of the service will + * always be consistent with the events. + * The purpose of this pattern is to allow clients that listen to service + * events and track service state, to be perfectly in sync with the service + * state. + */ +public class PDARunControl extends AbstractDsfService + implements IRunControl, IEventListener +{ + + private PDACommandControl fCommandControl; + private CommandCache fCommandCache; + + // state flags + private boolean fSuspended = true; + private boolean fResumePending = false; + private boolean fStepping = false; + + private StateChangeReason fStateChangeReason; + + public PDARunControl(DsfSession session) { + super(session); + } + + @Override + public void initialize(final RequestMonitor rm) { + super.initialize( + new RequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + doInitialize(rm); + }}); + } + + private void doInitialize(final RequestMonitor rm) { + fCommandControl = getServicesTracker().getService(PDACommandControl.class); + fCommandCache = new CommandCache(fCommandControl); + + fCommandControl.addEventListener(this); + getSession().addServiceEventListener(this, null); + + register(new String[]{IRunControl.class.getName(), PDARunControl.class.getName()}, new Hashtable()); + + rm.done(); + } + + @Override + public void shutdown(final RequestMonitor rm) { + fCommandControl.removeEventListener(this); + + getSession().removeServiceEventListener(this); + fCommandCache.reset(); + super.shutdown(rm); + } + + public boolean isValid() { return true; } + + @SuppressWarnings("unchecked") + public void getModelData(IDMContext dmc, DataRequestMonitor rm) { + if (dmc instanceof IExecutionDMContext) { + getExecutionData((IExecutionDMContext)dmc, (DataRequestMonitor)rm); + } else { + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ + rm.done(); + } + } + + public CommandCache getCache() { return fCommandCache; } + + + public void eventReceived(Object output) { + if (!(output instanceof String)) return; + String event = (String)output; + + if (event.startsWith("suspended")) { + suspendedEventReceived(event); + } else if (event.startsWith("resumed")) { + resumedEventReceived(event); + } + } + + private void suspendedEventReceived(String event) { + IDMEvent dmEvent = new SuspendedEvent(fCommandControl.getDMContext(), event); + getSession().dispatchEvent(dmEvent, getProperties()); + } + + + @DsfServiceEventHandler + private void resumedEventReceived(String event) { + IDMEvent dmEvent = new ResumedEvent(fCommandControl.getDMContext(), event); + getSession().dispatchEvent(dmEvent, getProperties()); + } + + + @DsfServiceEventHandler + public void eventDispatched(ResumedEvent e) { + fSuspended = false; + fResumePending = false; + fStateChangeReason = e.getReason(); + fCommandCache.setTargetAvailable(false); + //fStateChangeTriggeringContext = e.getTriggeringContext(); + if (e.getReason().equals(StateChangeReason.STEP)) { + fStepping = true; + } else { + fCommandCache.reset(); + } + } + + + @DsfServiceEventHandler + public void eventDispatched(SuspendedEvent e) { + fCommandCache.setTargetAvailable(true); + fCommandCache.reset(); + fStateChangeReason = e.getReason(); + fResumePending = false; + fSuspended = true; + fStepping = false; + } + + + /////////////////////////////////////////////////////////////////////////// + // AbstractService + @Override + protected BundleContext getBundleContext() { + return PDAPlugin.getBundleContext(); + } + + /////////////////////////////////////////////////////////////////////////// + // IRunControl + public boolean canResume(IExecutionDMContext context) { + return isSuspended(context) && !fResumePending; + } + + public boolean canSuspend(IExecutionDMContext context) { + return !isSuspended(context); + } + + public boolean isSuspended(IExecutionDMContext context) { + return fSuspended; + } + + public boolean isStepping(IExecutionDMContext context) { + return !isSuspended(context) && fStepping; + } + + public void resume(IExecutionDMContext context, final RequestMonitor rm) { + assert context != null; + + if (canResume(context)) { + fResumePending = true; + // Cygwin GDB will accept commands and execute them after the step + // which is not what we want, so mark the target as unavailable + // as soon as we send a resume command. + fCommandCache.setTargetAvailable(false); + + fCommandControl.queueCommand( + new PDACommand(fCommandControl.getDMContext(), "resume"), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + rm.done(); + } + } + ); + }else { + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Given context: " + context + ", is already running.", null)); //$NON-NLS-1$ //$NON-NLS-2$ + rm.done(); + } + } + + public void suspend(IExecutionDMContext context, final RequestMonitor rm){ + assert context != null; + + if (canSuspend(context)) { + fCommandControl.queueCommand( + new PDACommand(fCommandControl.getDMContext(), "suspend"), + new DataRequestMonitor(getExecutor(), rm)); + + } else { + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Given context: " + context + ", is already suspended.", null)); //$NON-NLS-1$ //$NON-NLS-2$ + rm.done(); + } + } + + public boolean canStep(IExecutionDMContext context) { + return canResume(context); + } + + public void step(IExecutionDMContext context, StepType stepType, final RequestMonitor rm) { + assert context != null; + + if (canResume(context)) { + fResumePending = true; + fStepping = true; + fCommandCache.setTargetAvailable(false); + + fCommandControl.queueCommand( + new PDACommand(fCommandControl.getDMContext(), "step"), + new DataRequestMonitor(getExecutor(), rm)); + + } else { + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, INVALID_STATE, "Cannot resume context", null)); //$NON-NLS-1$ + rm.done(); + return; + } + } + + public boolean canInstructionStep(IExecutionDMContext context) { + return false; + } + + public void instructionStep(IExecutionDMContext context, StepType stepType, RequestMonitor rm) { + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, NOT_SUPPORTED, "Operation not implemented", null)); //$NON-NLS-1$ + rm.done(); + } + + public void getExecutionContexts(final IContainerDMContext containerDmc, final DataRequestMonitor rm) { + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, NOT_SUPPORTED, "Operation not implemented", null)); //$NON-NLS-1$ + rm.done(); + } + + public void getExecutionData(IExecutionDMContext dmc, DataRequestMonitor rm){ + rm.setData( new ExecutionData(fStateChangeReason) ); + rm.done(); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/ResumedEvent.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/ResumedEvent.java new file mode 100644 index 00000000000..68ee1d725d2 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/ResumedEvent.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.runcontrol; + +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.datamodel.AbstractDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason; + +@Immutable +class ResumedEvent extends AbstractDMEvent + implements IResumedDMEvent +{ + private final String fPDAEvent; + + ResumedEvent(IExecutionDMContext ctx, String pdaEvent) { + super(ctx); + fPDAEvent = pdaEvent; + } + + public StateChangeReason getReason() { + if (fPDAEvent.startsWith("resumed breakpoint") || fPDAEvent.startsWith("suspended watch")) { + return StateChangeReason.BREAKPOINT; + } else if (fPDAEvent.equals("resumed step") || fPDAEvent.equals("resumed drop")) { + return StateChangeReason.STEP; + } else if (fPDAEvent.equals("resumed client")) { + return StateChangeReason.USER_REQUEST; + } else { + return StateChangeReason.UNKNOWN; + } + } +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/SuspendedEvent.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/SuspendedEvent.java new file mode 100644 index 00000000000..04bf54aebd8 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/SuspendedEvent.java @@ -0,0 +1,34 @@ +package org.eclipse.dd.examples.pda.service.runcontrol; + +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.datamodel.AbstractDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason; + +/** + * Indicates that the given thread has been suspended. + */ +@Immutable +class SuspendedEvent extends AbstractDMEvent + implements ISuspendedDMEvent +{ + private final String fPDAEvent; + + SuspendedEvent(IExecutionDMContext ctx, String pdaEvent) { + super(ctx); + fPDAEvent = pdaEvent; + } + + public StateChangeReason getReason() { + if (fPDAEvent.startsWith("suspended breakpoint") || fPDAEvent.startsWith("suspended watch")) { + return StateChangeReason.BREAKPOINT; + } else if (fPDAEvent.equals("suspended step") || fPDAEvent.equals("suspended drop")) { + return StateChangeReason.STEP; + } else if (fPDAEvent.equals("suspended client")) { + return StateChangeReason.USER_REQUEST; + } else { + return StateChangeReason.UNKNOWN; + } + } +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/BasicTests.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/BasicTests.java new file mode 100644 index 00000000000..20127ad2d3c --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/BasicTests.java @@ -0,0 +1,134 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.tests.pda.service.command; + +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.ExecutionException; + +import junit.framework.Assert; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.Query; +import org.eclipse.dd.dsf.debug.service.command.ICommand; +import org.eclipse.dd.dsf.debug.service.command.ICommandListener; +import org.eclipse.dd.dsf.debug.service.command.ICommandResult; +import org.eclipse.dd.examples.pda.service.command.PDACommand; +import org.eclipse.dd.examples.pda.service.command.PDACommandResult; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * + */ +public class BasicTests extends CommandControlTestsBase { + + @BeforeClass + public static void setProgram() { + fProgram = "samples/example.pda"; + } + + @Test + public void testCommandListener() throws CoreException, InterruptedException, ExecutionException { + + class CommandInfo { + CommandInfo(ICommand command, ICommandResult result) { fCommand = command; fResult = result; } + ICommand fCommand; + ICommandResult fResult; + } + + class CommandListener implements ICommandListener { + + List fDoneCommands = new LinkedList(); + List fQueuedCommands = new LinkedList(); + List fRemovedCommands = new LinkedList(); + List fSentCommands = new LinkedList(); + + public void commandDone(ICommand command, ICommandResult result) { + fDoneCommands.add(new CommandInfo(command, result)); + } + public void commandQueued(ICommand command) { + fQueuedCommands.add(new CommandInfo(command, null)); + } + public void commandRemoved(ICommand command) { + fRemovedCommands.add(new CommandInfo(command, null)); + } + public void commandSent(ICommand command) { + fSentCommands.add(new CommandInfo(command, null)); + } + + void reset() { + fDoneCommands.clear(); + fQueuedCommands.clear(); + fRemovedCommands.clear(); + fSentCommands.clear(); + } + } + + final CommandListener listener = new CommandListener(); + fExecutor.execute(new DsfRunnable() { + public void run() { + fCommandControl.addCommandListener(listener); + } + }); + + final PDACommand testCommand = new PDACommand(fCommandControl.getDMContext(), "data"); + + // Test sending the command and checking all listeners were called. + Query sendCommandQuery = new Query() { + @Override + protected void execute(DataRequestMonitor rm) { + fCommandControl.queueCommand(testCommand, rm); + } + }; + fExecutor.execute(sendCommandQuery); + PDACommandResult result = sendCommandQuery.get(); + Assert.assertEquals(1, listener.fQueuedCommands.size()); + Assert.assertEquals(testCommand, listener.fQueuedCommands.get(0).fCommand); + Assert.assertEquals(0, listener.fRemovedCommands.size()); + Assert.assertEquals(1, listener.fSentCommands.size()); + Assert.assertEquals(testCommand, listener.fSentCommands.get(0).fCommand); + Assert.assertEquals(1, listener.fDoneCommands.size()); + Assert.assertEquals(testCommand, listener.fDoneCommands.get(0).fCommand); + Assert.assertEquals(result, listener.fDoneCommands.get(0).fResult); + + // Test queuing then removing command + listener.reset(); + Query queueRemoveCommandQuery = new Query() { + @Override + protected void execute(DataRequestMonitor rm) { + fCommandControl.queueCommand( + testCommand, + new DataRequestMonitor(fExecutor, null) { + @Override + protected void handleCompleted() { + Assert.fail("This command should never have been executed."); + } + }); + fCommandControl.removeCommand(testCommand); + + rm.setData(new Object()); + rm.done(); + } + }; + fExecutor.execute(queueRemoveCommandQuery); + queueRemoveCommandQuery.get(); + Assert.assertEquals(1, listener.fQueuedCommands.size()); + Assert.assertEquals(testCommand, listener.fQueuedCommands.get(0).fCommand); + Assert.assertEquals(1, listener.fRemovedCommands.size()); + Assert.assertEquals(testCommand, listener.fRemovedCommands.get(0).fCommand); + Assert.assertEquals(0, listener.fSentCommands.size()); + Assert.assertEquals(0, listener.fDoneCommands.size()); + + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/CommandControlTestsBase.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/CommandControlTestsBase.java new file mode 100644 index 00000000000..27b2429eba4 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/CommandControlTestsBase.java @@ -0,0 +1,140 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.tests.pda.service.command; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.LinkedBlockingQueue; + +import junit.framework.Assert; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.Query; +import org.eclipse.dd.dsf.debug.service.command.IEventListener; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.examples.pda.service.command.PDACommandControl; +import org.eclipse.dd.examples.pda.service.command.PDACommand; +import org.eclipse.dd.examples.pda.service.command.PDACommandResult; +import org.eclipse.dd.tests.pda.util.Launching; +import org.junit.After; +import org.junit.Before; + +/** + * + */ +public class CommandControlTestsBase { + + protected static String fProgram; + + protected DsfExecutor fExecutor; + protected DsfSession fSession; + protected Process fPDAProcess; + protected PDACommandControl fCommandControl; + private BlockingQueue fEventsQueue = new LinkedBlockingQueue(); + + private BufferedReader fOutputReader; + + @Before + public void startup() throws CoreException, InterruptedException, ExecutionException, IOException { + + class InitializeCommandServiceQuery extends Query { + @Override + protected void execute(DataRequestMonitor rm) { + fCommandControl.initialize(rm); + } + }; + + int requestPort = Launching.findFreePort(); + int eventPort = Launching.findFreePort(); + + fPDAProcess = Launching.launchPDA(fProgram, requestPort, eventPort); + fOutputReader = new BufferedReader(new InputStreamReader(fPDAProcess.getInputStream())); + Assert.assertEquals("-debug " + requestPort + " " + eventPort, fOutputReader.readLine()); + + fExecutor = new DefaultDsfExecutor(); + fSession = DsfSession.startSession(fExecutor, "PDA Test"); + fCommandControl = new PDACommandControl(fSession, requestPort, eventPort); + + fCommandControl.addEventListener(new IEventListener() { + public void eventReceived(Object output) { + fEventsQueue.add(output); + } + }); + + InitializeCommandServiceQuery initQuery = new InitializeCommandServiceQuery(); + fExecutor.execute(initQuery); + initQuery.get(); + Assert.assertEquals("debug connection accepted", fOutputReader.readLine()); + } + + @After + public void shutdown() throws CoreException, InterruptedException, ExecutionException, IOException { + fOutputReader.close(); + fPDAProcess.destroy(); + + class ShutdownCommandServiceQuery extends Query { + @Override + protected void execute(DataRequestMonitor rm) { + fCommandControl.shutdown(rm); + } + }; + + if (fExecutor != null) { + ShutdownCommandServiceQuery shutdownQuery = new ShutdownCommandServiceQuery(); + fExecutor.execute(shutdownQuery); + shutdownQuery.get(); + } + } + + protected void sendCommand(String command) throws Throwable { + sendCommand(command, "ok"); + } + + protected void sendCommand(String command, String expectedResult) throws Throwable { + + final PDACommand testCommand = new PDACommand(fCommandControl.getDMContext(), command); + + // Test sending the command and checking all listeners were called. + Query sendCommandQuery = new Query() { + @Override + protected void execute(DataRequestMonitor rm) { + fCommandControl.queueCommand(testCommand, rm); + } + }; + + fExecutor.execute(sendCommandQuery); + try { + PDACommandResult result = sendCommandQuery.get(); + Assert.assertEquals("Command returned an unexpected result", expectedResult, result.fResponseText); + } catch (ExecutionException e) { + throw e.getCause(); + } + } + + protected void clearEvents() { + fEventsQueue.clear(); + } + + protected void expectEvent(String expectedEvent) throws InterruptedException { + Assert.assertEquals("Unexpected event received", expectedEvent, fEventsQueue.take()); + } + + protected void expectOutput(String expectedOutput) throws IOException { + Assert.assertEquals("Unexpected output received", expectedOutput, fOutputReader.readLine()); + } + +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/PDATestEvent.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/PDATestEvent.java new file mode 100644 index 00000000000..8a069cdbbf3 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/PDATestEvent.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.tests.pda.service.command; + +/** + * + */ +public class PDATestEvent { + final public String fEventText; + PDATestEvent(String event) { + fEventText = event; + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/Test1.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/Test1.java new file mode 100644 index 00000000000..2225c20f1ef --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/Test1.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.tests.pda.service.command; + +import java.io.File; + +import org.eclipse.core.runtime.Path; +import org.eclipse.dd.examples.pda.PDAPlugin; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * + */ +public class Test1 extends CommandControlTestsBase { + + @BeforeClass + public static void setProgram() { + File programFile = PDAPlugin.getFileInPlugin(new Path("samples/example.pda")); + fProgram = programFile.getPath(); + } + + @Test + public void testRun() throws Throwable { + sendCommand("resume"); + expectOutput("\"hello\""); + expectOutput("\"barfoo\""); + expectOutput("\"first\""); + expectOutput("\"second\""); + expectOutput("12"); + expectOutput("11"); + expectOutput("10"); + expectOutput("\"barfoo\""); + expectOutput("\"first\""); + expectOutput("\"second\""); + expectOutput("\"end\""); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/Test2.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/Test2.java new file mode 100644 index 00000000000..f51fd7d0986 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/Test2.java @@ -0,0 +1,109 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.tests.pda.service.command; + +import java.io.File; + +import org.eclipse.core.runtime.Path; +import org.eclipse.dd.examples.pda.PDAPlugin; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * + */ +public class Test2 extends CommandControlTestsBase { + + @BeforeClass + public static void setProgram() { + File programFile = PDAPlugin.getFileInPlugin(new Path("pdavm/tests/vmtest2.pda")); + + fProgram = programFile.getPath(); + } + + @Test + public void testCommonDebugCommands() throws Throwable { + expectEvent("started"); + // test step + sendCommand("step"); + expectEvent("resumed step"); + expectEvent("suspended step"); + // test breakpoint + sendCommand("set 4"); + sendCommand("data", "6|"); + sendCommand("resume"); + expectEvent("resumed client"); + expectEvent("suspended breakpoint 4"); + // test data stack + sendCommand("data", "6|7|8|9|"); + sendCommand("popdata"); + sendCommand("data", "6|7|8|"); + sendCommand("pushdata 11"); + sendCommand("data", "6|7|8|11|"); + sendCommand("setdata 1 2"); + sendCommand("data", "6|2|8|11|"); + // test call stack + sendCommand("set 12"); + sendCommand("set 19"); + sendCommand("stepreturn"); + expectEvent("resumed client"); + expectEvent("suspended breakpoint 12"); + sendCommand("clear 19"); + sendCommand("stack", fProgram + "|6|main#" + fProgram + "|18|sub1|n|m#" + fProgram + "|12|sub2" ); + sendCommand("stepreturn"); + expectEvent("resumed client"); + expectEvent("suspended step"); + sendCommand("stack", fProgram + "|6|main#" + fProgram + "|18|sub1|n|m#" + fProgram + "|13|sub2" ); + sendCommand("stepreturn"); + expectEvent("resumed client"); + expectEvent("suspended step"); + sendCommand("stack", fProgram + "|6|main#" + fProgram + "|22|sub1|n|m" ); + sendCommand("set 6"); + sendCommand("stepreturn"); + expectEvent("resumed client"); + expectEvent("suspended breakpoint 6"); + // test set and clear + sendCommand("set 27"); + sendCommand("set 29"); + sendCommand("set 33"); + sendCommand("resume"); + expectEvent("resumed client"); + expectEvent("suspended breakpoint 33"); + sendCommand("resume"); + expectEvent("resumed client"); + expectEvent("suspended breakpoint 27"); + sendCommand("clear 33"); + sendCommand("resume"); + expectEvent("resumed client"); + expectEvent("suspended breakpoint 29"); + // test var and setvar + sendCommand("set 47"); + sendCommand("resume"); + expectEvent("resumed client"); + expectEvent("suspended breakpoint 47"); + sendCommand("var 1 b", "4"); + sendCommand("var 2 b", "2"); + sendCommand("var 1 a", "0"); + sendCommand("setvar 1 a 99"); + sendCommand("data", "6|2|8|11|27|1|4|"); + sendCommand("step"); + expectEvent("resumed step"); + expectEvent("suspended step"); + sendCommand("var 1 a", "99"); + sendCommand("step"); + expectEvent("resumed step"); + expectEvent("suspended step"); + sendCommand("data", "6|2|8|11|27|1|4|99|"); + // test exit + sendCommand("exit"); + expectEvent("terminated"); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/Test3.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/Test3.java new file mode 100644 index 00000000000..2df4d2339b1 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/Test3.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.tests.pda.service.command; + +import java.io.File; + +import org.eclipse.core.runtime.Path; +import org.eclipse.dd.examples.pda.PDAPlugin; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * + */ +public class Test3 extends CommandControlTestsBase { + + @BeforeClass + public static void setProgram() { + File programFile = PDAPlugin.getFileInPlugin(new Path("pdavm/tests/vmtest3.pda")); + + fProgram = programFile.getPath(); + } + + @Test + public void testUncaughtEvents() throws Throwable { + expectEvent("started"); + sendCommand("resume"); + expectEvent("resumed client"); + expectEvent("unimplemented instruction foobar"); + expectEvent("no such label zippy"); + expectEvent("terminated"); + } + + @Test + public void testCaughtUnimpinstrEvents() throws Throwable { + expectEvent("started"); + sendCommand("eventstop unimpinstr 1"); + sendCommand("resume"); + expectEvent("resumed client"); + expectEvent("unimplemented instruction foobar"); + expectEvent("suspended event unimpinstr"); + sendCommand("eventstop unimpinstr 0"); + sendCommand("resume"); + expectEvent("resumed client"); + expectEvent("unimplemented instruction foobar"); + expectEvent("no such label zippy"); + expectEvent("terminated"); + } + + @Test + public void testCaughtNosuchlabelEvents() throws Throwable { + expectEvent("started"); + sendCommand("eventstop nosuchlabel 1"); + sendCommand("resume"); + expectEvent("resumed client"); + expectEvent("unimplemented instruction foobar"); + expectEvent("no such label zippy"); + expectEvent("suspended event nosuchlabel"); + sendCommand("eventstop nosuchlabel 0"); + sendCommand("resume"); + expectEvent("resumed client"); + expectEvent("no such label zippy"); + expectEvent("terminated"); + } + +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/Test6.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/Test6.java new file mode 100644 index 00000000000..11650200afd --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/Test6.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.tests.pda.service.command; + +import java.io.File; + +import org.eclipse.core.runtime.Path; +import org.eclipse.dd.examples.pda.PDAPlugin; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * + */ +public class Test6 extends CommandControlTestsBase { + + @BeforeClass + public static void setProgram() { + File programFile = PDAPlugin.getFileInPlugin(new Path("pdavm/tests/vmtest6.pda")); + + fProgram = programFile.getPath(); + } + + @Test + public void testWatchPoints() throws Throwable { + expectEvent("started"); + sendCommand("watch inner::a 1"); + sendCommand("watch main::a 2"); + sendCommand("resume"); + expectEvent("resumed client"); + expectEvent("suspended watch write main::a"); + sendCommand("stack", fProgram + "|4|main|a|b"); + sendCommand("resume"); + expectEvent("resumed client"); + expectEvent("suspended watch read inner::a"); + sendCommand("stack", fProgram + "|10|main|a|b#" + fProgram + "|25|inner|c|a"); + sendCommand("watch inner::a 0"); + sendCommand("resume"); + expectEvent("resumed client"); + expectEvent("terminated"); + } + + @Test + public void testEval() throws Throwable { + expectEvent("started"); + sendCommand("set 25"); + sendCommand("resume"); + expectEvent("resumed client"); + expectEvent("suspended breakpoint 25"); + + sendCommand("eval push%204|push%205|add"); + expectEvent("resumed client"); + expectEvent("evalresult 9"); + expectEvent("suspended eval"); + + sendCommand("step"); + expectEvent("resumed step"); + expectEvent("suspended step"); + sendCommand("stack", fProgram + "|10|main|a|b#" + fProgram + "|26|inner|c|a"); + sendCommand("data", "4|4|"); + sendCommand("eval call%20other"); + expectEvent("resumed client"); + expectEvent("evalresult 15"); + expectEvent("suspended eval"); + sendCommand("stack", fProgram + "|10|main|a|b#" + fProgram + "|26|inner|c|a"); + sendCommand("data", "4|4|"); + sendCommand("resume"); + expectEvent("resumed client"); + expectEvent("terminated"); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/Test8.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/Test8.java new file mode 100644 index 00000000000..389f227d617 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/Test8.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.tests.pda.service.command; + +import java.io.File; + +import org.eclipse.core.runtime.Path; +import org.eclipse.dd.examples.pda.PDAPlugin; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * + */ +public class Test8 extends CommandControlTestsBase { + + @BeforeClass + public static void setProgram() { + File programFile = PDAPlugin.getFileInPlugin(new Path("pdavm/tests/vmtest8.pda")); + + fProgram = programFile.getPath(); + } + + @Test + public void testDropFrame() throws Throwable { + expectEvent("started"); + sendCommand("step"); + expectEvent("resumed step"); + expectEvent("suspended step"); + sendCommand("step"); + expectEvent("resumed step"); + expectEvent("suspended step"); + sendCommand("step"); + expectEvent("resumed step"); + expectEvent("suspended step"); + sendCommand("step"); + expectEvent("resumed step"); + expectEvent("suspended step"); + sendCommand("step"); + expectEvent("resumed step"); + expectEvent("suspended step"); + sendCommand("step"); + expectEvent("resumed step"); + expectEvent("suspended step"); + sendCommand("step"); + expectEvent("resumed step"); + expectEvent("suspended step"); + sendCommand("stack", fProgram + "|2|main|a#" + fProgram + "|8|inner|b#" + fProgram + "|12|inner2|c"); + sendCommand("drop"); + expectEvent("resumed drop"); + expectEvent("suspended drop"); + sendCommand("stack", fProgram + "|2|main|a#" + fProgram + "|7|inner|b"); + sendCommand("step"); + expectEvent("resumed step"); + expectEvent("suspended step"); + sendCommand("stack", fProgram + "|2|main|a#" + fProgram + "|8|inner|b#" + fProgram + "|10|inner2"); + sendCommand("resume"); + expectEvent("resumed client"); + expectEvent("terminated"); + } + +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/util/Launching.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/util/Launching.java new file mode 100644 index 00000000000..92778794db1 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/util/Launching.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.tests.pda.util; + +import java.io.File; +import java.io.IOException; +import java.net.ServerSocket; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; + +import junit.framework.Assert; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.variables.IValueVariable; +import org.eclipse.core.variables.VariablesPlugin; +import org.eclipse.dd.examples.pda.PDAPlugin; +import org.eclipse.debug.core.DebugPlugin; + +/** + * + */ +public class Launching { + public static String getPerlPath() { + // Perl executable + IValueVariable perl = VariablesPlugin.getDefault().getStringVariableManager().getValueVariable(PDAPlugin.VARIALBE_PERL_EXECUTABLE); + Assert.assertNotNull("Perl executable location undefined. Check value of ${dsfPerlExecutable}.", perl); + + String path = perl.getValue(); + Assert.assertNotNull("Perl executable location undefined. Check value of ${dsfPerlExecutable}.", path); + Assert.assertTrue( + MessageFormat.format("Specified Perl executable {0} does not exist. Check value of $dsfPerlExecutable.", new Object[]{path}), + new File(path).exists()); + + return path; + } + + public static Process launchPDA(String pdaProgram, int requestPort, int eventPort) throws CoreException { + Assert.assertTrue("Invalid request port", requestPort > 0); + Assert.assertTrue("Invalid event port", eventPort > 0); + + List commandList = new ArrayList(); + + commandList.add(getPerlPath()); + + File pdaVM = PDAPlugin.getFileInPlugin(new Path("pdavm/pda.pl")); + Assert.assertNotNull("File " + pdaVM + " not found in plugin.", pdaVM); + commandList.add(pdaVM.getAbsolutePath()); + + commandList.add(pdaProgram); + + // if in debug mode, add debug arguments - i.e. '-debug requestPort eventPort' + + commandList.add("-debug"); + commandList.add("" + requestPort); + commandList.add("" + eventPort); + + String[] commandLine = commandList.toArray(new String[commandList.size()]); + + return DebugPlugin.exec(commandLine, null); + } + + /** + * Returns a free port number on localhost, or -1 if unable to find a free port. + * + * @return a free port number on localhost, or -1 if unable to find a free port + */ + public static int findFreePort() { + ServerSocket socket= null; + try { + socket= new ServerSocket(0); + return socket.getLocalPort(); + } catch (IOException e) { + } finally { + if (socket != null) { + try { + socket.close(); + } catch (IOException e) { + } + } + } + return -1; + } + +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourceLookupDirector.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourceLookupDirector.java new file mode 100644 index 00000000000..f975cf7c338 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourceLookupDirector.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2005, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Bjorn Freeman-Benson - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.examples.core.pda.sourcelookup; + +import org.eclipse.debug.core.sourcelookup.AbstractSourceLookupDirector; +import org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant; + +/** + * PDA source lookup director. For PDA source lookup there is one source + * lookup participant. + */ +public class PDASourceLookupDirector extends AbstractSourceLookupDirector { + /* (non-Javadoc) + * @see org.eclipse.debug.internal.core.sourcelookup.ISourceLookupDirector#initializeParticipants() + */ + public void initializeParticipants() { + //#ifdef ex4 +//# // TODO: Exercise 4 - add our participant to this director + //#else + addParticipants(new ISourceLookupParticipant[]{new PDASourceLookupParticipant()}); + //#endif + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourceLookupParticipant.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourceLookupParticipant.java new file mode 100644 index 00000000000..66243d6518f --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourceLookupParticipant.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2005, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Bjorn Freeman-Benson - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.examples.core.pda.sourcelookup; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.core.sourcelookup.AbstractSourceLookupParticipant; + + +/** + * The PDA source lookup participant knows how to translate a + * PDA stack frame into a source file name + */ +public class PDASourceLookupParticipant extends AbstractSourceLookupParticipant { + /* (non-Javadoc) + * @see org.eclipse.debug.internal.core.sourcelookup.ISourceLookupParticipant#getSourceName(java.lang.Object) + */ + public String getSourceName(Object object) throws CoreException { + return null; + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourcePathComputerDelegate.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourcePathComputerDelegate.java new file mode 100644 index 00000000000..6087abf01a5 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourcePathComputerDelegate.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (c) 2005, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Bjorn Freeman-Benson - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.examples.core.pda.sourcelookup; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.dd.examples.pda.PDAPlugin; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.sourcelookup.ISourceContainer; +import org.eclipse.debug.core.sourcelookup.ISourcePathComputerDelegate; +import org.eclipse.debug.core.sourcelookup.containers.FolderSourceContainer; +import org.eclipse.debug.core.sourcelookup.containers.ProjectSourceContainer; +import org.eclipse.debug.core.sourcelookup.containers.WorkspaceSourceContainer; + + +/** + * Computes the default source lookup path for a PDA launch configuration. + * The default source lookup path is the folder or project containing + * the PDA program being launched. If the program is not specified, the workspace + * is searched by default. + */ +public class PDASourcePathComputerDelegate implements ISourcePathComputerDelegate { + + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.core.sourcelookup.ISourcePathComputerDelegate#computeSourceContainers(org.eclipse.debug.core.ILaunchConfiguration, org.eclipse.core.runtime.IProgressMonitor) + */ + public ISourceContainer[] computeSourceContainers(ILaunchConfiguration configuration, IProgressMonitor monitor) throws CoreException { + String path = configuration.getAttribute(PDAPlugin.ATTR_PDA_PROGRAM, (String)null); + ISourceContainer sourceContainer = null; + if (path != null) { + IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(new Path(path)); + if (resource != null) { + //#ifdef ex4 +//# // TODO: Exercise 4 - seed the source lookup path + //#else + IContainer container = resource.getParent(); + if (container.getType() == IResource.PROJECT) { + sourceContainer = new ProjectSourceContainer((IProject)container, false); + } else if (container.getType() == IResource.FOLDER) { + sourceContainer = new FolderSourceContainer(container, false); + } + //#endif + } + } + if (sourceContainer == null) { + sourceContainer = new WorkspaceSourceContainer(); + } + return new ISourceContainer[]{sourceContainer}; + } +} From e98b65ea7c22d57a7c2fbce68cb9baa7853c435a Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 13 Feb 2008 20:27:01 +0000 Subject: [PATCH 240/834] [179102] Re-aligned plugin and package names to confirm with Eclipse policy. --- .../org.eclipse.dd.examples.dsf/.classpath | 7 + plugins/org.eclipse.dd.examples.dsf/.project | 28 + .../.settings/org.eclipse.jdt.core.prefs | 65 ++ .../META-INF/MANIFEST.MF | 18 + .../org.eclipse.dd.examples.dsf/about.html | 24 + .../build.properties | 7 + .../icons/alarm.gif | Bin 0 -> 85 bytes .../icons/alarm_triggered.gif | Bin 0 -> 206 bytes .../icons/layout.gif | Bin 0 -> 857 bytes .../icons/remove.gif | Bin 0 -> 163 bytes .../icons/sample.gif | Bin 0 -> 983 bytes .../icons/timer.gif | Bin 0 -> 153 bytes .../plugin.properties | 13 + .../org.eclipse.dd.examples.dsf/plugin.xml | 57 ++ .../dd/examples/dsf/DsfExamplesPlugin.java | 92 +++ ...llableInputCoalescingSlowDataProvider.java | 440 +++++++++++++ ...InputCoalescingSlowDataProviderAction.java | 54 ++ ...ellingSlowDataProviderContentProvider.java | 292 +++++++++ .../examples/dsf/concurrent/DataProvider.java | 64 ++ .../InputCoalescingSlowDataProvider.java | 408 ++++++++++++ ...InputCoalescingSlowDataProviderAction.java | 54 ++ .../dsf/concurrent/SlowDataProvider.java | 330 ++++++++++ .../concurrent/SlowDataProviderAction.java | 53 ++ .../SlowDataProviderContentProvider.java | 190 ++++++ .../concurrent/SlowDataProviderDialog.java | 50 ++ .../doc-files/dsf_concurrency_model-1.png | Bin 0 -> 6256 bytes .../dd/examples/dsf/concurrent/package.html | 289 +++++++++ .../dsf/filebrowser/FileBrowserAction.java | 39 ++ .../dsf/filebrowser/FileBrowserDialog.java | 113 ++++ .../filebrowser/FileBrowserModelAdapter.java | 62 ++ .../filebrowser/FileBrowserVMProvider.java | 98 +++ .../dsf/filebrowser/FileVMContext.java | 37 ++ .../examples/dsf/filebrowser/FileVMNode.java | 308 +++++++++ .../filebrowser/FilesystemRootsVMNode.java | 192 ++++++ .../dd/examples/dsf/filebrowser/package.html | 127 ++++ .../dsf/timers/AlarmCellModifier.java | 263 ++++++++ .../dd/examples/dsf/timers/AlarmService.java | 361 +++++++++++ .../dsf/timers/AlarmStatusVMNode.java | 112 ++++ .../dd/examples/dsf/timers/AlarmsVMNode.java | 212 +++++++ .../dsf/timers/ServicesShutdownSequence.java | 92 +++ .../dsf/timers/ServicesStartupSequence.java | 57 ++ .../dd/examples/dsf/timers/TimerService.java | 260 ++++++++ .../dsf/timers/TimersModelAdapter.java | 62 ++ .../dd/examples/dsf/timers/TimersVMNode.java | 160 +++++ .../examples/dsf/timers/TimersVMProvider.java | 111 ++++ .../dd/examples/dsf/timers/TimersView.java | 296 +++++++++ .../timers/TimersViewColumnPresentation.java | 69 ++ .../dsf/timers/doc-files/package-1.png | Bin 0 -> 14399 bytes .../dd/examples/dsf/timers/package.html | 28 + plugins/org.eclipse.dd.gdb/.classpath | 7 + plugins/org.eclipse.dd.gdb/.project | 28 + .../.settings/org.eclipse.jdt.core.prefs | 65 ++ .../org.eclipse.dd.gdb/META-INF/MANIFEST.MF | 22 + plugins/org.eclipse.dd.gdb/about.html | 24 + plugins/org.eclipse.dd.gdb/build.properties | 6 + plugins/org.eclipse.dd.gdb/plugin.xml | 26 + .../CBreakpointGdbThreadsFilterExtension.java | 102 +++ .../eclipse/dd/gdb/internal/GdbPlugin.java | 110 ++++ .../eclipse/dd/gdb/launching/GdbLaunch.java | 175 +++++ .../dd/gdb/launching/GdbLaunchDelegate.java | 290 +++++++++ .../dd/gdb/launching/LaunchSequence.java | 267 ++++++++ .../dd/gdb/launching/ShutdownSequence.java | 173 +++++ .../eclipse/dd/gdb/service/GDBRunControl.java | 192 ++++++ .../dd/gdb/service/command/GDBCLIProcess.java | 101 +++ .../dd/gdb/service/command/GDBControl.java | 596 ++++++++++++++++++ .../service/command/GDBControlDMContext.java | 33 + .../service/command/GDBInferiorProcess.java | 72 +++ 67 files changed, 7883 insertions(+) create mode 100644 plugins/org.eclipse.dd.examples.dsf/.classpath create mode 100644 plugins/org.eclipse.dd.examples.dsf/.project create mode 100644 plugins/org.eclipse.dd.examples.dsf/.settings/org.eclipse.jdt.core.prefs create mode 100644 plugins/org.eclipse.dd.examples.dsf/META-INF/MANIFEST.MF create mode 100644 plugins/org.eclipse.dd.examples.dsf/about.html create mode 100644 plugins/org.eclipse.dd.examples.dsf/build.properties create mode 100644 plugins/org.eclipse.dd.examples.dsf/icons/alarm.gif create mode 100644 plugins/org.eclipse.dd.examples.dsf/icons/alarm_triggered.gif create mode 100644 plugins/org.eclipse.dd.examples.dsf/icons/layout.gif create mode 100644 plugins/org.eclipse.dd.examples.dsf/icons/remove.gif create mode 100644 plugins/org.eclipse.dd.examples.dsf/icons/sample.gif create mode 100644 plugins/org.eclipse.dd.examples.dsf/icons/timer.gif create mode 100644 plugins/org.eclipse.dd.examples.dsf/plugin.properties create mode 100644 plugins/org.eclipse.dd.examples.dsf/plugin.xml create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/DsfExamplesPlugin.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/CancellableInputCoalescingSlowDataProvider.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/CancellableInputCoalescingSlowDataProviderAction.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/CancellingSlowDataProviderContentProvider.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/DataProvider.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/InputCoalescingSlowDataProvider.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/InputCoalescingSlowDataProviderAction.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/SlowDataProvider.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/SlowDataProviderAction.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/SlowDataProviderContentProvider.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/SlowDataProviderDialog.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/doc-files/dsf_concurrency_model-1.png create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/package.html create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileBrowserAction.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileBrowserDialog.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileBrowserModelAdapter.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileBrowserVMProvider.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileVMContext.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileVMNode.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FilesystemRootsVMNode.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/package.html create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmCellModifier.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmService.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmStatusVMNode.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmsVMNode.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/ServicesShutdownSequence.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/ServicesStartupSequence.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimerService.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersModelAdapter.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersVMNode.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersVMProvider.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersView.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersViewColumnPresentation.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/doc-files/package-1.png create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/package.html create mode 100644 plugins/org.eclipse.dd.gdb/.classpath create mode 100644 plugins/org.eclipse.dd.gdb/.project create mode 100644 plugins/org.eclipse.dd.gdb/.settings/org.eclipse.jdt.core.prefs create mode 100644 plugins/org.eclipse.dd.gdb/META-INF/MANIFEST.MF create mode 100644 plugins/org.eclipse.dd.gdb/about.html create mode 100644 plugins/org.eclipse.dd.gdb/build.properties create mode 100644 plugins/org.eclipse.dd.gdb/plugin.xml create mode 100644 plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/breakpoints/CBreakpointGdbThreadsFilterExtension.java create mode 100644 plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/GdbPlugin.java create mode 100644 plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunch.java create mode 100644 plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunchDelegate.java create mode 100644 plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/LaunchSequence.java create mode 100644 plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/ShutdownSequence.java create mode 100644 plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/GDBRunControl.java create mode 100644 plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBCLIProcess.java create mode 100644 plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControl.java create mode 100644 plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControlDMContext.java create mode 100644 plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBInferiorProcess.java diff --git a/plugins/org.eclipse.dd.examples.dsf/.classpath b/plugins/org.eclipse.dd.examples.dsf/.classpath new file mode 100644 index 00000000000..304e86186aa --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/plugins/org.eclipse.dd.examples.dsf/.project b/plugins/org.eclipse.dd.examples.dsf/.project new file mode 100644 index 00000000000..5bc60355c8c --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/.project @@ -0,0 +1,28 @@ + + + org.eclipse.dd.examples.dsf + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/plugins/org.eclipse.dd.examples.dsf/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.dd.examples.dsf/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000000..3d7e8d5439f --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,65 @@ +#Thu Jun 07 11:07:55 PDT 2007 +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.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=warning +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning +org.eclipse.jdt.core.compiler.problem.nullReference=ignore +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning +org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=error +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/plugins/org.eclipse.dd.examples.dsf/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.examples.dsf/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..68022d0409e --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/META-INF/MANIFEST.MF @@ -0,0 +1,18 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Debug Services Framework Examples +Bundle-Vendor: Eclipse.org +Bundle-SymbolicName: org.eclipse.dd.examples.dsf;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: org.eclipse.dd.examples.dsf.DsfExamplesPlugin +Bundle-Localization: plugin +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.debug.core, + org.eclipse.debug.ui, + org.eclipse.dd.dsf, + org.eclipse.ui, + org.eclipse.dd.dsf.ui + +Eclipse-LazyStart: true +Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/plugins/org.eclipse.dd.examples.dsf/about.html b/plugins/org.eclipse.dd.examples.dsf/about.html new file mode 100644 index 00000000000..cb740ae8bc8 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/about.html @@ -0,0 +1,24 @@ + + + + +About +

    About This Content

    + +

    June 5, 2007

    +

    License

    + +

    The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at http://www.eclipse.org/legal/epl-v10.html. +For purposes of the EPL, "Program" will mean the Content.

    + +

    If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at http://www.eclipse.org.

    + + \ No newline at end of file diff --git a/plugins/org.eclipse.dd.examples.dsf/build.properties b/plugins/org.eclipse.dd.examples.dsf/build.properties new file mode 100644 index 00000000000..bc3b0f2bf1f --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/build.properties @@ -0,0 +1,7 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml,\ + plugin.properties,\ + about.html diff --git a/plugins/org.eclipse.dd.examples.dsf/icons/alarm.gif b/plugins/org.eclipse.dd.examples.dsf/icons/alarm.gif new file mode 100644 index 0000000000000000000000000000000000000000..33cc76e9dc508087adbd43317a6a67a9f5750bf5 GIT binary patch literal 85 zcmZ?wbhEHb6krfwSj50EZQ+i_2`h4Hr`v`WYkFk=|Nox>3>1H|FfuT(GU$MKAhit4 jQW3lE{4+RplWn0FPt2iX2i#j@A~WWsuFHv5VXy`ORM#6E literal 0 HcmV?d00001 diff --git a/plugins/org.eclipse.dd.examples.dsf/icons/alarm_triggered.gif b/plugins/org.eclipse.dd.examples.dsf/icons/alarm_triggered.gif new file mode 100644 index 0000000000000000000000000000000000000000..609dbb7269c7930105402a19ecfb599e6fa03751 GIT binary patch literal 206 zcmZ?wbhEHb6krfwIKsg2!@%U1vH4G9^FL;me=V(k7nl91sQO(|^>f$m&+7W0)b+n< z8-3F;`jb=iJGbahartXW_19AB@8q=J%4xn3QF$q*`ch2oZ&1=-zxdxZHUGhY0SPGn zWMO1rkY>;UiGl27VD)~W)|Zl*m60_`%1NMOTc6a#)E1lkTLt{PX1Wy^urz7&J_uw` u@b7MG{;0E1g!78ulvPotlRC?mcgE-m=&x-$7;z9*?jxd%4aX0yzy`dymabz zw#(eg=y~&N&n)dZv2xzduG}5lraiApo3(c4*{Ylg5#|$JO_EEZ<^|a2`Z*=9ns7DV zy=TR&gYw*7f%auV?ip3tvjRPmcdoho{K?x$_vR?C#t5&<;~V}S*>OMCr>h}%%bLZ9 zmo3`hYEwTICo-TTCZwgTsC&VjZRgJ1eE#fBa^%9R zmmfWS@;bnyJ27HWY}kxYzv(Hl>yu;FCPlAEh+34Muq-8Rb6C)<8qA3{r2e5 z`$vyngh#H=FWlqqvnapfc5%(!sQ4v?r7J61-&eJNEN^;KTK}T7{#i-gJh%G*9vcYdwv_*~xdw!Gz4Va?T!sXyyF@8?w<>X`X=#(U);MJOAs663NE1$erPKUvwBW*mY od^sy7DjaQ*k}P_oQJ`|NUrat}PN7lii7q|ft`yIpBnJj-0OA7hy#N3J literal 0 HcmV?d00001 diff --git a/plugins/org.eclipse.dd.examples.dsf/icons/remove.gif b/plugins/org.eclipse.dd.examples.dsf/icons/remove.gif new file mode 100644 index 0000000000000000000000000000000000000000..2cd9c544436c47a57f20b348b3fb024bb50701a7 GIT binary patch literal 163 zcmZ?wbhEHb6krfw*v!DNV#SID3l_|nF=N7n2^}3B4Gj$y6%_>q1sNF`2?+`R|Nmz| z1&Tje7#SG27<53wATtBYuHJj2L#xNM)vQ#JRl<>hDKU#-N&yE`p}?0M(Gw4T zcQCOfDoF5h^e6?|s2Q}nBw9^9*?jxd%4aX0yzy`dymabz zw#(eg=y~&N&n)dZv2xzduG}5lraiApo3(c4*{Ylg5#|$JO_EEZ<^|a2`Z*=9ns7DV zy=TR&gYw*7f%auV?ip3tvjRPmcdoho{K?x$_vR?C#t5&<;~V}S*>OMCr>h}%%bLZ9 zmo3`hYEwTICo-TTCZwgTsC&VjZRgJ1eE#fBa^%9R zmmfWS@;bnyJ27HWY}kxYzv(Hl>yu;FCPlAEh+34Muq-8Rb6C)<8qA3{r2e5 z`$vyngh#H=FWlqqvnapfc5%(!sQ4v?r7J61-&eJNEN^;KTK}T7{#i-gJh%G*9vcYdwv_*~xdw!Gz4Va?T!sXyyF@8?w<>X`X=#j%uHV4GRvj@+tE@ zQ%F!a)GKcn^~8abN>4la1UNXVL;{ZWi)lEwyeatDu%Lr6;aASiLrXXW zQm#%`5%NsW|KA-(W lfLU=-_{}pDbY>s@=CVUi;c|z7MPf|j0bOUk*~Wql)&K+PGMxYb literal 0 HcmV?d00001 diff --git a/plugins/org.eclipse.dd.examples.dsf/plugin.properties b/plugins/org.eclipse.dd.examples.dsf/plugin.properties new file mode 100644 index 00000000000..36cabf984ee --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/plugin.properties @@ -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) Examples +providerName=Eclipse.org + diff --git a/plugins/org.eclipse.dd.examples.dsf/plugin.xml b/plugins/org.eclipse.dd.examples.dsf/plugin.xml new file mode 100644 index 00000000000..798b7f3e230 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/plugin.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/DsfExamplesPlugin.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/DsfExamplesPlugin.java new file mode 100644 index 00000000000..92203c6d2cd --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/DsfExamplesPlugin.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * 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.examples.dsf; + +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 DsfExamplesPlugin extends AbstractUIPlugin { + + // The plug-in ID + public static final String PLUGIN_ID = "org.eclipse.dd.examples.dsf"; //$NON-NLS-1$ + + public static final String IMG_LAYOUT_TOGGLE = "icons/layout.gif"; //$NON-NLS-1$ + public static final String IMG_ALARM = "icons/alarm.gif"; //$NON-NLS-1$ + public static final String IMG_ALARM_TRIGGERED = "icons/alarm_triggered.gif"; //$NON-NLS-1$ + public static final String IMG_TIMER = "icons/timer.gif"; //$NON-NLS-1$ + public static final String IMG_REMOVE = "icons/remove.gif"; //$NON-NLS-1$ + + // The shared instance + private static DsfExamplesPlugin fgPlugin; + + private static BundleContext fgBundleContext; + + /** + * The constructor + */ + public DsfExamplesPlugin() { + fgPlugin = this; + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) + */ + @Override + public void start(BundleContext context) throws Exception { + fgBundleContext = context; + super.start(context); + getImageRegistry().put(IMG_ALARM, imageDescriptorFromPlugin(PLUGIN_ID, IMG_ALARM)); + getImageRegistry().put(IMG_ALARM_TRIGGERED, imageDescriptorFromPlugin(PLUGIN_ID, IMG_ALARM_TRIGGERED)); + getImageRegistry().put(IMG_TIMER, imageDescriptorFromPlugin(PLUGIN_ID, IMG_TIMER)); + getImageRegistry().put(IMG_REMOVE, imageDescriptorFromPlugin(PLUGIN_ID, IMG_REMOVE)); + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) + */ + @Override + public void stop(BundleContext context) throws Exception { + super.stop(context); + fgPlugin = null; + fgBundleContext = null; + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static DsfExamplesPlugin getDefault() { + return fgPlugin; + } + + public static BundleContext getBundleContext() { + return fgBundleContext; + } + + /** + * 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); + } + +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/CancellableInputCoalescingSlowDataProvider.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/CancellableInputCoalescingSlowDataProvider.java new file mode 100644 index 00000000000..d9839e94334 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/CancellableInputCoalescingSlowDataProvider.java @@ -0,0 +1,440 @@ +/******************************************************************************* + * 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.examples.dsf.concurrent; + +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Random; +import java.util.Set; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.DelayQueue; +import java.util.concurrent.Delayed; +import java.util.concurrent.TimeUnit; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; + +/** + * Example data provider which has a built-in delay when fetching data. This + * data provider simulates a service which retrieves data from an external + * source such as a networked target, which incurs a considerable delay when + * retrieving data. The data items are simulated values which consist of the + * time when data is being retrieved followed by the item's index. + *

    + * This version of the data provider builds on the input-coalescing feature, + * it adds a test to check if the requests were cancelled by the user, before + * they are coalesced and queued to be processed by the provider thread. + */ +public class CancellableInputCoalescingSlowDataProvider implements DataProvider { + + /** Minimum count of data items */ + private final static int MIN_COUNT = 1000; + + /** Maximum count of data items */ + private final static int MAX_COUNT = 2000; + + /** Time interval how often random changes occur. */ + private final static int RANDOM_CHANGE_MILIS = 10000; + + /** Number of times random changes are made, before count is changed. */ + private final static int RANDOM_COUNT_CHANGE_INTERVALS = 3; + + /** Percentage of values that is changed upon random change (0-100). */ + private final static int RANDOM_CHANGE_SET_PERCENTAGE = 10; + + /** + * Amount of time (in miliseconds) how long the requests to provider, and + * events from provider are delayed by. + */ + private final static int TRANSMISSION_DELAY_TIME = 500; + + /** + * Amount of time (in milliseconds) how long the provider takes to process + * a request. + */ + private final static int PROCESSING_TIME = 100; + + /** + * Maximum number of item requests that can be coalesced into a single + * request. + */ + private final static int COALESCING_COUNT_LIMIT = 10; + + /** + * Delay in processing the buffer of getItem() calls. This delay helps + * to ensure that a meaningful number of items is present in the buffer + * before the buffer data is coalesced into a request. + */ + private final static int COALESCING_DELAY_TIME = 100; + + /** + * Maximum allowed number of requests in transmission to provider thread. + * This limit causes most of the client calls to be buffered at the input + * rather than in the request queue, which in truns allows the stale + * requests to be cancelled, before they are sent to the provider thread + * for processing. + */ + private final static int REQUEST_QUEUE_SIZE_LIMIT = 100; + + /** Delay before processing calls buffer, if the request queue is full */ + private final static int REQUEST_BUFFER_FULL_RETRY_DELAY = PROCESSING_TIME; + + /** Dispatch-thread executor that this provider uses. */ + private DsfExecutor fExecutor; + + /** List of listeners registered for events from provider. */ + private List fListeners = new LinkedList(); + + /** Thread that handles data requests. */ + private ProviderThread fProviderThread; + + /** Queue of currently pending data requests. */ + private final BlockingQueue fQueue = new DelayQueue(); + + /** + * Runnable to be submitted when the data provider thread is shut down. + * This variable acts like a flag: when client want to shut down the + * provider, it sets this runnable, and when the backgroun thread sees + * that it's set, it shuts itself down, and posts this runnable with + * the executor. + */ + private RequestMonitor fShutdownRequestMonitor = null; + + /** + * Buffers for coalescing getItem() calls into a single request. + */ + private List fGetItemIndexesBuffer = new LinkedList(); + private List> fGetItemRequestMonitorsBuffer = new LinkedList>(); + + /** + * Base class for requests that are queued by the data provider. It + * implements java.util.concurrent.Delayed to allow for use of DelayedQueue. + * Every request into the queue is delayed by the simulated transmission + * time. + */ + private static abstract class Request implements Delayed { + /** Sequence counter and number are used to ensure FIFO order **/ + private static int fSequenceCounter = 0; + private int fSequenceNumber = fSequenceCounter++; + + /** Time delay tracks how items will be delayed. **/ + private long fTime = System.currentTimeMillis() + TRANSMISSION_DELAY_TIME; + + // @see java.util.concurrent.Delayed + public long getDelay(TimeUnit unit) { + return unit.convert(fTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS); + } + + // @see java.lang.Comparable + public int compareTo(Delayed other) { + if (other == this) // compare zero ONLY if same object + return 0; + Request x = (Request)other; + long diff = fTime - x.fTime; + + if (diff < 0) return -1; + else if (diff > 0) return 1; + else if (fSequenceNumber < x.fSequenceNumber) return -1; + else return 1; + } + + /** All requests have an associated array of RequestMonitor tokens **/ + abstract RequestMonitor[] getRequestMonitors(); + } + + /** + * Object used to encapsulate the "getItemCount" requests. Instances of it + * are queued till processed. + */ + private static class CountRequest extends Request + { + DataRequestMonitor fRequestMonitor; + CountRequest(DataRequestMonitor rm) { fRequestMonitor = rm; } + @Override + DataRequestMonitor[] getRequestMonitors() { return new DataRequestMonitor[] { fRequestMonitor }; } + } + + /** + * Object used to encapsulate the "getItem" requests. Instances of it + * are queued till processed. + */ + private static class ItemRequest extends Request + { + DataRequestMonitor[] fRequestMonitors; + Integer[] fIndexes; + ItemRequest(Integer[] indexes, DataRequestMonitor[] rms) { fIndexes = indexes; fRequestMonitors = rms; } + @Override + DataRequestMonitor[] getRequestMonitors() { return fRequestMonitors; } + } + + /** + * The background thread of data provider. This thread retrieves the + * requests from the provider's queue and processes them. It also + * initiates random changes in the data set and issues corresponding + * events. + */ + private class ProviderThread extends Thread + { + /** + * Current count of items in the data set. It is changed + * periodically for simulation purposes. + */ + private int fCount = MIN_COUNT; + + /** + * Incremented with every data change, it causes the count to be reset + * every four random changes. + */ + private int fCountTrigger = 0; + + /** Time when the last change was performed. */ + private long fLastChangeTime = System.currentTimeMillis(); + + /** Random number generator */ + private Random fRandom = new java.util.Random(); + + @Override + public void run() { + try { + // Initialize the count. + randomCount(); + + // Perform the loop until the shutdown runnable is set. + while(fShutdownRequestMonitor == null) { + // Get the next request from the queue. The time-out + // ensures that that we get to process the random changes. + final Request request = fQueue.poll(RANDOM_CHANGE_MILIS / 10, TimeUnit.MILLISECONDS); + + // If a request was dequeued, process it. + if (request != null) { + // Simulate a processing delay. + Thread.sleep(PROCESSING_TIME); + + if (request instanceof CountRequest) { + processCountRequest((CountRequest)request); + } else if (request instanceof ItemRequest) { + processItemRequest((ItemRequest)request); + } + + // Whatever the results, post it to dispatch thread + // executor (with transmission delay). + fExecutor.schedule( + new DsfRunnable() { + public void run() { + for (RequestMonitor requestMonitor : request.getRequestMonitors()) { + requestMonitor.done(); + } + } + }, + TRANSMISSION_DELAY_TIME, TimeUnit.MILLISECONDS); + } + + // Simulate data changes. + randomChanges(); + } + } + catch (InterruptedException x) { + DsfExamplesPlugin.getDefault().getLog().log( new Status( + IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, 0, "Interrupted exception in slow data provider thread.", x )); //$NON-NLS-1$ + } + + // Notify the client that requested shutdown, that shutdown is complete. + fShutdownRequestMonitor.done(); + fShutdownRequestMonitor = null; + } + + private void processCountRequest(CountRequest request) { + // Calculate the simulated values. + request.fRequestMonitor.setData(fCount); + } + + private void processItemRequest(ItemRequest request) { + // Check to make sure that the number of indexes matches the number + // of return tokens. + assert request.fRequestMonitors.length == request.fIndexes.length; + + // Calculate the simulated values for each index in request. + for (int i = 0; i < request.fIndexes.length; i++) { + request.fRequestMonitors[i].setData(Long.toHexString(fLastChangeTime) + "." + request.fIndexes[i]); //$NON-NLS-1$ + } + } + + /** + * This method simulates changes in provider's data set. + */ + private void randomChanges() + { + if (System.currentTimeMillis() > fLastChangeTime + RANDOM_CHANGE_MILIS) { + fLastChangeTime = System.currentTimeMillis(); + // once in every 30 seconds broadcast item count change + if (++fCountTrigger % RANDOM_COUNT_CHANGE_INTERVALS == 0) randomCount(); + else randomDataChange(); + } + } + + + /** + * Calculates new size for provider's data set. + */ + private void randomCount() + { + fCount = MIN_COUNT + Math.abs(fRandom.nextInt()) % (MAX_COUNT - MIN_COUNT); + + // Generate the event that the count has changed, and post it to + // dispatch thread with transmission delay. + fExecutor.schedule( + new Runnable() { public void run() { + for (Listener listener : fListeners) { + listener.countChanged(); + } + }}, + TRANSMISSION_DELAY_TIME, TimeUnit.MILLISECONDS); + } + + + /** + * Invalidates a random range of indexes. + */ + private void randomDataChange() + { + final Set set = new HashSet(); + // Change one in ten values. + for (int i = 0; i < fCount * RANDOM_CHANGE_SET_PERCENTAGE / 100; i++) { + set.add( new Integer(Math.abs(fRandom.nextInt()) % fCount) ); + } + + // Generate the event that the data has changed. + // Post dispatch thread with transmission delay. + fExecutor.schedule( + new Runnable() { public void run() { + for (Listener listener : fListeners) { + listener.dataChanged(set); + } + }}, + TRANSMISSION_DELAY_TIME, TimeUnit.MILLISECONDS); + } + } + + + public CancellableInputCoalescingSlowDataProvider(DsfExecutor executor) { + fExecutor = executor; + fProviderThread = new ProviderThread(); + fProviderThread.start(); + } + + /** + * Requests shutdown of this data provider. + * @param requestMonitor Monitor to call when shutdown is complete. + */ + public void shutdown(RequestMonitor requestMonitor) { + fShutdownRequestMonitor = requestMonitor; + } + + /////////////////////////////////////////////////////////////////////////// + // DataProvider + public DsfExecutor getDsfExecutor() { + return fExecutor; + } + + public void getItemCount(final DataRequestMonitor rm) { + fQueue.add(new CountRequest(rm)); + } + + public void getItem(final int index, final DataRequestMonitor rm) { + // Schedule a buffer-servicing call, if one is needed. + if (fGetItemIndexesBuffer.isEmpty()) { + fExecutor.schedule( + new Runnable() { public void run() { + fileBufferedRequests(); + }}, + COALESCING_DELAY_TIME, + TimeUnit.MILLISECONDS); + } + + // Add the call data to the buffer. + // Note: it doesn't matter that the items were added to the buffer + // after the buffer-servicing request was scheduled. This is because + // the buffers are guaranteed not to be modified until this dispatch + // cycle is over. + fGetItemIndexesBuffer.add(index); + fGetItemRequestMonitorsBuffer.add(rm); + } + + @SuppressWarnings("unchecked") + public void fileBufferedRequests() { + // Check if there is room in the request queue. If not, re-schedule the + // buffer-servicing for later. + if (fQueue.size() >= REQUEST_QUEUE_SIZE_LIMIT) { + if (fGetItemIndexesBuffer.isEmpty()) { + fExecutor.schedule( + new Runnable() { public void run() { + fileBufferedRequests(); + }}, + REQUEST_BUFFER_FULL_RETRY_DELAY, + TimeUnit.MILLISECONDS); + } + return; + } + + // Remove a number of getItem() calls from the buffer, and combine them + // into a request. + List indexes = new LinkedList(); + List rms = new LinkedList(); + int numToCoalesce = 0; + while (!fGetItemIndexesBuffer.isEmpty() && numToCoalesce < COALESCING_COUNT_LIMIT) { + // Get the next call from buffer. + Integer index = fGetItemIndexesBuffer.remove(0); + DataRequestMonitor rm = fGetItemRequestMonitorsBuffer.remove(0); + + // If call is already cancelled, ignore it. + if (rm.getStatus().getSeverity() == IStatus.CANCEL) continue; + + // Otherwise add it to the request. + indexes.add(index); + rms.add(rm); + numToCoalesce++; + } + + // Queue the coalesced request. + fQueue.add( new ItemRequest( + indexes.toArray(new Integer[indexes.size()]), + rms.toArray(new DataRequestMonitor[rms.size()])) + ); + + // If there are still calls left in the buffer, execute another + // buffer-servicing call, but without any delay. + if (!fGetItemIndexesBuffer.isEmpty()) { + fExecutor.execute(new Runnable() { public void run() { + fileBufferedRequests(); + }}); + } + } + + public void addListener(Listener listener) { + assert fExecutor.isInExecutorThread(); + fListeners.add(listener); + } + + public void removeListener(Listener listener) { + assert fExecutor.isInExecutorThread(); + fListeners.remove(listener); + } + + // + /////////////////////////////////////////////////////////////////////////// + +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/CancellableInputCoalescingSlowDataProviderAction.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/CancellableInputCoalescingSlowDataProviderAction.java new file mode 100644 index 00000000000..32bee8ca4e4 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/CancellableInputCoalescingSlowDataProviderAction.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * 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.examples.dsf.concurrent; + +import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.IWorkbenchWindowActionDelegate; +import org.eclipse.ui.actions.ActionDelegate; + +public class CancellableInputCoalescingSlowDataProviderAction extends ActionDelegate + implements IWorkbenchWindowActionDelegate +{ + private IWorkbenchWindow fWindow; + + @Override + public void run(IAction action) { + if (fWindow != null) { + // Create the standard data provider. + final CancellableInputCoalescingSlowDataProvider dataProvider = + new CancellableInputCoalescingSlowDataProvider(new DefaultDsfExecutor()); + + // Create the dialog and open it. + Dialog dialog = new SlowDataProviderDialog( + fWindow.getShell(), new CancellingSlowDataProviderContentProvider(), dataProvider); + dialog.open(); + + // Shut down the data provider thread and the DSF executor thread. + // Note, since data provider is running in background thread, we have to + // wait until this background thread has completed shutdown before + // killing the executor thread itself. + dataProvider.shutdown(new RequestMonitor(dataProvider.getDsfExecutor(), null) { + @Override + public void handleCompleted() { + dataProvider.getDsfExecutor().shutdown(); + } + }); + } + } + + public void init(IWorkbenchWindow window) { + fWindow = window; + } +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/CancellingSlowDataProviderContentProvider.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/CancellingSlowDataProviderContentProvider.java new file mode 100644 index 00000000000..dfb153fa6b1 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/CancellingSlowDataProviderContentProvider.java @@ -0,0 +1,292 @@ +/******************************************************************************* + * 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.examples.dsf.concurrent; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; +import org.eclipse.jface.viewers.ILazyContentProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Table; + +public class CancellingSlowDataProviderContentProvider + implements ILazyContentProvider, DataProvider.Listener +{ + TableViewer fTableViewer; + DataProvider fDataProvider; + Display fDisplay; + List fItemDataRequestMonitors = new LinkedList(); + Set fCancelledIdxs = new HashSet(); + AtomicInteger fCancelCallsPending = new AtomicInteger(); + + /////////////////////////////////////////////////////////////////////////// + // ILazyContentProvider + public void dispose() { + if (fDataProvider != null) { + final DataProvider dataProvider = fDataProvider; + dataProvider.getDsfExecutor().execute( + new Runnable() { public void run() { + dataProvider.removeListener(CancellingSlowDataProviderContentProvider.this); + fTableViewer = null; + fDisplay = null; + fDataProvider = null; + }}); + } else { + fTableViewer = null; + fDisplay = null; + } + } + + public void inputChanged(final Viewer viewer, Object oldInput, final Object newInput) { + // If old data provider is not-null, unregister from it as listener. + if (fDataProvider != null) { + final DataProvider dataProvider = fDataProvider; + dataProvider.getDsfExecutor().execute( + new Runnable() { public void run() { + dataProvider.removeListener(CancellingSlowDataProviderContentProvider.this); + }}); + } + + + // Register as listener with new data provider. + // Note: if old data provider and new data provider use different executors, + // there is a chance of a race condition here. + if (newInput != null) { + ((DataProvider)newInput).getDsfExecutor().execute( + new Runnable() { public void run() { + if ( ((TableViewer)viewer).getTable().isDisposed() ) return; + fTableViewer = (TableViewer)viewer; + fDisplay = fTableViewer.getTable().getDisplay(); + fDataProvider = (DataProvider)newInput; + fDataProvider.addListener(CancellingSlowDataProviderContentProvider.this); + queryItemCount(); + }}); + } + } + + public void updateElement(final int index) { + assert fTableViewer != null; + if (fDataProvider == null) return; + + // Calculate the visible index range. + final int topIdx = fTableViewer.getTable().getTopIndex(); + final int botIdx = topIdx + getVisibleItemCount(topIdx); + + fCancelCallsPending.incrementAndGet(); + fDataProvider.getDsfExecutor().execute( + new Runnable() { public void run() { + // Must check again, in case disposed while re-dispatching. + if (fDataProvider == null || fTableViewer.getTable().isDisposed()) return; + if (index >= topIdx && index <= botIdx) { + queryItemData(index); + } + cancelStaleRequests(topIdx, botIdx); + }}); + } + + protected int getVisibleItemCount(int top) { + Table table = fTableViewer.getTable(); + int itemCount = table.getItemCount(); + return Math.min((table.getBounds().height / table.getItemHeight()) + 2, itemCount - top); + } + + /////////////////////////////////////////////////////////////////////////// + // DataProvider.Listener + public void countChanged() { + // Check for dispose. + if (fDataProvider == null) return; + + // Request new count. + queryItemCount(); + } + + public void dataChanged(final Set indexes) { + // Check for dispose. + if (fDataProvider == null) return; + + // Clear changed items in table viewer. + final TableViewer tableViewer = fTableViewer; + fDisplay.asyncExec( + new Runnable() { public void run() { + // Check again if table wasn't disposed when + // switching to the display thread. + if (fTableViewer == null || fTableViewer.getTable().isDisposed()) return; + for (Integer index : indexes) { + tableViewer.clear(index); + } + }}); + } + // + /////////////////////////////////////////////////////////////////////////// + + + /** + * Convenience extension to standard data return runnable. This extension + * automatically checks for errors and asynchronous dispose. + * @param + */ + private abstract class CPGetDataRequestMonitor extends DataRequestMonitor { + public CPGetDataRequestMonitor(DsfExecutor executor) { super(executor, null); } + abstract protected void doRun(); + @Override + public void handleCompleted() { + // If there is an error processing request, return. + if (!getStatus().isOK()) return; + + // If content provider was disposed, return. + if (fTableViewer == null || fTableViewer.getTable().isDisposed()) return; + + // Otherwise execute runnable. + doRun(); + } + } + + /** + * Executes the item count query with DataProvider. Must be called on + * data provider's dispatch thread. + */ + private void queryItemCount() { + assert fDataProvider.getDsfExecutor().isInExecutorThread(); + + // Request coumt from data provider. When the count is returned, we + // have to re-dispatch into the display thread to avoid calling + // the table widget on the DSF dispatch thread. + fCancelledIdxs.clear(); + fDataProvider.getItemCount( + new CPGetDataRequestMonitor(fDataProvider.getDsfExecutor()) { + @Override + protected void doRun() { + final TableViewer tableViewer = fTableViewer; + tableViewer.getTable().getDisplay().asyncExec( + new Runnable() { public void run() { + // Check again if table wasn't disposed when + // switching to the display thread. + if (tableViewer.getTable().isDisposed()) return; // disposed + tableViewer.setItemCount(getData()); + tableViewer.getTable().clearAll(); + }}); + }}); + + } + + + /** + * Dedicated class for data item requests. This class holds the index + * argument so it can be examined when cancelling stale requests. + */ + // Request data from data provider. Likewise, when the data is + // returned, we have to re-dispatch into the display thread to + // call the table widget. + class ItemGetDataRequestMonitor extends CPGetDataRequestMonitor { + + /** Index is used when cancelling stale requests. */ + int fIndex; + + ItemGetDataRequestMonitor(DsfExecutor executor, int index) { + super(executor); + fIndex = index; + } + + // Remove the request from list of outstanding requests. This has + // to be done in run() because doRun() is not always called. + @Override + public void handleCompleted() { + fItemDataRequestMonitors.remove(this); + super.handleCompleted(); + } + + // Process the result as usual. + @Override + protected void doRun() { + final TableViewer tableViewer = fTableViewer; + tableViewer.getTable().getDisplay().asyncExec( + new Runnable() { public void run() { + // Check again if table wasn't disposed when + // switching to the display thread. + if (tableViewer.getTable().isDisposed()) return; // disposed + tableViewer.replace(getData(), fIndex); + }}); + } + } + + /** + * Executes the data query with DataProvider. Must be called on dispatch + * thread. + * @param index Index of item to fetch. + */ + private void queryItemData(final int index) { + assert fDataProvider.getDsfExecutor().isInExecutorThread(); + + ItemGetDataRequestMonitor rm = new ItemGetDataRequestMonitor(fDataProvider.getDsfExecutor(), index); + fItemDataRequestMonitors.add(rm); + fDataProvider.getItem(index, rm); + } + + /** + * Iterates through the outstanding requests to data provider and + * cancells any that are nto visible any more. + * @param topIdx Top index of the visible items + * @param botIdx Bottom index of the visible items + */ + private void cancelStaleRequests(int topIdx, int botIdx) { + // Go through the outstanding requests and cencel any that + // are not visible anymore. + for (Iterator itr = fItemDataRequestMonitors.iterator(); itr.hasNext();) { + ItemGetDataRequestMonitor item = itr.next(); + if (item.fIndex < topIdx || item.fIndex > botIdx) { + // Set the item to cancelled status, so that the data provider + // will ignore it. + item.setStatus(new Status(IStatus.CANCEL, DsfExamplesPlugin.PLUGIN_ID, 0, "Cancelled", null)); //$NON-NLS-1$ + + // Add the item index to list of indexes that were cancelled, + // which will be sent to the table widget. + fCancelledIdxs.add(item.fIndex); + + // Remove the item from the outstanding cancel requests. + itr.remove(); + } + } + int cancelRequestsPending = fCancelCallsPending.decrementAndGet(); + if (!fCancelledIdxs.isEmpty() && cancelRequestsPending == 0) { + final Set cancelledIdxs = fCancelledIdxs; + fCancelledIdxs = new HashSet(); + final TableViewer tableViewer = fTableViewer; + tableViewer.getTable().getDisplay().asyncExec( + new Runnable() { public void run() { + // Check again if table wasn't disposed when + // switching to the display thread. + if (tableViewer.getTable().isDisposed()) return; + + // Clear the indexes of the cancelled request, so that the + // viewer knows to request them again when needed. + // Note: clearing using TableViewer.clear(int) seems very + // inefficient, it's better to use Table.clear(int[]). + int[] cancelledIdxsArray = new int[cancelledIdxs.size()]; + int i = 0; + for (Integer index : cancelledIdxs) { + cancelledIdxsArray[i++] = index; + } + tableViewer.getTable().clear(cancelledIdxsArray); + }}); + } + } +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/DataProvider.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/DataProvider.java new file mode 100644 index 00000000000..b2990b1c2ca --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/DataProvider.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * 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.examples.dsf.concurrent; + +import java.util.Set; + +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; + +public interface DataProvider { + + /** + * Interface for listeners for changes in Provider's data. + */ + public interface Listener { + /** + * Indicates that the count of data items has changed. + */ + void countChanged(); + + /** + * Indicates that some of the data values have changed. + * @param indexes Indexes of the changed items. + */ + void dataChanged(Set indexes); + } + + /** + * Returns the DSF executor that has to be used to call this data + * provider. + */ + DsfExecutor getDsfExecutor(); + + /** + * Retrieves the current item count. + * @param rm Request monitor, to be filled in with the Integer value. + */ + void getItemCount(DataRequestMonitor rm); + + /** + * Retrieves data value for given index. + * @param index Index of the item to retrieve + * @param rm Return data token, to be filled in with a String value + */ + void getItem(int index, DataRequestMonitor rm); + + /** + * Registers given listener with data provider. + */ + void addListener(Listener listener); + + /** + * Removes given listener from data provider. + */ + void removeListener(Listener listener); +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/InputCoalescingSlowDataProvider.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/InputCoalescingSlowDataProvider.java new file mode 100644 index 00000000000..62d2a910084 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/InputCoalescingSlowDataProvider.java @@ -0,0 +1,408 @@ +/******************************************************************************* + * 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.examples.dsf.concurrent; + +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Random; +import java.util.Set; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.DelayQueue; +import java.util.concurrent.Delayed; +import java.util.concurrent.TimeUnit; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; + +/** + * Example data provider which has a built-in delay when fetching data. This + * data provider simulates a service which retrieves data from an external + * source such as a networked target, which incurs a considerable delay when + * retrieving data. The data items are simulated values which consist of the + * time when data is being retrieved followed by the item's index. + *

    + * This version of the data provider features an optimization which causes + * item requests to be grouped together even before they are filed into the + * processing queue. This example demonstrates how the service can implement + * coalescing impelemntation in a situation where the provider has an + * interface which only accepts aggregate requests, so the requests have to be + * coalesed before they are sent to the provider. + */ +public class InputCoalescingSlowDataProvider implements DataProvider { + + /** Minimum count of data items */ + private final static int MIN_COUNT = 1000; + + /** Maximum count of data items */ + private final static int MAX_COUNT = 2000; + + /** Time interval how often random changes occur. */ + private final static int RANDOM_CHANGE_MILIS = 10000; + + /** Number of times random changes are made, before count is changed. */ + private final static int RANDOM_COUNT_CHANGE_INTERVALS = 3; + + /** Percentage of values that is changed upon random change (0-100). */ + private final static int RANDOM_CHANGE_SET_PERCENTAGE = 10; + + /** + * Amount of time (in miliseconds) how long the requests to provider, and + * events from provider are delayed by. + */ + private final static int TRANSMISSION_DELAY_TIME = 500; + + /** + * Amount of time (in milliseconds) how long the provider takes to process + * a request. + */ + private final static int PROCESSING_TIME = 100; + + /** + * Maximum number of item requests that can be coalesced into a single + * request. + */ + private final static int COALESCING_COUNT_LIMIT = 10; + + /** + * Delay in processing the buffer of getItem() calls. This delay helps + * to ensure that a meaningful number of items is present in the buffer + * before the buffer data is coalesced into a request. + */ + private final static int COALESCING_DELAY_TIME = 10; + + /** Dispatch-thread executor that this provider uses. */ + private DsfExecutor fExecutor; + + /** List of listeners registered for events from provider. */ + private List fListeners = new LinkedList(); + + /** Thread that handles data requests. */ + private ProviderThread fProviderThread; + + /** Queue of currently pending data requests. */ + private final BlockingQueue fQueue = new DelayQueue(); + + /** + * Runnable to be submitted when the data provider thread is shut down. + * This variable acts like a flag: when client want to shut down the + * provider, it sets this runnable, and when the backgroun thread sees + * that it's set, it shuts itself down, and posts this runnable with + * the executor. + */ + private RequestMonitor fShutdownRequestMonitor = null; + + /** + * Buffers for coalescing getItem() calls into a single request. + */ + private List fGetItemIndexesBuffer = new LinkedList(); + private List> fGetItemRequestMonitorsBuffer = new LinkedList>(); + + /** + * Base class for requests that are queued by the data provider. It + * implements java.util.concurrent.Delayed to allow for use of DelayedQueue. + * Every request into the queue is delayed by the simulated transmission + * time. + */ + private static abstract class Request implements Delayed { + /** Sequence counter and number are used to ensure FIFO order **/ + private static int fSequenceCounter = 0; + private int fSequenceNumber = fSequenceCounter++; + + /** Time delay tracks how items will be delayed. **/ + private long fTime = System.currentTimeMillis() + TRANSMISSION_DELAY_TIME; + + // @see java.util.concurrent.Delayed + public long getDelay(TimeUnit unit) { + return unit.convert(fTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS); + } + + // @see java.lang.Comparable + public int compareTo(Delayed other) { + if (other == this) // compare zero ONLY if same object + return 0; + Request x = (Request)other; + long diff = fTime - x.fTime; + + if (diff < 0) return -1; + else if (diff > 0) return 1; + else if (fSequenceNumber < x.fSequenceNumber) return -1; + else return 1; + } + + /** All requests have an associated array of RequestMonitor tokens **/ + abstract RequestMonitor[] getRequestMonitors(); + } + + /** + * Object used to encapsulate the "getItemCount" requests. Instances of it + * are queued till processed. + */ + private static class CountRequest extends Request + { + DataRequestMonitor fRequestMonitors; + CountRequest(DataRequestMonitor rms) { fRequestMonitors = rms; } + @Override + DataRequestMonitor[] getRequestMonitors() { return new DataRequestMonitor[] { fRequestMonitors }; } + } + + /** + * Object used to encapsulate the "getItem" requests. Instances of it + * are queued till processed. + */ + private static class ItemRequest extends Request + { + DataRequestMonitor[] fRequestMonitors; + Integer[] fIndexes; + ItemRequest(Integer[] indexes, DataRequestMonitor[] rms) { fIndexes = indexes; fRequestMonitors = rms; } + @Override + DataRequestMonitor[] getRequestMonitors() { return fRequestMonitors; } + } + + /** + * The background thread of data provider. This thread retrieves the + * requests from the provider's queue and processes them. It also + * initiates random changes in the data set and issues corresponding + * events. + */ + private class ProviderThread extends Thread + { + /** + * Current count of items in the data set. It is changed + * periodically for simulation purposes. + */ + private int fCount = MIN_COUNT; + + /** + * Incremented with every data change, it causes the count to be reset + * every four random changes. + */ + private int fCountTrigger = 0; + + /** Time when the last change was performed. */ + private long fLastChangeTime = System.currentTimeMillis(); + + /** Random number generator */ + private Random fRandom = new java.util.Random(); + + @Override + public void run() { + try { + // Initialize the count. + randomCount(); + + // Perform the loop until the shutdown runnable is set. + while(fShutdownRequestMonitor == null) { + // Get the next request from the queue. The time-out + // ensures that that we get to process the random changes. + final Request request = fQueue.poll(RANDOM_CHANGE_MILIS / 10, TimeUnit.MILLISECONDS); + + // If a request was dequeued, process it. + if (request != null) { + // Simulate a processing delay. + Thread.sleep(PROCESSING_TIME); + + if (request instanceof CountRequest) { + processCountRequest((CountRequest)request); + } else if (request instanceof ItemRequest) { + processItemRequest((ItemRequest)request); + } + // Whatever the results, post it to dispatch thread + // executor (with transmission delay). + fExecutor.schedule( + new DsfRunnable() { + public void run() { + for (RequestMonitor requestMonitor : request.getRequestMonitors()) { + requestMonitor.done(); + } + } + }, + TRANSMISSION_DELAY_TIME, TimeUnit.MILLISECONDS); + } + + // Simulate data changes. + randomChanges(); + } + } + catch (InterruptedException x) { + DsfExamplesPlugin.getDefault().getLog().log( new Status( + IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, 0, "Interrupted exception in slow data provider thread.", x )); //$NON-NLS-1$ + } + + // Notify the client that requested shutdown, that shutdown is complete. + fShutdownRequestMonitor.done(); + fShutdownRequestMonitor = null; + } + + private void processCountRequest(CountRequest request) { + // Calculate the simulated values. + request.fRequestMonitors.setData(fCount); + } + + private void processItemRequest(ItemRequest request) { + // Check to make sure that the number of indexes matches the number + // of return tokens. + assert request.fRequestMonitors.length == request.fIndexes.length; + + // Calculate the simulated values for each index in request. + for (int i = 0; i < request.fIndexes.length; i++) { + request.fRequestMonitors[i].setData(Long.toHexString(fLastChangeTime) + "." + request.fIndexes[i]); //$NON-NLS-1$ + } + } + + /** + * This method simulates changes in provider's data set. + */ + private void randomChanges() + { + if (System.currentTimeMillis() > fLastChangeTime + RANDOM_CHANGE_MILIS) { + fLastChangeTime = System.currentTimeMillis(); + // once in every 30 seconds broadcast item count change + if (++fCountTrigger % RANDOM_COUNT_CHANGE_INTERVALS == 0) randomCount(); + else randomDataChange(); + } + } + + + /** + * Calculates new size for provider's data set. + */ + private void randomCount() + { + fCount = MIN_COUNT + Math.abs(fRandom.nextInt()) % (MAX_COUNT - MIN_COUNT); + + // Generate the event that the count has changed, and post it to + // dispatch thread with transmission delay. + fExecutor.schedule( + new Runnable() { public void run() { + for (Listener listener : fListeners) { + listener.countChanged(); + } + }}, + TRANSMISSION_DELAY_TIME, TimeUnit.MILLISECONDS); + } + + + /** + * Invalidates a random range of indexes. + */ + private void randomDataChange() + { + final Set set = new HashSet(); + // Change one in ten values. + for (int i = 0; i < fCount * RANDOM_CHANGE_SET_PERCENTAGE / 100; i++) { + set.add( new Integer(Math.abs(fRandom.nextInt()) % fCount) ); + } + + // Generate the event that the data has changed. + // Post dispatch thread with transmission delay. + fExecutor.schedule( + new Runnable() { public void run() { + for (Listener listener : fListeners) { + listener.dataChanged(set); + } + }}, + TRANSMISSION_DELAY_TIME, TimeUnit.MILLISECONDS); + } + } + + + public InputCoalescingSlowDataProvider(DsfExecutor executor) { + fExecutor = executor; + fProviderThread = new ProviderThread(); + fProviderThread.start(); + } + + /** + * Requests shutdown of this data provider. + * @param requestMonitor Monitor to call when shutdown is complete. + */ + public void shutdown(RequestMonitor requestMonitor) { + fShutdownRequestMonitor = requestMonitor; + } + + /////////////////////////////////////////////////////////////////////////// + // DataProvider + public DsfExecutor getDsfExecutor() { + return fExecutor; + } + + public void getItemCount(final DataRequestMonitor rm) { + fExecutor.schedule( + new Runnable() { public void run() { + fQueue.add(new CountRequest(rm)); + }}, + TRANSMISSION_DELAY_TIME, + TimeUnit.MILLISECONDS); + } + + public void getItem(final int index, final DataRequestMonitor rm) { + // Schedule a buffer-servicing call, if one is needed. + if (fGetItemIndexesBuffer.isEmpty()) { + fExecutor.schedule( + new Runnable() { public void run() { + fileBufferedRequests(); + }}, + COALESCING_DELAY_TIME, + TimeUnit.MILLISECONDS); + } + + // Add the call data to the buffer. + // Note: it doesn't matter that the items were added to the buffer + // after the buffer-servicing request was scheduled. This is because + // the buffers are guaranteed not to be modified until this dispatch + // cycle is over. + fGetItemIndexesBuffer.add(index); + fGetItemRequestMonitorsBuffer.add(rm); + } + + @SuppressWarnings("unchecked") + public void fileBufferedRequests() { + // Remove a number of getItem() calls from the buffer, and combine them + // into a request. + int numToCoalesce = Math.min(fGetItemIndexesBuffer.size(), COALESCING_COUNT_LIMIT); + final ItemRequest request = new ItemRequest(new Integer[numToCoalesce], new DataRequestMonitor[numToCoalesce]); + for (int i = 0; i < numToCoalesce; i++) { + request.fIndexes[i] = fGetItemIndexesBuffer.remove(0); + request.fRequestMonitors[i] = fGetItemRequestMonitorsBuffer.remove(0); + } + + // Queue the coalesced request, with the appropriate transmission delay. + fQueue.add(request); + + // If there are still calls left in the buffer, execute another + // buffer-servicing call, but without any delay. + if (!fGetItemIndexesBuffer.isEmpty()) { + fExecutor.execute(new Runnable() { public void run() { + fileBufferedRequests(); + }}); + } + } + + public void addListener(Listener listener) { + assert fExecutor.isInExecutorThread(); + fListeners.add(listener); + } + + public void removeListener(Listener listener) { + assert fExecutor.isInExecutorThread(); + fListeners.remove(listener); + } + + // + /////////////////////////////////////////////////////////////////////////// + +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/InputCoalescingSlowDataProviderAction.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/InputCoalescingSlowDataProviderAction.java new file mode 100644 index 00000000000..dccf8b8d92f --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/InputCoalescingSlowDataProviderAction.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * 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.examples.dsf.concurrent; + +import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.IWorkbenchWindowActionDelegate; +import org.eclipse.ui.actions.ActionDelegate; + +public class InputCoalescingSlowDataProviderAction extends ActionDelegate + implements IWorkbenchWindowActionDelegate +{ + private IWorkbenchWindow fWindow; + + @Override + public void run(IAction action) { + if (fWindow != null) { + // Create the standard data provider. + final InputCoalescingSlowDataProvider dataProvider = + new InputCoalescingSlowDataProvider(new DefaultDsfExecutor()); + + // Create the dialog and open it. + Dialog dialog = new SlowDataProviderDialog( + fWindow.getShell(), new SlowDataProviderContentProvider(), dataProvider); + dialog.open(); + + // Shut down the data provider thread and the DSF executor thread. + // Note, since data provider is running in background thread, we have to + // wait until this background thread has completed shutdown before + // killing the executor thread itself. + dataProvider.shutdown(new RequestMonitor(dataProvider.getDsfExecutor(), null) { + @Override + public void handleCompleted() { + dataProvider.getDsfExecutor().shutdown(); + } + }); + } + } + + public void init(IWorkbenchWindow window) { + fWindow = window; + } +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/SlowDataProvider.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/SlowDataProvider.java new file mode 100644 index 00000000000..f0c350581d9 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/SlowDataProvider.java @@ -0,0 +1,330 @@ +/******************************************************************************* + * 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.examples.dsf.concurrent; + +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Random; +import java.util.Set; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.DelayQueue; +import java.util.concurrent.Delayed; +import java.util.concurrent.TimeUnit; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; + +/** + * Example data provider which has a built-in delay when fetching data. This + * data provider simulates a service which retrieves data from an external + * source such as a networked target, which incurs a considerable delay when + * retrieving data. The data items are simulated values which consist of the + * time when data is being retrieved followed by the item's index. + */ +public class SlowDataProvider implements DataProvider { + + /** Minimum count of data items */ + private final static int MIN_COUNT = 1000; + + /** Maximum count of data items */ + private final static int MAX_COUNT = 2000; + + /** Time interval how often random changes occur. */ + private final static int RANDOM_CHANGE_MILIS = 10000; + + /** Number of times random changes are made, before count is changed. */ + private final static int RANDOM_COUNT_CHANGE_INTERVALS = 3; + + /** Percentage of values that is changed upon random change (0-100). */ + private final static int RANDOM_CHANGE_SET_PERCENTAGE = 10; + + /** + * Amount of time (in miliseconds) how long the requests to provider, and + * events from provider are delayed by. + */ + private final static int TRANSMISSION_DELAY_TIME = 500; + + /** + * Amount of time (in milliseconds) how long the provider takes to process + * a request. + */ + private final static int PROCESSING_TIME = 100; + + /** Dispatch-thread executor that this provider uses. */ + private DsfExecutor fExecutor; + + /** List of listeners registered for events from provider. */ + private List fListeners = new LinkedList(); + + /** Thread that handles data requests. */ + private ProviderThread fProviderThread; + + /** Queue of currently pending data requests. */ + private final BlockingQueue fQueue = new DelayQueue(); + + /** + * Runnable to be submitted when the data provider thread is shut down. + * This variable acts like a flag: when client want to shut down the + * provider, it sets this runnable, and when the backgroun thread sees + * that it's set, it shuts itself down, and posts this runnable with + * the executor. + */ + private RequestMonitor fShutdownRequestMonitor = null; + + /** + * Base class for requests that are queued by the data provider. It + * implements java.util.concurrent.Delayed to allow for use of DelayedQueue. + * Every request into the queue is delayed by the simulated transmission + * time. + */ + private static abstract class Request implements Delayed { + /** Sequence counter and number are used to ensure FIFO order **/ + private static int fSequenceCounter = 0; + private int fSequenceNumber = fSequenceCounter++; + + /** Time delay tracks how items will be delayed. **/ + private long fTime = System.currentTimeMillis() + TRANSMISSION_DELAY_TIME; + + // @see java.util.concurrent.Delayed + public long getDelay(TimeUnit unit) { + return unit.convert(fTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS); + } + + // @see java.lang.Comparable + public int compareTo(Delayed other) { + if (other == this) // compare zero ONLY if same object + return 0; + Request x = (Request)other; + long diff = fTime - x.fTime; + + if (diff < 0) return -1; + else if (diff > 0) return 1; + else if (fSequenceNumber < x.fSequenceNumber) return -1; + else return 1; + } + + /** All requests have an associated RequestMonitor token **/ + abstract RequestMonitor getRequestMonitor(); + } + + /** + * Object used to encapsulate the "getItemCount" requests. Instances of it + * are queued till processed. + */ + private static class CountRequest extends Request + { + DataRequestMonitor fRequestMonitor; + CountRequest(DataRequestMonitor rm) { fRequestMonitor = rm; } + @Override + DataRequestMonitor getRequestMonitor() { return fRequestMonitor; } + } + + /** + * Object used to encapsulate the "getItem" requests. Instances of it + * are queued till processed. + */ + private static class ItemRequest extends Request + { + DataRequestMonitor fRequestMonitor; + int fIndex; + ItemRequest(int index, DataRequestMonitor rm) { fIndex = index; fRequestMonitor = rm; } + @Override + DataRequestMonitor getRequestMonitor() { return fRequestMonitor; } + } + + /** + * The background thread of data provider. This thread retrieves the + * requests from the provider's queue and processes them. It also + * initiates random changes in the data set and issues corresponding + * events. + */ + private class ProviderThread extends Thread + { + /** + * Current count of items in the data set. It is changed + * periodically for simulation purposes. + */ + private int fCount = MIN_COUNT; + + /** + * Incremented with every data change, it causes the count to be reset + * every four random changes. + */ + private int fCountTrigger = 0; + + /** Time when the last change was performed. */ + private long fLastChangeTime = System.currentTimeMillis(); + + /** Random number generator */ + private Random fRandom = new java.util.Random(); + + @Override + public void run() { + try { + // Initialize the count. + randomCount(); + + // Perform the loop until the shutdown runnable is set. + while(fShutdownRequestMonitor == null) { + // Get the next request from the queue. The time-out + // ensures that that we get to process the random changes. + final Request request = fQueue.poll(RANDOM_CHANGE_MILIS / 10, TimeUnit.MILLISECONDS); + + // If a request was dequeued, process it. + if (request != null) { + // Simulate a processing delay. + Thread.sleep(PROCESSING_TIME); + + if (request instanceof CountRequest) { + processCountRequest((CountRequest)request); + } else if (request instanceof ItemRequest) { + processItemRequest((ItemRequest)request); + } + // Whatever the result, post it to dispatch thread + // executor (with transmission delay). + fExecutor.schedule( + new DsfRunnable() { + public void run() { + request.getRequestMonitor().done(); + } + }, + TRANSMISSION_DELAY_TIME, TimeUnit.MILLISECONDS); + } + + // Simulate data changes. + randomChanges(); + } + } + catch (InterruptedException x) { + DsfExamplesPlugin.getDefault().getLog().log( new Status( + IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, 0, "Interrupted exception in slow data provider thread.", x )); //$NON-NLS-1$ + } + + // Notify the client that requested shutdown, that shutdown is complete. + fShutdownRequestMonitor.done(); + fShutdownRequestMonitor = null; + } + + private void processCountRequest(CountRequest request) { + // Calculate the simulated values. + request.fRequestMonitor.setData(fCount); + } + + private void processItemRequest(ItemRequest request) { + // Calculate the simulated values. + request.fRequestMonitor.setData(Long.toHexString(fLastChangeTime) + "." + request.fIndex); //$NON-NLS-1$ + } + + /** + * This method simulates changes in provider's data set. + */ + private void randomChanges() + { + if (System.currentTimeMillis() > fLastChangeTime + RANDOM_CHANGE_MILIS) { + fLastChangeTime = System.currentTimeMillis(); + // once in every 30 seconds broadcast item count change + if (++fCountTrigger % RANDOM_COUNT_CHANGE_INTERVALS == 0) randomCount(); + else randomDataChange(); + } + } + + + /** + * Calculates new size for provider's data set. + */ + private void randomCount() + { + fCount = MIN_COUNT + Math.abs(fRandom.nextInt()) % (MAX_COUNT - MIN_COUNT); + + // Generate the event that the count has changed, and post it to + // dispatch thread with transmission delay. + fExecutor.schedule( + new Runnable() { public void run() { + for (Listener listener : fListeners) { + listener.countChanged(); + } + }}, + TRANSMISSION_DELAY_TIME, TimeUnit.MILLISECONDS); + } + + + /** + * Invalidates a random range of indexes. + */ + private void randomDataChange() + { + final Set set = new HashSet(); + // Change one in ten values. + for (int i = 0; i < fCount * RANDOM_CHANGE_SET_PERCENTAGE / 100; i++) { + set.add( new Integer(Math.abs(fRandom.nextInt()) % fCount) ); + } + + // Generate the event that the data has changed. + // Post dispatch thread with transmission delay. + fExecutor.schedule( + new Runnable() { public void run() { + for (Listener listener : fListeners) { + listener.dataChanged(set); + } + }}, + TRANSMISSION_DELAY_TIME, TimeUnit.MILLISECONDS); + } + } + + + public SlowDataProvider(DsfExecutor executor) { + fExecutor = executor; + fProviderThread = new ProviderThread(); + fProviderThread.start(); + } + + /** + * Requests shutdown of this data provider. + * @param requestMonitor Request completion monitor. + */ + public void shutdown(RequestMonitor requestMonitor) { + fShutdownRequestMonitor = requestMonitor; + } + + /////////////////////////////////////////////////////////////////////////// + // DataProvider + public DsfExecutor getDsfExecutor() { + return fExecutor; + } + + public void getItemCount(final DataRequestMonitor rm) { + fQueue.add(new CountRequest(rm)); + } + + public void getItem(final int index, final DataRequestMonitor rm) { + fQueue.add(new ItemRequest(index, rm)); + } + + public void addListener(Listener listener) { + assert fExecutor.isInExecutorThread(); + fListeners.add(listener); + } + + public void removeListener(Listener listener) { + assert fExecutor.isInExecutorThread(); + fListeners.remove(listener); + } + + // + /////////////////////////////////////////////////////////////////////////// + +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/SlowDataProviderAction.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/SlowDataProviderAction.java new file mode 100644 index 00000000000..77c0c37e192 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/SlowDataProviderAction.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * 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.examples.dsf.concurrent; + +import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.IWorkbenchWindowActionDelegate; +import org.eclipse.ui.actions.ActionDelegate; + +public class SlowDataProviderAction extends ActionDelegate + implements IWorkbenchWindowActionDelegate +{ + private IWorkbenchWindow fWindow; + + @Override + public void run(IAction action) { + if (fWindow != null) { + // Create the standard data provider. + final SlowDataProvider dataProvider = new SlowDataProvider(new DefaultDsfExecutor()); + + // Create the dialog and open it. + Dialog dialog = new SlowDataProviderDialog( + fWindow.getShell(), new SlowDataProviderContentProvider(), dataProvider); + dialog.open(); + + // Shut down the data provider thread and the DSF executor thread. + // Note, since data provider is running in background thread, we have to + // wait until this background thread has completed shutdown before + // killing the executor thread itself. + dataProvider.shutdown(new RequestMonitor(dataProvider.getDsfExecutor(), null) { + @Override + public void handleCompleted() { + dataProvider.getDsfExecutor().shutdown(); + } + }); + } + } + + public void init(IWorkbenchWindow window) { + fWindow = window; + } +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/SlowDataProviderContentProvider.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/SlowDataProviderContentProvider.java new file mode 100644 index 00000000000..a71d5019c8c --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/SlowDataProviderContentProvider.java @@ -0,0 +1,190 @@ +/******************************************************************************* + * 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.examples.dsf.concurrent; + +import java.util.Set; + +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.jface.viewers.ILazyContentProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; + +public class SlowDataProviderContentProvider + implements ILazyContentProvider, DataProvider.Listener +{ + + TableViewer fTableViewer; + DataProvider fDataProvider; + + /////////////////////////////////////////////////////////////////////////// + // ILazyContentProvider + public void dispose() { + if (fDataProvider != null) { + final DataProvider dataProvider = fDataProvider; + dataProvider.getDsfExecutor().execute( + new Runnable() { public void run() { + dataProvider.removeListener(SlowDataProviderContentProvider.this); + fTableViewer = null; + fDataProvider = null; + }}); + } else { + fTableViewer = null; + } + } + + public void inputChanged(final Viewer viewer, Object oldInput, final Object newInput) { + // If old data provider is not-null, unregister from it as listener. + if (fDataProvider != null) { + final DataProvider dataProvider = fDataProvider; + dataProvider.getDsfExecutor().execute( + new Runnable() { public void run() { + dataProvider.removeListener(SlowDataProviderContentProvider.this); + }}); + } + + + // Register as listener with new data provider. + // Note: if old data provider and new data provider use different executors, + // there is a chance of a race condition here. + if (newInput != null) { + ((DataProvider)newInput).getDsfExecutor().execute( + new Runnable() { public void run() { + fTableViewer = (TableViewer)viewer; + fDataProvider = (DataProvider)newInput; + fDataProvider.addListener(SlowDataProviderContentProvider.this); + queryItemCount(); + }}); + } + } + + public void updateElement(final int index) { + assert fTableViewer != null; + if (fDataProvider == null) return; + + fDataProvider.getDsfExecutor().execute( + new Runnable() { public void run() { + // Must check again, in case disposed while re-dispatching. + if (fDataProvider == null) return; + + queryItemData(index); + }}); + } + + + /////////////////////////////////////////////////////////////////////////// + // DataProvider.Listener + public void countChanged() { + // Check for dispose. + if (fDataProvider == null) return; + + // Request new count. + queryItemCount(); + } + + public void dataChanged(final Set indexes) { + // Check for dispose. + if (fDataProvider == null) return; + + // Clear changed items in table viewer. + if (fTableViewer != null) { + final TableViewer tableViewer = fTableViewer; + tableViewer.getTable().getDisplay().asyncExec( + new Runnable() { public void run() { + // Check again if table wasn't disposed when + // switching to the display thread. + if (tableViewer.getTable().isDisposed()) return; // disposed + for (Integer index : indexes) { + tableViewer.clear(index); + } + }}); + } + } + // + /////////////////////////////////////////////////////////////////////////// + + + /** + * Convenience extension to standard data return runnable. This extension + * automatically checks for errors and asynchronous dipose. + * @param + */ + private abstract class CPGetDataRequestMonitor extends DataRequestMonitor { + CPGetDataRequestMonitor(DsfExecutor executor) { super(executor, null); } + abstract protected void doRun(); + @Override + final public void handleCompleted() { + // If there is an error processing request, return. + if (!getStatus().isOK()) return; + + // If content provider was disposed, return. + if (fTableViewer == null) return; + + // Otherwise execute runnable. + doRun(); + } + } + + /** + * Executes the item count query with DataProvider. Must be called on + * data provider's dispatch thread. + */ + private void queryItemCount() { + assert fDataProvider.getDsfExecutor().isInExecutorThread(); + + // Request coumt from data provider. When the count is returned, we + // have to re-dispatch into the display thread to avoid calling + // the table widget on the DSF dispatch thread. + fDataProvider.getItemCount( + new CPGetDataRequestMonitor(fDataProvider.getDsfExecutor()) { + @Override + protected void doRun() { + final TableViewer tableViewer = fTableViewer; + tableViewer.getTable().getDisplay().asyncExec( + new Runnable() { public void run() { + // Check again if table wasn't disposed when + // switching to the display thread. + if (tableViewer.getTable().isDisposed()) return; // disposed + tableViewer.setItemCount(getData()); + tableViewer.getTable().clearAll(); + }}); + }}); + + } + + /** + * Executes the data query with DataProvider. Must be called on dispatch + * thread. + * @param index Index of item to fetch. + */ + private void queryItemData(final int index) { + assert fDataProvider.getDsfExecutor().isInExecutorThread(); + + // Request data from data provider. Likewise, when the data is + // returned, we have to re-dispatch into the display thread to + // call the table widget. + fDataProvider.getItem( + index, + new CPGetDataRequestMonitor(fDataProvider.getDsfExecutor()) { + @Override + protected void doRun() { + final TableViewer tableViewer = fTableViewer; + tableViewer.getTable().getDisplay().asyncExec( + new Runnable() { public void run() { + // Check again if table wasn't disposed when + // switching to the display thread. + if (tableViewer.getTable().isDisposed()) return; // disposed + tableViewer.replace(getData(), index); + }}); + }}); + } + +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/SlowDataProviderDialog.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/SlowDataProviderDialog.java new file mode 100644 index 00000000000..4c763724658 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/SlowDataProviderDialog.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * 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.examples.dsf.concurrent; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.viewers.IContentProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; + +/** + * Dialog shared by all slow data provider examples. It accepts the data + * provider and the content provider as arguments to the constructor. So the + * only thing that the dialog does is to create the table viewer and + * initialize it with the providers. + */ +public class SlowDataProviderDialog extends Dialog { + + private TableViewer fDataViewer; + private DataProvider fDataProvider; + private IContentProvider fContentProvider; + + public SlowDataProviderDialog(Shell parent, IContentProvider contentProvider, DataProvider dataProvider) { + super(parent); + setShellStyle(getShellStyle() | SWT.RESIZE); + fContentProvider = contentProvider; + fDataProvider = dataProvider; + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite area = (Composite) super.createDialogArea(parent); + fDataViewer = new TableViewer(area, SWT.VIRTUAL); + fDataViewer.getTable().setLayoutData(new GridData(GridData.FILL_BOTH)); + fDataViewer.setContentProvider(fContentProvider); + fDataViewer.setInput(fDataProvider); + return area; + } +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/doc-files/dsf_concurrency_model-1.png b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/doc-files/dsf_concurrency_model-1.png new file mode 100644 index 0000000000000000000000000000000000000000..1bb373447d7bd0f17cd54f8298fc6f65658c8420 GIT binary patch literal 6256 zcmb7IXH-*Nvra<5D1dv zrDzaB2SJe=-}hVJk9&XJv(_nlpPAWn=FB{MX5x(vb)nZ-t^oi5s2=RL2><{JBR)q! zK*TG%I*&f_26odh&;S7HQ^J1TODB%6`ogRN0045@zb6p4_~kZU?c` z%=YG5e(+_`D3-r6fDIHE_W)^gCW$PQFC;a=@elm|^<$>?@g6w@0OSOKBLLKv5nWXH zuZ+|HkUHS+WE~*#F~iRY@_*kFXID-uUE1vI_LNpR85OSoOC&)Rc?+XF1{C3l?i$-z zDSAL7^jE-&0$3gUG1Jqri*qr4rAOxPTv3}H8NK?-nFfh3aYS4qG8ke%@iKNNI7E5M)_@JV>mW2sXncXP&W*nXvO^PVoj0 z+-Ks*L|JKDTDj2NVY?GM?wTIzQ7!D*nS`0@aDnFAB}Q(f|B#N#}f z{RaI?y}2?TknigAm8Q42&nfojJASl~d7;k45sY_`sai_+a48AbX4N`j-{B~olEKj% zx5{7JxgX+?Z`#)TiG?T)>8plI)WCj_5IwAsYnwESad$}*duu9867zDg$RTW!y=Y|Z zCc-J$B~99-EZpUnm)#0e)7y5%jp$fE!+lB~BsBnE(|raL--4{Ly}pqA+-+bXCfPK% zb0cHKYMLJQ=05ZJ!Jy;peY!7jTxMt)RwTsRU8mpbi^R$Ck!X`~D+|l}B>4f#CiXE9 z1J;o4&mc9+<}L7V3{s?HYp?joiH?7ff3iAG^u};Q`qDIoGQR(SLO2Vj;fcFC*^*(!7tR1a`o;)cS$F(@l`552e3Gj*|)pUeJ>#AGsSJPHqeYg3vLGa73 zjbM1t$GLayiDTQ_C-t3V-@*^trD;F(*MIr8CeEjpgao)6j!f!0#d zS=VKFEN3Cy02~w)6g98PV{cH(juXA*0-ssd?A@Z``F6a{61Lg@IKgElOut0uD;S?r zbn3Sls?+u2ZXTwxLupgD@!S3DqaNe3Kb^HhYuHx8ymx-5MWHS%5&Xe_SADZp()_t% z3<@fke~H}7ebGbnA@Y#Mg@u9^qYPQep4w#wBBe6z3R?O$O8ngU*4_(Ax027SNGm5^ z?2vrBK+3Rl!Gdn|j#94&QvR%+>=_#P6N$zVZaSWlWv zCD0%heIfOn&z%MBmY@{a*#X^%wTclFPb#$H**i5&`J`uvR-9%OCsQ&@N|*#D=iKV^ z2mfdW7^AAOw*3{HSIR5hB0;&(xpOq@)76p$SssVAgP1Zk=9bQ?cUPWbDbjZpLHI|t zrS8nK@^^F|qJD@LP9e%vFs3Hq<$S$25HM_FS->n?q4@f)Zf5QGD`%+;+0*T9E)G;v zuBizw1B8PdbfZvAkHQ!w#R(k|boic}$(kZCLowNsL+dA|Ut+hJZwo&5wT4zqTotRO zqlR@C%`S5J(Km+HCt} z00qwFSFEja>2on&IXMoe2Qhk2vB;D^mYx;n`dxn>_7FTU!oo0{avf|%)=h2Zo!0_- zGjf(4(6U|K9E3v1b*{(MM1YJ+Xi}QA!xqN?2^0K6 zMiMdtS0vyif}7rTfjvJzZO!Q0-kiH~W?PKVGUDB(jR@f?e?tNK4yRh%ZltPbBZfS| z_^E+YonAJLTY%}Si7am>m*IifrrPxc3;CzYMXcfEQohL_6+L=#yDF$nMe8U zm{m2W&$U|Xi&dGr%^ux|@#|b;Q1Npe$iMDoKHV}0#4nler-TvxTrd}>swY--&<_YL zuBZ#QsDPCTzTZ~ITE*9ex2yp~7)SJjgI9cKBLT1$lBzGaZz+N%8Dj)J{<}@un11nTO5e@UL@Lw&!u>2oI+p3pC-?#_h9%DmTl>*A9y&arSCc=Bw-b)MI z%!gQ$C^s%mt&!yRaUvLP3g-zWmgnaYCa_yyw3*}AtE?O3 zM?3aKHTQ!$iJIg>NK-_BxFi2yp+0s?*)G-Fn|$dnD#=W9b@9j8)H3)Iw6|}ciKh|{ z=d=C*%>KX{)&)8wj`Rlsj!88{d?kC>%UZay4?_lvGQ=moHgP`g)aT0dMuckvD-u~60Gedr}qAH z0TQZEHt8L}w9K_=Yy4d*&Ezd(GR)b(eoKExdj{c`LOwRym@TD&U6WP)+_S9)mvpGr z%a>H>ALM=BzM}WWP&B4y)`S}`b-;(G)O4a~5QF6G*~6QW)5|8adRVw8Ev3sc3-FMB zaiN%1`-m~6aJchw436S*%^Vzgs;E>_6#GH(HQGR6678jfqc3`d99c*bWZdKS4I=n4n;9w}*-|e0x@= ztrosDie|dPdFe^dlC7%!BlB@hHgOtsQjZk#k!^LQRVPz}t@w%ns{?bdFnK+T4frvE zCoiI&X5u;5)a)H@ZRDF5)tQAf)o&v`1n$j{ZEA~9qoIu!A*jd+iq7VD-isId;wng45%l9U*cAACz)7wq&(u)=I*n7O znU!wl(d-+^;xySGJzq;s7B~?MXurW(xU0ON=R9|9QiO$J4-rCENdJKlyKbvMp>I^J zag}#%TdU-Q7hekqo(y4rc)qm!*w-lc{;fiqB3#7w#oEEnVB?*K!U8>MvDaJlA79!N zIhD+^^Zj?T!GhUPvZi#@&c^N0uwz$yaOYK|gberPiPRTJsIv03n`HIUtXOvE6=!AB zlk->P45gLm49Vv@l-WvmokSNi{f9{#mx{sj#ToVb+7IaTABp~O{d_E6FmItV7Jxnf zb$R%TtgC8geBdf3apJ%XjD9dKJIj)L&JRmBhWbN)pjYX{9$3~3t3XJ;v4#LJp<0h?7HDK4k_cR{N9w0+$>4) z*e%pIhj;u)x6+J856qDBPaxf8YQcKHX7tl-XmRHHNc5CKiOVl0g?+!5ypSmxz^FXx z3T(z~Lz${q)k;~qNw1~tlMBbJn!eSvWg0WHseg62c{MZZ`z=sj4U&79#{XpX#)#KL0;D|-3mgI>EH!bA3Qw^28AAgJD zkCLC?DloJRY)0KO%zx>)yV)?dQ_Waocg8X*t89@jw#a0{@C4c#b`w*z$r|sFOdvYO z9{3-}NRl)V*F$XVc~Tm7uHhAUPW!gYl)eZaAH$TQJd1%iGtP?R`e?OEiV-C*USFf> zQ)d>W#6KI@oqj8|ZJ}6OerGs)$anuOx4unH6~c^Dca({~Ebkk)gD{`C#0~O6*@Tz( zV)_*+v4=80iV_VbcL!w16!zj*rz@xKU{PL06Zw?#uBI1T^@q2I)UxTn=R5a|&{%)X zu)~PG=EY~bik3Adjlh!Y0ov+cjkPlM831!y^HP7r;QNkD%<;G-j)md@HNkWEmBXrlHxU=oVx5f*#(hmb5OS zDsvE63(?+pGF+_Q;cQJbWGSABMWpe6Y0cjwwP=JZvbKhd3yI(ey!*SD*9_b2$9 zM2EDnsI}~%qMku1l~jVTE*@SsLgVY<7{?0nj8{MGo5S2;RLCRq2z^yAKByfWeJK!o zChwEUHkaTo-q*ZrokEr=C-0d`$kO$iDSE+UKhs6SNUcB%JnoxAa)cjRt=(+Sz3%Y} zo1p^l$%=+6bbQdmmF`E+XDdiBj#RmO7EEr_TdI60tvq*W|5RPyz&7_DqI4CQ>P?#} zK?1ggtn|INSF#mIM~&^|1n|^0-PhL<)S9m=_M? zj=|Pfc)Fr!og>s4Kni|VFoLIB9BL;p-772OZ2hQgyO`E4;H`5v?7$UVYLbB!96S$9 z6HBxuO)*hUsZ|s*Kf|c9ggv)s)() zH+D;3zj9U^8^aw4xA}3Q$DCIq^Y#C7D&Se}a4qgojHWuGR-F=>!ta&P83CF$a4Cat z)0BC3v3fA)$-GEw`s0zvGC@g@ihu?g#F;CCF8k^FDEcd=HNZShloXg0LC@p>hA7Z< z#Rq@_8<}9I-w#Hh>^$~j9d(r8KRN(@LQD#=J7m0JpTY#xSSca{YZ8@zYOj3vDkjvj z+dL+brjFL@Cx~bi`6B@AG)Cx3KpzAGx+2R-tqI^41AlSQ=UnW))+}Y46p{I$myx_+|SdY)$LjthE7D?%jw&8y?fW_p&*9!`(hL+Ye|bK!84^s?`jQZi{@VXhxh8v>2V6F=WL=l+t> zJu&`ceqOu}Go>;!&Uc~kxJl~3+}W3GUEW`HE}QhWSUT{yMW{`v6SsZswxRP)jK_I= zhG6JHUit>1$};ot{?|q5?%W)I3Lw+xdxrDjOQ@7wHnKIYVq;$uYO-{oA})0|ZOV@C zdoVXiIj|%~D6&GaX}=aY^zlk?C*qerR9&;IB51=fR7cc6`lmHN)3(~f6*{8@`}@_1{;i*QPQ zyHjVNec=`GxQThO(@}p{bWM^_p7&n(*H9gd34mN70Q8;)Wm@1nx!-a z;n~gWGFKhJRkv9?A^?U9P*nh~{ncRi4N1_GE)6Ioni$aJ-RK-z*lFF9Y6?akd*1my z(!XneCw~3kGAfRS8cgY-&KV6bw1qVHW~gIhuY0<@V*(0)juGdKpbOHXia`04`%CC1 zMR58WlYqF0+?sW4rC^+DmA!CpKg2R#E(}P-?*C?Lj$m+P6bm(kh-ZvXb|iRH2@a$- z%wjrS`i-mPM0{EtC*fRVt++8v!@~)=F&Uu_A#ziD#tPywzYgg;BLF&G4rR=%>?r`( zQC`Tn+Qr4?M8Eid+wk^4BHWO2_LBamQy;lZbc)Yc{_V#DzzoEHfdI=a0D%8;{N!*+ W(|ar%1~vi^4?S(e+clc@PyPove1psY literal 0 HcmV?d00001 diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/package.html b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/package.html new file mode 100644 index 00000000000..f0efe705346 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/package.html @@ -0,0 +1,289 @@ + + + + + DSF Slow Data Provider Example + + +

    Version +1.0
    +Pawel Piech
    +© 2006, Wind River Systems.  Release +under EPL version 1.0.

    +

    Slow Data Provider Example

    +The point of DSF concurrency can be most easily explained through +a practical example.  Suppose there is a viewer which needs to +show data that originates from a remote "provider".  There is a +considerable delay in transmitting the data to and from the provider, +and some delay in processing the data.  The viewer is a +lazy-loading table, which means that it request information only about +items that are visible on the screen, and as the table is scrolled, new +requests for data are generated.  The diagram below illustrates +the +logical relationship between components:
    +
    +.
    +

    In detail, these components look like this:

    +

    +Table Viewer
    +

    The table viewer is the standard +org.eclipse.jface.viewers.TableViewer, +created with SWT.VIRTUAL +flag.  It has an associated content +provider, SlowDataProviderContentProvider) which handles all the +interactions with the data provider.  The lazy content provider +operates in a very simple cycle:

    +
      +
    1. Table viewer tells content provider that the input has changed by +calling IContentProvider.inputChanged().  +This means that the content provider has to query initial state of the +data.
    2. +
    3. Next the content provider tells the viewer how many elements +there are, by calling TableViewer.setItemCount().
    4. +
    5. At this point, the table resizes, and it requests data values for +items that are visible.  So for each visible item it calls: ILazyContentProvider.updateElement().
    6. +
    7. After calculating the value, the content provider tells the table +what the value is, by calling TableViewer.replace().
    8. +
    9. If the data ever changes, the content provider tells the table to +rerequest the data, by calling TableViewer.clear().
    10. +
    +Table viewer operates in the +SWT display thread, which means that the content provider must switch +from the display thread to the DSF dispatch thread, whenever it is +called by the table viewer, as in the example below:
    +
        public void updateElement(final int index) {
    assert fTableViewer != null;
    if (fDataProvider == null) return;

    fDataProvider.getExecutor().execute(
    new Runnable() { public void run() {
    // Must check again, in case disposed while redispatching.
    if (fDataProvider == null) return;

    queryItemData(index);
    }});
    }
    +Likewise, when the content provider calls the table viewer, it also has +to switch back into the display thread as in following example, when +the content provider receives an event from the data provider, that an +item value has changed.
    +
        public void dataChanged(final Set<Integer> indexes) {
    // Check for dispose.
    if (fDataProvider == null) return;

    // Clear changed items in table viewer.
    if (fTableViewer != null) {
    final TableViewer tableViewer = fTableViewer;
    tableViewer.getTable().getDisplay().asyncExec(
    new Runnable() { public void run() {
    // Check again if table wasn't disposed when
    // switching to the display thread.
    if (tableViewer.getTable().isDisposed()) return; // disposed
    for (Integer index : indexes) {
    tableViewer.clear(index);
    }
    }});
    }
    }
    +All of this switching back and forth between threads makes the code +look a lot more complicated than it really is, and it takes some +getting used to, but this is the price to be paid for multi-threading. +Whether the participants use semaphores or the dispatch thread, the +logic is equally complicated, and we believe that using a single +dispatch thread, makes the synchronization very explicit and thus less +error-prone.
    +

    Data Provider Service

    +

    The data provider service interface, DataProvider, is very similar +to that of the lazy content provider.  It has methods to:

    +
      +
    • get item count
    • +
    • get a value for given item
    • +
    • register as listener for changes in data count and data values
    • +
    +But this is a DSF interface, and all methods must be called on the +service's dispatch thread.  For this reason, the DataProvider interface returns +an instance of DsfExecutor, +which must be used with the interface.
    +

    Slow Data Provider

    +

    The data provider is actually implemented as a thread which is an +inner class of SlowDataProvider +service.  The provider thread +communicates with the service by reading Request objects from a shared +queue, and by posting Runnable objects directly to the DsfExecutor but +with a simulated transmission delay.  Separately, an additional +flag is also used to control the shutdown of the provider thread.

    +To simulate a real back end, the data provider randomly invalidates a +set of items and notifies the listeners to update themselves.  It +also periodically invalidates the whole table and forces the clients to +requery all items.
    +

    Data and Control Flow
    +

    +This can be described in following steps:
    +
      +
    1. The table viewer requests data for an item at a given index (SlowDataProviderContentProvider.updateElement).
      +
    2. +
    3. The table viewer's content provider executes a Runnable in the DSF +dispatch thread and calls the data provider interface (SlowDataProviderContentProvider.queryItemData).
    4. +
    5. Data provider service creates a Request object, and files it in a +queue (SlowDataProvider.getItem).
    6. +
    7. Data provider thread de-queues the Request object and acts on it, +calculating the value (ProviderThread.processItemRequest).
    8. +
    9. Data provider thread schedules the calculation result to be +posted with DSF executor (SlowDataProvider.java:185).
    10. +
    11. The RequestMonitor callback sets the result data in the table +viewer (SlowDataProviderContentProvider.java:167).
      +
    12. +
    +

    Running the example and full sources

    +This example is implemented in the org.eclipse.dd.examples.dsf +plugin, in the org.eclipse.dd.examples.dsf.concurrent +package. 
    +
    +To run the example:
    +
      +
    1. Build the test plugin (along with the org.eclipse.dsdp.DSF plugin) +and launch the PDE. 
      +
    2. +
    3. Make sure to add the DSF +Tests action set to your current perspective.
    4. +
    5. From the main menu, select DSF +Tests -> Slow Data Provider.
    6. +
    7. A dialog will open and after a delay it will populate with data.
    8. +
    9. Scroll and resize dialog and observe the update behavior.
    10. +
    +

    Initial Notes
    +

    +This example is supposed to be representative of a typical embedded +debugger design problem.  Embedded debuggers are often slow in +retrieving and processing data, and can sometimes be accessed through a +relatively slow data channel, such as serial port or JTAG +connection.  But as such, this basic example presents a couple +of major usability problems
    +
      +
    1. The data provider service interface mirrors the table's content +provider interface, in that it has a method to retrieve a single piece +of data at a time.  The result of this is visible to the user as +lines of data are filled in one-by-one in the table.  However, +most debugger back ends are in fact capable of retrieving data in +batches and are much more efficient at it than retrieving data items +one-by-one.
    2. +
    3. When scrolling quickly through the table, the requests are +generated by the table viewer for items which are quickly scrolled out +of view, but the service still queues them up and calculates them in +the order they were received.  As a result, it takes a very long +time for the table to be populated with data at the location where the +user is looking. 
      +
    4. +
    +These two problems are very common in creating UI for embedded +debugging, and there are common patterns which can be used to solve +these problems in DSF services.
    +

    Coalescing

    +Coalescing many single-item requests into fewer multi-item requests is +the surest way to improve performance in communication with a remote +debugger, although it's not necessarily the simplest.  There are +two basic patterns in which coalescing is achieved:
    +
      +
    1. The back end provides an interface for retrieving data in large +chunks.  So when the service implementation receives a request for +a single item, it retrieves a whole chunk of data, returns the single +item, and stores the rest of the data in a local cache.
    2. +
    3. The back end providers an interface for retrieving data in +variable size chunks.  When the service implementation receives a +request for a single item, it buffers the request, and waits for other +requests to come in.  After a delay, the service clears the buffer +and submits a request for the combined items to the data provider.
    4. +
    +In practice, a combination of the two patterns is needed, but for +purpose of an example, we implemented the second pattern in the +"Input-Coalescing Slow Data Provider" (InputCoalescingSlowDataProvider.java).  +
    +

    Input Buffer

    +

    The main feature of this pattern is a buffer for holding the +requests before sending them to the data provider.  In this +example the user requests are buffered in two arrays: fGetItemIndexesBuffer and fGetItemRequestMonitorsBuffer.  The +DataProvider.getItem() +implementation is changed as follows:

    +
        public void getItem(final int index, final DataRequestMonitor<String> rm) {
    // Schedule a buffer-servicing call, if one is needed.
    if (fGetItemRequestMonitorsBuffer.isEmpty()) {
    fExecutor.schedule(
    new Runnable() { public void run() {
    fileBufferedRequests();
    }},
    COALESCING_DELAY_TIME,
    TimeUnit.MILLISECONDS);
    }

    // Add the call data to the buffer.
    // Note: it doesn't matter that the items were added to the buffer
    // after the buffer-servicing request was scheduled. This is because
    // the buffers are guaranteed not to be modified until this dispatch
    // cycle is over.
    fGetItemIndexesBuffer.add(index);
    fGetItemRequestMonitorsBuffer.add(rm);
    }

    +And method that services the buffer looks like this:
    +
        public void fileBufferedRequests() { 
    // Remove a number of getItem() calls from the buffer, and combine them
    // into a request.
    int numToCoalesce = Math.min(fGetItemIndexesBuffer.size(), COALESCING_COUNT_LIMIT);
    final ItemRequest request = new ItemRequest(new Integer[numToCoalesce], new DataRequestMonitor[numToCoalesce]);
    for (int i = 0; i < numToCoalesce; i++) {
    request.fIndexes[i] = fGetItemIndexesBuffer.remove(0);
    request.fDones[i] = fGetItemRequestMonitorsBuffer.remove(0);
    }

    // Queue the coalesced request, with the appropriate transmission delay.
    fQueue.add(request);

    // If there are still calls left in the buffer, execute another
    // buffer-servicing call, but without any delay.
    if (!fGetItemIndexesBuffer.isEmpty()) {
    fExecutor.execute(new Runnable() { public void run() {
    fileBufferedRequests();
    }});
    }
    }
    +The most interesting feature of this implementation is the fact that +there are no semaphores anywhere to control access to the input +buffers.  Even though the buffers are serviced with a delay and +multiple clients can call the getItem() +method, the use of a single +dispatch thread prevents any race conditions that could corrupt the +buffer data.  In real-world implementations, the buffers and +caches that need to be used are far more sophisticated with much more +complicated logic, and this is where managing access to them using the +dispatch thread is ever more important.
    +

    Cancellability

    +

    Table Viewer

    +

    +Unlike coalescing, which can be implemented entirely within the +service, cancellability requires that the client be modified as well +to take advantage of this capability.  For the table viewer +content provider, this means that additional features have to be +added.  In CancellingSlowDataProviderContentProvider.java +ILazyContentProvider.updateElement() +was changes as follows:
    +
        public void updateElement(final int index) {
    assert fTableViewer != null;
    if (fDataProvider == null) return;

    // Calculate the visible index range.
    final int topIdx = fTableViewer.getTable().getTopIndex();
    final int botIdx = topIdx + getVisibleItemCount(topIdx);

    fCancelCallsPending.incrementAndGet();
    fDataProvider.getExecutor().execute(
    new Runnable() { public void run() {
    // Must check again, in case disposed while redispatching.
    if (fDataProvider == null || fTableViewer.getTable().isDisposed()) return;
    if (index >= topIdx && index <= botIdx) {
    queryItemData(index);
    }
    cancelStaleRequests(topIdx, botIdx);
    }});
    }
    +Now the client keeps track of the requests it made to the service in fItemDataDones, and above, cancelStaleRequests() iterates +through all the outstanding requests and cancels the ones that are no +longer in the visible range.
    +

    Data Provider Service

    +

    +

    The data provider implementation +(CancellableInputCoalescingSlowDataProvider.java), +builds on top of the +coalescing data provider.  To make the canceling feature useful, +the data provider service has to limit the size of the request +queue.  This is because in this example which simulates +communication with a target and once requests are filed into the +request +queue, they cannot be canceled, just like a client can't cancel +request once it sends them over a socket.  So instead, if a flood +of getItem() +calls comes in, the service has to hold most of them in the coalescing +buffer in case the client decides to cancel them.  Therefore the +fileBufferedRequests() +method includes a simple check before servicing +the buffer, and if the request queue is full, the buffer servicing call +is delayed.

    +
            if (fQueue.size() >= REQUEST_QUEUE_SIZE_LIMIT) {
    if (fGetItemIndexesBuffer.isEmpty()) {
    fExecutor.schedule(
    new Runnable() { public void run() {
    fileBufferedRequests();
    }},
    REQUEST_BUFFER_FULL_RETRY_DELAY,
    TimeUnit.MILLISECONDS);
    }
    return;
    }
    +Beyond this change, the only other significant change is that before +the requests are queued, they are checked for cancellation.
    +

    Final Notes
    +

    +The example given here is fairly simplistic, and chances are that the +same example could be implemented using semaphores and free threading +with perhaps fewer lines of code.  But what we have found is that +as the problem gets bigger, the amount of +features in the data provider increases, the state of the +communication protocol gets more complicated, and the number of modules +needed in the service layer increases, using free threading and +semaphores does not safely scale.  Using a dispatch thread for +synchronization certainly doesn't make the inherent problems of the +system less complicated, but it does help eliminate the race conditions +and deadlocks from the overall system.
    +

    Coalescing and Cancellability are both optimizations.  Neither +of these optimizations affected the original interface of the service, +and one of them only needed a service-side modification.  But as +with all optimizations, it is often better to first make sure that the +whole system is working correctly and then add optimizations where they +can make the biggest difference in user experience. 

    +

    The above examples of optimizations can take many forms, and as +mentioned with coalescing, caching data that is retrieved from the data +provider is the most common form of data coalescing.  For +cancellation, many services in DSF build on top of other services, +which means that even a low-level service can cause a higher +level service to retrieve data, while another event might cause it to +cancel those requests.  The perfect example of this is a Variables +service, which is responsible for calculating the value of expressions +shown in the Variables view.  The Variables service reacts to the +Run Control service, which issues a suspended event and then requests a +set of variables to be evaluated by the debugger back end.  But as +soon as a resumed event is issued by Run Control, the Variables service +needs to cancel  the pending evaluation requests.
    +

    +
    +
    + + diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileBrowserAction.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileBrowserAction.java new file mode 100644 index 00000000000..76b5d5cee71 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileBrowserAction.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * 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.examples.dsf.filebrowser; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.IWorkbenchWindowActionDelegate; +import org.eclipse.ui.actions.ActionDelegate; + +/** + * Action that opens the File Browser example dialog. + */ +public class FileBrowserAction extends ActionDelegate + implements IWorkbenchWindowActionDelegate +{ + private IWorkbenchWindow fWindow; + + @Override + public void run(IAction action) { + if (fWindow != null) { + // Create the dialog and open it. + Dialog dialog = new FileBrowserDialog(fWindow.getShell()); + dialog.open(); + } + } + + public void init(IWorkbenchWindow window) { + fWindow = window; + } +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileBrowserDialog.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileBrowserDialog.java new file mode 100644 index 00000000000..2cd32389d60 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileBrowserDialog.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * 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.examples.dsf.filebrowser; + +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.PresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +/** + * File Browser example dialog. It hold a tree viewer that displays + * file system contents and a text box for entering a file path to be + * shown in the tree. + */ +@SuppressWarnings("restriction") +public class FileBrowserDialog extends Dialog { + + /** + * Tree viewer for showing the filesystem contents. + */ + private TreeModelViewer fViewer; + + /** + * The model adapter for the tree viewer. + */ + private FileBrowserModelAdapter fModelAdapter; + + /** + * Flag used to disable text-box changed events, when the text + * box is updated due to selection change in tree. + */ + private boolean fDisableTextChangeNotifications = false; + + public FileBrowserDialog(Shell parent) { + super(parent); + setShellStyle(getShellStyle() | SWT.RESIZE); + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite area = (Composite) super.createDialogArea(parent); + IPresentationContext presentationContext = new PresentationContext("org.eclipse.dd.examples.dsf.filebrowser"); //$NON-NLS-1$ + + fViewer = new TreeModelViewer(area, SWT.VIRTUAL, presentationContext); + fViewer.getControl().setLayoutData(new GridData(GridData.FILL_BOTH)); + + fModelAdapter = new FileBrowserModelAdapter(presentationContext); + fViewer.setInput(fModelAdapter.getVMProvider().getViewerInputObject()); + + final Text text = new Text(area, SWT.SINGLE | SWT.BORDER); + text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + fViewer.addSelectionChangedListener(new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent event) { + /* + * Update the file name in the text control, to match the + * selection in the tree. Do this only if the user is not + * actively typing in the text field (test if text has focus). + */ + if (!text.isFocusControl() && + event.getSelection() instanceof IStructuredSelection && + ((IStructuredSelection)event.getSelection()).getFirstElement() instanceof FileVMContext) + { + FileVMContext fileVmc = (FileVMContext)((IStructuredSelection)event.getSelection()).getFirstElement(); + + fDisableTextChangeNotifications = true; + text.setText(fileVmc.getFile().getAbsolutePath()); + fDisableTextChangeNotifications = false; + } + } + }); + + text.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + if (!fDisableTextChangeNotifications) { + fModelAdapter.getVMProvider().selectionTextChanged(text.getText()); + } + } + }); + + return area; + } + + @Override + public boolean close() { + if (super.close()) { + fModelAdapter.dispose(); + fModelAdapter = null; + return true; + } + return false; + } + +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileBrowserModelAdapter.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileBrowserModelAdapter.java new file mode 100644 index 00000000000..d77d489a7be --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileBrowserModelAdapter.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * 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.examples.dsf.filebrowser; + +import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; +import org.eclipse.dd.dsf.ui.viewmodel.IVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; + +/** + * This is the adapter that implements the flexible hierarchy viewer interfaces + * for providing content, labels, and event proxy-ing for the viewer. This + * adapter is registered with the DSF Session object, and is returned by the + * IDMContext.getAdapter() and IVMContext.getAdapter() methods, + * which both call {@link DsfSession#getModelAdapter(Class)}. + *

    + * The adapter implementation for this excercise is hard-coded to provide + * contents for only one view. In turn the view contens are determined using + * the configurable ViewModelProvider. For demonstration purposes, this model + * adapter has two different layout configurations that can be used. These + * layout configurations can be set by calling the {@link #setViewLayout} method. + *

    + * This class is primarily accessed by the flexible hierarchy viewer from a + * non-executor thread. So the class is thread-safe, except for a view methods + * which must be called on the executor thread. + * + * @see AbstractDMVMProvider + */ +@SuppressWarnings("restriction") +@ThreadSafe +public class FileBrowserModelAdapter extends AbstractVMAdapter +{ + FileBrowserVMProvider fViewModelProvider; + + @Override + protected IVMProvider createViewModelProvider(IPresentationContext context) { + /* + * In this example there is only one viewer, so there is only one + * VMProvider. + */ + return fViewModelProvider; + } + + public FileBrowserModelAdapter(IPresentationContext presentationContext) { + super(); + fViewModelProvider = new FileBrowserVMProvider(this, presentationContext); + } + + FileBrowserVMProvider getVMProvider() { + return fViewModelProvider; + } +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileBrowserVMProvider.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileBrowserVMProvider.java new file mode 100644 index 00000000000..b8395919d37 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileBrowserVMProvider.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * 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.examples.dsf.filebrowser; + +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.IRootVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.IVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.RootVMNode; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; + +/** + * + */ +@SuppressWarnings("restriction") +public class FileBrowserVMProvider extends AbstractVMProvider +{ + /** + * The object to be set to the viewer that shows contents supplied by this provider. + * @see org.eclipse.jface.viewers.TreeViewer#setInput(Object) + */ + private final IAdaptable fViewerInputObject = + new IAdaptable() { + /** + * The input object provides the viewer access to the viewer model adapter. + */ + @SuppressWarnings("unchecked") + public Object getAdapter(Class adapter) { + if ( adapter.isInstance(getVMAdapter()) ) { + return getVMAdapter(); + } + return null; + } + + @Override + public String toString() { + return "File Browser Viewer Input"; //$NON-NLS-1$ + } + }; + + /** + * Constructor creates and configures the layout nodes to display file + * system contents. + * @param adapter The viewer model adapter that this provider is registered with. + * @param presentationContext The presentation context that this provider is + * generating contents for. + */ + public FileBrowserVMProvider(AbstractVMAdapter adapter, IPresentationContext presentationContext) { + super(adapter, presentationContext); + + IRootVMNode root = new RootVMNode(this); + IVMNode fileSystemRoots = new FilesystemRootsVMNode(this); + addChildNodes(root, new IVMNode[] { fileSystemRoots }); + IVMNode files = new FileVMNode(this); + addChildNodes(fileSystemRoots, new IVMNode[] { files }); + setRootNode(root); + } + + /** + * Returns the input object to be set to the viewer that shows contents + * supplied by this provider. + */ + public Object getViewerInputObject() { + return fViewerInputObject; + } + + /** + * Event handler for file selection text changes in the dialog. + * @param text New text entered in file selection text box. + */ + void selectionTextChanged(final String text) { + if (isDisposed()) return; + + // We're in the UI thread. Re-dispach to VM Adapter executor thread + // and then call root layout node. + try { + getExecutor().execute(new Runnable() { + public void run() { + if (isDisposed()) return; + handleEvent(text); + }}); + } catch (RejectedExecutionException e) { + // Ignore. This exception could be thrown if the provider is being + // shut down. + } + } +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileVMContext.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileVMContext.java new file mode 100644 index 00000000000..a4da73f10eb --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileVMContext.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * 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.examples.dsf.filebrowser; + +import java.io.File; + +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.IVMAdapter; +import org.eclipse.dd.dsf.ui.viewmodel.IVMNode; + +class FileVMContext extends AbstractVMContext { + private File fFile; + FileVMContext(IVMAdapter adapter, IVMNode layoutNode, File file) { + super(adapter, layoutNode); + fFile = file; + } + + File getFile() { return fFile; } + + @Override + public boolean equals(Object obj) { + return obj instanceof FileVMContext && ((FileVMContext)obj).getFile().equals(fFile); + } + + @Override + public int hashCode() { + return fFile.hashCode(); + } +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileVMNode.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileVMNode.java new file mode 100644 index 00000000000..e9699c78a9e --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileVMNode.java @@ -0,0 +1,308 @@ +/******************************************************************************* + * 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.examples.dsf.filebrowser; + +import java.io.File; +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.internal.ui.DsfUIPlugin; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.IVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.IVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; + + +/** + * File view model node which returns file elements that are found in the directory + * specified by the parent element. The child nodes of this node are fixed to + * reference this element, and therefore this node will recursively populate + * the contents of the tree reflecting the underlying filesystem directories. + *
    + * Note: this node does NOT sub-class the {@link org.eclipse.dd.dsf.ui.viewmodel.AbstractVMNode} + */ +@SuppressWarnings("restriction") +class FileVMNode + implements IElementLabelProvider, IVMNode +{ + /** + * Reference to the viewer model provider. It's mainly used to access the + * viewer model adapter and its executor. + */ + private final FileBrowserVMProvider fProvider; + + public FileVMNode(FileBrowserVMProvider provider) { + fProvider = provider; + } + + public void dispose() { + // All resources garbage collected. + } + + public void setChildNodes(IVMNode[] childNodes) { + throw new UnsupportedOperationException("This node does not support children."); //$NON-NLS-1$ + } + + /** + * List of child nodes containing only a reference to this. + */ + private final IVMNode[] fChildNodes = { this }; + + public IVMNode[] getChildNodes() { + return fChildNodes; + } + + public void update(final IHasChildrenUpdate[] updates) { + new Job("") { //$NON-NLS-1$ + { + setSystem(true); + setPriority(INTERACTIVE); + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + for (IHasChildrenUpdate update : updates) { + /* + * Do not retrieve directory contents just to mark the plus + * sign in the tree. If it's a directory, just assume that + * it has children. + */ + FileVMContext vmc = (FileVMContext)update.getElement(); + update.setHasChilren(vmc.getFile().isDirectory()); + update.done(); + } + + return Status.OK_STATUS; + } + }.schedule(); + } + + public void update(final IChildrenCountUpdate[] updates) { + new Job("") { //$NON-NLS-1$ + { + setSystem(true); + setPriority(INTERACTIVE); + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + for (IChildrenCountUpdate update : updates) { + update.setChildCount(getFiles(update).length); + update.done(); + } + return Status.OK_STATUS; + } + }.schedule(); + } + + public void update(final IChildrenUpdate[] updates) { + new Job("") { //$NON-NLS-1$ + { + setSystem(true); + setPriority(INTERACTIVE); + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + for (IChildrenUpdate update : updates) { + File[] files = getFiles(update); + int offset = update.getOffset() != -1 ? update.getOffset() : 0; + int length = update.getLength() != -1 ? update.getLength() : files.length; + for (int i = offset; (i < files.length) && (i < (offset + length)); i++) { + update.setChild(new FileVMContext(fProvider.getVMAdapter(), FileVMNode.this, files[i]), i); + } + update.done(); + } + return Status.OK_STATUS; + } + }.schedule(); + } + + public void update(final ILabelUpdate[] updates) { + new Job("") { //$NON-NLS-1$ + { + setSystem(true); + setPriority(INTERACTIVE); + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + for (ILabelUpdate update : updates) { + update.setLabel(getLabel((FileVMContext)update.getElement()), 0); + update.done(); + } + + return Status.OK_STATUS; + } + }.schedule(); + } + + private static final File[] EMPTY_FILE_LIST = new File[0]; + + /** + * Retrieves the list of files for this node. The list of files is based + * on the parent element in the tree, which must be of type FileVMC. + * + * @param update Update object containing the path (and the parent element) + * in the tree viewer. + * @return List of files contained in the directory specified in the + * update object. An empty list if the parent element is not a directory. + * @throws ClassCastException If the parent element contained in the update + * is NOT of type FileVMC. + */ + private File[] getFiles(IViewerUpdate update) { + FileVMContext vmc = (FileVMContext)update.getElement(); + File[] files = vmc.getFile().listFiles(); + return files != null ? files : EMPTY_FILE_LIST; + } + + /** + * Returs the text label to show in the tree for given element. + */ + private String getLabel(FileVMContext vmc) { + return vmc.getFile().getName(); + } + + public void getContextsForEvent(VMDelta parentDelta, Object event, DataRequestMonitor rm) { + rm.setStatus(new Status(IStatus.OK, DsfUIPlugin.PLUGIN_ID, IDsfService.NOT_SUPPORTED, "", null)); //$NON-NLS-1$ + rm.done(); + } + + public int getDeltaFlags(Object e) { + /* + * @see buildDelta() + */ + int retVal = IModelDelta.NO_CHANGE; + if (e instanceof String) { + retVal |= IModelDelta.SELECT | IModelDelta.EXPAND; + } + + return retVal; + } + + public void buildDelta(final Object event, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) { + /* + * The FileLayoutNode is recursive, with itself as the only child. In this + * method the delta is calculated for a full path VMContext elements, and the + * implementation of this method is not recursive. + */ + if (event instanceof String) { + new Job("") { //$NON-NLS-1$ + { + setSystem(true); + setPriority(INTERACTIVE); + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + /* + * Requirements for a selection event to be issued is that the file exist, and + * that the parentDelta contain a FileVMC of a parent directory as its element. + * + * The test for first the former requirement could be performed inside getDeltaFlags() + * but getDeltaFlags() is synchronous, so it is better to perform this test here using + * a background thread (job). + * + * The latter is requirement is needed because this node does not have the algorithm + * calculate the complete list of root nodes. That algorithm is implemented inside the + * {@link FileSystemRootsLayoutNode#updateElements} method. + */ + + final File eventFile = new File((String)event); + File parentFile = null; + if (parentDelta.getElement() instanceof FileVMContext) { + parentFile = ((FileVMContext)parentDelta.getElement()).getFile(); + } + + // The file has to exist in order for us to be able to select + // it in the tree. + if (eventFile.exists() && parentFile != null) { + // Create a list containing all files in path + List filePath = new LinkedList(); + for (File file = eventFile; file != null && !file.equals(parentFile); file = file.getParentFile()) { + filePath.add(0, file); + } + + if (filePath.size() != 0) { + // Build the delta for all files in path. + ModelDelta delta = parentDelta; + File[] allFilesInDirectory = parentFile.listFiles(); + for (File pathSegment : filePath) { + // All files in path should be directories, and should therefore + // have a valid list of elements. + assert allFilesInDirectory != null; + + File[] pathSegmentDirectoryFiles = pathSegment.listFiles(); + delta = delta.addNode( + new FileVMContext(fProvider.getVMAdapter(), FileVMNode.this, pathSegment), + nodeOffset + Arrays.asList(allFilesInDirectory).indexOf(pathSegment), + IModelDelta.NO_CHANGE, + pathSegmentDirectoryFiles != null ? pathSegmentDirectoryFiles.length : 0); + allFilesInDirectory = pathSegmentDirectoryFiles; + } + + // The last file in path gets the EXPAND | SELECT flags. + delta.setFlags(delta.getFlags() | IModelDelta.SELECT | IModelDelta.EXPAND); + } + } + + // Invoke the request monitor. + + requestMonitor.done(); + + return Status.OK_STATUS; + } + }.schedule(); + } else { + requestMonitor.done(); + } + } + + /** + * Override the behavior which checks for delta flags of all the child nodes, + * because we would get stuck in a recursive loop. Instead call only the child + * nodes which are not us. + */ + protected Map getChildNodesWithDeltas(Object e) { + Map nodes = new HashMap(); + for (final IVMNode childNode : getChildNodes()) { + int delta = childNode.getDeltaFlags(e); + if (delta != IModelDelta.NO_CHANGE) { + nodes.put(childNode, delta); + } + } + return nodes; + } + + public IVMProvider getVMProvider() { + return fProvider; + } + + +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FilesystemRootsVMNode.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FilesystemRootsVMNode.java new file mode 100644 index 00000000000..3e64684267f --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FilesystemRootsVMNode.java @@ -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.examples.dsf.filebrowser; + +import java.io.File; +import java.util.LinkedList; +import java.util.List; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; + + +/** + * Viewer model node that populates the filesystem root elements. + */ +@SuppressWarnings("restriction") +class FilesystemRootsVMNode extends AbstractVMNode + implements IElementLabelProvider +{ + public FilesystemRootsVMNode(AbstractVMProvider provider) { + super(provider); + } + + public void update(final IChildrenUpdate[] updates) { + new Job("") { //$NON-NLS-1$ + { + setSystem(true); + setPriority(INTERACTIVE); + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + File[] files = File.listRoots(); + for (IChildrenUpdate update : updates) { + int offset = update.getOffset() != -1 ? update.getOffset() : 0; + int length = update.getLength() != -1 ? update.getLength() : files.length; + for (int i = offset; (i < files.length) && (i < (offset + length)); i++) { + update.setChild(new FileVMContext(getVMProvider().getVMAdapter(), FilesystemRootsVMNode.this, files[i]), i); + } + update.done(); + } + return Status.OK_STATUS; + } + }.schedule(); + } + + public void update(final IHasChildrenUpdate[] updates) { + for (IHasChildrenUpdate update : updates) { + /* + * Assume that all filesystem roots have children. If user attempts + * to expand an empty directory, the plus sign will be removed + * from the element. + */ + update.setHasChilren(true); + update.done(); + } + } + + public void update(final IChildrenCountUpdate[] updates) { + new Job("") { //$NON-NLS-1$ + { + setSystem(true); + setPriority(INTERACTIVE); + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + for (IChildrenCountUpdate update : updates) { + if (!checkUpdate(update)) continue; + update.setChildCount(File.listRoots().length); + update.done(); + } + return Status.OK_STATUS; + } + }.schedule(); + } + + public void update(final ILabelUpdate[] updates) { + new Job("") { //$NON-NLS-1$ + { + setSystem(true); + setPriority(INTERACTIVE); + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + for (ILabelUpdate update : updates) { + update.setLabel(getLabel((FileVMContext)update.getElement()), 0); + update.done(); + } + + return Status.OK_STATUS; + } + }.schedule(); + } + + + /** + * Returs the text label to show in the tree for given element. Filesystem + * roots return an empty string for call to File.getName(), use the abolute path + * string instead. + */ + private String getLabel(FileVMContext vmc) { + return vmc.getFile().getAbsolutePath(); + } + + public int getDeltaFlags(Object e) { + /* + * @see buildDelta() + */ + int retVal = IModelDelta.NO_CHANGE; + if (e instanceof String) { + retVal |= IModelDelta.SELECT | IModelDelta.EXPAND; + } + + return retVal; + } + + public void buildDelta(final Object event, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) { + if (event instanceof String) { + new Job("") { //$NON-NLS-1$ + { + setSystem(true); + setPriority(INTERACTIVE); + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + final File eventFile = new File((String)event); + + if (eventFile.exists()) { + // Create a list containing all files in path of the file from the event + List filePath = new LinkedList(); + for (File file = eventFile; file != null; file = file.getParentFile()) { + filePath.add(0, file); + } + File eventRoot = filePath.get(0); + + // Get the index of the file in list of filesystem roots. + File[] roots = File.listRoots(); + + int index = 0; + for (; index < roots.length; index++) { + if (eventRoot.equals(roots[index])) break; + } + + // Check if the specified file is not one of the roots. + if (index < roots.length) { + ModelDelta delta = parentDelta.addNode( + new FileVMContext(getVMProvider().getVMAdapter(), FilesystemRootsVMNode.this, eventRoot), + index, IModelDelta.NO_CHANGE); + + if (eventFile.equals(eventRoot)) { + // The event is for the root node. Select it and extend parent node. + delta.setFlags(delta.getFlags() | IModelDelta.SELECT | IModelDelta.EXPAND); + } + } + } + + // Invoke the request monitor. + requestMonitor.done(); + + return Status.OK_STATUS; + } + }.schedule(); + } else { + requestMonitor.done(); + } + } + +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/package.html b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/package.html new file mode 100644 index 00000000000..c9b2441c5d5 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/package.html @@ -0,0 +1,127 @@ + + + + + DSF Filesystem Browser Example + + +

    DSF Filesystem Browser Example

    +

    Goals

    +This example demonstrates an implementation of a viewer model with a +layout node that has itself as a child.  Such layout nodes are +needed to represents elements which themselves have a natural tree +structures.  This example uses filesystem folders as the +tree-structured data, which is retrieved directly from the java.io.File +class.  This example also demonstrates a viewer model +implementation which does not retrieve data using DSF services and +associated data model interfaces. 
    +

    Design

    +Model Adapter Hookup
    +A flexible-hierarchy tree viewer {@link +org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer} +is created within a model dialog.  Corresponding {@link +FileBrowserModelAdapter} and {@link FileBrowserVMProvider} classes are +instanciated, and the root element object created by +FileBrowserVMProvider is set as input to the tree viewer.  From +there FileBrowserModelAdapter is returned as the {@link +IElementContentProvier} and {@link IModelProxyFactory} for all elements +in the tree.
    +
    +

    Layout Nodes
    +There are three layout nodes:
    +

    +
      +
    • {@link FileBrowserVMProvider.VMRootLayoutNode} is just a root +node, which generates the input element for the viewer.
    • +
    • {@link FilesystemRootsLayoutNode} retrieves the roots of the +filesystem hierarchy ("C:\", "D:\", etc on Windows). 
      +
    • +
    • {@link FileLayoutNode} is a child of FilesystemRootsLayoutNode and +it recursively retrieves all folders and files under the given parent +file element.  This layout node does not allow any children nodes +to be added to it, and it returns only itself as a child node (through +a call to IVMLayoutNode.getChildLayoutNodes).
      +
    • +
    +Both FilesystemRootsLayoutNode +and FileLayoutNode create +elements of the same type: {@link FileVMContext}.  Additionally, +when populating elements in the tree, the FileLayoutNode requires that a FileVMContext element be the +parent element in order to be able to retrieve its children. 
    + +

    +Event Handling/Generating +Model Deltas
    +The view model responds to events generated by a text box in the +dialog, where the user can type in a filesystem path.  If the +entered path resolves to a file on the filesystem, the view model +generates a delta to select and reveal the given file in the +tree.  The two file layout nodes handle generating the delta in +different ways:
    +
      +
    • FilesystemRootsLayoutNode +is a standard layout node. 
      +
    • +
        +
      1. In the event handler implementation {@link +org.eclipse.dd.dsf.ui.viewermodel.IVMLayoutNode#buildDelta}, the user +specified file-path is compared to the list of file-system roots.  +
        +
      2. +
      3. If the user file-path contains one of the filesystem roots, a +new delta node is added for that root and the child layout node is +called to continue the delta processing. 
        +
      4. +
      5. If the user file-path points to one of the filesystem roots, +the IModelDelta.SELECT +and IModelDelta.EXPAND +flags are also added to the delta so that the root will be selected in +the viewer.
        +
      6. +
      +
    • FileLayoutNode is +the special case, because it is a recusrive node.  This node does +not call any child nodes to process the delta, instead it calculates +the delta for all file elements in user file-path, starting at the +parent element.
      +
    • +
        +
      1. First the parent FileVMContext +element is retrieved from the delta. 
        +
      2. +
      3. Then the user file-path is broken down into {@link +java.io.File} objects representing each segment in the path, starting +at the parent file element retrieved in step 1.
      4. +
      5. Then a delta node is added for each segment of the calculated +path. 
        +
      6. +
      7. IModelDelta.SELECT +and IModelDelta.EXPAND +flags are added to the last delta.
        +
      8. +
      +
    +

    How to use

    +
      +
    1. Make sure that the DSF examples menu is visible in the perspective
    2. +
        +
      • Go to Windows -> Customize Perspective...
      • +
      • Select Commands tab
      • +
      • Check the "DSF Examples" in the "Available command groups" +table.
      • +
      +
    3. Open the dialog by selecting DSF Examples->Open File Browser +Dialog menu item.
    4. +
    5. Expand the items in the tree to see filesystem contents.
    6. +
    7. Select elements in the tree, to fill in text box with selected +file's path.
    8. +
    9. Type in a file path in text box and have the tree expand to the +specified element.
      +
    10. +
    + + diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmCellModifier.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmCellModifier.java new file mode 100644 index 00000000000..e0ae7d54606 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmCellModifier.java @@ -0,0 +1,263 @@ +/******************************************************************************* + * 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.examples.dsf.timers; + +import java.util.concurrent.ExecutionException; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.Query; +import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.dd.dsf.concurrent.ThreadSafeAndProhibitedFromDsfExecutor; +import org.eclipse.dd.dsf.service.DsfServices; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; +import org.eclipse.dd.examples.dsf.timers.AlarmService.AlarmDMC; +import org.eclipse.dd.examples.dsf.timers.AlarmService.AlarmData; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ICellModifier; +import org.eclipse.swt.widgets.Shell; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.util.tracker.ServiceTracker; + +/** + * + */ +@ThreadSafeAndProhibitedFromDsfExecutor("") +public class AlarmCellModifier implements ICellModifier { + + private final DsfSession fSession; + + /** + * Need to use the OSGi service tracker here (instead of DsfServiceTracker), + * because we're accessing it in non-dispatch thread. DsfServiceTracker is not + * thread-safe. + */ + @ThreadSafe + private ServiceTracker fServiceTracker; + + /** + * Constructor for the modifier requires a valid DSF session in order to + * initialize the service tracker. + * @param session DSF session this modifier will use. + */ + public AlarmCellModifier(DsfSession session) { + fSession = session; + } + + public boolean canModify(Object element, String property) { + return TimersViewColumnPresentation.COL_VALUE.equals(property) && getAlarmDMC(element) != null; + } + + public Object getValue(Object element, String property) { + if (!TimersViewColumnPresentation.COL_VALUE.equals(property)) return ""; //$NON-NLS-1$ + + // Get the DMC and the session. If element is not an alarm DMC, or + // session is stale, then bail out. + AlarmDMC dmc = getAlarmDMC(element); + if (dmc == null) return ""; //$NON-NLS-1$ + DsfSession session = DsfSession.getSession(dmc.getSessionId()); + if (session == null) return ""; //$NON-NLS-1$ + + /* + * Create the query to request the value from service. + * Note: no need to guard against RejectedExecutionException, because + * DsfSession.getSession() above would only return an active session. + */ + GetValueQuery query = new GetValueQuery(dmc); + session.getExecutor().execute(query); + try { + return query.get().toString(); + } catch (InterruptedException e) { + assert false; + return ""; //$NON-NLS-1$ + } catch (ExecutionException e) { + return ""; //$NON-NLS-1$ + } + } + + + public void modify(Object element, String property, Object value) { + if (!TimersViewColumnPresentation.COL_VALUE.equals(property)) return; + + AlarmDMC dmc = getAlarmDMC(element); + if (dmc == null) return; + DsfSession session = DsfSession.getSession(dmc.getSessionId()); + if (session == null) return; + + // Shell is used in displaying error dialogs. + Shell shell = getShell(); + if (shell == null) return; + + Integer intValue = null; + if (value instanceof String) { + try { + intValue = new Integer(((String)value).trim()); + } catch (NumberFormatException e) { + MessageDialog.openError(shell, "Invalid Value", "Please enter a positive integer"); //$NON-NLS-1$ //$NON-NLS-2$ + return; + } + if (intValue.intValue() <= 0) { + MessageDialog.openError(shell, "Invalid Value", "Please enter a positive integer"); //$NON-NLS-1$ //$NON-NLS-2$ + return; + } + } + + /* + * Create the query to write the value to the service. + * Note: no need to guard against RejectedExecutionException, because + * DsfSession.getSession() above would only return an active session. + */ + SetValueQuery query = new SetValueQuery(dmc, intValue); + + session.getExecutor().execute(query); + + try { + // Return value is irrelevant, any error would come through with an exception. + query.get().toString(); + } catch (InterruptedException e) { + assert false; + } catch (ExecutionException e) { + // View must be shutting down, no need to show erro dialog. + } + } + + /** + * Need to dispose the cell modifier property because of the service + * tracker. + */ + @ThreadSafe + public synchronized void dispose() { + if (fServiceTracker != null) { + fServiceTracker.close(); + } + } + + private Shell getShell() { + if (DsfExamplesPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow() != null) { + return DsfExamplesPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell(); + } + return null; + } + + private AlarmDMC getAlarmDMC(Object element) { + if (element instanceof IAdaptable) { + return (AlarmDMC)((IAdaptable)element).getAdapter(AlarmDMC.class); + } + return null; + } + + @ThreadSafe + private synchronized AlarmService getService(AlarmDMC dmc) { + String serviceId = DsfServices.createServiceFilter( AlarmService.class, fSession.getId() ); + if (fServiceTracker == null) { + try { + fServiceTracker = new ServiceTracker( + DsfExamplesPlugin.getBundleContext(), + DsfExamplesPlugin.getBundleContext().createFilter(serviceId), + null); + fServiceTracker.open(); + } catch (InvalidSyntaxException e) { + return null; + } + } + return (AlarmService)fServiceTracker.getService(); + } + + private class GetValueQuery extends Query { + + final AlarmDMC fDmc; + + private GetValueQuery(AlarmDMC dmc) { + super(); + fDmc = dmc; + } + + @Override + protected void execute(final DataRequestMonitor rm) { + /* + * Guard against the session being disposed. If session is disposed + * it could mean that the executor is shut-down, which in turn + * could mean that we can't execute the "done" argument. + * In that case, cancel to notify waiting thread. + */ + final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); + if (session == null) { + cancel(false); + return; + } + + AlarmService service = getService(fDmc); + if (service == null) { + rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, + "Service not available", null)); //$NON-NLS-1$ + return; + } + + service.getAlarmData(fDmc, new DataRequestMonitor(session.getExecutor(), rm) { + @Override + protected void handleCompleted() { + // We're in another dispatch, so we must guard against executor shutdown again. + if (DsfSession.isSessionActive(session.getId())) { + super.handleCompleted(); + } + } + + @Override + protected void handleOK() { + rm.setData(getData().getTriggeringValue()); + rm.done(); + } + }); + } + } + + private class SetValueQuery extends Query { + + AlarmDMC fDmc; + int fValue; + + SetValueQuery(AlarmDMC dmc, int value) { + super(); + fDmc = dmc; + fValue = value; + } + + @Override + protected void execute(final DataRequestMonitor rm) { + // Guard against terminated session + final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); + if (session == null) { + cancel(false); + return; + } + + // Guard against a disposed service + AlarmService service = getService(fDmc); + if (service == null) { + rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, + "Service not available", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + // Finally set the value and return. + service.setAlarmValue(fDmc, fValue); + + // Return value is irrelevant. + rm.setData(new Object()); + rm.done(); + } + } +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmService.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmService.java new file mode 100644 index 00000000000..ec4ef5c0e6b --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmService.java @@ -0,0 +1,361 @@ +/******************************************************************************* + * 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.examples.dsf.timers; + +import java.util.Hashtable; +import java.util.Map; +import java.util.TreeMap; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.AbstractDMContext; +import org.eclipse.dd.dsf.datamodel.AbstractDMEvent; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.datamodel.IDMData; +import org.eclipse.dd.dsf.datamodel.IDMService; +import org.eclipse.dd.dsf.service.AbstractDsfService; +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; +import org.eclipse.dd.examples.dsf.timers.TimerService.TimerDMC; +import org.eclipse.dd.examples.dsf.timers.TimerService.TimerData; +import org.eclipse.dd.examples.dsf.timers.TimerService.TimerTickEvent; +import org.osgi.framework.BundleContext; + +/** + * Alarm service tracks a set of alarm objects which are occacionally + * triggered by the timers from the TimerService. + *

    + * This service depends on the TimerService, so the TimerService has to be + * running before this service is initialized. However, the alarm objects + * themeselves do not depend on the timers, they can be listed, created, + * removed without any timers present. So a separate context object exists + * to track alarm status, which requires both an alarm and a timer in order + * to exist. + */ +public class AlarmService extends AbstractDsfService + implements IDMService +{ + /** + * Event indicating that the list of alarms is changed and the clients + * which display alarms should re-query this list. + */ + public class AlarmsChangedEvent extends AbstractDMEvent { + AlarmsChangedEvent() { super(fAlarmsContext); } + } + + /** + * Context representing an alarm tracked by this service. + */ + public static class AlarmDMC extends AbstractDMContext { + /** Alarm number, also index into alarm map */ + final int fAlarm; + + public AlarmDMC(AlarmService service, int alarm) { + super(service, new IDMContext[] { service.fAlarmsContext }); + fAlarm = alarm; + } + + @Override + public boolean equals(Object other) { + return baseEquals(other) && ((AlarmDMC)other).fAlarm == fAlarm; + } + + @Override + public int hashCode() { return baseHashCode() + fAlarm; } + @Override + public String toString() { return baseToString() + ".alarm[" + fAlarm + "]"; } //$NON-NLS-1$ //$NON-NLS-2$ + } + + /** + * Data object containing information about the alarm. This object + * references internal service data, so it has to guard agains this data + * being obsolete. + */ + public class AlarmData implements IDMData { + private int fAlarmNumber; + + AlarmData(int alarmNumber) { fAlarmNumber = alarmNumber; } + public boolean isValid() { return fAlarms.containsKey(fAlarmNumber); } + public int getAlarmNumber() { return fAlarmNumber; } + + public int getTriggeringValue() { + if (!isValid()) return -1; + return fAlarms.get(fAlarmNumber); + } + } + + /** + * Context representing the "triggered" status of an alarm with respect to + * a specific timer. Having this object separate from the alarm itself + * allows the alarm object to exist independently of the timers. + */ + public class AlarmStatusContext extends AbstractDMContext { + /** + * An alarm status requires both a timer and alarm context, both of which + * become parents of the status context. + */ + public AlarmStatusContext(AbstractDsfService service, TimerDMC timerCtx, AlarmDMC alarmCtx) { + super(service.getSession().getId(), new IDMContext[] { timerCtx, alarmCtx }); + } + + @Override + public boolean equals(Object other) { return baseEquals(other); } + @Override + public int hashCode() { return baseHashCode(); } + @Override + public String toString() { + return baseToString() + ":alarm_status"; //$NON-NLS-1$ + } + } + + /** + * Data about alarm status. No surprises here. + * + */ + public class AlarmStatusData implements IDMData { + private boolean fIsTriggered; + + public boolean isValid() { return true; } + AlarmStatusData(boolean triggered) { fIsTriggered = triggered; } + public boolean isTriggered() { return fIsTriggered; } + } + + /** + * Event indicating that an alarm has been triggered by a timer. The + * status context object's parents indicate which alarm and timer are + * involved. + */ + public class AlarmTriggeredEvent extends AbstractDMEvent { + public AlarmTriggeredEvent(AlarmStatusContext context) { + super(context); + } + } + + + /** Parent context for all alarms */ + private final IDMContext fAlarmsContext; + + /** Counter for generating alarm numbers */ + private int fAlarmCounter = 1; + + /** Map holding the alarms */ + private Map fAlarms = new TreeMap(); + + /** Constructor requires only the session for this service */ + AlarmService(DsfSession session) { + super(session); + fAlarmsContext = new AbstractDMContext(this, new IDMContext[0]) { + private final Object fHashObject = new Object(); + + @Override + public boolean equals(Object obj) { return (this == obj); }; + + @Override + public int hashCode() { return fHashObject.hashCode(); } + + @Override + public String toString() { return "#alarms"; } //$NON-NLS-1$ + }; + } + + @Override + protected BundleContext getBundleContext() { + return DsfExamplesPlugin.getBundleContext(); + } + + @Override + public void initialize(final RequestMonitor requestMonitor) { + super.initialize( + new RequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleOK() { + doInitialize(requestMonitor); + }}); + } + + /** + * Initialization routine registers the service, and adds it as a listener + * to service events. + */ + private void doInitialize(RequestMonitor requestMonitor) { + getSession().addServiceEventListener(this, null); + register(new String[]{AlarmService.class.getName()}, new Hashtable()); + requestMonitor.done(); + } + + @Override + public void shutdown(RequestMonitor requestMonitor) { + getSession().removeServiceEventListener(this); + unregister(); + super.shutdown(requestMonitor); + } + + public boolean isValid() { return true; } + + @SuppressWarnings("unchecked") + public void getModelData(IDMContext dmc, DataRequestMonitor rm) { + if (dmc instanceof AlarmDMC) { + getAlarmData((AlarmDMC)dmc, (DataRequestMonitor)rm); + return; + } else if (dmc instanceof AlarmStatusContext) { + getAlarmStatusData((AlarmStatusContext)dmc, (DataRequestMonitor)rm); + return; + } else if (dmc == fAlarmsContext) { + ((DataRequestMonitor)rm).setData(this); + } else { + rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ + } + rm.done(); + } + + /** + * Listener for timer ticks events. If a timer triggers an alarm, this + * service needs to issue an alarm triggered event. + * @param event + */ + @DsfServiceEventHandler + public void eventDispatched(TimerTickEvent event) { + final TimerDMC timerContext = event.getDMContext(); + + getServicesTracker().getService(TimerService.class).getTimerData( + event.getDMContext(), + new DataRequestMonitor(getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) return; + checkAlarmsForTimer(timerContext, getData().getTimerValue()); + } + @Override public String toString() { return "Got timer data: " + getData(); } //$NON-NLS-1$ + }); + } + + /** + * Checks the existing alarms for whether they are triggered by given timer. + * @param timerContext Context of the timer that is changed. + * @param timerValue Current value of the timer. + */ + private void checkAlarmsForTimer(TimerDMC timerContext, int timerValue) { + for (Map.Entry entry : fAlarms.entrySet()) { + if (timerValue == entry.getValue()) { + getSession().dispatchEvent(new AlarmTriggeredEvent( + new AlarmStatusContext(this, timerContext, new AlarmDMC(this, entry.getKey()))), + getProperties()); + } + } + } + + + /** + * Retrieves the list of alarm contexts. + * + *
    Note: this method doesn't need to be asynchronous, because all the + * data is stored locally. But using an asynchronous method makes this a + * more applicable example. + * + * @param rm Return data token. + */ + public void getAlarms(DataRequestMonitor rm) { + AlarmDMC[] alarmContexts = new AlarmDMC[fAlarms.size()]; + int i = 0; + for (int alarm : fAlarms.keySet()) { + alarmContexts[i++] = new AlarmDMC(this, alarm); + } + rm.setData(alarmContexts); + rm.done(); + } + + /** + * Retrieves the data object for given alarm context. + * + *
    Note: likewise this method doesn't need to be asynchronous. + */ + public void getAlarmData(AlarmDMC alarmCtx, DataRequestMonitor rm) { + if (!fAlarms.containsKey(alarmCtx.fAlarm)) { + rm.setStatus(new Status( + IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, INVALID_HANDLE, "Alarm context invalid", null)); //$NON-NLS-1$ + rm.done(); + return; + } + rm.setData(new AlarmData(alarmCtx.fAlarm)); + rm.done(); + } + + /** + * Returns the alarm status context object, for given timer and alarms. + * + *
    Note: this method is synchronous... for variety. + */ + public AlarmStatusContext getAlarmStatus(AlarmDMC alarmCtx, TimerDMC timerCtx) { + return new AlarmStatusContext(this, timerCtx, alarmCtx); + } + + /** + * Returns the data object for given alarm status object. + */ + public void getAlarmStatusData(AlarmStatusContext alarmStatusCtx, final DataRequestMonitor rm) { + final TimerService.TimerDMC timerCtx = DMContexts.getAncestorOfType( + alarmStatusCtx, TimerService.TimerDMC.class); + final AlarmDMC alarmCtx = DMContexts.getAncestorOfType( + alarmStatusCtx, AlarmDMC.class); + + assert alarmCtx != null && timerCtx != null; + + getServicesTracker().getService(TimerService.class).getTimerData( + timerCtx, + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + if (!fAlarms.containsKey(alarmCtx.fAlarm)) { + rm.setStatus(new Status( + IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, INVALID_HANDLE, "Alarm context invalid", null)); //$NON-NLS-1$ + rm.done(); + return; + } + boolean isTriggered = getData().getTimerValue() >= fAlarms.get(alarmCtx.fAlarm); + rm.setData(new AlarmStatusData(isTriggered)); + rm.done(); + } + }); + } + + /** + * Creates a new alarm object with given value. + * @return context of the new alarm. + */ + public AlarmDMC createAlarm(int value) { + int newAlarm = fAlarmCounter++; + fAlarms.put(newAlarm, value); + getSession().dispatchEvent(new AlarmsChangedEvent(), getProperties()); + return new AlarmDMC(this, newAlarm); + } + + /** Removes given alarm from service. */ + public void deleteAlarm(AlarmDMC alarmCtx) { + fAlarms.remove(alarmCtx.fAlarm); + getSession().dispatchEvent(new AlarmsChangedEvent(), getProperties()); + } + + /** + * Changes the value of the given alarm. + * @param dmc Alarm to change + * @param newValue New alarm value. + */ + public void setAlarmValue(AlarmDMC dmc, int newValue) { + if (fAlarms.containsKey(dmc.fAlarm)) { + fAlarms.put(dmc.fAlarm, newValue); + } + getSession().dispatchEvent(new AlarmsChangedEvent(), getProperties()); + } +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmStatusVMNode.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmStatusVMNode.java new file mode 100644 index 00000000000..7f0213ade34 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmStatusVMNode.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * 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.examples.dsf.timers; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; +import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; +import org.eclipse.dd.examples.dsf.timers.AlarmService.AlarmDMC; +import org.eclipse.dd.examples.dsf.timers.AlarmService.AlarmStatusContext; +import org.eclipse.dd.examples.dsf.timers.AlarmService.AlarmStatusData; +import org.eclipse.dd.examples.dsf.timers.TimerService.TimerDMC; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; + +/** + * View model node that determines whether an "alarm triggered" indicator is + * shown in the tree. This indicator is only shown if a given alarm is + * triggered for a given timer. + * + * @see AlarmStatusContext + */ +@SuppressWarnings("restriction") +class AlarmStatusVMNode extends AbstractDMVMNode + implements IElementLabelProvider +{ + public AlarmStatusVMNode(AbstractDMVMProvider provider, DsfSession session) { + super(provider, session, AlarmStatusContext.class); + } + + @Override + protected void updateElementsInSessionThread(final IChildrenUpdate update) { + if (!checkService(AlarmService.class, null, update)) return; + if (!checkService(TimerService.class, null, update)) return; + + AlarmDMC alarmDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), AlarmDMC.class); + TimerDMC timerDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), TimerDMC.class); + if (alarmDmc == null || timerDmc == null) { + update.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, "Required elements not found in path")); //$NON-NLS-1$ + update.done(); + return; + } + + // Get the alarm status DMC then check the triggered value to make sure it's triggered. + final AlarmStatusContext alarmStatusDmc = getServicesTracker().getService(AlarmService.class). + getAlarmStatus(alarmDmc, timerDmc); + getServicesTracker().getService(AlarmService.class).getAlarmStatusData( + alarmStatusDmc, + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + public void handleCompleted() { + if (isDisposed()) return; + if (!getStatus().isOK()) { + update.setStatus(getStatus()); + } else { + if (getData().isTriggered()) { + update.setChild(createVMContext(alarmStatusDmc), 0); + } + } + update.done(); + }}); + } + + public void update(ILabelUpdate[] updates) { + for (ILabelUpdate update : updates) { + update.setLabel("ALARM TRIGGERED", 0); //$NON-NLS-1$ + update.setImageDescriptor( + DsfExamplesPlugin.getDefault().getImageRegistry().getDescriptor( + DsfExamplesPlugin.IMG_ALARM_TRIGGERED), + 0); + update.done(); + } + } + + + public int getDeltaFlags(Object e) { + // This node generates delta if the timers have changed, or if the + // label has changed. + if (e instanceof AlarmService.AlarmTriggeredEvent) { + return IModelDelta.ADDED | IModelDelta.SELECT | IModelDelta.EXPAND; + } + return IModelDelta.NO_CHANGE; + } + + public void buildDelta(Object e, VMDelta parentDelta, int nodeOffset, RequestMonitor requestMonitor) { + // An element is added when and selected upon a triggered event. + // Parent element is also expanded allow element to be selected. + if (e instanceof AlarmService.AlarmTriggeredEvent) { + parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.EXPAND); + parentDelta.addNode( + createVMContext( ((AlarmService.AlarmTriggeredEvent)e).getDMContext() ), + 0, + IModelDelta.ADDED | IModelDelta.SELECT); + } + requestMonitor.done(); + } +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmsVMNode.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmsVMNode.java new file mode 100644 index 00000000000..885934bf736 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmsVMNode.java @@ -0,0 +1,212 @@ +/******************************************************************************* + * 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.examples.dsf.timers; + +import java.text.MessageFormat; +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.properties.IElementPropertiesProvider; +import org.eclipse.dd.dsf.ui.viewmodel.properties.IPropertiesUpdate; +import org.eclipse.dd.dsf.ui.viewmodel.properties.LabelAttribute; +import org.eclipse.dd.dsf.ui.viewmodel.properties.LabelColumnInfo; +import org.eclipse.dd.dsf.ui.viewmodel.properties.LabelImage; +import org.eclipse.dd.dsf.ui.viewmodel.properties.LabelText; +import org.eclipse.dd.dsf.ui.viewmodel.properties.PropertyBasedLabelProvider; +import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; +import org.eclipse.dd.examples.dsf.timers.AlarmService.AlarmDMC; +import org.eclipse.dd.examples.dsf.timers.AlarmService.AlarmData; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementEditor; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ICellModifier; +import org.eclipse.jface.viewers.TextCellEditor; +import org.eclipse.swt.widgets.Composite; + + +/** + * View model node that defines how alarm DMContexts are displayed in the view. Alarm + * nodes are fairly static, once they are created their label doesn't change. + * @see AlarmDMC + */ +@SuppressWarnings("restriction") +class AlarmsVMNode extends AbstractDMVMNode + implements IElementEditor, IElementPropertiesProvider, IElementLabelProvider +{ + public static final String PROP_ALARM_NUMBER = "alarmNumber"; //$NON-NLS-1$ + public static final String PROP_ALARM_TRIGGER_VALUE = "alarmTriggerValue"; //$NON-NLS-1$ + + private AlarmCellModifier fAlarmCellModifier; + private PropertyBasedLabelProvider fLabelProvider; + + + public AlarmsVMNode(AbstractDMVMProvider provider, DsfSession session) { + super(provider, session, AlarmDMC.class); + + fLabelProvider = new PropertyBasedLabelProvider(); + + LabelColumnInfo idCol = new LabelColumnInfo( + new LabelAttribute[] { + new LabelText(new MessageFormat("Alarm #{0}"), new String[] { PROP_ALARM_NUMBER }), //$NON-NLS-1$ + new LabelImage(DsfExamplesPlugin.getDefault().getImageRegistry().getDescriptor(DsfExamplesPlugin.IMG_ALARM)) + }); + fLabelProvider.setColumnInfo(TimersViewColumnPresentation.COL_ID, idCol); + + LabelText valueText = new LabelText(new MessageFormat("{0}"), new String[] { PROP_ALARM_TRIGGER_VALUE }); //$NON-NLS-1$ + LabelColumnInfo valueCol = new LabelColumnInfo( + new LabelAttribute[] { + new LabelText(new MessageFormat("{0}"), new String[] { PROP_ALARM_TRIGGER_VALUE }) //$NON-NLS-1$ + }); + fLabelProvider.setColumnInfo(TimersViewColumnPresentation.COL_VALUE, valueCol); + + } + + @Override + protected void updateElementsInSessionThread(final IChildrenUpdate update) { + if (!checkService(AlarmService.class, null, update)) return; + + // Retrieve the alarm DMContexts, create the corresponding VMCs array, and + // set them as result. + getServicesTracker().getService(AlarmService.class).getAlarms( + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + public void handleCompleted() { + if (!getStatus().isOK()) { + update.setStatus(getStatus()); + } else { + fillUpdateWithVMCs(update, getData()); + } + update.done(); + }}); + } + + public void update(ILabelUpdate[] updates) { + fLabelProvider.update(updates); + } + + public void update(final IPropertiesUpdate[] updates) { + try { + getSession().getExecutor().execute(new DsfRunnable() { + public void run() { + for (IPropertiesUpdate update : updates) { + updatePropertiesInSessionThread(update); + } + }}); + } catch (RejectedExecutionException e) { + for (IViewerUpdate update : updates) { + handleFailedUpdate(update); + } + } + } + + @ConfinedToDsfExecutor("getSession#getExecutor") + protected void updatePropertiesInSessionThread(final IPropertiesUpdate update) { + final AlarmDMC dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), AlarmDMC.class); + if (!checkDmc(dmc, update) || !checkService(AlarmService.class, null, update)) return; + + getDMVMProvider().getModelData( + this, update, + getServicesTracker().getService(AlarmService.class, null), + dmc, + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + protected void handleCompleted() { + /* + * Check that the request was evaluated and data is still + * valid. The request could fail if the state of the + * service changed during the request, but the view model + * has not been updated yet. + */ + if (!getStatus().isOK() || !getData().isValid()) { + assert getStatus().isOK() || + getStatus().getCode() != IDsfService.INTERNAL_ERROR || + getStatus().getCode() != IDsfService.NOT_SUPPORTED; + handleFailedUpdate(update); + return; + } + + update.setProperty(PROP_ALARM_NUMBER, getData().getAlarmNumber()); + update.setProperty(PROP_ALARM_TRIGGER_VALUE, getData().getTriggeringValue()); + update.done(); + } + }, + getExecutor()); + } + + public CellEditor getCellEditor(IPresentationContext context, String columnId, Object element, Composite parent) { + if (TimersViewColumnPresentation.COL_VALUE.equals(columnId)) { + return new TextCellEditor(parent); + } + return null; + } + + // Note: this method is synchronized because IElementEditor.getCellModifier can be called + // on any thread, even though in practice it should be only called on the UI thread. + public synchronized ICellModifier getCellModifier(IPresentationContext context, Object element) { + if (fAlarmCellModifier == null) { + fAlarmCellModifier = new AlarmCellModifier(getSession()); + } + return fAlarmCellModifier; + } + + public int getDeltaFlags(Object e) { + // Since the label for alarms doesn't change, this node will generate + // delta info only if the list of alarms is changed. + if (e instanceof AlarmService.AlarmsChangedEvent) { + return IModelDelta.CONTENT; + } + return IModelDelta.NO_CHANGE; + } + + + public void buildDelta(Object event, VMDelta parentDelta, int nodeOffset, RequestMonitor requestMonitor) { + if (event instanceof AlarmService.AlarmsChangedEvent) { + // The list of alarms has changed, which means that the parent + // node needs to refresh its contents, which in turn will re-fetch the + // elements from this node. + parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); + } + requestMonitor.done(); + } + + @Override + public synchronized void dispose() { + synchronized(this) { + if (fAlarmCellModifier != null) { + fAlarmCellModifier.dispose(); + } + } + super.dispose(); + } + + public String getPropertyDescription(String property) { + // TODO Auto-generated method stub + return null; + } + + public String getPropertyName(String property) { + // TODO Auto-generated method stub + return null; + } +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/ServicesShutdownSequence.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/ServicesShutdownSequence.java new file mode 100644 index 00000000000..8ad1baa9a9c --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/ServicesShutdownSequence.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * 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.examples.dsf.timers; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.concurrent.Sequence; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; + +/** + * Shutdown sequence that stops the services in the timers session. + * + */ +class ServicesShutdownSequence extends Sequence { + + DsfSession fSession; + DsfServicesTracker fTracker; + + ServicesShutdownSequence(DsfSession session) { + super(session.getExecutor()); + fSession = session; + } + + Step[] fSteps = new Step[] { + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + fTracker = new DsfServicesTracker(DsfExamplesPlugin.getBundleContext(), fSession.getId()); + requestMonitor.done(); + } + + @Override + public void rollBack(RequestMonitor requestMonitor) { + fTracker.dispose(); + fTracker = null; + requestMonitor.done(); + } + }, + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(AlarmService.class, requestMonitor); + } + }, + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(TimerService.class, requestMonitor); + } + }, + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + fTracker.dispose(); + fTracker = null; + requestMonitor.done(); + } + } + }; + + @Override + public Step[] getSteps() { return fSteps; } + + /** + * Convenience method that shuts down given service. Only service class + * is used to identify the service. + */ + private void shutdownService(Class clazz, RequestMonitor requestMonitor) { + IDsfService service = fTracker.getService(clazz); + if (service != null) { + service.shutdown(requestMonitor); + } + else { + requestMonitor.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, + "Service '" + clazz.getName() + "' not found.", null)); //$NON-NLS-1$ //$NON-NLS-2$ + requestMonitor.done(); + } + } + +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/ServicesStartupSequence.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/ServicesStartupSequence.java new file mode 100644 index 00000000000..5ac0f2c7252 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/ServicesStartupSequence.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * 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.examples.dsf.timers; + +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.concurrent.Sequence; +import org.eclipse.dd.dsf.service.DsfSession; + +/** + * Startup sequence for the timers session. With only two services, this is + * a very simple sequence. Last step creates the first timer and alarm. + */ +class ServicesStartupSequence extends Sequence { + + DsfSession fSession; + private TimerService fTimerService = null; + private AlarmService fAlarmService = null; + + + ServicesStartupSequence(DsfSession session) { + super(session.getExecutor()); + fSession = session; + } + + Step[] fSteps = new Step[] { + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + fTimerService = new TimerService(fSession); + fTimerService.initialize(requestMonitor); + }}, + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + fAlarmService = new AlarmService(fSession); + fAlarmService.initialize(requestMonitor); + }}, + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + fTimerService.startTimer(); + fAlarmService.createAlarm(5); + requestMonitor.done(); + }} + }; + + @Override + public Step[] getSteps() { return fSteps; } +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimerService.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimerService.java new file mode 100644 index 00000000000..154e4ce1a8e --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimerService.java @@ -0,0 +1,260 @@ +/******************************************************************************* + * 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.examples.dsf.timers; + +import java.util.Hashtable; +import java.util.Map; +import java.util.TreeMap; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.AbstractDMContext; +import org.eclipse.dd.dsf.datamodel.AbstractDMEvent; +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.service.AbstractDsfService; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; +import org.osgi.framework.BundleContext; + +/** + * Timer service tracks a set of timers, which are created per user request. + * The timers and their data are provided by the service using the DSF data + * model interfaces. + *

    + * When each timer is created, an event is issued that the service contents are + * changed, and clients should re-query the list of timers. The timers + * increment their value at rate of one per second (but they are not synchronous), + * and an event is issued for every tick. + */ +public class TimerService extends AbstractDsfService + implements IDMService +{ + /** + * Event indicating that the list of timers is changed and the clients + * which display timers should re-query this list. + */ + public class TimersChangedEvent extends AbstractDMEvent { + TimersChangedEvent() { super(fTimersContext); } + } + + /** + * Timer context represents a timer in this service. Clients can use this + * context to retrieve timer data. This class implements the Comaparable + * interfaces so that the objects can be stored in a TreeMap, which keeps them sorted. + */ + public static class TimerDMC extends AbstractDMContext + implements Comparable + { + /** + * Timer number, which is also index to timers map. + */ + final int fTimer; + + public TimerDMC(TimerService service, int timer) { + super(service, new IDMContext[] { service.fTimersContext }); + fTimer = timer; + } + + /** + * Timer context objects are created as needed and not cached, so the + * equals method implementation is critical. + */ + @Override + public boolean equals(Object other) { + return baseEquals(other) && ((TimerDMC)other).fTimer == fTimer; + } + + @Override + public int hashCode() { return baseHashCode() + fTimer; } + + @Override + public String toString() { + return baseToString() + ".timer[" + fTimer + "]"; //$NON-NLS-1$ //$NON-NLS-2$ + } + + public int compareTo(TimerDMC other) { + TimerDMC otherTimer = other; + return (fTimer < otherTimer.fTimer ? -1 : (fTimer == otherTimer.fTimer ? 0 : 1)); + } + } + + /** + * Data about the timer in the service. This object references internal + * service data, so it has to guard agains this data being obsolete. + */ + public class TimerData implements IDMData { + TimerDMC fTimerDMC; + + TimerData(TimerDMC timer) { fTimerDMC = timer; } + public boolean isValid() { return fTimers.containsKey(fTimerDMC); } + public int getTimerNumber() { return fTimerDMC.fTimer; } + + public int getTimerValue() { + if (!isValid()) return -1; + return fTimers.get(fTimerDMC); + } + + @Override public String toString() { return "Timer " + fTimerDMC.fTimer + " = " + getTimerValue(); } //$NON-NLS-1$ //$NON-NLS-2$ + } + + /** + * Event indicating that a timer's value has incremented. The context in + * the event points to the timer that has changed. + */ + public class TimerTickEvent extends AbstractDMEvent { + public TimerTickEvent(TimerDMC context) { + super(context); + } + } + + /** Parnet context for all timers */ + private final IDMContext fTimersContext; + + /** Counter for generating timer numbers */ + private int fTimerCounter = 1; + + /** Map holding the timers */ + private Map fTimers = new TreeMap(); + + private Map> fTimerFutures = new TreeMap>(); + + /** Constructor requires only the session for this service */ + TimerService(DsfSession session) { + super(session); + fTimersContext = new AbstractDMContext(this, new IDMContext[0]) { + private final Object fHashObject = new Object(); + + @Override + public boolean equals(Object obj) { return (this == obj); }; + + @Override + public int hashCode() { return fHashObject.hashCode(); } + + @Override + public String toString() { return "#timers"; } //$NON-NLS-1$ + }; + } + + @Override + protected BundleContext getBundleContext() { + return DsfExamplesPlugin.getBundleContext(); + } + + @Override + public void initialize(final RequestMonitor requestMonitor) { + super.initialize( + new RequestMonitor(getExecutor(), requestMonitor) { + @Override + public void handleOK() { + doInitialize(requestMonitor); + }}); + } + + @Override + public void shutdown(RequestMonitor requestMonitor) { + /* + * Go through all the timer futures and cancel them, so that they + * don't fire any more events. + */ + for (Future future : fTimerFutures.values()) { + future.cancel(false); + } + unregister(); + super.shutdown(requestMonitor); + } + + /** + * Performs the relevant initialization for this service: registering and + * scheduling the timer. + * @param requestMonitor + */ + private void doInitialize(RequestMonitor requestMonitor) { + register(new String[]{TimerService.class.getName()}, new Hashtable()); + requestMonitor.done(); + } + + public boolean isValid() { return true; } + + @SuppressWarnings("unchecked") + public void getModelData(IDMContext dmc, DataRequestMonitor rm) { + if (dmc instanceof TimerDMC) { + getTimerData((TimerDMC)dmc, (DataRequestMonitor)rm); + return; + } else if (dmc == fTimersContext) { + ((DataRequestMonitor)rm).setData(this); + } else { + rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ + } + rm.done(); + } + + /** + * Retrieves the list of timer contexts. + * + *
    Note: this method doesn't need to be asynchronous, because all the + * data is stored locally. But using an asynchronous method makes this a + * more applicable example. + * + * @param rm Return data token. + */ + public void getTimers(DataRequestMonitor rm) { + rm.setData( fTimers.keySet().toArray(new TimerDMC[fTimers.size()]) ); + rm.done(); + } + + /** + * Retrieves the data object for given timer context. + * + *
    Note: likewise this method doesn't need to be asynchronous. + */ + public void getTimerData(TimerDMC context, DataRequestMonitor rm) { + rm.setData(new TimerData(context)); + rm.done(); + } + + /** + * Creates a new timer and returns its context. + */ + public TimerDMC startTimer() { + final TimerDMC newTimer = new TimerDMC(this, fTimerCounter++); + fTimers.put(newTimer, 0); + Future timerFuture = getExecutor().scheduleAtFixedRate( + new Runnable() { + public void run() { + fTimers.put(newTimer, fTimers.get(newTimer) + 1); + getSession().dispatchEvent(new TimerTickEvent(newTimer), getProperties()); + } + @Override + public String toString() { return "Scheduled timer runnable for timer " + newTimer; } //$NON-NLS-1$ + }, + 1, 1, TimeUnit.SECONDS); + fTimerFutures.put(newTimer, timerFuture); + getSession().dispatchEvent(new TimersChangedEvent(), getProperties()); + return newTimer; + } + + /** + * Removes given timer from list of timers. + */ + public void killTimer(TimerDMC timerContext) { + if (fTimers.containsKey(timerContext)) { + fTimers.remove(timerContext); + fTimerFutures.remove(timerContext).cancel(false); + } + getSession().dispatchEvent(new TimersChangedEvent(), getProperties()); + } +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersModelAdapter.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersModelAdapter.java new file mode 100644 index 00000000000..bd694680da7 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersModelAdapter.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * 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.examples.dsf.timers; + +import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.viewmodel.IVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMAdapter; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; + +/** + * This is the adapter that implements the flexible hierarchy viewer interfaces + * for providing content, labels, and event proxy-ing for the viewer. This + * adapter is registered with the DSF Session object, and is returned by the + * IDMContext.getAdapter() and IVMContext.getAdapter() methods, + * which both call {@link DsfSession#getModelAdapter(Class)}. + *

    + * The adapter implementation for this excercise is hard-coded to provide + * contents for only one view. In turn the view contens are determined using + * the configurable ViewModelProvider. For demonstration purposes, this model + * adapter has two different layout configurations that can be used. These + * layout configurations can be set by calling the {@link #setViewLayout} method. + *

    + * This class is primarily accessed by the flexible hierarchy viewer from a + * non-executor thread. So the class is thread-safe, except for a view methods + * which must be called on the executor thread. + * + * @see AbstractDMVMProvider + */ +@SuppressWarnings("restriction") +@ThreadSafe +public class TimersModelAdapter extends AbstractDMVMAdapter +{ + TimersVMProvider fViewModelProvider; + + @Override + protected IVMProvider createViewModelProvider(IPresentationContext context) { + /* + * In this example there is only one viewer, so there is only one + * VMProvider. + */ + return fViewModelProvider; + } + + public TimersModelAdapter(DsfSession session, IPresentationContext presentationContext) { + super(session); + fViewModelProvider = new TimersVMProvider(this, presentationContext, getSession()); + } + + TimersVMProvider getTimersVMProvider() { + return fViewModelProvider; + } +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersVMNode.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersVMNode.java new file mode 100644 index 00000000000..52fd1a7f444 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersVMNode.java @@ -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.examples.dsf.timers; + +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; +import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; +import org.eclipse.dd.examples.dsf.timers.TimerService.TimerDMC; +import org.eclipse.dd.examples.dsf.timers.TimerService.TimerData; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; + + +/** + * View model node that defines how timer DMContexts are displayed in the view. Timers + * change with every tick of the timer, so the label has to be repained + * upon timer tick events. + * @see TimerDMC + */ +@SuppressWarnings("restriction") +class TimersVMNode extends AbstractDMVMNode + implements IElementLabelProvider +{ + + public TimersVMNode(AbstractDMVMProvider provider, DsfSession session) { + super(provider, session, TimerDMC.class); + } + + @Override + protected void updateElementsInSessionThread(final IChildrenUpdate update) { + if (!checkService(AlarmService.class, null, update)) return; + + // Retrieve the timer DMContexts, create the corresponding VMCs array, and + // set them as result. + getServicesTracker().getService(TimerService.class).getTimers( + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + public void handleCompleted() { + if (!getStatus().isOK()) { + update.setStatus(getStatus()); + } else { + fillUpdateWithVMCs(update, getData()); + } + update.done(); + }}); + } + + + public void update(final ILabelUpdate[] updates) { + try { + getSession().getExecutor().execute(new DsfRunnable() { + public void run() { + updateLabelInSessionThread(updates); + }}); + } catch (RejectedExecutionException e) { + for (ILabelUpdate update : updates) { + handleFailedUpdate(update); + } + } + } + + + protected void updateLabelInSessionThread(ILabelUpdate[] updates) { + for (final ILabelUpdate update : updates) { + final TimerDMC dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), TimerDMC.class); + if (!checkDmc(dmc, update) || !checkService(TimerService.class, null, update)) continue; + + getDMVMProvider().getModelData( + this, update, + getServicesTracker().getService(TimerService.class, null), + dmc, + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + protected void handleCompleted() { + /* + * Check that the request was evaluated and data is still + * valid. The request could fail if the state of the + * service changed during the request, but the view model + * has not been updated yet. + */ + if (!getStatus().isOK() || !getData().isValid()) { + assert getStatus().isOK() || + getStatus().getCode() != IDsfService.INTERNAL_ERROR || + getStatus().getCode() != IDsfService.NOT_SUPPORTED; + handleFailedUpdate(update); + return; + } + + /* + * If columns are configured, call the protected methods to + * fill in column values. + */ + String[] localColumns = update.getPresentationContext().getColumns(); + if (localColumns == null) localColumns = new String[] { null }; + + for (int i = 0; i < localColumns.length; i++) { + fillColumnLabel(dmc, getData(), localColumns[i], i, update); + } + update.done(); + } + }, + getExecutor()); + } + } + + protected void fillColumnLabel(TimerDMC dmContext, TimerData dmData, String columnId, int idx, + ILabelUpdate update) + { + if (TimersViewColumnPresentation.COL_ID.equals(columnId)) { + update.setLabel( Integer.toString(dmData.getTimerNumber()), idx ); + update.setImageDescriptor( + DsfExamplesPlugin.getDefault().getImageRegistry().getDescriptor(DsfExamplesPlugin.IMG_TIMER), idx); + } else if (TimersViewColumnPresentation.COL_VALUE.equals(columnId)) { + update.setLabel( Integer.toString(dmData.getTimerValue()), idx); + } + } + + public int getDeltaFlags(Object e) { + // This node generates delta if the timers have changed, or if the + // label has changed. + if (e instanceof TimerService.TimerTickEvent) { + return IModelDelta.STATE; + } else if (e instanceof TimerService.TimersChangedEvent) { + return IModelDelta.CONTENT; + } + return IModelDelta.NO_CHANGE; + } + + public void buildDelta(Object e, VMDelta parentDelta, int nodeOffset, RequestMonitor requestMonitor) { + if (e instanceof TimerService.TimerTickEvent) { + // Add delta indicating that the VMC for the given timer context + // has changed. + parentDelta.addNode( createVMContext(((TimerService.TimerTickEvent)e).getDMContext()), IModelDelta.STATE ); + } else if (e instanceof TimerService.TimersChangedEvent) { + // The list of timers has changed, which means that the parent + // node needs to refresh its contents, which in turn will re-fetch the + // elements from this node. + parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); + } + requestMonitor.done(); + } +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersVMProvider.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersVMProvider.java new file mode 100644 index 00000000000..92f55d00aec --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersVMProvider.java @@ -0,0 +1,111 @@ +/******************************************************************************* + * 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.examples.dsf.timers; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; +import org.eclipse.dd.dsf.ui.viewmodel.IRootVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.IVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.RootVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.DefaultVMModelProxyStrategy; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; + +/** + * + */ +@SuppressWarnings("restriction") +public class TimersVMProvider extends AbstractDMVMProvider { + + /** + * The object to be set to the viewer that shows contents supplied by this provider. + * @see org.eclipse.jface.viewers.TreeViewer#setInput(Object) + */ + private final IAdaptable fViewerInputObject = + new IAdaptable() { + /** + * The input object provides the viewer access to the viewer model adapter. + */ + @SuppressWarnings("unchecked") + public Object getAdapter(Class adapter) { + if ( adapter.isInstance(getVMAdapter()) ) { + return getVMAdapter(); + } + return null; + } + + @Override + public String toString() { + return "Timers View Root"; //$NON-NLS-1$ + } + }; + + private DefaultVMModelProxyStrategy fModelProxyStrategy; + + + /** Enumeration of possible layouts for the timers view model */ + public enum ViewLayout { ALARMS_AT_TOP, TIMERS_AT_TOP } + + public TimersVMProvider(AbstractVMAdapter adapter, IPresentationContext presentationContext, DsfSession session) { + super(adapter, presentationContext, session); + setViewLayout(ViewLayout.ALARMS_AT_TOP); + } + + + public Object getViewerInputObject() { + return fViewerInputObject; + } + + /** + * Configures a new layout for the timers view model. + * @param layout New layout to use. + */ + public void setViewLayout(ViewLayout layout) { + if (layout == ViewLayout.ALARMS_AT_TOP) { + IRootVMNode root = new RootVMNode(this); + IVMNode alarmsNode = new AlarmsVMNode(this, getSession()); + IVMNode timersNode0 = new TimersVMNode(this, getSession()); + addChildNodes(root, new IVMNode[] { alarmsNode, timersNode0 }); + IVMNode timersNode = new TimersVMNode(this, getSession()); + addChildNodes(alarmsNode, new IVMNode[] { timersNode }); + IVMNode alarmStatusNode = new AlarmStatusVMNode(this, getSession()); + addChildNodes(timersNode, new IVMNode[] { alarmStatusNode }); + setRootNode(root); + } else if (layout == ViewLayout.TIMERS_AT_TOP) { + IRootVMNode root = new RootVMNode(this); + IVMNode timersNode = new TimersVMNode(this, getSession()); + addChildNodes(root, new IVMNode[] { timersNode }); + IVMNode alarmsNode = new AlarmsVMNode(this, getSession()); + addChildNodes(timersNode, new IVMNode[] { alarmsNode }); + IVMNode alarmStatusNode = new AlarmStatusVMNode(this, getSession()); + addChildNodes(alarmsNode, new IVMNode[] { alarmStatusNode }); + setRootNode(root); + } + + /* TODO: replace with an event + fModelProxyStrategy.fireModelChanged( + new ModelDelta(getRootElement(), IModelDelta.CONTENT)); + */ + } + + @Override + public IColumnPresentation createColumnPresentation(IPresentationContext context, Object element) { + return new TimersViewColumnPresentation(); + } + + @Override + public String getColumnPresentationId(IPresentationContext context, Object element) { + return TimersViewColumnPresentation.ID; + } + +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersView.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersView.java new file mode 100644 index 00000000000..f9b4afe2be7 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersView.java @@ -0,0 +1,296 @@ +/******************************************************************************* + * 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.examples.dsf.timers; + +import java.util.concurrent.ExecutionException; + +import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext; +import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; +import org.eclipse.dd.examples.dsf.timers.TimerService.TimerDMC; +import org.eclipse.dd.examples.dsf.timers.TimersVMProvider.ViewLayout; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.PresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.dialogs.IInputValidator; +import org.eclipse.jface.dialogs.InputDialog; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.part.ViewPart; + + +/** + * Example view which displays data from timers and alarms DSF services. This + * starts a new DSF session and configures the services for it. Then it + * configures a data model provider to process the service data and display it + * in a flexible-hierarchy asynchronous viewer. + */ +@SuppressWarnings("restriction") +public class TimersView extends ViewPart { + + /** Asynchronous tree viewer from the platform debug.ui plugin. */ + private TreeModelViewer fViewer; + + /** DSF executor to use for a new session with timers and alarms services */ + private DsfExecutor fExecutor; + + /** DSF session */ + private DsfSession fSession; + + /** DSF services tracker used by actions in the viewer. */ + private DsfServicesTracker fServices; + + /** Adapter used to provide view model for flexible-hierarchy viewer */ + private TimersModelAdapter fTimersModelAdapter; + + /** Action which toggles the layout in the viewer */ + private Action fToggleLayoutAction; + + /** Action that adds a new timer */ + private Action fAddTimerAction; + + /** Action that adds a new alarm */ + private Action fAddAlarmAction; + + /** Action that removes the selected alarm or timer */ + private Action fRemoveAction; + + public TimersView() {} + + /** + * This is a callback that will allow us to create the viewer and + * initialize it. For this view, it creates the DSF session, along + * with its services. Then it creates the viewer model adapter and + * registers it with the session. + */ + @Override + public void createPartControl(Composite parent) { + /* + * Create the Flexible Hierarchy viewer. Also create a presentation + * context which will be given to the content/label provider adapters + * to distinguish this view from other flex-hierarchy views. + */ + final IPresentationContext presentationContext = new PresentationContext("org.eclipse.dd.examples.dsf.timers"); //$NON-NLS-1$ + fViewer = new TreeModelViewer(parent, SWT.VIRTUAL | SWT.FULL_SELECTION, presentationContext); + + /* + * Create the executor, which will be used exclusively with this view, + * as well as a session and a services tracker for managing references + * to services. + */ + fExecutor = new DefaultDsfExecutor(); + fSession = DsfSession.startSession(fExecutor, "org.eclipse.dd.examples.dsf.timers"); //$NON-NLS-1$ + fServices = new DsfServicesTracker(DsfExamplesPlugin.getBundleContext(), fSession.getId()); + + /* + * Start the services using a sequence. The sequence runs in the + * dispatch thread, so we have to block this thread using Future.get() + * until it completes. The Future.get() will throw an exception if + * the sequence fails. + */ + ServicesStartupSequence startupSeq = new ServicesStartupSequence(fSession); + fSession.getExecutor().execute(startupSeq); + try { + startupSeq.get(); + } catch (InterruptedException e) { assert false; + } catch (ExecutionException e) { assert false; + } + + /* + * Create the flexible hierarchy content/label adapter. Then register + * it with the session. + */ + fTimersModelAdapter = new TimersModelAdapter(fSession, presentationContext); + fSession.registerModelAdapter(IElementContentProvider.class, fTimersModelAdapter); + fSession.registerModelAdapter(IModelProxyFactory.class, fTimersModelAdapter); + fSession.registerModelAdapter(IColumnPresentationFactory.class, fTimersModelAdapter); + + /* + * Set the root element for the timers tree viewer. The root element + * comes from the content provider. + */ + fViewer.setInput(fTimersModelAdapter.getTimersVMProvider().getViewerInputObject()); + + makeActions(); + contributeToActionBars(); + } + + @Override + public void dispose() { + try { + /* + * First dispose the view model, which is the client of services. + * We are not in the dispatch thread + */ + fSession.getExecutor().submit(new Runnable() { + public void run() { + fSession.unregisterModelAdapter(IElementContentProvider.class); + fSession.unregisterModelAdapter(IModelProxyFactory.class); + fSession.unregisterModelAdapter(IColumnPresentationFactory.class); + fTimersModelAdapter.dispose(); + fTimersModelAdapter = null; + }}).get(); + + // Then invoke the shutdown sequence for the services. + ServicesShutdownSequence shutdownSeq = new ServicesShutdownSequence(fSession); + fSession.getExecutor().execute(shutdownSeq); + try { + shutdownSeq.get(); + } catch (InterruptedException e) { assert false; + } catch (ExecutionException e) { assert false; + } + + // Finally end the session and the executor: + fSession.getExecutor().submit(new Runnable() { + public void run() { + DsfSession.endSession(fSession); + fSession = null; + fExecutor.shutdown(); + fExecutor = null; + }}).get(); + } catch (InterruptedException e) { + } catch (ExecutionException e) { + } + //fViewer.dispose(); + super.dispose(); + } + + private void contributeToActionBars() { + IActionBars bars = getViewSite().getActionBars(); + fillLocalToolBar(bars.getToolBarManager()); + } + + private void fillLocalToolBar(IToolBarManager manager) { + manager.add(fToggleLayoutAction); + manager.add(fAddTimerAction); + manager.add(fAddAlarmAction); + manager.add(fRemoveAction); + manager.add(new Separator()); + } + + private void makeActions() { + fToggleLayoutAction = new Action("Toggle Layout", IAction.AS_CHECK_BOX) { //$NON-NLS-1$ + @Override + public void run() { + // Get the toggle state of the action while on UI thread. + final ViewLayout layout = isChecked() ? ViewLayout.ALARMS_AT_TOP : ViewLayout.TIMERS_AT_TOP; + + // Switch to executor thread to perform the change in layout. + fExecutor.submit(new Runnable() { public void run() { + fTimersModelAdapter.getTimersVMProvider().setViewLayout(layout); + }}); + } + }; + fToggleLayoutAction.setToolTipText("Toggle Layout"); //$NON-NLS-1$ + fToggleLayoutAction.setImageDescriptor(DsfExamplesPlugin.getDefault().getImageRegistry().getDescriptor( + DsfExamplesPlugin.IMG_LAYOUT_TOGGLE)); + + fAddTimerAction = new Action("Add New Timer") { //$NON-NLS-1$ + @Override + public void run() { + fExecutor.submit(new Runnable() { public void run() { + // Only need to create the new timer, the events will cause + // the view to refresh. + fServices.getService(TimerService.class).startTimer(); + }}); + } + }; + fAddTimerAction.setToolTipText("Add new timer"); //$NON-NLS-1$ + fAddTimerAction.setImageDescriptor(DsfExamplesPlugin.getDefault().getImageRegistry().getDescriptor( + DsfExamplesPlugin.IMG_TIMER)); + + fAddAlarmAction = new Action("Add New Alarm") { //$NON-NLS-1$ + @Override + public void run() { + // Ask user for the new alarm value. + InputDialog inputDialog = new InputDialog( + fViewer.getControl().getShell(), + "New Alarm", //$NON-NLS-1$ + "Please enter alarm time", //$NON-NLS-1$ + "", //$NON-NLS-1$ + new IInputValidator() { + public String isValid(String input) { + try { + int i= Integer.parseInt(input); + if (i <= 0) + return "Please enter a positive integer"; //$NON-NLS-1$ + + } catch (NumberFormatException x) { + return "Please enter a positive integer"; //$NON-NLS-1$ + } + return null; + } + } + ); + if (inputDialog.open() != Window.OK) return; + int tmpAlarmValue = -1; + try { + tmpAlarmValue = Integer.parseInt(inputDialog.getValue()); + } catch (NumberFormatException x) { assert false; } + final int alarmValue = tmpAlarmValue; + fExecutor.submit(new Runnable() { public void run() { + // Create the new alarm. + fServices.getService(AlarmService.class).createAlarm(alarmValue); + }}); + } + }; + fAddAlarmAction.setToolTipText("Add new alarm"); //$NON-NLS-1$ + fAddAlarmAction.setImageDescriptor(DsfExamplesPlugin.getDefault().getImageRegistry().getDescriptor( + DsfExamplesPlugin.IMG_ALARM)); + + fRemoveAction = new Action("Remove") { //$NON-NLS-1$ + @Override + public void run() { + final Object selectedElement = ((IStructuredSelection)fViewer.getSelection()).getFirstElement(); + if (!(selectedElement instanceof IDMVMContext)) return; + final IDMContext selectedDmc = ((IDMVMContext)selectedElement).getDMContext(); + // Based on the DMC from the selection, call the appropriate service to + // remove the item. + if (selectedDmc instanceof TimerDMC) { + fExecutor.submit(new Runnable() { public void run() { + fServices.getService(TimerService.class).killTimer( + ((TimerDMC)selectedDmc)); + }}); + } else if (selectedDmc instanceof AlarmService.AlarmDMC) { + fExecutor.submit(new Runnable() { public void run() { + fServices.getService(AlarmService.class).deleteAlarm( + (AlarmService.AlarmDMC)selectedDmc); + }}); + } + } + }; + fRemoveAction.setToolTipText("Remove selected item"); //$NON-NLS-1$ + fRemoveAction.setImageDescriptor(DsfExamplesPlugin.getDefault().getImageRegistry().getDescriptor( + DsfExamplesPlugin.IMG_REMOVE)); + } + + /** + * Passing the focus request to the viewer's control. + */ + @Override + public void setFocus() { + fViewer.getControl().setFocus(); + } +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersViewColumnPresentation.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersViewColumnPresentation.java new file mode 100644 index 00000000000..ba24f6b68dc --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersViewColumnPresentation.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.dsf.timers; + +import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.jface.resource.ImageDescriptor; + +/** + * + */ +@SuppressWarnings("restriction") +public class TimersViewColumnPresentation implements IColumnPresentation { + + public static final String ID = DsfExamplesPlugin.PLUGIN_ID + ".TIMER_COLUMN_PRESENTATION_ID"; //$NON-NLS-1$ + public static final String COL_ID = ID + ".COL_ID"; //$NON-NLS-1$ + public static final String COL_VALUE = ID + ".COL_VALUE"; //$NON-NLS-1$ + + // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#init(org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext) + public void init(IPresentationContext context) {} + + // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#dispose() + public void dispose() {} + + // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getAvailableColumns() + public String[] getAvailableColumns() { + return new String[] { COL_ID, COL_VALUE }; + } + + // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getHeader(java.lang.String) + public String getHeader(String id) { + if (COL_ID.equals(id)) { + return "ID"; //$NON-NLS-1$ + } else if (COL_VALUE.equals(id)) { + return "Value"; //$NON-NLS-1$ + } + return null; + } + + // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getId() + public String getId() { + return ID; + } + + // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getImageDescriptor(java.lang.String) + public ImageDescriptor getImageDescriptor(String id) { + return null; + } + + // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getInitialColumns() + public String[] getInitialColumns() { + return getAvailableColumns(); + } + + // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#isOptional() + public boolean isOptional() { + return true; + } + +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/doc-files/package-1.png b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/doc-files/package-1.png new file mode 100644 index 0000000000000000000000000000000000000000..0e7c8683d616a1bbd10da2ec53387dd6bd51b298 GIT binary patch literal 14399 zcmeHucUY7Aw&sVZSU^ApHd10i*eFdAkRnl0F;W!}lrFtX?*R)%P*IBXrW64w(gTDb z5Rk5P2oPz(&_aMf2n6Pbd!Ie`x#ygF=gi!hXP$Y6KQP4P%kNw3U2DDTT`Mm%)sxbBVY}=UTRU$U!{Q^>6&)_>3 zI~V7X>l8V?mG(|Q41Sc4RJ&e+k6)l{(swpecMuR1xZydI?73E6US7q&AA-Imz==NK z)K?R4_(4!;SSTw5-DM{;Kqt?gR)nA%HyfFtz>lF+2x8-4he6Q$(-Vx)Rqg-T7o+m$ z7@+p3%*;$TZ#%oZhPTjF4xRrKAN;@Xmi}+NvawsL-*O9$M(b7!VTB>*@+)e$mfIYa zIrjG~{07}(Gpa2xtd@StjkzB=8dWR$68hUfF8WCBu(kUOINV85LMF|X*JK#E#<&C|kW9Xafsh6E6 zCa~e7uh>nt=LbKV?QGMnx>E83=rvyCiJ=m!brL?+f8T!V@K8+J5k9$SffoPuQQfjH z+w{#SfsKIx`T+6O!IOsq);$Aa1zO}uHCiQVl~VQxzsa!&q>olQf0)fmmiH7yL?&m! z{Fc5jHAlc$vxE5H$Qrj=8=vk$eJ3=>yM}sTF)hhBs}yfb8yjKfoYm429vR1)wP8DA z{Fk}8Ibc+88!ff{-jhwQD#m=~mc|<--BT{GJ<+@(>pXFz4^c5tU?>kBx!5IV&br|e zxJtX=JAO7c#IgaS^Na3l^FvE=4{C&K-rPqc_c*hWxq81mV~P@x^ zSpW{!MqIms#9>cAC`TY?AP?1$<_#wB6>FgtBUeLS6wMWqtfv2<=guf z7OP2P)t*jkK^NQ?M^G7`RHFo1(v?Ei7Ds*8M?Gb#gzEeNqI$tOQUqFF91~hZua9YR zp3tjP1m^;OAK_P^j)%a4S9i$GFqneZQsawbnL+Qt5o_1SeD(G9W5o=8R=+D_*3qQ1 zh~*|8r)X*Z_Z~jO559LH*GjpBBVr^igg>#QyQpk1q`&tl2n)r8>q_(b?|B zglEh*3wPf~?>51eJFqG&T_uMf4rK35a>Fg%zy*t22W-R!#0#_pY&8d%uhR>6XoXV* zVVxa1ekU1C?9qU$t?xN4I3ZpDkXpOitwO3GeIGSse}tu8lwz|ML=*O=SSZ|T4siJ6Swf#HThZ~|P^f;$W$ z1>pTwIsoW2hvELT)s-%IYG8ac9*jf~3@?u+nZ~q}IJ1NM zY}U*Otlq1ofnIJs4?|MN!Hc_6u2iE?+>R_gan^w3}mAT2(F2)|fu49-W>JGvvBz#;u`Mh*7 z6Tg=UX$%ca#Ii3N>zEmR)N!4ys3PYT3G=TfwN`1z}Dt&NB37vLjZP1MPJjr#YGgDSkK2s=( zz*Bo?-+Q46@%Kyn9O?UhG`MY)*3%c90_3?@bJEg7_pSTx<79(4kyB`Di=TQ$6BoB z$8+6u0!CJ9KF`rww&t8=VZ$-SyU)di8eZ3({<)E!8stu%z@~!2t<&Sao2%DBzz-e# z04mkyP#5yP&vX)SySRSrp_%1=*h9cEj=(+L0Tw6nv7EalWoxC2OF40_3RtP@7N^W% zc#)2z3#Y-FwtHdfCFh0VG7L2wbD%BNf9*lvjjiqhG{|&AM*aQ$F79CiM!uq3WB5#! zSZ%WDwNPsKVw8sB2FOyL+glrNQr1Dpdy>Y$FJ1qbEnp5mP)SblhP>LX71Lr*@B$OS zlw?p{#A;RgN*@E%033ki6(Umu64IlA4yO3Abx`br;l^I$K_ujQH48?`%Jc>G<;mXT zv*!=!6efX$7nztDH8D3U1c=nvGZDu>z}YUa!%PkUQe4ty@c$xXjln&%x3jUy!S+K5 zgTuqKJ_jHPeeGYJfWv+AGb9G@lL*~J8x_u-g6c%>VgF0}g1;ltBmET6mHbxU-Fv#L}Kqh>mgD(+S=OCMo!+|C@-zTfy8BQ z{((YcxGSN(we`+V+Sj*d5)%`n<{W9BY|zO^XwJe#?t<>wtwnZ&%EzVvX{H;X#EzEP z>8|y&1!S+)8KHeB%5d8Erlwnt^jiN-BY#TY0$wNoZb5jR7Bb z=*z~w7wThfx3a?E$9Btv0KzDMPH{si71q*bo0^((w6Y5fP~D{UP5O4sdENWEx-!zz z$dyFA>igzzZ2}MXLwZ+psiW0MI&GkKt;~OO4NYIefg9rC;W757=#=XzPM`L)@icwY z!@Hk3BaBr<@I~ISTq^Sn2pB}<6ky)YG$%c+>H46<;||QIy}az= zSd8=#FiiwWYlQFMT%j>0B{3YsVEJ?MOvFUrsnhK&!AS! z8;#!>D|$R$A9P0fwF3C>@qUBDrzS#(RAWE#&A!{Od1Z?M-J?(_-{w=U_|}JnP2A=O zWF160cy7KqI8V2*ps=toKc7Qr9Zp~E0jb2C`g?J0Es}&@Hv(S%h-3&nHyOPX{>1k> zd(FTc#py(TxXq%}vm0Bl{mED^K;iT9@+$C1-$()QdvkVn7IZ^8&m*p@9(l@_~hJvuMnIA`~frY>FFJQqt%Eh3G1kj`}$6{2SXw%{W-k=Tu1|l>- z0W1z~#kAFUOk;JE9wnr4q)!~uJj)a78fEGt!x8IhQ%(Jx?&hIJ^h-=9jGOxkFUF}~ zZ5@4^;QP>rsX6KEC9Nb!+~ob(%jDteiso}r`%WMbfXCI7Nyn--<&TwQ{e~f3fh$IO_C5|c@w{*Xvhe)hnC(>wZvz<@yY9#v8h=g ztLKot1tvU+x)_>Hq(A_*0YZc1_1C>KVszz zXqrm`g0);4o>P-@-&Hu_k-#BVpm5Iij;1b@I5SpWg5ayPr9qvM(nn#yItER-Yz*pd5yxXN&ZtwFf2xj{d$NwrO$Gyd6tYtwc^|ry{EWTqg2&F$l;y z&IyAC+5+$9N7F31;`V^&^xSl!T8n#}YzZsoo`v{* zSxP{s<22OauH9J7tp2+0wyWD&t4S}0Q~!7v^+L|AvkDs%zhPyD+167}~Lmn!QFy`PnVx|6_l{IR}Yq3FLr|JfSKN zwMlfTQgiP38c~;#Gr=ek-YwHxz;y8#jT;LW8YbPqS^24`s3aRm3(-mO^umWy4wi$L z6uvV$U3+Z{jLSJtqk%OtAEMFYu3-?Iq@`Rbt;MR+>LGF5Ox#DtI)#>65}|ga%Q1@n z=t{M-&KYc?i*bJl1^ZxcW}*~POlE#$H86KP#`bdkTm6FJ3WAtGg?h;E9uIjXC++NJ z)pL%dW~Ep0!$X@dxT`fXnGm$qyz;xEr4|G#1UnP#uk^Y^bu@9iMlB>p6xq^?v_7j; zESo06l0Z$q});5D=aoEffp_6A){=0b|TSX=vxxMZ3;gAVzx5-aTe8& zYOmKuddHvOF4^ab@_CGA^yD)43h=y=wZz~aI&C#)d(Pc7bIGoIjZt_Jv#_RLW#Df2 z{j$avsxh|xP9sy`$=D;|G4%qo8oBu+&AC$-)W29v`RjOFYT01XQEw#~H!(w{ta~bU3gnrxg|-Sbuw=Z)$Ui{i|D6&{^O%rP;2*#2aJDLCndC zqqs${6Y80tMoTEu;`8na21#1*G&LvOYT|9s#H~A_>n(}P z2O8`KCyPWQYDiSi5W;icdjNxy=09#MrPo{ZrDnd;cEB%vYBa6R8_L>Nl;-ZT1{uaF z+dEN>FwsVvY*VjiUj*^V01;vyYY4N$0#RJ_m`kUu07>?)^pq{z2O>aX{kbpatBETV zpoj-vezk(A+b1(Koa%NZFr5QqZ%d!c9#dP8RzV}+C20M!L6<1?>>fTy^_rJ)-VXb8 zf4~ux_cMw03_RSk4U5 z4QE8@vY3&!E*@z!FwHM5Gvy(TZWUPlct@`n|17g}x9NAa@%Rq9i}~lj+l=bqo5$XwI_bc1t0gj=vlK z&Jb_*zUHG)_{se0%pn=!8%wzqwG&RhHCnbchOSyzar(K8)u;*WkiM(LH_;EZdIBux zFjd^?A94#1Je<+nW72;-ulFWjQ;D$W6?syx>oIcFb+2>Djxls(MvQuMz@1!|4D)vh z^^&-ybbizaK|G_}J3T!~JwJx5oCeR2=~b_Z$v%pLv(bvb)Acp5Umf5Nl~K|-|BE#( z9BK>keEphyeSYR$j+1(OPTuKQv0GCiJ#p>Xjlqh}N_@^tP8eL1rrl@WNO&b+F=N3w z5St5cE18XR^vWV=dJ5Sg^J*sHC0M?ah+E{1T$+=yT%c)0d}l-^Rw3+X<7Lbzly$xM z3!lbNjk%r&Dm=WiEIvQ>Cu6iCoD@$Z`;^`&nqx)753|HFdFYm9l{UX!f5_J3XUU_O zPvO%k>)DFSc}N0AFzUs?I0l&g=Ip1hpvPPHA^ca^$%t1Ts&3m3?2_2Kdm-n<2oy-p zSC#(paOa}FZm)C8>q>7VgGsFyDMc%HckmPQAZH?CG7#P4?ZT%5)md{|zgPe2cP#lHXVrmQbJhvIH_f`c z?AL5MuAms@`Mk9O^i0eTA14cm>Pn}qHXl4q(AxtwotoH59a9^U!UmLZjL?3>sM-7n z&`rA;evu0<8Xo-A+S$d`W4dnIh_LrtcYm;hLUPQ7$8BzjPu8uksRD>{eh!13!a9knRIoy&~KMc-xvW$%#D%G+MN z+x&Sibct(+Se{AFBpf|^W@ghMaiJ-Tdn-8IRm;~hL`qv(3QL)n1|OM*x|uV<8XcVL zET*X!U}Wj+pF=BA$m@J*|L<_*I#AJa#aM>{?FKdQOD4lq!o80()cL)DPYk3wJn%`e za84gzu3OCQk6ydHY;^chLYI9*c3JI*T#p2pq|O|0&(-@|?5Vxh#EzOH#k@D6_F^!T z%g@g*Q2vgl&Vb5ZcYQbWg?<4IIF0o5*e@LbfTq1P^XXfhji%k`r&UM@FY%xzAoniNq}>JCA(Gr(;v)Zj1B#Qf$r4ZDjw~=}Z@9$~ zP*i&0p$=Pq0@vNDk+vjgIHP7b;|mg#%A*fhPe+|^>B+36_TYC7?*OVMT%xkGa)V4O zJVn0vwOEpK<0UC)*92D_?o`+mPimHI%vJyHm?NjsS@+Dr6k|7A=GE1(Q?=m}(bZI( z;IN-iGttzL)sTCEc?9{KKO`(zjsJbT4x9?mE%hwNXDZS2(vle>YEwSh%;viCU2Bh4 zalAUk?0WYB9ObHI^1p$;pyjC2N9`~{5satL1WulNg@x7Ok zWy6|pyrg`%Z)O{ccv?~lW1aPKr`<9&^pO^JCT})8s9RPR1k>xYdY7;pqKt(n6@xCQ zemrwhrLjc< zJ>0RrNAMa43_2a#`LU%SM`P?mva)==k@{c|f{n~@5~-uLpc12A2(vCl_fk!d-q;dw zzCarEMn1WD|6x&=+K0j+PZKT1b=$87e%5cn_&+>v_0Go7`5AMk4#T@bUz5M;kK_>& zWQRnjeXZ{nVt4M22jt*u8M4m!!6m2l-h|8d%qLX#8Qgcd^|4rT({g9$dvE3YBmZ`F zpw2`PUdQ`)65rn~6*$_Vu}i*Dpgalvr90Ap-~Zvk!-scx;SeNx_n(T6KkGoAsvNBQ z$^&VG4@zSkzxW7@84QW{%<8NGHT$V2J)JkgI0^Dt8V~lgzcl{*IOCbWvYJ~~u6E&b z)|b0o)UR!aZ<&w27#)QD7WKD%h%~dIV)Ri(3B|uHL0nzGP6n^A4*KP1Pvizl0M)i@_tNHibB~pA0Ss5&ofqeO2uva00_vx$8*Wz#2oC|TtwtU9! z!SKjke}EAR{0zhvH`KtK#ZLRE93S?A>M8vY^>D+AL9e-vJy9RRb~ikLB~Mz~?32rP z4WSTQ=TnJdAa^KM`#R!B7E!i71^5I$6(+3`|6@vJ4_4S%Y9_JGOh4a*vev!-dX|*& zMl-5DBl?k^xER-t{pH|Xq-!eEevjw^5xUz2?L_Q!g7h5hSeg=mY0>XZNm<4v{?*?- zj$V^pztSL3^^Rof@ezc8XhIU7K3w>0zF)0kTTuV7lC4)cM7^Q5OEMtJhw^9uh3tE4&$k^4IE!xIpwkf&y7Ii$@l;S$7CSD{t z>=l>;a1*L*gQ#B3N`U8ertwu~WhD!8m2%r|uAYmhsJ)U%d9q$QKFR3z^#+k_9*UqeNg{ zq0i2sP)jF%vNJwR|I^i^dl)>)=RiAe$vcL?3!owXR~LA;szf0u{1I4h5V3b~aF>sK zu`BmxQK+jfn_c{hQoMALvXMynHA@|goH z;nJ6e>}+?phd2$T@iXrO0Qi)j5`5Jb7C~nX)xFQ_!cS(q?#9kfRU$9_$+7it9`o$Y zaKJ+)oOPnC!p^JAjIfTJ7gk+|`F~Qn2si~umSX8W0a_FK)I_`a$TNZf^-*<7`V$}$~Eay-g55j z*b9dLY*=76V|7W4TtAWQFJV|zA$0GD*I zA_WWp2I>g}%eY&Znwq3UC78#?M7TJ3MFg+xJ-NWY8w;?=AHo6Me@gDqe;)+^ZTpC? zVXYr(gKsYs2R>>vPMrf@ttf)|V|+o}pNgar3z3vOv*y>CcDqB7UC~?wChH>Ls}(5# zlsWiDi$?LQ!h!;Rc@L3l-Tt7%TpnNq4zxnp4z;=3V*!Yn)pwfV+RDbrjcKrX0tP8A zn+p{oECpah)6D1jDL?W zyZrB@`gtG*0-ZepO#Uv~qfjVsu;1`Q%RQ z&IBtTBI4o!lRWsJ6dy2bnQ#i&#LY`Lc&sipu!f+EMFkMW;PeJ0FuMUiHf@ENZJ$U1 zFkDaqdZ~n`Ho5w{4hLL+>xdl~4&|-3N)Ih41m0?@k}gGgmo~7jU>qqx!t5Zyq>XCw6 z&n4c@IA-E^T5-A_`?y|#k`yco+;X-;J%P2r7^7&ZjH_^hyU+H5EBJy*)9$DhfIJiP zUdQK3DkteARA+ybEW8djn}iU><>l{gP3;c!Ywa62|Giwj$|{6;J@Oq4zT*U1_&i76 z3be2ym!2g!82J!0zxh^5Tl;+JAd^mB4ga%fqW~u9C@Nw|>g@UgZha+nMWT!Sc?fhOau_9s-n?J0dUpkt`q4W9(ONn ztjqwLZRb`$rqd`gV_s+4H;oMq{b|H(5^5$TnC@}2G1d9>wx%tzilb=?e)8t&-4DD~ z&7K+;N|jV^goTB6O;K5IzYR^T+Fh+=lbvQB)^Y7KJNbAwXaBFSZ?eT073!AM&i0oN z!!XGc`_UJbC{pvk4co$gwmKLBDv_0qCq>|I7Y?+QNfK2Jcs-n%^DiB41dKHBBOoG= zemI_GV{AVR5;Es)={YO-L9hU%u}3E$Sc84Y!zJ~6nCMLZfZsuhdF8kEBqI7F#&`%F z7I7=;Gl%>>OR$c5)&9;IFULgMrPS!4AHlf~3utZ^9t$W@EmG>>BrMEmzAu&+vcAC`!NfVMBW~Ip*dm<}SWE zWs>SoFoe107Jtd1$92gsS*&AU$U!3SM-Z7&@-fm5vemV=-dk^9_7A%??N@yTZlUy! z3Q4NsNVRU%v?)%w;1g><(z zb-{>Zy5t4M57qCCGHGtIqgj<% znIT{S*fN(IZc!>rn>4pW@j@o8+GG@VRj5IA;rdk|?_Y16;cUp7B|q~bE}~w@)fu>+ zW~qyg|EPpYnDFsPG*AHNPp3_SkHAxm``j?R!+p_&5Gb?8pkL7t}huf zsD1@a{eV&&4-n*EC^K8X2!*8^n5gZ1k{c-B<{c5VOR#?+_ww!f9w;p=R72p_CbNkL z8^i{4{hJ{14=_FvCb!a>X#zpNXa326QsI+Z2ed!ZH@StOz|a>|0R*-*6>K!jQHJRX zZ#<^V_Cs}m9S9%b_I2x4DS0{84Lq%G2@c zud#%h3M*hbpR};qIo}CCBck%BU7$erj}tu!M2+D1;h;bWB7}x&*afTgO)`NUPS<1Z z;G(Zy$dwjmRi=z)VGk_YKZF9K&nYf^6{P0Q8w8tX+L|k}dRiUOY0s=?imcnSMlFsX@M~5ri%vyI zCZ`0;~kS{2xbS{PqL@> zPq{p%S@ogHDKkH$AM}{Fb(_Ad;evkkJ8>eg7&D9aXWB*n6KFFxQ;q@O0v@xQ-#JpV z42DiXCSsta`u0kKTxd%({%cHEQnBVJrCu_5z8v3gxStRT-cn+hL}CSIcU(u@80FhI##Sf(@;IucX5B$Dy^)9R^xoVzYAIiE=B89dQH<#76`bw^=$D(gvOWB!AxEpf=M5j!8!qBxz<$!6wIOSZb;d0eM&9nYNB4VXwBmJ!j z#)%0xFiH!3J_9#FCX%Y?#|;mk@HS2h24)zITiy5oP{M)XndOAk4$wa@Uy)V?@%PUQ ztifHTz!sN<2)wOGy>n~;8tyM&0js0yl162%@EW# z=hj<&rTbyO+%*&FsMo1h)FK^c_&{gdDKarUUq?z0W8qOpG;|z9#vB~AFgdzwK0O=G zE(giS&rD;$ORWdp*UXeUJlPqmc`7aLQSG%Pi=NyMud+BN^tvThU4{@p|`1~ntFa%kUG)l6DI|H)?QIMYY>H%uNhNmC;+;9f3{%<$dZExR&$you#$hFYBPgZ^%Jv%kbp5XAFGPhdMjqI3D zBY(iSD7xJQgkmtGrMU82zl;8PJEVi{QTmZG-8n<9SFZW0RzI)r3ND1Mj4s%|I6H8J zM#RsEm<_nZoBzyBL({{;&>79Y+!WrlvC!>|l;k+M2V6$voy11A?IF#75>vO*K!x$1 z+`8xp2+)G!iv#+@Di!dbxQ$==84CXhx&+RYpx(DJiW$FDt&`&aT1f4xS$dk84-_go z>R5txhD|)uO$UY|SfnI9_It=YZp&C2%Ca;;g_Mp~Ghf=ZBJ-(^{vlgWn{Lqpr*5hy z50g|jj&Q55sQUZbiC4U=QQ*LJ6L<1Dr5@BYY)rFMi*XL#U5 zaM4w5ASzDk(s%TUd%Yp|cZc5B?Tp+zJN*mgP#(`M6RqiT^!!p|NqOt7pM^=RlfZm| zcciS!$_Gts1Pe%2l`1xN6thkv*=+9&$6{Sa=KK+hG+B@xu-#Kz-)SpqcGACjcn`)f z;yl0XP kBN!max;fc%Y-0y9v)=PzRXpY?1bz@V)o&DBH+lNs0FRceu>b%7 literal 0 HcmV?d00001 diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/package.html b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/package.html new file mode 100644 index 00000000000..a4b276be052 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/package.html @@ -0,0 +1,28 @@ + + + + + Eclipse Device Debug - Debugger Services Framework - Data Model + + +Example demostrationg use of Debugger Services Framework (DSF) data +model interfaces.
    +

    Package Specification

    +The example consists of two services, one that monitors a set of timers +(TimerService), and another that tracks a set of alarms +(AlarmService).  The timers are incremented at a rate of one per +second, although for visual interest, timers are not synchronous as +each timer is incremented at a slightly different moment.  There +is also a "Timers" view that displays the timers and alarms, and has +actions for adding and removing new timers and alarms.  Most +interestingly, the view has a toggle action, which switches the layout +of the view from having timers at the root level, with alarms listed +below each timer, to having alarms at the root level with timers listed +below each alarm.
    +
    +
    +
    + + diff --git a/plugins/org.eclipse.dd.gdb/.classpath b/plugins/org.eclipse.dd.gdb/.classpath new file mode 100644 index 00000000000..304e86186aa --- /dev/null +++ b/plugins/org.eclipse.dd.gdb/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/plugins/org.eclipse.dd.gdb/.project b/plugins/org.eclipse.dd.gdb/.project new file mode 100644 index 00000000000..5d4f83fccd0 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb/.project @@ -0,0 +1,28 @@ + + + org.eclipse.dd.gdb + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/plugins/org.eclipse.dd.gdb/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.dd.gdb/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000000..c9eb6de4787 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,65 @@ +#Thu Jun 07 11:08:01 PDT 2007 +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.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=warning +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning +org.eclipse.jdt.core.compiler.problem.nullReference=ignore +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning +org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=error +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/plugins/org.eclipse.dd.gdb/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.gdb/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..ec667323401 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb/META-INF/MANIFEST.MF @@ -0,0 +1,22 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: GDB DSF Debugger Integration Core +Bundle-Vendor: Eclipse.org +Bundle-SymbolicName: org.eclipse.dd.gdb;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: org.eclipse.dd.gdb.internal.GdbPlugin +Require-Bundle: org.eclipse.core.runtime, + org.eclipse.dd.dsf, + org.eclipse.dd.dsf.debug, + org.eclipse.dd.mi, + org.eclipse.debug.core, + org.eclipse.cdt.core, + org.eclipse.cdt.launch, + org.eclipse.cdt.debug.core, + org.eclipse.cdt.debug.mi.core +Bundle-ActivationPolicy: lazy +Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Export-Package: org.eclipse.dd.gdb.breakpoints, + org.eclipse.dd.gdb.launching, + org.eclipse.dd.gdb.service, + org.eclipse.dd.gdb.service.command diff --git a/plugins/org.eclipse.dd.gdb/about.html b/plugins/org.eclipse.dd.gdb/about.html new file mode 100644 index 00000000000..cb740ae8bc8 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb/about.html @@ -0,0 +1,24 @@ + + + + +About +

    About This Content

    + +

    June 5, 2007

    +

    License

    + +

    The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at http://www.eclipse.org/legal/epl-v10.html. +For purposes of the EPL, "Program" will mean the Content.

    + +

    If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at http://www.eclipse.org.

    + + \ No newline at end of file diff --git a/plugins/org.eclipse.dd.gdb/build.properties b/plugins/org.eclipse.dd.gdb/build.properties new file mode 100644 index 00000000000..786b1df9364 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb/build.properties @@ -0,0 +1,6 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml,\ + about.html diff --git a/plugins/org.eclipse.dd.gdb/plugin.xml b/plugins/org.eclipse.dd.gdb/plugin.xml new file mode 100644 index 00000000000..b57c16f117e --- /dev/null +++ b/plugins/org.eclipse.dd.gdb/plugin.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/breakpoints/CBreakpointGdbThreadsFilterExtension.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/breakpoints/CBreakpointGdbThreadsFilterExtension.java new file mode 100644 index 00000000000..1a81d3f5fc3 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/breakpoints/CBreakpointGdbThreadsFilterExtension.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.gdb.breakpoints; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.eclipse.cdt.debug.core.model.ICBreakpoint; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.debug.service.IDsfBreakpointExtension; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; + +/** + * + */ +public class CBreakpointGdbThreadsFilterExtension implements IDsfBreakpointExtension { + + private Map> fFilteredThreadsByTarget = + new HashMap>(1); + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.core.model.ICBreakpointExtension#initialize(org.eclipse.cdt.debug.core.model.ICBreakpoint) + */ + public void initialize(ICBreakpoint breakpoint) { + // TODO: Initialize fFilteredThreadsByTarget with current IContainerDMContext[] + // TODO: IRunControl? + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.core.model.ICBreakpoint#getTargetFilters() + */ + public IContainerDMContext[] getTargetFilters() throws CoreException { + Set set = fFilteredThreadsByTarget.keySet(); + return set.toArray( new IContainerDMContext[set.size()] ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.core.model.ICBreakpoint#getThreadFilters(org.eclipse.cdt.debug.core.model.ICDebugTarget) + */ + public IExecutionDMContext[] getThreadFilters( IContainerDMContext target ) throws CoreException { + Set set = fFilteredThreadsByTarget.get( target ); + return ( set != null ) ? set.toArray( new IExecutionDMContext[set.size()] ) : null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.core.model.ICBreakpoint#removeTargetFilter(org.eclipse.cdt.debug.core.model.ICDebugTarget) + */ + public void removeTargetFilter( IContainerDMContext target ) throws CoreException { + if ( fFilteredThreadsByTarget.containsKey( target ) ) { + fFilteredThreadsByTarget.remove( target ); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.core.model.ICBreakpoint#removeThreadFilters(org.eclipse.cdt.debug.core.model.ICThread[]) + */ + public void removeThreadFilters( IExecutionDMContext[] threads ) throws CoreException { + if ( threads != null && threads.length > 0 ) { + IContainerDMContext target = DMContexts.getAncestorOfType(threads[0], IContainerDMContext.class); + if ( fFilteredThreadsByTarget.containsKey( target ) ) { + Set set = fFilteredThreadsByTarget.get( target ); + if ( set != null ) { + set.removeAll( Arrays.asList( threads ) ); + if ( set.isEmpty() ) { + fFilteredThreadsByTarget.remove( target ); + } + } + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.core.model.ICBreakpoint#setTargetFilter(org.eclipse.cdt.debug.core.model.ICDebugTarget) + */ + public void setTargetFilter( IContainerDMContext target ) throws CoreException { + fFilteredThreadsByTarget.put( target, null ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.core.model.ICBreakpoint#setThreadFilters(org.eclipse.cdt.debug.core.model.ICThread[]) + */ + public void setThreadFilters( IExecutionDMContext[] threads ) throws CoreException { + if ( threads != null && threads.length > 0 ) { + IContainerDMContext target = DMContexts.getAncestorOfType(threads[0], IContainerDMContext.class); + fFilteredThreadsByTarget.put( target, new HashSet( Arrays.asList( threads ) ) ); + } + } + +} diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/GdbPlugin.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/GdbPlugin.java new file mode 100644 index 00000000000..679534ccf74 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/GdbPlugin.java @@ -0,0 +1,110 @@ +package org.eclipse.dd.gdb.internal; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Plugin; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.Query; +import org.eclipse.dd.gdb.launching.GdbLaunch; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunch; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class GdbPlugin extends Plugin { + + // The plug-in ID + public static final String PLUGIN_ID = "org.eclipse.dd.gdb"; //$NON-NLS-1$ + + // The shared instance + private static GdbPlugin plugin; + + private static BundleContext fgBundleContext; + + /** + * The constructor + */ + public GdbPlugin() { + } + + /* + * (non-Javadoc) + * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext) + */ + @Override + public void start(BundleContext context) throws Exception { + fgBundleContext = context; + super.start(context); + plugin = this; + } + + /* + * (non-Javadoc) + * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext) + */ + @Override + public void stop(BundleContext context) throws Exception { + shutdownActiveLaunches(); + plugin = null; + super.stop(context); + fgBundleContext = null; + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static GdbPlugin getDefault() { + return plugin; + } + + public static BundleContext getBundleContext() { + return fgBundleContext; + } + + /** + * Shuts down any active launches. We must shutdown any active sessions + * and services associated with this plugin before this plugin is stopped. + * Any attempts to use the plugins {@link BundleContext} after the plugin + * is shut down will result in exceptions. + */ + private void shutdownActiveLaunches() { + for (ILaunch launch : DebugPlugin.getDefault().getLaunchManager().getLaunches()) { + if (launch instanceof GdbLaunch && ((GdbLaunch)launch).getSession().isActive()) { + final GdbLaunch gdbLaunch = (GdbLaunch)launch; + + Query launchShutdownQuery = new Query() { + @Override + protected void execute(DataRequestMonitor rm) { + gdbLaunch.shutdownSession(rm); + } + }; + + try { + gdbLaunch.getSession().getExecutor().execute(launchShutdownQuery); + } catch (RejectedExecutionException e) { + // We can get this exception if the session is shutdown concurrently + // to this method running. + break; + } + + // The Query.get() method is a synchronous call which blocks until the + // query completes. + try { + launchShutdownQuery.get(); + } catch (InterruptedException e) { + getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, "InterruptedException while shutting down PDA debugger launch " + gdbLaunch, e.getCause())); //$NON-NLS-1$ + } catch (ExecutionException e) { + getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, "Exception while shutting down PDA debugger launch " + gdbLaunch, e.getCause())); //$NON-NLS-1$ + } + } + } + } + +} diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunch.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunch.java new file mode 100644 index 00000000000..95592eafde4 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunch.java @@ -0,0 +1,175 @@ +/******************************************************************************* + * 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.gdb.launching; + +import java.util.concurrent.ExecutionException; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; +import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.concurrent.Sequence; +import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.gdb.internal.GdbPlugin; +import org.eclipse.dd.gdb.service.command.GDBControl; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.Launch; +import org.eclipse.debug.core.model.ISourceLocator; +import org.eclipse.debug.core.model.ITerminate; + +/** + * The only object in the model that implements the traditional interfaces. + */ +@ThreadSafe +public class GdbLaunch extends Launch + implements ITerminate +{ + private DefaultDsfExecutor fExecutor; + private DsfSession fSession; + private DsfServicesTracker fTracker; + private boolean fInitialized = false; + private boolean fShutDown = false; + + + public GdbLaunch(ILaunchConfiguration launchConfiguration, String mode, ISourceLocator locator) { + super(launchConfiguration, mode, locator); + + // Create the dispatch queue to be used by debugger control and services + // that belong to this launch + final DefaultDsfExecutor dsfExecutor = new DefaultDsfExecutor(GdbLaunchDelegate.GDB_DEBUG_MODEL_ID); + dsfExecutor.prestartCoreThread(); + fExecutor = dsfExecutor; + fSession = DsfSession.startSession(fExecutor, GdbLaunchDelegate.GDB_DEBUG_MODEL_ID); + } + + public DsfExecutor getDsfExecutor() { return fExecutor; } + + @ConfinedToDsfExecutor("getExecutor") + public void initializeControl() + throws CoreException + { + + Runnable initRunnable = new DsfRunnable() { + public void run() { + fTracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), fSession.getId()); + fSession.addServiceEventListener(GdbLaunch.this, null); + + fInitialized = true; + fireChanged(); + } + }; + + // Invoke the execution code and block waiting for the result. + try { + fExecutor.submit(initRunnable).get(); + } catch (InterruptedException e) { + new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Error initializing launch", e); //$NON-NLS-1$ + } catch (ExecutionException e) { + new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Error initializing launch", e); //$NON-NLS-1$ + } + } + + public DsfSession getSession() { return fSession; } + + /////////////////////////////////////////////////////////////////////////// + // IServiceEventListener + @DsfServiceEventHandler public void eventDispatched(GDBControl.ExitedEvent event) { + shutdownSession(new RequestMonitor(ImmediateExecutor.getInstance(), null)); + } + + /////////////////////////////////////////////////////////////////////////// + // ITerminate + @Override + public boolean canTerminate() { + return super.canTerminate() && fInitialized && !fShutDown; + } + + @Override + public boolean isTerminated() { + return super.isTerminated() || fShutDown; + } + + + @Override + public void terminate() throws DebugException { + if (fShutDown) return; + super.terminate(); + } + // ITerminate + /////////////////////////////////////////////////////////////////////////// + + /** + * Shuts down the services, the session and the executor associated with + * this launch. + *

    + * Note: The argument request monitor to this method should NOT use the + * executor that belongs to this launch. By the time the shutdown is + * complete, this executor will not be dispatching anymore and the + * request monitor will never be invoked. Instead callers should use + * the {@link ImmediateExecutor}. + *

    + * @param rm The request monitor invoked when the shutdown is complete. + */ + @ConfinedToDsfExecutor("getSession().getExecutor()") + public void shutdownSession(final RequestMonitor rm) { + if (fShutDown) { + rm.done(); + return; + } + fShutDown = true; + + Sequence shutdownSeq = new ShutdownSequence( + getDsfExecutor(), fSession.getId(), + new RequestMonitor(fSession.getExecutor(), rm) { + @Override + public void handleCompleted() { + fSession.removeServiceEventListener(GdbLaunch.this); + if (!getStatus().isOK()) { + GdbPlugin.getDefault().getLog().log(new MultiStatus( + GdbPlugin.PLUGIN_ID, -1, new IStatus[]{getStatus()}, "Session shutdown failed", null)); //$NON-NLS-1$ + } + // Last order of business, shutdown the dispatch queue. + fTracker.dispose(); + fTracker = null; + DsfSession.endSession(fSession); + // endSession takes a full dispatch to distribute the + // session-ended event, finish step only after the dispatch. + fExecutor.shutdown(); + fExecutor = null; + fireTerminate(); + + rm.setStatus(getStatus()); + rm.done(); + } + }); + fExecutor.execute(shutdownSeq); + } + + @SuppressWarnings("unchecked") + @Override + public Object getAdapter(Class adapter) { + // Must force adapters to be loaded. + Platform.getAdapterManager().loadAdapter(this, adapter.getName()); + return super.getAdapter(adapter); + } +} diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunchDelegate.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunchDelegate.java new file mode 100644 index 00000000000..0535874e5cf --- /dev/null +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunchDelegate.java @@ -0,0 +1,290 @@ +/******************************************************************************* + * Copyright (c) 2004, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.gdb.launching; + +import java.io.File; +import java.io.IOException; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.atomic.AtomicReference; + +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; +import org.eclipse.cdt.launch.AbstractCLaunchDelegate; +import org.eclipse.cdt.launch.internal.ui.LaunchMessages; +import org.eclipse.cdt.launch.internal.ui.LaunchUIPlugin; +import org.eclipse.cdt.utils.pty.PTY; +import org.eclipse.cdt.utils.spawner.ProcessFactory; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.dd.dsf.debug.model.DsfMemoryBlockRetrieval; +import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryDMContext; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.gdb.internal.GdbPlugin; +import org.eclipse.dd.gdb.service.command.GDBControl; +import org.eclipse.dd.mi.service.command.AbstractCLIProcess; +import org.eclipse.dd.mi.service.command.MIInferiorProcess; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchManager; +import org.eclipse.debug.core.IStatusHandler; +import org.eclipse.debug.core.model.ILaunchConfigurationDelegate2; +import org.eclipse.debug.core.model.IMemoryBlockRetrieval; +import org.eclipse.debug.core.model.IPersistableSourceLocator; +import org.eclipse.debug.core.model.ISourceLocator; +import org.eclipse.debug.core.sourcelookup.IPersistableSourceLocator2; + +/** + * The launch configuration delegate for the CDI debugger session types. + */ +@ThreadSafe +public class GdbLaunchDelegate extends AbstractCLaunchDelegate + implements ILaunchConfigurationDelegate2 +{ + public final static String GDB_DEBUG_MODEL_ID = "org.eclipse.dd.dsf.gdb"; //$NON-NLS-1$ + + /* (non-Javadoc) + * @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#launch(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.debug.core.ILaunch, org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public void launch( ILaunchConfiguration config, String mode, ILaunch launch, IProgressMonitor monitor ) throws CoreException { + if ( monitor == null ) { + monitor = new NullProgressMonitor(); + } + if ( mode.equals( ILaunchManager.DEBUG_MODE ) ) { + launchDebugger( config, launch, monitor ); + } + } + + private void launchDebugger( ILaunchConfiguration config, ILaunch launch, IProgressMonitor monitor ) throws CoreException { + monitor.beginTask("Launching debugger session", 10); //$NON-NLS-1$ + if ( monitor.isCanceled() ) { + return; + } + try { + String debugMode = config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN ); + if ( debugMode.equals( ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN ) ) { + launchLocalDebugSession( config, launch, monitor ); + } + } + finally { + monitor.done(); + } + } + + private void launchLocalDebugSession( ILaunchConfiguration config, ILaunch l, IProgressMonitor monitor ) throws CoreException { + if ( monitor.isCanceled() ) { + return; + } + final GdbLaunch launch = (GdbLaunch)l; + + monitor.subTask( "Debugging local C/C++ application" ); //$NON-NLS-1$ + IPath exePath = verifyProgramPath( config ); + ICProject project = verifyCProject( config ); + if ( exePath != null ) { + verifyBinary( project, exePath ); + } + + setDefaultSourceLocator(launch, config); + + monitor.worked( 1 ); + + + // Create and invoke the launch sequence to create the debug control and services + final LaunchSequence launchSequence = + new LaunchSequence(launch.getSession(), launch, exePath); + launch.getSession().getExecutor().execute(launchSequence); + try { + launchSequence.get(); + } catch (InterruptedException e1) { + throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, "Interrupted Exception in dispatch thread", e1)); //$NON-NLS-1$ + } catch (ExecutionException e1) { + throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Error in launch sequence", e1.getCause())); //$NON-NLS-1$ + } + + launch.initializeControl(); + + // Add the CLI and "inferior" process objects to the launch. + final AtomicReference cliProcessRef = new AtomicReference(); + final AtomicReference inferiorProcessRef = new AtomicReference(); + try { + launch.getDsfExecutor().submit( new Callable() { + public Object call() throws CoreException { + DsfServicesTracker tracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), launch.getSession().getId()); + GDBControl gdb = tracker.getService(GDBControl.class); + if (gdb != null) { + cliProcessRef.set(gdb.getCLIProcess()); + inferiorProcessRef.set(gdb.getInferiorProcess()); + } + tracker.dispose(); + return null; + } + }).get(); + launch.addProcess(DebugPlugin.newProcess(launch, cliProcessRef.get(), "gdb")); //$NON-NLS-1$ + launch.addProcess(DebugPlugin.newProcess(launch, inferiorProcessRef.get(), exePath.lastSegment())); + } catch (InterruptedException e) { + throw new CoreException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, 0, "Interrupted while waiting for get process callable.", e)); //$NON-NLS-1$ + } catch (ExecutionException e) { + throw (CoreException)e.getCause(); + } catch (RejectedExecutionException e) { + throw new CoreException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, 0, "Debugger shut down before launch was completed.", e)); //$NON-NLS-1$ + } + + // Create a memory retrieval and register it with session + try { + launch.getDsfExecutor().submit( new Callable() { + public Object call() throws CoreException { + DsfServicesTracker tracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), launch.getSession().getId()); + GDBControl gdbControl = tracker.getService(GDBControl.class); + if (gdbControl != null) { + IMemoryBlockRetrieval memRetrieval = new DsfMemoryBlockRetrieval( + GDB_DEBUG_MODEL_ID, (IMemoryDMContext)gdbControl.getControlDMContext()); + launch.getSession().registerModelAdapter(IMemoryBlockRetrieval.class, memRetrieval); + } + tracker.dispose(); + return null; + } + }).get(); + } catch (InterruptedException e) { + throw new CoreException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, 0, "Interrupted while waiting for get process callable.", e)); //$NON-NLS-1$ + } catch (ExecutionException e) { + throw (CoreException)e.getCause(); + } catch (RejectedExecutionException e) { + throw new CoreException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, 0, "Debugger shut down before launch was completed.", e)); //$NON-NLS-1$ + } + } + + + /* (non-Javadoc) + * @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#getPluginID() + */ + @Override + protected String getPluginID() { + return LaunchUIPlugin.getUniqueIdentifier(); + } + + /** + * Performs a runtime exec on the given command line in the context of the + * specified working directory, and returns the resulting process. If the + * current runtime does not support the specification of a working + * directory, the status handler for error code + * ERR_WORKING_DIRECTORY_NOT_SUPPORTED is queried to see if + * the exec should be re-executed without specifying a working directory. + * + * @param cmdLine + * the command line + * @param workingDirectory + * the working directory, or null + * @return the resulting process or null if the exec is + * cancelled + * @see Runtime + */ + protected Process exec( String[] cmdLine, String[] environ, File workingDirectory, boolean usePty ) throws CoreException { + Process p = null; + try { + if ( workingDirectory == null ) { + p = ProcessFactory.getFactory().exec( cmdLine, environ ); + } + else { + if ( usePty && PTY.isSupported() ) { + p = ProcessFactory.getFactory().exec( cmdLine, environ, workingDirectory, new PTY() ); + } + else { + p = ProcessFactory.getFactory().exec( cmdLine, environ, workingDirectory ); + } + } + } + catch( IOException e ) { + if ( p != null ) { + p.destroy(); + } + abort( "Error starting process.", e, ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR ); //$NON-NLS-1$ + } + catch( NoSuchMethodError e ) { + // attempting launches on 1.2.* - no ability to set working + // directory + IStatus status = new Status( IStatus.ERROR, LaunchUIPlugin.getUniqueIdentifier(), ICDTLaunchConfigurationConstants.ERR_WORKING_DIRECTORY_NOT_SUPPORTED, LaunchMessages.getString( "LocalDsfLaunchDelegate.9" ), e ); //$NON-NLS-1$ + IStatusHandler handler = DebugPlugin.getDefault().getStatusHandler( status ); + if ( handler != null ) { + Object result = handler.handleStatus( status, this ); + if ( result instanceof Boolean && ((Boolean)result).booleanValue() ) { + p = exec( cmdLine, environ, null, usePty ); + } + } + } + return p; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#preLaunchCheck(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public boolean preLaunchCheck( ILaunchConfiguration config, String mode, IProgressMonitor monitor ) throws CoreException { + // no pre launch check for core file + if ( mode.equals( ILaunchManager.DEBUG_MODE ) ) { + if ( ICDTLaunchConfigurationConstants.DEBUGGER_MODE_CORE.equals( config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN ) ) ) + return true; + } + return super.preLaunchCheck( config, mode, monitor ); + } + + /////////////////////////////////////////////////////////////////////////// + // ILaunchConfigurationDelegate2 + @Override + public boolean buildForLaunch(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException { + return false; + } + + @Override + public boolean finalLaunchCheck(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException { + return true; + } + + @Override + public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) throws CoreException { + // Need to configure the source locator before creating the launch + // because once the launch is created and added to launch manager, + // the adapters will be created for the whole session, including + // the source lookup adapter. + ISourceLocator locator = getSourceLocator(configuration); + + return new GdbLaunch(configuration, mode, locator); + } + + private ISourceLocator getSourceLocator(ILaunchConfiguration configuration) throws CoreException { + String type = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_ID, (String)null); + if (type == null) { + type = configuration.getType().getSourceLocatorId(); + } + if (type != null) { + IPersistableSourceLocator locator = DebugPlugin.getDefault().getLaunchManager().newSourceLocator(type); + String memento = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_MEMENTO, (String)null); + if (memento == null) { + locator.initializeDefaults(configuration); + } else { + if(locator instanceof IPersistableSourceLocator2) + ((IPersistableSourceLocator2)locator).initializeFromMemento(memento, configuration); + else + locator.initializeFromMemento(memento); + } + return locator; + } + return null; + } +} diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/LaunchSequence.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/LaunchSequence.java new file mode 100644 index 00000000000..9f49b87e9a0 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/LaunchSequence.java @@ -0,0 +1,267 @@ +/******************************************************************************* + * 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.gdb.launching; + +import java.util.concurrent.TimeUnit; + +import org.eclipse.cdt.debug.core.CDebugCorePlugin; +import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; +import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector; +import org.eclipse.cdt.debug.mi.core.IMILaunchConfigurationConstants; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.concurrent.Sequence; +import org.eclipse.dd.dsf.debug.service.StepQueueManager; +import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.gdb.internal.GdbPlugin; +import org.eclipse.dd.gdb.service.GDBRunControl; +import org.eclipse.dd.gdb.service.command.GDBControl; +import org.eclipse.dd.mi.service.CSourceLookup; +import org.eclipse.dd.mi.service.ExpressionService; +import org.eclipse.dd.mi.service.MIBreakpoints; +import org.eclipse.dd.mi.service.MIBreakpointsManager; +import org.eclipse.dd.mi.service.MIMemory; +import org.eclipse.dd.mi.service.MIModules; +import org.eclipse.dd.mi.service.MIRegisters; +import org.eclipse.dd.mi.service.MIStack; +import org.eclipse.dd.mi.service.command.commands.MIBreakInsert; +import org.eclipse.dd.mi.service.command.commands.MIExecRun; +import org.eclipse.dd.mi.service.command.events.MIStoppedEvent; +import org.eclipse.dd.mi.service.command.output.MIBreakInsertInfo; +import org.eclipse.dd.mi.service.command.output.MIInfo; +import org.eclipse.debug.core.DebugException; + +public class LaunchSequence extends Sequence { + + public class EntryPointHitEventListener { + boolean fAborted = false; + boolean fFinished = false; + final RequestMonitor fRequestMonitor; + + EntryPointHitEventListener(RequestMonitor requestMonitor) { + fRequestMonitor = requestMonitor; + } + + @DsfServiceEventHandler + public void eventDispatched(MIStoppedEvent e) { + fFinished = true; + if (!fAborted) { + fSession.removeServiceEventListener(this); + fRequestMonitor.done(); + } + } + } + + + Step[] fSteps = new Step[] { + // Create and initialize the Connection service. + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + // + // Create the connection. + // + fCommandControl = new GDBControl( + fSession, getGDBPath(), fExecPath, GDBControl.SessionType.RUN, 30); + fCommandControl.initialize(requestMonitor); + } + }, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new GDBRunControl(fSession).initialize(requestMonitor); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new StepQueueManager(fSession).initialize(requestMonitor); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new MIMemory(fSession).initialize(requestMonitor); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new MIModules(fSession).initialize(requestMonitor); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new MIStack(fSession).initialize(requestMonitor); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new ExpressionService(fSession).initialize(requestMonitor); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + fSourceLookup = new CSourceLookup(fSession); + fSourceLookup.initialize(requestMonitor); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + fSourceLookup.setSourceLookupDirector( + fCommandControl.getGDBDMContext(), + ((CSourceLookupDirector)fLaunch.getSourceLocator())); + requestMonitor.done(); + }}, + new Step() { @Override + public void execute(final RequestMonitor requestMonitor) { + // Create the low-level breakpoint service + final MIBreakpoints bpService = new MIBreakpoints(fSession); + bpService.initialize(new RequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleOK() { + requestMonitor.done(); + } + }); + }}, + new Step() { @Override + public void execute(final RequestMonitor requestMonitor) { + // Create high-level breakpoint service and install breakpoints + // for the GDB debug context. + final MIBreakpointsManager bpmService = new MIBreakpointsManager(fSession, CDebugCorePlugin.PLUGIN_ID); + bpmService.initialize(new RequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleOK() { + bpmService.startTrackingBreakpoints(fCommandControl.getGDBDMContext(), requestMonitor); + } + }); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new MIRegisters(fSession).initialize(requestMonitor); + }}, + /* + * If needed, insert breakpoint at main and run to it. + */ + new Step() { + private boolean fStopInMain = false; + private String fStopSymbol = null; + + /** + * @return The return value actually indicates whether the get operation succeeded, + * not whether to stop. + */ + private boolean readStopAtMain(RequestMonitor requestMonitor) { + try { + fStopInMain = fLaunch.getLaunchConfiguration().getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN, false ); + } catch (CoreException e) { + requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Cannot retrieve the entry point symbol", e)); //$NON-NLS-1$ + requestMonitor.done(); + return false; + } + return true; + } + + private boolean readStopSymbol(RequestMonitor requestMonitor) { + try { + fStopSymbol = fLaunch.getLaunchConfiguration().getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN_SYMBOL, ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_SYMBOL_DEFAULT ); + } catch (CoreException e) { + requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.CONFIGURATION_INVALID, "Cannot retrieve the entry point symbol", e)); //$NON-NLS-1$ + requestMonitor.done(); + return false; + } + return true; + } + + @Override + public void execute(final RequestMonitor requestMonitor) { + if (!readStopAtMain(requestMonitor)) return; + if (!fStopInMain) { + requestMonitor.done(); + return; + } + + if (!readStopSymbol(requestMonitor)) return; + + // Create a listener to wait for the stopped event, and register as even handler. + // This handler will execute the requestMonitor. + final EntryPointHitEventListener entryPointHitListener = new EntryPointHitEventListener(requestMonitor); + fSession.addServiceEventListener(entryPointHitListener, null); + + // Create a time-out, to abort if breakpoint not hit. + fSession.getExecutor().schedule( + new Runnable() { public void run() { + // Only process the event if we have not finished yet (hit the breakpoint). + if (!entryPointHitListener.fFinished) { + // Mark the listener as aborted, and unregister it as event listener. + entryPointHitListener.fAborted = true; + fSession.removeServiceEventListener(entryPointHitListener); + + // Submit the error result for the step. + requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.TARGET_REQUEST_FAILED, "Timed out running to entry point.", null)); //$NON-NLS-1$ + requestMonitor.done(); + } + }}, + 60, TimeUnit.SECONDS); + + // Insert a breakpoint at the requested stop symbol. + fCommandControl.queueCommand( + new MIBreakInsert( + (IBreakpointsTargetDMContext)fCommandControl.getControlDMContext(), + true, false, null, 0, fStopSymbol, 0), + new DataRequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleOK() { + + // After the break-insert is done, execute the -exec-run command. + fCommandControl.queueCommand( + new MIExecRun((IContainerDMContext)fCommandControl.getControlDMContext(), new String[0]), + new DataRequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleOK() { + // Note : Do we not need to do something with the original requestMonitor? + // Do nothing. Execution was resumed and the EntryPointHitEventListener + // will resume execution + } + } + ); + } + }); + } + }, + }; + + DsfSession fSession; + GdbLaunch fLaunch; + IPath fExecPath; + + GDBControl fCommandControl; + CSourceLookup fSourceLookup; + + public LaunchSequence(DsfSession session, GdbLaunch launch, IPath execPath) { + super(session.getExecutor()); + fSession = session; + fLaunch = launch; + fExecPath = execPath; + } + + @Override + public Step[] getSteps() { + return fSteps; + } + + private IPath getGDBPath() { + IPath retVal = new Path("gdb.exe"); //$NON-NLS-1$ + try { + retVal = new Path( fLaunch.getLaunchConfiguration().getAttribute( IMILaunchConfigurationConstants.ATTR_DEBUG_NAME, IMILaunchConfigurationConstants.DEBUGGER_DEBUG_NAME_DEFAULT ) ); + } catch (CoreException e) { + } + return retVal; + } + +} diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/ShutdownSequence.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/ShutdownSequence.java new file mode 100644 index 00000000000..b902a74bd80 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/ShutdownSequence.java @@ -0,0 +1,173 @@ +/******************************************************************************* + * 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.gdb.launching; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.concurrent.Sequence; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.gdb.internal.GdbPlugin; +import org.eclipse.dd.gdb.service.GDBRunControl; +import org.eclipse.dd.gdb.service.command.GDBControl; +import org.eclipse.dd.mi.service.CSourceLookup; +import org.eclipse.dd.mi.service.ExpressionService; +import org.eclipse.dd.mi.service.MIBreakpoints; +import org.eclipse.dd.mi.service.MIBreakpointsManager; +import org.eclipse.dd.mi.service.MIMemory; +import org.eclipse.dd.mi.service.MIModules; +import org.eclipse.dd.mi.service.MIRegisters; +import org.eclipse.dd.mi.service.MIStack; + +public class ShutdownSequence extends Sequence { + + String fSessionId; + + String fApplicationName; + + String fDebugModelId; + + DsfServicesTracker fTracker; + + public ShutdownSequence(DsfExecutor executor, String sessionId, RequestMonitor requestMonitor) { + super(executor, requestMonitor); + fSessionId = sessionId; + } + + @Override + public Step[] getSteps() { + return fSteps; + } + + private final Step[] fSteps = new Step[] { new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + assert GdbPlugin.getBundleContext() != null; + fTracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), fSessionId); + requestMonitor.done(); + } + + @Override + public void rollBack(RequestMonitor requestMonitor) { + fTracker.dispose(); + fTracker = null; + requestMonitor.done(); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(MIRegisters.class, requestMonitor); + } +// TODO: As Pawel about the necessity of this step +// Not clear on the purpose of this step since the next one does it also +// (stopTrackingBreakpoints() is called as part of the shutdown method) +// Besides, the run control is already gone so removing breakpoints from +// the back-end is bound to fail... +// }, new Step() { +// @Override +// public void execute(final RequestMonitor requestMonitor) { +// MIBreakpointsManager bpm = fTracker.getService(MIBreakpointsManager.class); +// GDBControl commandControl = fTracker.getService(GDBControl.class); +// if (bpm != null && commandControl != null) { +// bpm.stopTrackingBreakpoints( +// commandControl.getGDBDMContext(), +// new RequestMonitor(getExecutor(), requestMonitor) { +// @Override +// protected void handleCompleted() { +// // If un-installing breakpoints fails, log the error but continue shutting down. +// if (!getStatus().isOK()) { +// DsfGdbPlugin.getDefault().getLog().log(getStatus()); +// } +// requestMonitor.done(); +// } +// }); +// } else { +// requestMonitor.setStatus(new Status(IStatus.ERROR, DsfGdbPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, +// "Needed services not found.", null)); //$NON-NLS-1$ +// requestMonitor.done(); +// } +// } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(MIBreakpointsManager.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(MIBreakpoints.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(CSourceLookup.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(ExpressionService.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(MIStack.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(MIModules.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(MIMemory.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(GDBRunControl.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(GDBControl.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + fTracker.dispose(); + fTracker = null; + requestMonitor.done(); + } + } }; + + @SuppressWarnings("unchecked") + private void shutdownService(Class clazz, final RequestMonitor requestMonitor) { + IDsfService service = fTracker.getService(clazz); + if (service != null) { + service.shutdown(new RequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + GdbPlugin.getDefault().getLog().log(getStatus()); + } + requestMonitor.done(); + } + }); + } else { + requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, + "Service '" + clazz.getName() + "' not found.", null)); //$NON-NLS-1$//$NON-NLS-2$ + requestMonitor.done(); + } + } +} diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/GDBRunControl.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/GDBRunControl.java new file mode 100644 index 00000000000..b6b3aabdd57 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/GDBRunControl.java @@ -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 + * Ericsson AB - Modified for additional functionality + *******************************************************************************/ + +package org.eclipse.dd.gdb.service; + + +import java.util.Arrays; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.gdb.internal.GdbPlugin; +import org.eclipse.dd.gdb.service.command.GDBControl; +import org.eclipse.dd.gdb.service.command.GDBControlDMContext; +import org.eclipse.dd.mi.service.IMIExecutionDMContext; +import org.eclipse.dd.mi.service.MIRunControl; +import org.eclipse.dd.mi.service.command.commands.CLIInfoThreads; +import org.eclipse.dd.mi.service.command.events.MIEvent; +import org.eclipse.dd.mi.service.command.events.MIThreadExitEvent; +import org.eclipse.dd.mi.service.command.output.CLIInfoThreadsInfo; +public class GDBRunControl extends MIRunControl { + + /** + * Implement a custom execution data for threads in order to provide additional + * information. This object can be made separate from IExecutionDMData after + * the deprecated method: IDMService.getModelData() is no longer used. + */ + public static class GDBThreadData { + private final String fId; + private final String fName; + + GDBThreadData(String id, String name) { + fId = id; + fName = name; + } + + public String getName() { + return fName; + } + public String getId() { return fId; } + + public boolean isDebuggerAttached() { return true; } + } + + /** + * Implement a custom execution data the process in order to provide additional + * information. This object can be made separate from IExecutionDMData after + * the deprecated method: IDMService.getModelData() is no longer used. + */ + public static class GDBProcessData { + private final String fName; + + GDBProcessData(String name) { + fName = name; + } + + public String getName() { + return fName; + } + } + + private GDBControl fGdb; + + // Record list of execution contexts + private IExecutionDMContext[] fOldExecutionCtxts; + + + public GDBRunControl(DsfSession session) { + super(session); + } + + @Override + public void initialize(final RequestMonitor requestMonitor) { + super.initialize( + new RequestMonitor(getExecutor(), requestMonitor) { + @Override + public void handleOK() { + doInitialize(requestMonitor); + }}); + } + + private void doInitialize(final RequestMonitor requestMonitor) { + + fGdb = getServicesTracker().getService(GDBControl.class); + register(new String[]{IRunControl.class.getName(), MIRunControl.class.getName()}, new Hashtable()); + + requestMonitor.done(); + } + + @Override + public void shutdown(final RequestMonitor requestMonitor) { + unregister(); + super.shutdown(requestMonitor); + } + + @Override + public void suspend(IExecutionDMContext context, RequestMonitor requestMonitor){ + if (canSuspend(context)) { + fGdb.interrupt(); + } else { + requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, "Context cannot be suspended.", null)); //$NON-NLS-1$ + } + requestMonitor.done(); + } + + + /* + * This is a HACK. Remove this method when GDB starts to account exited threads id in -thread-list-id command. + * Exited threads are reported in -thread-list-id command even after an exit event is raised by GDB + * Hence, this method needs a special handling in case of GDB. + * Raises ExitEvent when a thread really exits from the system. This is done by comparing the execution contexts list + * See bug 200615 for details. + */ + @Override + public void getExecutionContexts(IContainerDMContext c, final DataRequestMonitor rm) { + DataRequestMonitor rm1 = new DataRequestMonitor( + getExecutor(), rm) { + @Override + protected void handleOK() { + raiseExitEvents(getData()); + fOldExecutionCtxts = getData(); + rm.setData(fOldExecutionCtxts); + rm.done(); + } + }; + super.getExecutionContexts(c, rm1); + } + + public void getProcessData(GDBControlDMContext gdbDmc, DataRequestMonitor rm) { + rm.setData( new GDBProcessData(fGdb.getExecutablePath().lastSegment()) ); + rm.done(); + } + + public void getThreadData(final IMIExecutionDMContext execDmc, final DataRequestMonitor rm) { + IContainerDMContext containerDmc = DMContexts.getAncestorOfType(execDmc, IContainerDMContext.class); + assert containerDmc != null; // Every exec context should have a container as an ancestor. + getCache().execute(new CLIInfoThreads(containerDmc), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + rm.setData( createThreadInfo(execDmc, getData()) ); + rm.done(); + } + }); + } + + private GDBThreadData createThreadInfo(IMIExecutionDMContext dmc, CLIInfoThreadsInfo info){ + for (CLIInfoThreadsInfo.ThreadInfo thread : info.getThreadInfo()) { + if(Integer.parseInt(thread.getId()) == dmc.getThreadId()){ + //fMapThreadIds.put(thread.getId(), String.valueOf(dmc.getId())); + return new GDBThreadData(thread.getOsId(), thread.getName()); + } + } + return new GDBThreadData("",""); //$NON-NLS-1$ //$NON-NLS-2$ + } + + + private void raiseExitEvents(IExecutionDMContext[] ctxts){ + if(ctxts == null || fOldExecutionCtxts == null) + return; + List list = Arrays.asList(ctxts); + List oldThreadList = Arrays.asList(fOldExecutionCtxts); + Iterator iterator = oldThreadList.iterator(); + while(iterator.hasNext()){ + IExecutionDMContext ctxt = iterator.next(); + if(! list.contains(ctxt)){ + IContainerDMContext containerDmc = DMContexts.getAncestorOfType(ctxt, IContainerDMContext.class); + MIEvent e = new MIThreadExitEvent(containerDmc, ((IMIExecutionDMContext)ctxt).getThreadId()); + // Dispatch DsfMIThreadExitEvent + getSession().dispatchEvent(e, getProperties()); + } + } + } + + +} diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBCLIProcess.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBCLIProcess.java new file mode 100644 index 00000000000..6c6c80c251b --- /dev/null +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBCLIProcess.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.gdb.service.command; + +import java.io.IOException; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.mi.service.command.AbstractCLIProcess; + +/** + * + */ +class GDBCLIProcess extends AbstractCLIProcess { + + public GDBCLIProcess(GDBControl commandControl, boolean useExecConsole) throws IOException { + super(commandControl, useExecConsole); + } + + + /** + * @see java.lang.Process#waitFor() + */ + @Override + public int waitFor() throws InterruptedException { + if (!DsfSession.isSessionActive(getSession().getId())) return 0; + + Process process = null; + try { + process = getSession().getExecutor().submit(new Callable() { + public Process call() throws Exception { + if (isDisposed()) return null; + return ((GDBControl)getCommandControl()).getGDBProcess(); + }}).get(); + } catch (RejectedExecutionException e) { + } catch (ExecutionException e) { + } + if (process == null) return 0; + return process.waitFor(); + } + + + /** + * @see java.lang.Process#exitValue() + */ + @Override + public int exitValue() { + if (!DsfSession.isSessionActive(getSession().getId())) return 0; + try { + return getSession().getExecutor().submit(new Callable() { + public Integer call() throws Exception { + if (!DsfSession.isSessionActive(getSession().getId())) { + return new Integer(-1); + } else { + if (isDisposed()) return new Integer(-1); + GDBControl gdb = (GDBControl)getCommandControl(); + if (!gdb.isGDBExited()) { + throw new IllegalThreadStateException("GDB Process has not exited"); //$NON-NLS-1$ + } + return gdb.getGDBExitCode(); + } + }}).get().intValue(); + } catch (RejectedExecutionException e) { + } catch (InterruptedException e) { + } catch (ExecutionException e) { + if (e.getCause() instanceof RuntimeException) { + throw (RuntimeException)e.getCause(); + } + } + return 0; + } + /** + * @see java.lang.Process#destroy() + */ + @Override + public void destroy() { + try { + getSession().getExecutor().execute(new DsfRunnable() { public void run() { + if (!DsfSession.isSessionActive(getSession().getId())) return; + if (isDisposed()) return; + GDBControl gdb = (GDBControl)getCommandControl(); + gdb.destroy(); + }}); + } catch (RejectedExecutionException e) { + // Session disposed. + } + } + + +} diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControl.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControl.java new file mode 100644 index 00000000000..ea79486a158 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControl.java @@ -0,0 +1,596 @@ +/******************************************************************************* + * 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 + * Ericsson - Modified for additional features in DSF Reference implementation + *******************************************************************************/ +package org.eclipse.dd.gdb.service.command; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.List; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +import org.eclipse.cdt.utils.spawner.ProcessFactory; +import org.eclipse.cdt.utils.spawner.Spawner; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.concurrent.Sequence; +import org.eclipse.dd.dsf.datamodel.AbstractDMEvent; +import org.eclipse.dd.dsf.debug.service.command.CommandCache; +import org.eclipse.dd.dsf.debug.service.command.ICommandControl; +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.gdb.internal.GdbPlugin; +import org.eclipse.dd.mi.service.command.AbstractCLIProcess; +import org.eclipse.dd.mi.service.command.AbstractMIControl; +import org.eclipse.dd.mi.service.command.CLIEventProcessor; +import org.eclipse.dd.mi.service.command.MIControlDMContext; +import org.eclipse.dd.mi.service.command.MIInferiorProcess; +import org.eclipse.dd.mi.service.command.MIRunControlEventProcessor; +import org.eclipse.dd.mi.service.command.commands.MIGDBExit; +import org.eclipse.dd.mi.service.command.commands.MIGDBShowExitCode; +import org.eclipse.dd.mi.service.command.commands.MIInterpreterExecConsole; +import org.eclipse.dd.mi.service.command.output.MIGDBShowExitCodeInfo; +import org.eclipse.dd.mi.service.command.output.MIInfo; +import org.eclipse.debug.core.DebugException; +import org.osgi.framework.BundleContext; + +/** + * GDB Debugger control implementation. This implementation extends the + * base MI control implementation to provide the GDB-specific debugger + * features. This includes:
    + * - CLI console support,
    + * - inferior process status tracking.
    + */ +public class GDBControl extends AbstractMIControl { + + /** + * Event indicating that the back end process process has started. + */ + public static class StartedEvent extends AbstractDMEvent { + public StartedEvent(GDBControlDMContext context) { + super(context); + } + } + + + /** + * Event indicating that the back end process has terminated. + */ + public static class ExitedEvent extends AbstractDMEvent { + public ExitedEvent(GDBControlDMContext context) { + super(context); + } + } + + private static int fgInstanceCounter = 0; + private final GDBControlDMContext fControlDmc; + + public enum SessionType { RUN, ATTACH, CORE } + private SessionType fSessionType; + + private boolean fConnected = false; + private boolean fUseInterpreterConsole; + + private MonitorJob fMonitorJob; + private IPath fGdbPath; + private IPath fExecPath; + private Process fProcess; + private int fGDBExitValue; + final private int fGDBLaunchTimeout; + + private CommandCache fCommandCache; + + private MIRunControlEventProcessor fMIEventProcessor; + private CLIEventProcessor fCLICommandProcessor; + private AbstractCLIProcess fCLIProcess; + private MIInferiorProcess fInferiorProcess; + + public GDBControl(DsfSession session, IPath gdbPath, IPath execPath, SessionType type, int gdbLaunchTimeout) { + super(session); + fSessionType = type; + fGdbPath = gdbPath; + fExecPath = execPath; + fGDBLaunchTimeout = gdbLaunchTimeout; + fControlDmc = new GDBControlDMContext(session.getId(), getClass().getName() + ":" + ++fgInstanceCounter); //$NON-NLS-1$ + + } + + @Override + protected BundleContext getBundleContext() { + return GdbPlugin.getBundleContext(); + } + + @Override + public void initialize(final RequestMonitor requestMonitor) { + super.initialize( new RequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleOK() { + doInitialize(requestMonitor); + } + }); + } + + public void doInitialize(final RequestMonitor requestMonitor) { + final Sequence.Step[] initializeSteps = new Sequence.Step[] { + new GDBProcessStep(InitializationShutdownStep.Direction.INITIALIZING), + new MonitorJobStep(InitializationShutdownStep.Direction.INITIALIZING), + new CommandMonitoringStep(InitializationShutdownStep.Direction.INITIALIZING), + new CheckInterpreterConsoleStep(InitializationShutdownStep.Direction.INITIALIZING), + new CommandProcessorsStep(InitializationShutdownStep.Direction.INITIALIZING), + new RegisterStep(InitializationShutdownStep.Direction.INITIALIZING), + }; + + Sequence startupSequence = new Sequence(getExecutor(), requestMonitor) { + @Override public Step[] getSteps() { return initializeSteps; } + }; + getExecutor().execute(startupSequence); + } + + @Override + public void shutdown(final RequestMonitor requestMonitor) { + final Sequence.Step[] shutdownSteps = new Sequence.Step[] { + new RegisterStep(InitializationShutdownStep.Direction.SHUTTING_DOWN), + new CommandProcessorsStep(InitializationShutdownStep.Direction.SHUTTING_DOWN), + new CheckInterpreterConsoleStep(InitializationShutdownStep.Direction.SHUTTING_DOWN), + new CommandMonitoringStep(InitializationShutdownStep.Direction.SHUTTING_DOWN), + new MonitorJobStep(InitializationShutdownStep.Direction.SHUTTING_DOWN), + new GDBProcessStep(InitializationShutdownStep.Direction.SHUTTING_DOWN), + }; + Sequence shutdownSequence = new Sequence(getExecutor(), requestMonitor) { + @Override public Step[] getSteps() { return shutdownSteps; } + }; + getExecutor().execute(shutdownSequence); + + } + + @Override + public MIControlDMContext getControlDMContext() { + return fControlDmc; + } + + /** + * More strongly typed version of {@link #getControlDMContext()}. + */ + public GDBControlDMContext getGDBDMContext() { + return (GDBControlDMContext)getControlDMContext(); + } + + public SessionType getSessionType() { + return fSessionType; + } + + public boolean canInterrupt() { + return fProcess instanceof Spawner; + } + + public void interrupt() { + if (fProcess instanceof Spawner) { + Spawner gdbSpawner = (Spawner) fProcess; + gdbSpawner.interrupt(); + } + } + + public void destroy() { + if (fProcess instanceof Spawner) { + Spawner gdbSpawner = (Spawner) fProcess; + gdbSpawner.destroy(); + } + } + + public void terminate(final RequestMonitor rm) { + // Schedule a runnable to be executed 2 seconds from now. + // If we don't get a response to the quit command, this + // runnable will kill the task. + final Future quitTimeoutFuture = getExecutor().schedule( + new DsfRunnable() { + public void run() { + if (!isGDBExited()) + destroy(); + rm.done(); + } + + @Override + protected boolean isExecutionRequired() { + return false; + } + }, + 2, TimeUnit.SECONDS); + + MIGDBExit cmd = new MIGDBExit(fControlDmc); + queueCommand( + cmd, + new DataRequestMonitor(getExecutor(), rm) { + @Override + public void handleCompleted() { + // Cancel the time out runnable (if it hasn't run yet). + quitTimeoutFuture.cancel(false); + if (!getStatus().isOK() && !isGDBExited()) { + destroy(); + } + rm.done(); + } + } + ); + } + + public boolean isConnected() { + return fInferiorProcess.getState() != MIInferiorProcess.State.TERMINATED && fConnected; + } + + void setConnected(boolean connected) { + fConnected = connected; + } + + public Process getGDBProcess() { + return fProcess; + } + + public AbstractCLIProcess getCLIProcess() { + return fCLIProcess; + } + + public MIInferiorProcess getInferiorProcess() { + return fInferiorProcess; + } + + public boolean isGDBExited() { + return fMonitorJob != null && fMonitorJob.fExited; + } + + public int getGDBExitCode() { + return fGDBExitValue; + } + + public IPath getExecutablePath() { return fExecPath; } + + public void getInferiorExitCode(final DataRequestMonitor rm) { + fCommandCache.execute( + new MIGDBShowExitCode(fControlDmc), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + rm.setData(getData().getCode()); + rm.done(); + } + }); + } + + public void getInferiorProcessId(DataRequestMonitor rm) { + } + + @DsfServiceEventHandler + public void eventDispatched(ExitedEvent e) { + // Handle our "GDB Exited" event and stop processing commands. + stopCommandProcessing(); + } + + /** + * Monitors a system process, waiting for it to terminate, and + * then notifies the associated runtime process. + */ + private class MonitorJob extends Job { + boolean fExited = false; + DsfRunnable fMonitorStarted; + Process fMonProcess; + + @Override + protected IStatus run(IProgressMonitor monitor) { + synchronized(fMonProcess) { + getExecutor().submit(fMonitorStarted); + while (!fExited) { + try { + fMonProcess.waitFor(); + fGDBExitValue = fMonProcess.exitValue(); + } catch (InterruptedException ie) { + // clear interrupted state + Thread.interrupted(); + } finally { + fExited = true; + getSession().dispatchEvent(new ExitedEvent(fControlDmc) {}, getProperties()); + } + } + } + return Status.OK_STATUS; + } + + MonitorJob(Process process, DsfRunnable monitorStarted) { + super("GDB process monitor job."); //$NON-NLS-1$ + fMonProcess = process; + fMonitorStarted = monitorStarted; + setSystem(true); + } + + void kill() { + synchronized(fMonProcess) { + if (!fExited) { + getThread().interrupt(); + } + } + } + } + + public static class InitializationShutdownStep extends Sequence.Step { + public enum Direction { INITIALIZING, SHUTTING_DOWN } + + private Direction fDirection; + InitializationShutdownStep(Direction direction) { fDirection = direction; } + + @Override + final public void execute(RequestMonitor requestMonitor) { + if (fDirection == Direction.INITIALIZING) { + initialize(requestMonitor); + } else { + shutdown(requestMonitor); + } + } + + @Override + final public void rollBack(RequestMonitor requestMonitor) { + if (fDirection == Direction.INITIALIZING) { + shutdown(requestMonitor); + } else { + super.rollBack(requestMonitor); + } + } + + protected void initialize(RequestMonitor requestMonitor) { + requestMonitor.done(); + } + protected void shutdown(RequestMonitor requestMonitor) { + requestMonitor.done(); + } + } + + protected class GDBProcessStep extends InitializationShutdownStep { + GDBProcessStep(Direction direction) { super(direction); } + + @Override + public void initialize(final RequestMonitor requestMonitor) { + class GDBLaunchMonitor { + boolean fLaunched = false; + boolean fTimedOut = false; + } + final GDBLaunchMonitor fGDBLaunchMonitor = new GDBLaunchMonitor(); + + final RequestMonitor gdbLaunchRequestMonitor = new RequestMonitor(getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!fGDBLaunchMonitor.fTimedOut) { + fGDBLaunchMonitor.fLaunched = true; + if (!getStatus().isOK()) { + requestMonitor.setStatus(getStatus()); + } + requestMonitor.done(); + } + } + }; + + final Job startGdbJob = new Job("Start GDB Process Job") { //$NON-NLS-1$ + @Override + protected IStatus run(IProgressMonitor monitor) { + List commandList = new ArrayList(); + + commandList.add(fGdbPath.toOSString()); + if (fExecPath != null) { + commandList.add("--interpreter"); //$NON-NLS-1$ + commandList.add("mi"); //$NON-NLS-1$ + commandList.add(fExecPath.toOSString()); + } + + String[] commandLine = commandList.toArray(new String[commandList.size()]); + + try { + fProcess = ProcessFactory.getFactory().exec(commandLine); + } catch(IOException e) { + String message = MessageFormat.format("Error while launching command", //$NON-NLS-1$ + new Object[]{commandList.toString()}); + gdbLaunchRequestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, message, e)); + gdbLaunchRequestMonitor.done(); + return Status.OK_STATUS; + } + + try { + InputStream stream = fProcess.getInputStream(); + Reader r = new InputStreamReader(stream); + BufferedReader reader = new BufferedReader(r); + String line; + while ((line = reader.readLine()) != null) { + line = line.trim(); + //System.out.println("GDB " + line); + if (line.endsWith("(gdb)")) { //$NON-NLS-1$ + break; + } + } + } catch (IOException e) { + gdbLaunchRequestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Error reading GDB STDOUT", e)); //$NON-NLS-1$ + gdbLaunchRequestMonitor.done(); + return Status.OK_STATUS; + } + + gdbLaunchRequestMonitor.done(); + return Status.OK_STATUS; + } + }; + startGdbJob.schedule(); + + getExecutor().schedule(new Runnable() { + public void run() { + // Only process the event if we have not finished yet (hit the breakpoint). + if (!fGDBLaunchMonitor.fLaunched) { + fGDBLaunchMonitor.fTimedOut = true; + Thread jobThread = startGdbJob.getThread(); + if (jobThread != null) { + jobThread.interrupt(); + } + requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.TARGET_REQUEST_FAILED, "Timed out trying to launch GDB.", null)); //$NON-NLS-1$ + requestMonitor.done(); + } + }}, + fGDBLaunchTimeout, TimeUnit.SECONDS); + + } + + @Override + protected void shutdown(final RequestMonitor requestMonitor) { + new Job("Terminating GDB process.") { //$NON-NLS-1$ + @Override + protected IStatus run(IProgressMonitor monitor) { + if (fProcess == null) + fProcess.destroy(); + + int attempts = 0; + while (attempts < 10) { + try { + // Don't know if we really need the exit value... but what the hell. + fGDBExitValue = fProcess.exitValue(); // throws exception if process not exited + + requestMonitor.done(); + return Status.OK_STATUS; + } catch (IllegalThreadStateException ie) { + } + try { + Thread.sleep(500); + } catch (InterruptedException e) { + } + attempts++; + } + requestMonitor.setStatus(new Status( + IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, "Process terminate failed", null)); //$NON-NLS-1$ + requestMonitor.done(); + return Status.OK_STATUS; + } + }.schedule(); + } + } + + protected class MonitorJobStep extends InitializationShutdownStep { + MonitorJobStep(Direction direction) { super(direction); } + + @Override + public void initialize(final RequestMonitor requestMonitor) { + fMonitorJob = new MonitorJob( + fProcess, + new DsfRunnable() { + public void run() { + requestMonitor.done(); + } + }); + fMonitorJob.schedule(); + } + + @Override + protected void shutdown(RequestMonitor requestMonitor) { + if (!fMonitorJob.fExited) { + fMonitorJob.kill(); + } + requestMonitor.done(); + } + } + + protected class CommandMonitoringStep extends InitializationShutdownStep { + CommandMonitoringStep(Direction direction) { super(direction); } + + @Override + protected void initialize(final RequestMonitor requestMonitor) { + startCommandProcessing(fProcess.getInputStream(), fProcess.getOutputStream()); + requestMonitor.done(); + } + + @Override + protected void shutdown(RequestMonitor requestMonitor) { + stopCommandProcessing(); + requestMonitor.done(); + } + } + + protected class CheckInterpreterConsoleStep extends InitializationShutdownStep { + CheckInterpreterConsoleStep(Direction direction) { super(direction); } + + @Override + public void initialize(final RequestMonitor requestMonitor) { + MIInterpreterExecConsole cmd = new MIInterpreterExecConsole(fControlDmc, "echo"); //$NON-NLS-1$ + GDBControl.this.queueCommand( + cmd, + new DataRequestMonitor(getExecutor(), null) { + @Override + protected void handleCompleted() { + fUseInterpreterConsole = getStatus().isOK(); + requestMonitor.done(); + } + } + ); + } + } + + protected class CommandProcessorsStep extends InitializationShutdownStep { + CommandProcessorsStep(Direction direction) { super(direction); } + + @Override + public void initialize(final RequestMonitor requestMonitor) { + try { + fCLIProcess = new GDBCLIProcess(GDBControl.this, fUseInterpreterConsole); + } + catch(IOException e) { + requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, "Failed to create CLI Process", e)); //$NON-NLS-1$ + requestMonitor.done(); + return; + } + + fInferiorProcess = new GDBInferiorProcess(GDBControl.this, fProcess.getOutputStream()); + fCLICommandProcessor = new CLIEventProcessor(GDBControl.this, fControlDmc, fInferiorProcess); + fMIEventProcessor = new MIRunControlEventProcessor(GDBControl.this, fControlDmc); + fCommandCache = new CommandCache(GDBControl.this); + + requestMonitor.done(); + } + + @Override + protected void shutdown(RequestMonitor requestMonitor) { + fCLICommandProcessor.dispose(); + fMIEventProcessor.dispose(); + fCLIProcess.dispose(); + fInferiorProcess.dispose(); + + requestMonitor.done(); + } + } + + protected class RegisterStep extends InitializationShutdownStep { + RegisterStep(Direction direction) { super(direction); } + @Override + public void initialize(final RequestMonitor requestMonitor) { + getSession().addServiceEventListener(GDBControl.this, null); + register(new String[]{ ICommandControl.class.getName(), AbstractMIControl.class.getName() }, new Hashtable()); + getSession().dispatchEvent(new StartedEvent(getGDBDMContext()), getProperties()); + requestMonitor.done(); + } + + @Override + protected void shutdown(RequestMonitor requestMonitor) { + unregister(); + getSession().removeServiceEventListener(GDBControl.this); + requestMonitor.done(); + } + } +} diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControlDMContext.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControlDMContext.java new file mode 100644 index 00000000000..808536dfd15 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControlDMContext.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.gdb.service.command; + +import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; +import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryDMContext; +import org.eclipse.dd.dsf.debug.service.IModules.ISymbolDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.dd.dsf.debug.service.ISignals.ISignalsDMContext; +import org.eclipse.dd.dsf.debug.service.ISourceLookup.ISourceLookupDMContext; +import org.eclipse.dd.mi.service.command.MIControlDMContext; + +/** + * + */ +public class GDBControlDMContext extends MIControlDMContext + implements IContainerDMContext, ISymbolDMContext, IMemoryDMContext, IBreakpointsTargetDMContext, ISourceLookupDMContext, + ISignalsDMContext +{ + + public GDBControlDMContext(String sessionId, String commandControlId) { + super(sessionId, commandControlId); + } + +} diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBInferiorProcess.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBInferiorProcess.java new file mode 100644 index 00000000000..d4c16ab68c7 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBInferiorProcess.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.gdb.service.command; + +import java.io.OutputStream; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.cdt.utils.pty.PTY; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.ThreadSafeAndProhibitedFromDsfExecutor; +import org.eclipse.dd.gdb.service.command.GDBControl.SessionType; +import org.eclipse.dd.mi.service.command.MIInferiorProcess; + +/** + * + */ +class GDBInferiorProcess extends MIInferiorProcess { + + + public GDBInferiorProcess(GDBControl commandControl, PTY p) { + super(commandControl, p); + } + + public GDBInferiorProcess(GDBControl commandControl, OutputStream gdbOutputStream) { + super(commandControl, gdbOutputStream); + } + + @Override + @ThreadSafeAndProhibitedFromDsfExecutor("getSession#getExecutor") + public void destroy() { + try { + getSession().getExecutor().submit(new DsfRunnable() { + public void run() { + if (isDisposed() || !getSession().isActive()) return; + GDBControl gdb = (GDBControl)getCommandControl(); + if (gdb == null) return; + + // An inferior will be destroy():interrupt and kill if + // - For attach session: + // the inferior was not disconnected yet (no need to try + // to kill a disconnected program). + // - For Program session: + // if the inferior was not terminated. + // - For PostMortem(Core): send event + // else noop + if ((gdb.getSessionType() == SessionType.ATTACH && gdb.isConnected()) || + (gdb.getSessionType() == SessionType.RUN && getState() != State.TERMINATED)) + { + // Try to interrupt the inferior, first. + if (getState() == State.RUNNING) { + gdb.interrupt(); + } + } + } + }).get(); + } catch (RejectedExecutionException e) { + } catch (InterruptedException e) { + } catch (ExecutionException e) { + } finally { + super.destroy(); + } + } +} From dd1daa7a85c169829aae2e61320ccbd48546238f Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 13 Feb 2008 20:34:29 +0000 Subject: [PATCH 241/834] [179102] Re-aligned plugin and package names to confirm with Eclipse policy. --- plugins/org.eclipse.dd.gdb.ui/.classpath | 7 + plugins/org.eclipse.dd.gdb.ui/.project | 28 + .../.settings/org.eclipse.jdt.core.prefs | 65 + .../META-INF/MANIFEST.MF | 21 + plugins/org.eclipse.dd.gdb.ui/about.html | 24 + .../org.eclipse.dd.gdb.ui/build.properties | 8 + .../icons/full/obj16/c_app.gif | Bin 0 -> 1042 bytes plugins/org.eclipse.dd.gdb.ui/plugin.xml | 54 + .../dd/gdb/internal/ui/GdbAdapterFactory.java | 213 +++ .../dd/gdb/internal/ui/GdbUIPlugin.java | 59 + .../ui/actions/DsfTerminateCommand.java | 96 + .../CBreakpointGdbThreadFilterPage.java | 84 + .../ui/breakpoints/GdbThreadFilterEditor.java | 537 ++++++ .../DsfMIlRunLaunchConfigurationTabGroup.java | 36 + .../ui/viewmodel/GdbViewModelAdapter.java | 60 + .../ui/viewmodel/launch/ContainerVMNode.java | 146 ++ .../ui/viewmodel/launch/LaunchVMProvider.java | 129 ++ .../ui/viewmodel/launch/ThreadVMNode.java | 308 +++ plugins/org.eclipse.dd.mi/.classpath | 7 + plugins/org.eclipse.dd.mi/.options | 1 + plugins/org.eclipse.dd.mi/.project | 28 + .../.settings/org.eclipse.jdt.core.prefs | 65 + .../.settings/org.eclipse.jdt.ui.prefs | 3 + .../org.eclipse.dd.mi/META-INF/MANIFEST.MF | 24 + plugins/org.eclipse.dd.mi/about.html | 24 + plugins/org.eclipse.dd.mi/build.properties | 7 + plugins/org.eclipse.dd.mi/plugin.properties | 13 + plugins/org.eclipse.dd.mi/plugin.xml | 4 + .../org/eclipse/dd/mi/internal/MIPlugin.java | 94 + .../eclipse/dd/mi/service/CSourceLookup.java | 140 ++ .../dd/mi/service/ExpressionService.java | 898 +++++++++ .../dd/mi/service/IMIExecutionDMContext.java | 27 + .../dd/mi/service/MIBreakpointDMData.java | 267 +++ .../eclipse/dd/mi/service/MIBreakpoints.java | 956 ++++++++++ .../service/MIBreakpointsActionManager.java | 185 ++ .../dd/mi/service/MIBreakpointsManager.java | 1484 +++++++++++++++ .../org/eclipse/dd/mi/service/MIFormat.java | 109 ++ .../org/eclipse/dd/mi/service/MIMemory.java | 895 +++++++++ .../org/eclipse/dd/mi/service/MIModules.java | 217 +++ .../eclipse/dd/mi/service/MIRegisters.java | 583 ++++++ .../eclipse/dd/mi/service/MIRunControl.java | 668 +++++++ .../org/eclipse/dd/mi/service/MIStack.java | 559 ++++++ .../dd/mi/service/MIVariableManager.java | 1648 +++++++++++++++++ .../service/command/AbstractCLIProcess.java | 320 ++++ .../mi/service/command/AbstractMIControl.java | 736 ++++++++ .../mi/service/command/CLIEventProcessor.java | 353 ++++ .../service/command/MIControlDMContext.java | 62 + .../mi/service/command/MIInferiorProcess.java | 396 ++++ .../command/MIRunControlEventProcessor.java | 225 +++ .../service/command/commands/CLICommand.java | 26 + .../command/commands/CLIExecAbort.java | 30 + .../commands/CLIInfoSharedLibrary.java | 47 + .../command/commands/CLIInfoThreads.java | 45 + .../command/commands/ExprMetaCommand.java | 61 + .../commands/ExprMetaGetAttributes.java | 21 + .../commands/ExprMetaGetChildCount.java | 21 + .../command/commands/ExprMetaGetChildren.java | 21 + .../command/commands/ExprMetaGetValue.java | 21 + .../command/commands/ExprMetaGetVar.java | 21 + .../command/commands/MIBreakAfter.java | 32 + .../command/commands/MIBreakCondition.java | 36 + .../command/commands/MIBreakDelete.java | 42 + .../command/commands/MIBreakDisable.java | 41 + .../command/commands/MIBreakEnable.java | 40 + .../command/commands/MIBreakInsert.java | 120 ++ .../service/command/commands/MIBreakList.java | 62 + .../command/commands/MIBreakWatch.java | 55 + .../service/command/commands/MICommand.java | 256 +++ .../commands/MIDataEvaluateExpression.java | 53 + .../commands/MIDataListRegisterNames.java | 52 + .../commands/MIDataListRegisterValues.java | 145 ++ .../command/commands/MIDataReadMemory.java | 150 ++ .../command/commands/MIDataWriteMemory.java | 118 ++ .../command/commands/MIExecContinue.java | 31 + .../command/commands/MIExecFinish.java | 37 + .../command/commands/MIExecInterrupt.java | 36 + .../service/command/commands/MIExecNext.java | 36 + .../commands/MIExecNextInstruction.java | 37 + .../command/commands/MIExecReturn.java | 42 + .../service/command/commands/MIExecRun.java | 37 + .../service/command/commands/MIExecStep.java | 38 + .../commands/MIExecStepInstruction.java | 38 + .../service/command/commands/MIExecUntil.java | 39 + .../service/command/commands/MIGDBExit.java | 30 + .../command/commands/MIGDBShowExitCode.java | 37 + .../command/commands/MIInterpreterExec.java | 44 + .../commands/MIInterpreterExecConsole.java | 32 + .../command/commands/MIStackInfoDepth.java | 39 + .../commands/MIStackListArguments.java | 72 + .../command/commands/MIStackListFrames.java | 69 + .../command/commands/MIStackListLocals.java | 45 + .../command/commands/MIStackSelectFrame.java | 33 + .../command/commands/MIThreadListIds.java | 37 + .../command/commands/MIThreadSelect.java | 35 + .../service/command/commands/MIVarAssign.java | 36 + .../service/command/commands/MIVarCreate.java | 68 + .../service/command/commands/MIVarDelete.java | 38 + .../commands/MIVarEvaluateExpression.java | 41 + .../command/commands/MIVarInfoExpression.java | 41 + .../commands/MIVarInfoNumChildren.java | 37 + .../commands/MIVarInfoPathExpression.java | 42 + .../command/commands/MIVarInfoType.java | 39 + .../command/commands/MIVarListChildren.java | 40 + .../command/commands/MIVarSetFormat.java | 62 + .../command/commands/MIVarShowAttributes.java | 41 + .../command/commands/MIVarShowFormat.java | 38 + .../service/command/commands/MIVarUpdate.java | 42 + .../service/command/commands/RawCommand.java | 36 + .../events/MIBreakpointChangedEvent.java | 40 + .../command/events/MIBreakpointHitEvent.java | 65 + .../command/events/MIDetachedEvent.java | 34 + .../service/command/events/MIErrorEvent.java | 101 + .../dd/mi/service/command/events/MIEvent.java | 57 + .../events/MIFunctionFinishedEvent.java | 83 + .../command/events/MIGDBExitEvent.java | 28 + .../command/events/MIInferiorExitEvent.java | 64 + .../events/MIInferiorSignalExitEvent.java | 68 + .../events/MILocationReachedEvent.java | 38 + .../command/events/MIRunningEvent.java | 59 + .../command/events/MISharedLibEvent.java | 39 + .../command/events/MISignalChangedEvent.java | 40 + .../service/command/events/MISignalEvent.java | 75 + .../command/events/MISteppingRangeEvent.java | 39 + .../command/events/MIStoppedEvent.java | 73 + .../command/events/MIThreadCreatedEvent.java | 40 + .../command/events/MIThreadExitEvent.java | 40 + .../events/MIWatchpointScopeEvent.java | 66 + .../events/MIWatchpointTriggerEvent.java | 122 ++ .../output/CLIInfoSharedLibraryInfo.java | 105 ++ .../command/output/CLIInfoThreadsInfo.java | 95 + .../output/ExprMetaGetAttributesInfo.java | 29 + .../output/ExprMetaGetChildCountInfo.java | 29 + .../output/ExprMetaGetChildrenInfo.java | 30 + .../command/output/ExprMetaGetValueInfo.java | 29 + .../command/output/ExprMetaGetVarInfo.java | 38 + .../dd/mi/service/command/output/MIArg.java | 132 ++ .../service/command/output/MIAsyncRecord.java | 76 + .../command/output/MIBreakInsertInfo.java | 80 + .../command/output/MIBreakListInfo.java | 86 + .../service/command/output/MIBreakpoint.java | 294 +++ .../command/output/MIConsoleStreamOutput.java | 19 + .../dd/mi/service/command/output/MIConst.java | 124 ++ .../output/MIDataEvaluateExpressionInfo.java | 46 + .../output/MIDataListRegisterNamesInfo.java | 79 + .../output/MIDataListRegisterValuesInfo.java | 104 ++ .../command/output/MIDataReadMemoryInfo.java | 248 +++ .../command/output/MIDataWriteMemoryInfo.java | 35 + .../command/output/MIExecAsyncOutput.java | 19 + .../dd/mi/service/command/output/MIFrame.java | 136 ++ .../command/output/MIGDBShowExitCodeInfo.java | 38 + .../dd/mi/service/command/output/MIInfo.java | 100 + .../dd/mi/service/command/output/MIList.java | 61 + .../command/output/MILogStreamOutput.java | 20 + .../command/output/MINotifyAsyncOutput.java | 20 + .../service/command/output/MIOOBRecord.java | 19 + .../mi/service/command/output/MIOutput.java | 58 + .../mi/service/command/output/MIParser.java | 559 ++++++ .../command/output/MIRegisterValue.java | 98 + .../mi/service/command/output/MIResult.java | 53 + .../command/output/MIResultRecord.java | 66 + .../command/output/MIStackInfoDepthInfo.java | 52 + .../output/MIStackListArgumentsInfo.java | 79 + .../command/output/MIStackListFramesInfo.java | 78 + .../command/output/MIStackListLocalsInfo.java | 55 + .../command/output/MIStatusAsyncOutput.java | 21 + .../command/output/MIStreamRecord.java | 41 + .../command/output/MITargetStreamOutput.java | 21 + .../command/output/MIThreadListIdsInfo.java | 71 + .../dd/mi/service/command/output/MITuple.java | 60 + .../dd/mi/service/command/output/MIValue.java | 19 + .../dd/mi/service/command/output/MIVar.java | 79 + .../command/output/MIVarAssignInfo.java | 45 + .../service/command/output/MIVarChange.java | 54 + .../command/output/MIVarCreateInfo.java | 90 + .../command/output/MIVarDeleteInfo.java | 50 + .../output/MIVarEvaluateExpressionInfo.java | 44 + .../output/MIVarInfoExpressionInfo.java | 53 + .../output/MIVarInfoNumChildrenInfo.java | 50 + .../output/MIVarInfoPathExpressionInfo.java | 47 + .../command/output/MIVarInfoTypeInfo.java | 44 + .../command/output/MIVarListChildrenInfo.java | 84 + .../command/output/MIVarSetFormatInfo.java | 43 + .../output/MIVarShowAttributesInfo.java | 47 + .../command/output/MIVarShowFormatInfo.java | 57 + .../command/output/MIVarUpdateInfo.java | 103 ++ 185 files changed, 21317 insertions(+) create mode 100644 plugins/org.eclipse.dd.gdb.ui/.classpath create mode 100644 plugins/org.eclipse.dd.gdb.ui/.project create mode 100644 plugins/org.eclipse.dd.gdb.ui/.settings/org.eclipse.jdt.core.prefs create mode 100644 plugins/org.eclipse.dd.gdb.ui/META-INF/MANIFEST.MF create mode 100644 plugins/org.eclipse.dd.gdb.ui/about.html create mode 100644 plugins/org.eclipse.dd.gdb.ui/build.properties create mode 100644 plugins/org.eclipse.dd.gdb.ui/icons/full/obj16/c_app.gif create mode 100644 plugins/org.eclipse.dd.gdb.ui/plugin.xml create mode 100644 plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java create mode 100644 plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbUIPlugin.java create mode 100644 plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/actions/DsfTerminateCommand.java create mode 100644 plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/CBreakpointGdbThreadFilterPage.java create mode 100644 plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/GdbThreadFilterEditor.java create mode 100644 plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/DsfMIlRunLaunchConfigurationTabGroup.java create mode 100644 plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java create mode 100644 plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ContainerVMNode.java create mode 100644 plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/LaunchVMProvider.java create mode 100644 plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ThreadVMNode.java create mode 100644 plugins/org.eclipse.dd.mi/.classpath create mode 100644 plugins/org.eclipse.dd.mi/.options create mode 100644 plugins/org.eclipse.dd.mi/.project create mode 100644 plugins/org.eclipse.dd.mi/.settings/org.eclipse.jdt.core.prefs create mode 100644 plugins/org.eclipse.dd.mi/.settings/org.eclipse.jdt.ui.prefs create mode 100644 plugins/org.eclipse.dd.mi/META-INF/MANIFEST.MF create mode 100644 plugins/org.eclipse.dd.mi/about.html create mode 100644 plugins/org.eclipse.dd.mi/build.properties create mode 100644 plugins/org.eclipse.dd.mi/plugin.properties create mode 100644 plugins/org.eclipse.dd.mi/plugin.xml create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/internal/MIPlugin.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/CSourceLookup.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/ExpressionService.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/IMIExecutionDMContext.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointDMData.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpoints.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointsActionManager.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointsManager.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIFormat.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIMemory.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIModules.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRegisters.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIStack.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractCLIProcess.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/CLIEventProcessor.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIControlDMContext.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIInferiorProcess.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIRunControlEventProcessor.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLICommand.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLIExecAbort.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLIInfoSharedLibrary.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLIInfoThreads.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/ExprMetaCommand.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/ExprMetaGetAttributes.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/ExprMetaGetChildCount.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/ExprMetaGetChildren.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/ExprMetaGetValue.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/ExprMetaGetVar.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIBreakAfter.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIBreakCondition.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIBreakDelete.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIBreakDisable.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIBreakEnable.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIBreakInsert.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIBreakList.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIBreakWatch.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MICommand.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIDataEvaluateExpression.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIDataListRegisterNames.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIDataListRegisterValues.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIDataReadMemory.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIDataWriteMemory.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecContinue.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecFinish.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecInterrupt.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecNext.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecNextInstruction.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecReturn.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecRun.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecStep.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecStepInstruction.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecUntil.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIGDBExit.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIGDBShowExitCode.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIInterpreterExec.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIInterpreterExecConsole.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIStackInfoDepth.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIStackListArguments.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIStackListFrames.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIStackListLocals.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIStackSelectFrame.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIThreadListIds.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIThreadSelect.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarAssign.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarCreate.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarDelete.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarEvaluateExpression.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarInfoExpression.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarInfoNumChildren.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarInfoPathExpression.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarInfoType.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarListChildren.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarSetFormat.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarShowAttributes.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarShowFormat.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarUpdate.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/RawCommand.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIBreakpointChangedEvent.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIBreakpointHitEvent.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIDetachedEvent.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIErrorEvent.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIEvent.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIFunctionFinishedEvent.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIGDBExitEvent.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIInferiorExitEvent.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIInferiorSignalExitEvent.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MILocationReachedEvent.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIRunningEvent.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MISharedLibEvent.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MISignalChangedEvent.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MISignalEvent.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MISteppingRangeEvent.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIStoppedEvent.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIThreadCreatedEvent.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIThreadExitEvent.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIWatchpointScopeEvent.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIWatchpointTriggerEvent.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/CLIInfoSharedLibraryInfo.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/CLIInfoThreadsInfo.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/ExprMetaGetAttributesInfo.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/ExprMetaGetChildCountInfo.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/ExprMetaGetChildrenInfo.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/ExprMetaGetValueInfo.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/ExprMetaGetVarInfo.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIArg.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIAsyncRecord.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIBreakInsertInfo.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIBreakListInfo.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIBreakpoint.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIConsoleStreamOutput.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIConst.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIDataEvaluateExpressionInfo.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIDataListRegisterNamesInfo.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIDataListRegisterValuesInfo.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIDataReadMemoryInfo.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIDataWriteMemoryInfo.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIExecAsyncOutput.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIFrame.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIGDBShowExitCodeInfo.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIInfo.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIList.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MILogStreamOutput.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MINotifyAsyncOutput.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIOOBRecord.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIOutput.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIParser.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIRegisterValue.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIResult.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIResultRecord.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIStackInfoDepthInfo.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIStackListArgumentsInfo.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIStackListFramesInfo.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIStackListLocalsInfo.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIStatusAsyncOutput.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIStreamRecord.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MITargetStreamOutput.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIThreadListIdsInfo.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MITuple.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIValue.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVar.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarAssignInfo.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarChange.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarCreateInfo.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarDeleteInfo.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarEvaluateExpressionInfo.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarInfoExpressionInfo.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarInfoNumChildrenInfo.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarInfoPathExpressionInfo.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarInfoTypeInfo.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarListChildrenInfo.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarSetFormatInfo.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarShowAttributesInfo.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarShowFormatInfo.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarUpdateInfo.java diff --git a/plugins/org.eclipse.dd.gdb.ui/.classpath b/plugins/org.eclipse.dd.gdb.ui/.classpath new file mode 100644 index 00000000000..304e86186aa --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.ui/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/plugins/org.eclipse.dd.gdb.ui/.project b/plugins/org.eclipse.dd.gdb.ui/.project new file mode 100644 index 00000000000..82e21a8083e --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.ui/.project @@ -0,0 +1,28 @@ + + + org.eclipse.dd.gdb.ui + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/plugins/org.eclipse.dd.gdb.ui/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.dd.gdb.ui/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000000..ce05db9f058 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.ui/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,65 @@ +#Thu Jun 07 11:08:08 PDT 2007 +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.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=warning +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning +org.eclipse.jdt.core.compiler.problem.nullReference=ignore +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning +org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=error +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/plugins/org.eclipse.dd.gdb.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.gdb.ui/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..004856ef92b --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.ui/META-INF/MANIFEST.MF @@ -0,0 +1,21 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Debug Services Framework GDB UI Plug-in +Bundle-Vendor: Eclipse.org +Bundle-SymbolicName: org.eclipse.dd.gdb.ui;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: org.eclipse.dd.gdb.internal.ui.GdbUIPlugin +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.dd.dsf.debug.ui, + org.eclipse.dd.dsf, + org.eclipse.dd.dsf.ui, + org.eclipse.debug.ui, + org.eclipse.cdt.launch, + org.eclipse.cdt.debug.core, + org.eclipse.dd.mi, + org.eclipse.dd.gdb, + org.eclipse.dd.dsf.debug, + org.eclipse.cdt.debug.ui +Bundle-ActivationPolicy: lazy +Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/plugins/org.eclipse.dd.gdb.ui/about.html b/plugins/org.eclipse.dd.gdb.ui/about.html new file mode 100644 index 00000000000..cb740ae8bc8 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.ui/about.html @@ -0,0 +1,24 @@ + + + + +About +

    About This Content

    + +

    June 5, 2007

    +

    License

    + +

    The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at http://www.eclipse.org/legal/epl-v10.html. +For purposes of the EPL, "Program" will mean the Content.

    + +

    If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at http://www.eclipse.org.

    + + \ No newline at end of file diff --git a/plugins/org.eclipse.dd.gdb.ui/build.properties b/plugins/org.eclipse.dd.gdb.ui/build.properties new file mode 100644 index 00000000000..61543eefe00 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.ui/build.properties @@ -0,0 +1,8 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml,\ + about.html,\ + icons/ + \ No newline at end of file diff --git a/plugins/org.eclipse.dd.gdb.ui/icons/full/obj16/c_app.gif b/plugins/org.eclipse.dd.gdb.ui/icons/full/obj16/c_app.gif new file mode 100644 index 0000000000000000000000000000000000000000..805a1d0ab8b0dc4b86212fc35178db4d5af5a274 GIT binary patch literal 1042 zcmZ?wbhEHb6krfwcs_+eBWape%5?qo83ySyUCLIum9KWISnXN4#}3>Djrk z%_5_3Pe%WqWu4|Z6Zd6L+Pk{jtZ>Tu{K@kH=C2`df zhPA8MHmzk?v(zSI^TVy1g>$z)%HQ^A&koKl8@zU}EZMzN``}*oid|2(ZLB(anBmAl zsg?uJ_U&joa>Vw~{=~DVWF{PYari*P*)t}W&dHoVt9S04&atCqmoJK4zNmEZjQ{!b zLG#YM+Ij5w?&Bvmo_=xXmhS3HZ|~f;xOv<8&TZ?fSIQpVm%Vs9|IuUdhmU2p-+2Gv zLGtap8(zOPIDGHp<0n;b-Wt7mYxDGJ)zcS6Z$6m6eiQNWv;LV!pI^SIy#DaztJj_H zKZU*fnEdMX#LG{=eEq5a=408bSIb|&?|t*3_1Vj#@4uA3{ZjYsm+!a##;@LO`1RNB z(Yw!&KRmno`Tz3|pI(0W{Qm2SS0BE-{P_9Nmp_lb{(bS~`=f9F9)J7y|K1sz?nT;i3$qHU+=kB0C!VlFaEfHjx zXCWxS!QXGyAM)q-19l;mHO(xHmy+9Er`wzTEBtWzgy1!8*QS)h$4Wjj`kqEVJg0E1 zo~h*%Rj^R$xL1#q*dG}umeeCGI+@1~oGgBFY*M|@9|fu24gq;1ivt-8i_?$pXJ6zg v{^~RH$vLua-+ug + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java new file mode 100644 index 00000000000..c690ec99f9a --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java @@ -0,0 +1,213 @@ +/******************************************************************************* + * 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.gdb.internal.ui; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.runtime.IAdapterFactory; +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.dd.dsf.debug.ui.actions.DsfResumeCommand; +import org.eclipse.dd.dsf.debug.ui.actions.DsfStepIntoCommand; +import org.eclipse.dd.dsf.debug.ui.actions.DsfStepOverCommand; +import org.eclipse.dd.dsf.debug.ui.actions.DsfStepReturnCommand; +import org.eclipse.dd.dsf.debug.ui.actions.DsfSuspendCommand; +import org.eclipse.dd.dsf.debug.ui.contexts.DsfSuspendTrigger; +import org.eclipse.dd.dsf.debug.ui.sourcelookup.MISourceDisplayAdapter; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.gdb.internal.ui.actions.DsfTerminateCommand; +import org.eclipse.dd.gdb.internal.ui.viewmodel.GdbViewModelAdapter; +import org.eclipse.dd.gdb.launching.GdbLaunch; +import org.eclipse.dd.gdb.launching.GdbLaunchDelegate; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.ILaunchesListener2; +import org.eclipse.debug.core.commands.IResumeHandler; +import org.eclipse.debug.core.commands.IStepIntoHandler; +import org.eclipse.debug.core.commands.IStepOverHandler; +import org.eclipse.debug.core.commands.IStepReturnHandler; +import org.eclipse.debug.core.commands.ISuspendHandler; +import org.eclipse.debug.core.commands.ITerminateHandler; +import org.eclipse.debug.core.model.IDebugModelProvider; +import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory; +import org.eclipse.debug.ui.contexts.ISuspendTrigger; +import org.eclipse.debug.ui.sourcelookup.ISourceDisplay; + +/** + * This implementation of platform adapter factory only retrieves the adapters + * for the launch object. But it also manages the creation and descruction + * of the session-based adapters which are returned by the + * IDMContext.getAdapter() methods. + */ +@ThreadSafe +@SuppressWarnings({"restriction"}) +public class GdbAdapterFactory + implements IAdapterFactory, ILaunchesListener2 +{ + @Immutable + class SessionAdapterSet { + final GdbLaunch fLaunch; + final GdbViewModelAdapter fViewModelAdapter; + final MISourceDisplayAdapter fSourceDisplayAdapter; + final DsfStepIntoCommand fStepIntoCommand; + final DsfStepOverCommand fStepOverCommand; + final DsfStepReturnCommand fStepReturnCommand; + final DsfSuspendCommand fSuspendCommand; + final DsfResumeCommand fResumeCommand; + final DsfTerminateCommand fTerminateCommand; + final IDebugModelProvider fDebugModelProvider; + final DsfSuspendTrigger fSuspendTrigger; + + SessionAdapterSet(GdbLaunch launch) { + fLaunch = launch; + DsfSession session = launch.getSession(); + + fViewModelAdapter = new GdbViewModelAdapter(session); + + if (launch.getSourceLocator() instanceof ISourceLookupDirector) { + fSourceDisplayAdapter = new MISourceDisplayAdapter(session, (ISourceLookupDirector)launch.getSourceLocator()); + } else { + fSourceDisplayAdapter = null; + } + session.registerModelAdapter(ISourceDisplay.class, fSourceDisplayAdapter); + + fStepIntoCommand = new DsfStepIntoCommand(session); + fStepOverCommand = new DsfStepOverCommand(session); + fStepReturnCommand = new DsfStepReturnCommand(session); + fSuspendCommand = new DsfSuspendCommand(session); + fResumeCommand = new DsfResumeCommand(session); + fTerminateCommand = new DsfTerminateCommand(session); + fSuspendTrigger = new DsfSuspendTrigger(session, fLaunch); + session.registerModelAdapter(IStepIntoHandler.class, fStepIntoCommand); + session.registerModelAdapter(IStepOverHandler.class, fStepOverCommand); + session.registerModelAdapter(IStepReturnHandler.class, fStepReturnCommand); + session.registerModelAdapter(ISuspendHandler.class, fSuspendCommand); + session.registerModelAdapter(IResumeHandler.class, fResumeCommand); + session.registerModelAdapter(ITerminateHandler.class, fTerminateCommand); + + fDebugModelProvider = new IDebugModelProvider() { + // @see org.eclipse.debug.core.model.IDebugModelProvider#getModelIdentifiers() + public String[] getModelIdentifiers() { + return new String[] { GdbLaunchDelegate.GDB_DEBUG_MODEL_ID }; + } + }; + session.registerModelAdapter(IDebugModelProvider.class, fDebugModelProvider); + + /* + * Registering the launch as an adapter, ensures that this launch, + * and debug model ID will be associated with all DMContexts from this + * session. + */ + session.registerModelAdapter(ILaunch.class, fLaunch); + } + + void dispose() { + DsfSession session = fLaunch.getSession(); + + fViewModelAdapter.dispose(); + + session.unregisterModelAdapter(ISourceDisplay.class); + if (fSourceDisplayAdapter != null) fSourceDisplayAdapter.dispose(); + + session.unregisterModelAdapter(IStepIntoHandler.class); + session.unregisterModelAdapter(IStepOverHandler.class); + session.unregisterModelAdapter(IStepReturnHandler.class); + session.unregisterModelAdapter(ISuspendHandler.class); + session.unregisterModelAdapter(IResumeHandler.class); + session.unregisterModelAdapter(ITerminateHandler.class); + fStepIntoCommand.dispose(); + fStepOverCommand.dispose(); + fStepReturnCommand.dispose(); + fSuspendCommand.dispose(); + fResumeCommand.dispose(); + fTerminateCommand.dispose(); + fSuspendTrigger.dispose(); + } + + + } + + private Map fLaunchAdapterSets = + Collections.synchronizedMap(new HashMap()); + + public GdbAdapterFactory() { + DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this); + } + + /** + * This method only actually returns adapters for the launch object. + */ + @SuppressWarnings("unchecked") + public Object getAdapter(Object adaptableObject, Class adapterType) { + if (!(adaptableObject instanceof GdbLaunch)) return null; + + GdbLaunch launch = (GdbLaunch)adaptableObject; + + // Find the correct set of adapters based on the launch session-ID. If not found + // it means that we have a new launch and new session, and we have to create a + // new set of adapters. + DsfSession session = launch.getSession(); + if (session == null) return null; + + SessionAdapterSet adapterSet; + synchronized(fLaunchAdapterSets) { + adapterSet = fLaunchAdapterSets.get(launch); + if (adapterSet == null) { + adapterSet = new SessionAdapterSet(launch); + fLaunchAdapterSets.put(launch, adapterSet); + } + } + + // Returns the adapter type for the launch object. + if (adapterType.equals(IElementContentProvider.class)) return adapterSet.fViewModelAdapter; + else if (adapterType.equals(IModelProxyFactory.class)) return adapterSet.fViewModelAdapter; + else if (adapterType.equals(IColumnPresentationFactory.class)) return adapterSet.fViewModelAdapter; + else if (adapterType.equals(ISuspendTrigger.class)) return adapterSet.fSuspendTrigger; + else return null; + } + + @SuppressWarnings("unchecked") + public Class[] getAdapterList() { + return new Class[] { + IElementContentProvider.class, IModelProxyFactory.class, ISuspendTrigger.class, + IColumnPresentationFactory.class + }; + } + + public void launchesRemoved(ILaunch[] launches) { + // Dispose the set of adapters for a launch only after the launch is + // removed. + for (ILaunch launch : launches) { + if (launch instanceof GdbLaunch) { + synchronized(fLaunchAdapterSets) { + if ( fLaunchAdapterSets.containsKey(launch) ) { + fLaunchAdapterSets.remove(launch).dispose(); + } + } + } + } + } + + public void launchesTerminated(ILaunch[] launches) { + } + + public void launchesAdded(ILaunch[] launches) { + } + + public void launchesChanged(ILaunch[] launches) { + } + +} diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbUIPlugin.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbUIPlugin.java new file mode 100644 index 00000000000..f23897223f0 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbUIPlugin.java @@ -0,0 +1,59 @@ +package org.eclipse.dd.gdb.internal.ui; + +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class GdbUIPlugin extends AbstractUIPlugin { + + // The plug-in ID + public static final String PLUGIN_ID = "org.eclipse.dd.gdb.ui"; //$NON-NLS-1$ + + // The shared instance + private static GdbUIPlugin plugin; + + private static BundleContext fgBundleContext; + + /** + * The constructor + */ + public GdbUIPlugin() { + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) + */ + @Override + public void start(BundleContext context) throws Exception { + fgBundleContext = context; + super.start(context); + plugin = this; + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) + */ + @Override + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + fgBundleContext = null; + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static GdbUIPlugin getDefault() { + return plugin; + } + + public static BundleContext getBundleContext() { + return fgBundleContext; + } +} diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/actions/DsfTerminateCommand.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/actions/DsfTerminateCommand.java new file mode 100644 index 00000000000..2a9a1f99c0d --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/actions/DsfTerminateCommand.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * 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.gdb.internal.ui.actions; + +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.dsf.debug.ui.actions.DsfCommandRunnable; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext; +import org.eclipse.dd.gdb.internal.ui.GdbUIPlugin; +import org.eclipse.dd.gdb.service.command.GDBControl; +import org.eclipse.debug.core.commands.IDebugCommandRequest; +import org.eclipse.debug.core.commands.IEnabledStateRequest; +import org.eclipse.debug.core.commands.ITerminateHandler; + +public class DsfTerminateCommand implements ITerminateHandler { + private final DsfExecutor fExecutor; + private final DsfServicesTracker fTracker; + + public DsfTerminateCommand(DsfSession session) { + fExecutor = session.getExecutor(); + fTracker = new DsfServicesTracker(GdbUIPlugin.getBundleContext(), session.getId()); + } + + public void dispose() { + fTracker.dispose(); + } + + // Run control may not be avilable after a connection is terminated and shut down. + public void canExecute(final IEnabledStateRequest request) { + if (request.getElements().length != 1 || + !(request.getElements()[0] instanceof IDMVMContext) ) + { + request.setEnabled(false); + request.done(); + return; + } + + // Javac doesn't like the cast to "(AbstractDMVMLayoutNode.DMVMContext)" need to use the + // construct below and suppress warnings. + IDMVMContext vmc = (IDMVMContext)request.getElements()[0]; + final IExecutionDMContext dmc = DMContexts.getAncestorOfType(vmc.getDMContext(), IExecutionDMContext.class); + if (dmc == null) { + request.setEnabled(false); + request.done(); + return; + } + + fExecutor.execute( + new DsfRunnable() { + public void run() { + // Get the processes service and the exec context. + GDBControl gdbControl = fTracker.getService(GDBControl.class); + if (gdbControl == null || dmc == null) { + // Context or service already invalid. + request.setEnabled(false); + request.done(); + } else { + // Check the teriminate. + request.setEnabled(!gdbControl.isGDBExited()); + request.done(); + } + } + }); + } + + public boolean execute(final IDebugCommandRequest request) { + if (request.getElements().length != 1) { + request.done(); + return false; + } + + fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) { + @Override public void doExecute() { + GDBControl gdbControl = fTracker.getService(GDBControl.class); + if (gdbControl != null) { + gdbControl.terminate(new RequestMonitor(fExecutor, null)); + } + } + }); + return false; + } + +} diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/CBreakpointGdbThreadFilterPage.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/CBreakpointGdbThreadFilterPage.java new file mode 100644 index 00000000000..bec7fdadec9 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/CBreakpointGdbThreadFilterPage.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2004, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.gdb.internal.ui.breakpoints; + +import org.eclipse.cdt.debug.core.model.ICBreakpoint; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.dd.gdb.breakpoints.CBreakpointGdbThreadsFilterExtension; +import org.eclipse.dd.gdb.launching.GdbLaunchDelegate; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.dialogs.PropertyPage; + +public class CBreakpointGdbThreadFilterPage extends PropertyPage { + + private GdbThreadFilterEditor fThreadFilterEditor; + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite) + */ + @Override + protected Control createContents( Composite parent ) { + noDefaultAndApplyButton(); + Composite mainComposite = new Composite( parent, SWT.NONE ); + mainComposite.setFont( parent.getFont() ); + mainComposite.setLayout( new GridLayout() ); + mainComposite.setLayoutData( new GridData( GridData.FILL_BOTH ) ); + createThreadFilterEditor( mainComposite ); + setValid( true ); + return mainComposite; + } + + public ICBreakpoint getBreakpoint() { + return (ICBreakpoint)getElement().getAdapter(ICBreakpoint.class); + } + + public CBreakpointGdbThreadsFilterExtension getFilterExtension() { + ICBreakpoint bp = getBreakpoint(); + if (bp != null) { + try { + CBreakpointGdbThreadsFilterExtension filter = + (CBreakpointGdbThreadsFilterExtension) bp.getExtension( + GdbLaunchDelegate.GDB_DEBUG_MODEL_ID, CBreakpointGdbThreadsFilterExtension.class); + filter.initialize(bp); + return filter; + } catch (CoreException e) {} + } + return null; + } + + protected void createThreadFilterEditor( Composite parent ) { + fThreadFilterEditor = new GdbThreadFilterEditor( parent, this ); + } + + protected GdbThreadFilterEditor getThreadFilterEditor() { + return fThreadFilterEditor; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferencePage#performOk() + */ + @Override + public boolean performOk() { + doStore(); + return super.performOk(); + } + + /** + * Stores the values configured in this page. + */ + protected void doStore() { + fThreadFilterEditor.doStore(); + } +} diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/GdbThreadFilterEditor.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/GdbThreadFilterEditor.java new file mode 100644 index 00000000000..eb7017ee052 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/GdbThreadFilterEditor.java @@ -0,0 +1,537 @@ +/******************************************************************************* + * Copyright (c) 2004, 2005 QNX Software 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: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.gdb.internal.ui.breakpoints; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.cdt.debug.ui.CDebugUIPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; +import org.eclipse.dd.dsf.concurrent.Query; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; +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.gdb.breakpoints.CBreakpointGdbThreadsFilterExtension; +import org.eclipse.dd.gdb.internal.ui.GdbUIPlugin; +import org.eclipse.dd.gdb.launching.GdbLaunch; +import org.eclipse.dd.gdb.service.GDBRunControl; +import org.eclipse.dd.gdb.service.GDBRunControl.GDBThreadData; +import org.eclipse.dd.gdb.service.command.GDBControl; +import org.eclipse.dd.mi.service.IMIExecutionDMContext; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.ILaunchManager; +import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.debug.ui.IDebugUIConstants; +import org.eclipse.jface.viewers.AbstractTreeViewer; +import org.eclipse.jface.viewers.CheckStateChangedEvent; +import org.eclipse.jface.viewers.CheckboxTreeViewer; +import org.eclipse.jface.viewers.ICheckStateListener; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.osgi.util.tracker.ServiceTracker; + +public class GdbThreadFilterEditor { + + /** + * Comment for ThreadFilterEditor. + */ + public class CheckHandler implements ICheckStateListener { + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.ICheckStateListener#checkStateChanged(org.eclipse.jface.viewers.CheckStateChangedEvent) + */ + public void checkStateChanged(CheckStateChangedEvent event) { + Object element = event.getElement(); + if (element instanceof IContainerDMContext) { + checkTarget((IContainerDMContext) element, event.getChecked()); + } else if (element instanceof IExecutionDMContext) { + checkThread((IExecutionDMContext) element, event.getChecked()); + } + } + + /** + * Check or uncheck a debug target in the tree viewer. When a debug + * target is checked, attempt to check all of the target's threads by + * default. When a debug target is unchecked, uncheck all its threads. + */ + protected void checkTarget(IContainerDMContext target, boolean checked) { + getThreadViewer().setChecked(target, checked); + getThreadViewer().setGrayed(target, false); + getThreadViewer().expandToLevel(target, AbstractTreeViewer.ALL_LEVELS); + IExecutionDMContext[] threads = syncGetThreads(target); + for (int i = 0; i < threads.length; i++) { + getThreadViewer().setChecked(threads[i], checked); + getThreadViewer().setGrayed(threads[i], false); + } + } + + /** + * Check or uncheck a thread. Update the thread's debug target. + */ + protected void checkThread(IExecutionDMContext thread, boolean checked) { + getThreadViewer().setChecked(thread, checked); + IContainerDMContext target = DMContexts.getAncestorOfType(thread, IContainerDMContext.class); + IExecutionDMContext[] threads = syncGetThreads(target); + int checkedNumber = 0; + for (int i = 0; i < threads.length; i++) { + if (getThreadViewer().getChecked(threads[i])) { + ++checkedNumber; + } + } + if (checkedNumber == 0) { + getThreadViewer().setChecked(target, false); + getThreadViewer().setGrayed(target, false); + } else if (checkedNumber == threads.length) { + getThreadViewer().setChecked(target, true); + getThreadViewer().setGrayed(target, false); + } else { + getThreadViewer().setGrayChecked(target, true); + } + } + } + + /** + * Comment for ThreadFilterEditor. + */ + public class ThreadFilterContentProvider implements ITreeContentProvider { + + /** + * Constructor for ThreadFilterContentProvider. + */ + public ThreadFilterContentProvider() { + super(); + // TODO Auto-generated constructor stub + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object) + */ + public Object[] getChildren(Object parent) { + if (parent instanceof IContainerDMContext) { + return syncGetThreads((IContainerDMContext) parent); + } + + if (parent instanceof ILaunchManager) { + List children = new ArrayList(); + ILaunch[] launches = ((ILaunchManager) parent).getLaunches(); + IContainerDMContext target; + for (int i = 0; i < launches.length; i++) { + if (launches[i] instanceof GdbLaunch) { + target = syncGetContainer((GdbLaunch) launches[i]); + if (target != null) { + children.add(target); + } + } + } + return children.toArray(); + } + return new Object[0]; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object) + */ + public Object getParent(Object element) { + if (element instanceof IContainerDMContext) { + return DebugPlugin.getDefault().getLaunchManager(); + } + if (element instanceof IExecutionDMContext) { + return DMContexts.getAncestorOfType((IExecutionDMContext) element, IContainerDMContext.class); + } + return null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object) + */ + public boolean hasChildren(Object element) { + return getChildren(element).length > 0; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) + */ + public Object[] getElements(Object inputElement) { + return getChildren(inputElement); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IContentProvider#dispose() + */ + public void dispose() { + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, + * java.lang.Object, java.lang.Object) + */ + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + } + + public class ThreadFilterLabelProvider extends LabelProvider { + + @Override + public Image getImage(Object element) { + if (element instanceof IContainerDMContext) { + return DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_DEBUG_TARGET); + } else { + return DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_THREAD_RUNNING); + } + } + + @Override + public String getText(Object element) { + if (element instanceof IContainerDMContext) { + return syncGetContainerLabel((IContainerDMContext)element); + } else { + return syncGetThreadLabel((IExecutionDMContext)element); + } + } + } + + + private CBreakpointGdbThreadFilterPage fPage; + + private CheckboxTreeViewer fThreadViewer; + + private ThreadFilterContentProvider fContentProvider; + + private CheckHandler fCheckHandler; + + /** + * Constructor for ThreadFilterEditor. + */ + public GdbThreadFilterEditor(Composite parent, CBreakpointGdbThreadFilterPage page) { + fPage = page; + fContentProvider = new ThreadFilterContentProvider(); + fCheckHandler = new CheckHandler(); + createThreadViewer(parent); + } + + protected CBreakpointGdbThreadFilterPage getPage() { + return fPage; + } + + private void createThreadViewer(Composite parent) { + Label label = new Label(parent, SWT.NONE); + label.setText("&Restrict to Selected Targets and Threads:"); //$NON-NLS-1$ + label.setFont(parent.getFont()); + label.setLayoutData(new GridData()); + GridData data = new GridData(GridData.FILL_BOTH); + data.heightHint = 100; + fThreadViewer = new CheckboxTreeViewer(parent, SWT.BORDER); + fThreadViewer.addCheckStateListener(fCheckHandler); + fThreadViewer.getTree().setLayoutData(data); + fThreadViewer.getTree().setFont(parent.getFont()); + fThreadViewer.setContentProvider(fContentProvider); + fThreadViewer.setLabelProvider(new ThreadFilterLabelProvider()); + fThreadViewer.setInput(DebugPlugin.getDefault().getLaunchManager()); + setInitialCheckedState(); + } + + /** + * Returns the debug targets that appear in the tree + */ + protected IContainerDMContext[] getDebugTargets() { + Object input = fThreadViewer.getInput(); + if (!(input instanceof ILaunchManager)) { + return new IContainerDMContext[0]; + } + List targets = new ArrayList(); + ILaunch[] launches = ((ILaunchManager) input).getLaunches(); + IContainerDMContext target; + for (int i = 0; i < launches.length; i++) { + if (launches[i] instanceof GdbLaunch) { + target = syncGetContainer((GdbLaunch) launches[i]); + if (target != null) { + targets.add(target); + } + } + } + return targets.toArray(new IContainerDMContext[targets.size()]); + } + + protected CheckboxTreeViewer getThreadViewer() { + return fThreadViewer; + } + + /** + * Sets the initial checked state of the tree viewer. The initial state + * should reflect the current state of the breakpoint. If the breakpoint has + * a thread filter in a given thread, that thread should be checked. + */ + protected void setInitialCheckedState() { + CBreakpointGdbThreadsFilterExtension filterExtension = fPage.getFilterExtension(); + try { + IContainerDMContext[] targets = filterExtension.getTargetFilters(); + + // TODO: Hack to properly initialize the target/thread list + // Should be done in filterExtension.initialize() but we don't know + // how to get the target list from an ICBreakpoint... + if (targets.length == 0) { + targets = getDebugTargets(); + for (IContainerDMContext target : targets) { + filterExtension.setTargetFilter(target); + } + } + // TODO: End of hack + + for (int i = 0; i < targets.length; i++) { + IExecutionDMContext[] filteredThreads = filterExtension.getThreadFilters(targets[i]); + if (filteredThreads != null) { + for (int j = 0; j < filteredThreads.length; ++j) + fCheckHandler.checkThread(filteredThreads[j], true); + } else { + fCheckHandler.checkTarget(targets[i], true); + } + } + } catch (CoreException e) { + CDebugUIPlugin.log(e); + } + } + + protected void doStore() { + CBreakpointGdbThreadsFilterExtension filterExtension = fPage.getFilterExtension(); + IContainerDMContext[] targets = getDebugTargets(); + for (int i = 0; i < targets.length; ++i) { + try { + if (getThreadViewer().getChecked(targets[i])) { + if (getThreadViewer().getGrayed(targets[i])) { + IExecutionDMContext[] threads = getTargetThreadFilters(targets[i]); + filterExtension.setThreadFilters(threads); + } else { + filterExtension.setTargetFilter(targets[i]); + } + } else { + filterExtension.removeTargetFilter(targets[i]); + } + DebugPlugin.getDefault().getBreakpointManager().fireBreakpointChanged(fPage.getBreakpoint()); + } catch (CoreException e) { + CDebugUIPlugin.log(e); + } + } + } + + private IExecutionDMContext[] getTargetThreadFilters(IContainerDMContext target) { + Object[] threads = ((ITreeContentProvider) getThreadViewer().getContentProvider()).getChildren(target); + ArrayList list = new ArrayList(threads.length); + for (int i = 0; i < threads.length; ++i) { + if (getThreadViewer().getChecked(threads[i])) + list.add(threads[i]); + } + return list.toArray(new IExecutionDMContext[list.size()]); + } + + private IContainerDMContext syncGetContainer(final GdbLaunch launch) { + final DsfSession session = launch.getSession(); + + class ContainerQuery extends Query { + @Override + protected void execute(DataRequestMonitor rm) { + if (!session.isActive()) { + rm.setStatus(getFailStatus(IDsfService.INVALID_STATE, "Launch's session not active.")); //$NON-NLS-1$ + rm.done(); + return; + } + + ServiceTracker tracker = new ServiceTracker(GdbUIPlugin.getBundleContext(), GDBControl.class + .getName(), null); + tracker.open(); + GDBControl gdbControl = (GDBControl) tracker.getService(); + if (gdbControl != null) { + rm.setData(gdbControl.getGDBDMContext()); + } else { + rm.setStatus(getFailStatus(IDsfService.INVALID_STATE, "GDB Control not accessible.")); //$NON-NLS-1$ + } + rm.done(); + tracker.close(); + } + } + + ContainerQuery query = new ContainerQuery(); + try { + session.getExecutor().execute(query); + return query.get(); + } catch (RejectedExecutionException e) { + } catch (InterruptedException e) { + } catch (ExecutionException e) { + } + return null; + } + + private IExecutionDMContext[] syncGetThreads(final IContainerDMContext container) { + final DsfSession session = DsfSession.getSession(container.getSessionId()); + if (session == null) { + return new IExecutionDMContext[0]; + } + + class ThreadsQuery extends Query { + @Override + protected void execute(DataRequestMonitor rm) { + if (!session.isActive()) { + rm.setStatus(getFailStatus(IDsfService.INVALID_STATE, "Container's session not active.")); //$NON-NLS-1$ + rm.done(); + return; + } + + ServiceTracker tracker = new ServiceTracker(GdbUIPlugin.getBundleContext(), IRunControl.class + .getName(), null); + tracker.open(); + IRunControl runControl = (IRunControl) tracker.getService(); + if (runControl != null) { + runControl.getExecutionContexts(container, rm); + } else { + rm.setStatus(getFailStatus(IDsfService.INVALID_STATE, "GDB Control not accessible.")); //$NON-NLS-1$ + rm.done(); + } + tracker.close(); + } + } + + ThreadsQuery query = new ThreadsQuery(); + try { + session.getExecutor().execute(query); + return query.get(); + } catch (RejectedExecutionException e) { + } catch (InterruptedException e) { + } catch (ExecutionException e) { + } + return new IExecutionDMContext[0]; + } + + private String syncGetContainerLabel(final IContainerDMContext container) { + final DsfSession session = DsfSession.getSession(container.getSessionId()); + if (session == null) { + return "Error reading data"; //$NON-NLS-1$ + } + + class ContainerLabelQuery extends Query { + @Override + protected void execute(DataRequestMonitor rm) { + if (!session.isActive()) { + rm.setStatus(getFailStatus(IDsfService.INVALID_STATE, "Container's session not active.")); //$NON-NLS-1$ + rm.done(); + return; + } + + ServiceTracker tracker = new ServiceTracker(GdbUIPlugin.getBundleContext(), GDBControl.class + .getName(), null); + tracker.open(); + GDBControl gdbControl = (GDBControl) tracker.getService(); + if (gdbControl != null) { + rm.setData(gdbControl.getExecutablePath().toOSString()); + } else { + rm.setStatus(getFailStatus(IDsfService.INVALID_STATE, "GDB Control not accessible.")); //$NON-NLS-1$ + } + rm.done(); + tracker.close(); + } + } + + ContainerLabelQuery query = new ContainerLabelQuery(); + try { + session.getExecutor().execute(query); + return query.get(); + } catch (RejectedExecutionException e) { + } catch (InterruptedException e) { + } catch (ExecutionException e) { + } + return "Error reading data"; //$NON-NLS-1$ + } + + private String syncGetThreadLabel(final IExecutionDMContext thread) { + final DsfSession session = DsfSession.getSession(thread.getSessionId()); + if (session == null) { + return "Error reading data"; //$NON-NLS-1$ + } + + class ThreadLabelQuery extends Query { + @Override + protected void execute(final DataRequestMonitor rm) { + if (!session.isActive()) { + rm.setStatus(getFailStatus(IDsfService.INVALID_STATE, "Container's session not active.")); //$NON-NLS-1$ + rm.done(); + return; + } + + ServiceTracker tracker = new ServiceTracker(GdbUIPlugin.getBundleContext(), GDBRunControl.class + .getName(), null); + tracker.open(); + GDBRunControl runControl = (GDBRunControl) tracker.getService(); + if (runControl != null) { + runControl.getThreadData((IMIExecutionDMContext) thread, new DataRequestMonitor( + ImmediateExecutor.getInstance(), rm) { + @Override + protected void handleOK() { + final StringBuilder builder = new StringBuilder("Thread["); //$NON-NLS-1$ + builder.append(((IMIExecutionDMContext)thread).getThreadId()); + builder.append("] "); //$NON-NLS-1$ + builder.append(getData().getId()); + builder.append(getData().getName()); + + rm.setData(builder.toString()); + rm.done(); + } + }); + } else { + rm.setStatus(getFailStatus(IDsfService.INVALID_STATE, "GDB Control not accessible.")); //$NON-NLS-1$ + rm.done(); + } + tracker.close(); + } + } + + ThreadLabelQuery query = new ThreadLabelQuery(); + try { + session.getExecutor().execute(query); + return query.get(); + } catch (RejectedExecutionException e) { + } catch (InterruptedException e) { + } catch (ExecutionException e) { + } + return "Error reading data"; //$NON-NLS-1$ + } + + private Status getFailStatus(int code, String message) { + return new Status(IStatus.ERROR, GdbUIPlugin.PLUGIN_ID, code, message, null); + } +} diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/DsfMIlRunLaunchConfigurationTabGroup.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/DsfMIlRunLaunchConfigurationTabGroup.java new file mode 100644 index 00000000000..7c15f7b8ebb --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/DsfMIlRunLaunchConfigurationTabGroup.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2005 QNX Software 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: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.gdb.internal.ui.launching; + +import org.eclipse.cdt.launch.ui.CDebuggerTab; +import org.eclipse.cdt.launch.ui.CMainTab; +import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup; +import org.eclipse.debug.ui.CommonTab; +import org.eclipse.debug.ui.ILaunchConfigurationDialog; +import org.eclipse.debug.ui.ILaunchConfigurationTab; +import org.eclipse.debug.ui.sourcelookup.SourceLookupTab; + +public class DsfMIlRunLaunchConfigurationTabGroup extends AbstractLaunchConfigurationTabGroup { + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.ILaunchConfigurationTabGroup#createTabs(org.eclipse.debug.ui.ILaunchConfigurationDialog, java.lang.String) + */ + public void createTabs(ILaunchConfigurationDialog dialog, String mode) { + ILaunchConfigurationTab[] tabs = new ILaunchConfigurationTab[] { + new CMainTab(true), + new CDebuggerTab(false), + new SourceLookupTab(), + new CommonTab() + }; + setTabs(tabs); + } + +} diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java new file mode 100644 index 00000000000..a8f003eddf0 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * 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.gdb.internal.ui.viewmodel; + +import org.eclipse.cdt.debug.ui.ICDebugUIConstants; +import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.ExpressionVMProvider; +import org.eclipse.dd.dsf.debug.ui.viewmodel.modules.ModulesVMProvider; +import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterVMProvider; +import org.eclipse.dd.dsf.debug.ui.viewmodel.variable.VariableVMProvider; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMAdapter; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; +import org.eclipse.dd.gdb.internal.ui.viewmodel.launch.LaunchVMProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.ui.IDebugUIConstants; + +/* + * + */ +@ThreadSafe +@SuppressWarnings("restriction") +public class GdbViewModelAdapter extends AbstractDMVMAdapter +{ + public GdbViewModelAdapter(DsfSession session) { + super(session); + getSession().registerModelAdapter(IColumnPresentationFactory.class, this); + } + + @Override + public void dispose() { + getSession().unregisterModelAdapter(IColumnPresentationFactory.class); + super.dispose(); + } + + @Override + protected AbstractDMVMProvider createViewModelProvider(IPresentationContext context) { + if ( IDebugUIConstants.ID_DEBUG_VIEW.equals(context.getId()) ) { + return new LaunchVMProvider(this, context, getSession()); + } else if (IDebugUIConstants.ID_VARIABLE_VIEW.equals(context.getId()) ) { + return new VariableVMProvider(this, context, getSession()); + } else if (IDebugUIConstants.ID_REGISTER_VIEW.equals(context.getId()) ) { + return new RegisterVMProvider(this, context, getSession()); + } else if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(context.getId()) ) { + return new ExpressionVMProvider(this, context, getSession()); + } else if (ICDebugUIConstants.ID_MODULES_VIEW.equals(context.getId()) ) { + return new ModulesVMProvider(this, context, getSession()); + } + return null; + } +} diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ContainerVMNode.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ContainerVMNode.java new file mode 100644 index 00000000000..3cecaccba41 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ContainerVMNode.java @@ -0,0 +1,146 @@ +/******************************************************************************* + * Copyright (c) 2006 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.gdb.internal.ui.viewmodel.launch; + + +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.IDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExitedDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl.IStartedDMEvent; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; +import org.eclipse.dd.gdb.service.GDBRunControl; +import org.eclipse.dd.gdb.service.GDBRunControl.GDBProcessData; +import org.eclipse.dd.gdb.service.command.GDBControl; +import org.eclipse.dd.gdb.service.command.GDBControlDMContext; +import org.eclipse.dd.gdb.service.command.GDBControl.StartedEvent; +import org.eclipse.dd.mi.service.command.AbstractMIControl; +import org.eclipse.dd.mi.service.command.MIControlDMContext; +import org.eclipse.dd.mi.service.command.events.MIInferiorExitEvent; +import org.eclipse.dd.mi.service.command.events.MIInferiorSignalExitEvent; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.debug.ui.IDebugUIConstants; + +@SuppressWarnings("restriction") +public class ContainerVMNode extends AbstractDMVMNode + implements IElementLabelProvider +{ + + public ContainerVMNode(AbstractDMVMProvider provider, DsfSession session) { + super(provider, session, IRunControl.IExecutionDMContext.class); + } + + @Override + protected void updateElementsInSessionThread(IChildrenUpdate update) { + if (!checkService(AbstractMIControl.class, null, update)) return; + + MIControlDMContext containerCtx = getServicesTracker().getService(AbstractMIControl.class).getControlDMContext(); + update.setChild(createVMContext(containerCtx), 0); + update.done(); + } + + + public void update(final ILabelUpdate[] updates) { + try { + getSession().getExecutor().execute(new DsfRunnable() { + public void run() { + updateLabelInSessionThread(updates); + }}); + } catch (RejectedExecutionException e) { + for (ILabelUpdate update : updates) { + handleFailedUpdate(update); + } + } + } + + protected void updateLabelInSessionThread(ILabelUpdate[] updates) { + for (final ILabelUpdate update : updates) { + if (!checkService(GDBRunControl.class, null, update)) continue; + final GDBRunControl runControl = getServicesTracker().getService(GDBRunControl.class); + + final GDBControlDMContext dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), GDBControlDMContext.class); + + String imageKey = null; + if (runControl.isSuspended(dmc)) { + imageKey = IDebugUIConstants.IMG_OBJS_THREAD_SUSPENDED; + } else { + imageKey = IDebugUIConstants.IMG_OBJS_THREAD_RUNNING; + } + update.setImageDescriptor(DebugUITools.getImageDescriptor(imageKey), 0); + + runControl.getProcessData( + dmc, + new DataRequestMonitor(getExecutor(), null) { + @Override + public void handleCompleted() { + if (!getStatus().isOK()) { + update.done(); + return; + } + update.setLabel(getData().getName(), 0); + update.done(); + } + }); + } + } + + public int getDeltaFlags(Object e) { + if(e instanceof IStartedDMEvent || e instanceof IExitedDMEvent) { + return IModelDelta.CONTENT; + } else if(e instanceof IRunControl.IContainerResumedDMEvent || + e instanceof IRunControl.IContainerSuspendedDMEvent) + { + return IModelDelta.CONTENT; + } else if (e instanceof GDBControl.ExitedEvent || + e instanceof MIInferiorExitEvent || + e instanceof MIInferiorSignalExitEvent) + { + return IModelDelta.CONTENT; + } + if (e instanceof StartedEvent) { + return IModelDelta.EXPAND | IModelDelta.SELECT; + } + return IModelDelta.NO_CHANGE; + } + + public void buildDelta(Object e, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) { + + if(e instanceof IRunControl.IContainerResumedDMEvent || + e instanceof IRunControl.IContainerSuspendedDMEvent) + { + parentDelta.addNode(createVMContext(((IDMEvent)e).getDMContext()), IModelDelta.CONTENT); + } else if (e instanceof IStartedDMEvent || e instanceof IExitedDMEvent) { + parentDelta.addNode(createVMContext(((IDMEvent)e).getDMContext()), IModelDelta.CONTENT); + } else if (e instanceof GDBControl.ExitedEvent || + e instanceof MIInferiorExitEvent || + e instanceof MIInferiorSignalExitEvent) + { + parentDelta.addNode(createVMContext(((IDMEvent)e).getDMContext()), IModelDelta.CONTENT); + } + if (e instanceof StartedEvent) { + parentDelta.addNode(createVMContext(((IDMEvent)e).getDMContext()), IModelDelta.EXPAND | IModelDelta.SELECT); + } + + requestMonitor.done(); + } +} diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/LaunchVMProvider.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/LaunchVMProvider.java new file mode 100644 index 00000000000..87675c2b6f9 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/LaunchVMProvider.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * 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 + * Ericsson - Modified for new functionality + *******************************************************************************/ +package org.eclipse.dd.gdb.internal.ui.viewmodel.launch; + +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.LaunchRootVMNode; +import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.StackFramesVMNode; +import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.StandardProcessVMNode; +import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.LaunchRootVMNode.LaunchesEvent; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; +import org.eclipse.dd.dsf.ui.viewmodel.IRootVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.IVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; +import org.eclipse.debug.core.DebugEvent; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.IDebugEventSetListener; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.ILaunchesListener2; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; + + +/** + * + */ +@SuppressWarnings("restriction") +public class LaunchVMProvider extends AbstractDMVMProvider + implements IDebugEventSetListener, ILaunchesListener2 +{ + @ThreadSafe + public LaunchVMProvider(AbstractVMAdapter adapter, IPresentationContext presentationContext, DsfSession session) + { + super(adapter, presentationContext, session); + + IRootVMNode launchNode = new LaunchRootVMNode(this); + setRootNode(launchNode); + + // Container node to contain all processes and threads + IVMNode containerNode = new ContainerVMNode(this, getSession()); + IVMNode processesNode = new StandardProcessVMNode(this); + addChildNodes(launchNode, new IVMNode[] { containerNode, processesNode}); + + IVMNode threadsNode = new ThreadVMNode(this, getSession()); + addChildNodes(containerNode, new IVMNode[] { threadsNode }); + + IVMNode stackFramesNode = new StackFramesVMNode(this, getSession()); + addChildNodes(threadsNode, new IVMNode[] { stackFramesNode }); + + + DebugPlugin.getDefault().addDebugEventListener(this); + DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this); + } + + + public void handleDebugEvents(final DebugEvent[] events) { + if (isDisposed()) return; + + // We're in session's executor thread. Re-dispach to VM Adapter + // executor thread and then call root layout node. + try { + getExecutor().execute(new Runnable() { + public void run() { + if (isDisposed()) return; + + for (final DebugEvent event : events) { + handleEvent(event); + } + }}); + } catch (RejectedExecutionException e) { + // Ignore. This exception could be thrown if the provider is being + // shut down. + } + } + + @Override + public void dispose() { + DebugPlugin.getDefault().removeDebugEventListener(this); + DebugPlugin.getDefault().getLaunchManager().removeLaunchListener(this); + super.dispose(); + } + + public void launchesAdded(ILaunch[] launches) { + handleLaunchesEvent(new LaunchesEvent(launches, LaunchesEvent.Type.ADDED)); + } + + public void launchesRemoved(ILaunch[] launches) { + handleLaunchesEvent(new LaunchesEvent(launches, LaunchesEvent.Type.REMOVED)); + } + + public void launchesChanged(ILaunch[] launches) { + handleLaunchesEvent(new LaunchesEvent(launches, LaunchesEvent.Type.CHANGED)); + } + + public void launchesTerminated(ILaunch[] launches) { + handleLaunchesEvent(new LaunchesEvent(launches, LaunchesEvent.Type.TERMINATED)); + } + + private void handleLaunchesEvent(final LaunchesEvent event) { + if (isDisposed()) return; + + // We're in session's executor thread. Re-dispach to VM Adapter + // executor thread and then call root layout node. + try { + getExecutor().execute(new Runnable() { + public void run() { + if (isDisposed()) return; + + IRootVMNode rootLayoutNode = getRootVMNode(); + if (rootLayoutNode != null && rootLayoutNode.getDeltaFlags(event) != 0) { + handleEvent(event); + } + }}); + } catch (RejectedExecutionException e) { + // Ignore. This exception could be thrown if the provider is being + // shut down. + } + } +} diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ThreadVMNode.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ThreadVMNode.java new file mode 100644 index 00000000000..fefd36c28a9 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ThreadVMNode.java @@ -0,0 +1,308 @@ +/******************************************************************************* + * 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 + * Ericsson - Modified for multi threaded functionality + *******************************************************************************/ +package org.eclipse.dd.gdb.internal.ui.viewmodel.launch; + +import java.util.List; +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.datamodel.IDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerResumedDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerSuspendedDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMData; +import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason; +import org.eclipse.dd.dsf.internal.ui.DsfUIPlugin; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.ModelProxyInstalledEvent; +import org.eclipse.dd.dsf.ui.viewmodel.VMChildrenUpdate; +import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext; +import org.eclipse.dd.gdb.service.GDBRunControl; +import org.eclipse.dd.gdb.service.GDBRunControl.GDBThreadData; +import org.eclipse.dd.mi.service.IMIExecutionDMContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.debug.ui.IDebugUIConstants; + + +@SuppressWarnings("restriction") +public class ThreadVMNode extends AbstractDMVMNode + implements IElementLabelProvider +{ + public ThreadVMNode(AbstractDMVMProvider provider, DsfSession session) { + super(provider, session, IExecutionDMContext.class); + } + + @Override + protected void updateElementsInSessionThread(final IChildrenUpdate update) { + if (!checkService(IRunControl.class, null, update)) return; + final IContainerDMContext contDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IContainerDMContext.class); + + if (contDmc == null) { + handleFailedUpdate(update); + return; + } + + getServicesTracker().getService(IRunControl.class).getExecutionContexts(contDmc, + new DataRequestMonitor(getSession().getExecutor(), null){ + @Override + public void handleCompleted() { + if (!getStatus().isOK()) { + handleFailedUpdate(update); + return; + } + fillUpdateWithVMCs(update, getData()); + update.done(); + } + }); + } + + + public void update(final ILabelUpdate[] updates) { + try { + getSession().getExecutor().execute(new DsfRunnable() { + public void run() { + updateLabelInSessionThread(updates); + }}); + } catch (RejectedExecutionException e) { + for (ILabelUpdate update : updates) { + handleFailedUpdate(update); + } + } + } + + @Override + public void getContextsForEvent(VMDelta parentDelta, Object e, final DataRequestMonitor rm) { + if(e instanceof IContainerResumedDMEvent) { + IDMContext triggerContext = ((IContainerResumedDMEvent)e).getTriggeringContext(); + if (triggerContext != null) { + rm.setData(new IVMContext[] { createVMContext(triggerContext) }); + rm.done(); + return; + } + } else if(e instanceof IContainerSuspendedDMEvent) { + IDMContext triggerContext = ((IContainerSuspendedDMEvent)e).getTriggeringContext(); + if (triggerContext != null) { + rm.setData(new IVMContext[] { createVMContext(triggerContext) }); + rm.done(); + return; + } + } else if (e instanceof ModelProxyInstalledEvent) { + getThreadVMCForModelProxyInstallEvent( + parentDelta, + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + rm.setData(new IVMContext[] { getData().fVMContext }); + } else { + rm.setData(new IVMContext[0]); + } + rm.done(); + } + }); + return; + } + super.getContextsForEvent(parentDelta, e, rm); + } + + private static class VMContextInfo { + final IVMContext fVMContext; + final int fIndex; + final boolean fIsSuspended; + VMContextInfo(IVMContext vmContext, int index, boolean isSuspended) { + fVMContext = vmContext; + fIndex = index; + fIsSuspended = isSuspended; + } + } + + private void getThreadVMCForModelProxyInstallEvent(VMDelta parentDelta, final DataRequestMonitor rm) { + getVMProvider().updateNode(this, new VMChildrenUpdate( + parentDelta, getVMProvider().getPresentationContext(), -1, -1, + new DataRequestMonitor>(getExecutor(), rm) { + @Override + protected void handleOK() { + try { + getSession().getExecutor().execute(new DsfRunnable() { + public void run() { + final GDBRunControl runControl = getServicesTracker().getService(GDBRunControl.class); + if (runControl != null) { + int vmcIdx = -1; + int suspendedVmcIdx = -1; + + for (int i = 0; i < getData().size(); i++) { + if (getData().get(i) instanceof IDMVMContext) { + IDMVMContext vmc = (IDMVMContext)getData().get(i); + IExecutionDMContext execDmc = DMContexts.getAncestorOfType( + vmc.getDMContext(), IExecutionDMContext.class); + if (execDmc != null) { + vmcIdx = vmcIdx < 0 ? i : vmcIdx; + if (runControl.isSuspended(execDmc)) { + suspendedVmcIdx = suspendedVmcIdx < 0 ? i : suspendedVmcIdx; + } + } + } + } + if (suspendedVmcIdx >= 0) { + rm.setData(new VMContextInfo( + (IVMContext)getData().get(suspendedVmcIdx), suspendedVmcIdx, true)); + } else if (vmcIdx >= 0) { + rm.setData(new VMContextInfo((IVMContext)getData().get(vmcIdx), vmcIdx, false)); + } else { + rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, "No threads available", null)); //$NON-NLS-1$ + } + rm.done(); + } else { + rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, "No threads available", null)); //$NON-NLS-1$ + rm.done(); + } + } + }); + } catch (RejectedExecutionException e) { + rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.NOT_SUPPORTED, "", null)); //$NON-NLS-1$ + rm.done(); + } + } + })); + } + + protected void updateLabelInSessionThread(ILabelUpdate[] updates) { + for (final ILabelUpdate update : updates) { + if (!checkService(GDBRunControl.class, null, update)) continue; + final GDBRunControl runControl = getServicesTracker().getService(GDBRunControl.class); + + final IMIExecutionDMContext dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IMIExecutionDMContext.class); + + String imageKey = null; + if (getServicesTracker().getService(IRunControl.class).isSuspended(dmc)) { + imageKey = IDebugUIConstants.IMG_OBJS_THREAD_SUSPENDED; + } else { + imageKey = IDebugUIConstants.IMG_OBJS_THREAD_RUNNING; + } + update.setImageDescriptor(DebugUITools.getImageDescriptor(imageKey), 0); + + // Find the Reason for the State + runControl.getExecutionData(dmc, + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + public void handleCompleted(){ + if (!getStatus().isOK()) { + handleFailedUpdate(update); + return; + } + + // We're in a new dispatch cycle, and we have to check whether the + // service reference is still valid. + if (!checkService(GDBRunControl.class, null, update)) return; + + final StateChangeReason reason = getData().getStateChangeReason(); + + // Retrieve the rest of the thread information + runControl.getThreadData( + dmc, + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + public void handleCompleted() { + if (!getStatus().isOK()) { + update.done(); + return; + } + // Create Labels of type Thread[GDBthreadId]RealThreadID/Name (State: Reason) + // Thread[1] 3457 (Suspended:BREAKPOINT) + final StringBuilder builder = new StringBuilder("Thread["); //$NON-NLS-1$ + builder.append(dmc.getThreadId()); + builder.append("] "); //$NON-NLS-1$ + builder.append(getData().getId()); + builder.append(getData().getName()); + if(getServicesTracker().getService(IRunControl.class).isSuspended(dmc)) + builder.append(" (Suspended"); //$NON-NLS-1$ + else + builder.append(" (Running"); //$NON-NLS-1$ + // Reason will be null before ContainerSuspendEvent is fired + if(reason != null) { + builder.append(" : "); //$NON-NLS-1$ + builder.append(reason); + } + builder.append(")"); //$NON-NLS-1$ + update.setLabel(builder.toString(), 0); + update.done(); + } + }); + } + }); + + } + } + + public int getDeltaFlags(Object e) { + if(e instanceof IResumedDMEvent || e instanceof ISuspendedDMEvent) { + return IModelDelta.CONTENT; + } + if (e instanceof ModelProxyInstalledEvent) { + return IModelDelta.SELECT | IModelDelta.EXPAND; + } + return IModelDelta.NO_CHANGE; + } + + public void buildDelta(Object e, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor rm) { + if(e instanceof IContainerResumedDMEvent) { + IDMContext triggeringContext = ((IContainerResumedDMEvent)e).getTriggeringContext(); + if (triggeringContext != null) { + parentDelta.addNode(createVMContext(triggeringContext), IModelDelta.CONTENT); + } + rm.done(); + } else if (e instanceof IContainerSuspendedDMEvent) { + IDMContext triggeringContext = ((IContainerSuspendedDMEvent)e).getTriggeringContext(); + if (triggeringContext != null) { + parentDelta.addNode(createVMContext(triggeringContext), IModelDelta.CONTENT); + } + rm.done(); + } else if(e instanceof IResumedDMEvent || e instanceof ISuspendedDMEvent) { + parentDelta.addNode(createVMContext(((IDMEvent)e).getDMContext()), IModelDelta.CONTENT); + rm.done(); + } else if (e instanceof ModelProxyInstalledEvent) { + getThreadVMCForModelProxyInstallEvent( + parentDelta, + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + parentDelta.addNode( + getData().fVMContext, nodeOffset + getData().fIndex, + IModelDelta.EXPAND | (getData().fIsSuspended ? 0 : IModelDelta.SELECT)); + } + rm.done(); + } + }); + } + + } +} diff --git a/plugins/org.eclipse.dd.mi/.classpath b/plugins/org.eclipse.dd.mi/.classpath new file mode 100644 index 00000000000..65ed610be7e --- /dev/null +++ b/plugins/org.eclipse.dd.mi/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/plugins/org.eclipse.dd.mi/.options b/plugins/org.eclipse.dd.mi/.options new file mode 100644 index 00000000000..1d23c88ae93 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/.options @@ -0,0 +1 @@ +org.eclipse.dd.mi.core/debug = false diff --git a/plugins/org.eclipse.dd.mi/.project b/plugins/org.eclipse.dd.mi/.project new file mode 100644 index 00000000000..30d6696665e --- /dev/null +++ b/plugins/org.eclipse.dd.mi/.project @@ -0,0 +1,28 @@ + + + org.eclipse.dd.mi + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/plugins/org.eclipse.dd.mi/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.dd.mi/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000000..b6f154d6ec4 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,65 @@ +#Thu Jun 07 11:05:32 PDT 2007 +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.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=warning +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning +org.eclipse.jdt.core.compiler.problem.nullReference=ignore +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning +org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=error +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=enabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/plugins/org.eclipse.dd.mi/.settings/org.eclipse.jdt.ui.prefs b/plugins/org.eclipse.dd.mi/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 00000000000..77e5bae8c55 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,3 @@ +#Sun Aug 06 18:13:46 CEST 2006 +eclipse.preferences.version=1 +internal.default.compliance=default diff --git a/plugins/org.eclipse.dd.mi/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.mi/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..0378107a447 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/META-INF/MANIFEST.MF @@ -0,0 +1,24 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: GDB/MI Protocol-based DSF Debugger Integration Core +Bundle-Vendor: Eclipse.org +Bundle-SymbolicName: org.eclipse.dd.mi;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: org.eclipse.dd.mi.internal.MIPlugin +Bundle-Localization: plugin +Require-Bundle: org.eclipse.core.runtime, + org.eclipse.debug.core, + org.eclipse.core.resources, + org.eclipse.core.variables, + org.eclipse.dd.dsf, + org.eclipse.dd.dsf.debug, + org.eclipse.cdt.debug.core, + org.eclipse.cdt.core +Export-Package: + org.eclipse.dd.mi.service, + org.eclipse.dd.mi.service.command, + org.eclipse.dd.mi.service.command.commands, + org.eclipse.dd.mi.service.command.events, + org.eclipse.dd.mi.service.command.output +Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Bundle-ActivationPolicy: lazy diff --git a/plugins/org.eclipse.dd.mi/about.html b/plugins/org.eclipse.dd.mi/about.html new file mode 100644 index 00000000000..cb740ae8bc8 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/about.html @@ -0,0 +1,24 @@ + + + + +About +

    About This Content

    + +

    June 5, 2007

    +

    License

    + +

    The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at http://www.eclipse.org/legal/epl-v10.html. +For purposes of the EPL, "Program" will mean the Content.

    + +

    If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at http://www.eclipse.org.

    + + \ No newline at end of file diff --git a/plugins/org.eclipse.dd.mi/build.properties b/plugins/org.eclipse.dd.mi/build.properties new file mode 100644 index 00000000000..bc3b0f2bf1f --- /dev/null +++ b/plugins/org.eclipse.dd.mi/build.properties @@ -0,0 +1,7 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml,\ + plugin.properties,\ + about.html diff --git a/plugins/org.eclipse.dd.mi/plugin.properties b/plugins/org.eclipse.dd.mi/plugin.properties new file mode 100644 index 00000000000..740bb7f6d18 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/plugin.properties @@ -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 GDB/MI Debugger Implementation using DSF +providerName=Eclipse.org + diff --git a/plugins/org.eclipse.dd.mi/plugin.xml b/plugins/org.eclipse.dd.mi/plugin.xml new file mode 100644 index 00000000000..4d8a6316736 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/plugin.xml @@ -0,0 +1,4 @@ + + + + diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/internal/MIPlugin.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/internal/MIPlugin.java new file mode 100644 index 00000000000..c7804d164c3 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/internal/MIPlugin.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.mi.internal; + +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Plugin; +import org.osgi.framework.BundleContext; + +/** + * Plugin class. + */ +public class MIPlugin extends Plugin { + + public static final String PLUGIN_ID = "org.eclipse.dsdp.debug.gdb.core"; //$NON-NLS-1$ + + // Debugging flag + public static boolean DEBUG = false; + + //The shared instance. + private static MIPlugin fgPlugin; + + private static BundleContext fgBundleContext; + + /** + * The constructor. + */ + public MIPlugin() { + fgPlugin = this; + } + + /** + * This method is called upon plug-in activation + */ + @Override + public void start(BundleContext context) throws Exception { + fgBundleContext = context; + super.start(context); + DEBUG = "true".equals(Platform.getDebugOption("org.eclipse.dd.mi.core/debug")); //$NON-NLS-1$//$NON-NLS-2$ + } + + /** + * This method is called when the plug-in is stopped + */ + @Override + public void stop(BundleContext context) throws Exception { + super.stop(context); + fgBundleContext = null; + } + + /** + * Returns the shared instance. + * + * @return the shared instance. + */ + public static MIPlugin getDefault() { + return fgPlugin; + } + + public static BundleContext getBundleContext() { + return fgBundleContext; + } + + public static void debug(String message) { + if (DEBUG) { + System.out.print(message); + } + } + + public static String getDebugTime() { + StringBuilder traceBuilder = new StringBuilder(); + + // Record the time + long time = System.currentTimeMillis(); + long seconds = (time / 1000) % 1000; + if (seconds < 100) traceBuilder.append('0'); + if (seconds < 10) traceBuilder.append('0'); + traceBuilder.append(seconds); + traceBuilder.append(','); + long millis = time % 1000; + if (millis < 100) traceBuilder.append('0'); + if (millis < 10) traceBuilder.append('0'); + traceBuilder.append(millis); + return traceBuilder.toString(); + } + +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/CSourceLookup.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/CSourceLookup.java new file mode 100644 index 00000000000..f13439a23fc --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/CSourceLookup.java @@ -0,0 +1,140 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service; + +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Map; + +import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.debug.service.ISourceLookup; +import org.eclipse.dd.dsf.service.AbstractDsfService; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.mi.internal.MIPlugin; +import org.osgi.framework.BundleContext; + +/** + * ISourceLookup service implementation based on the CDT CSourceLookupDirector. + */ +public class CSourceLookup extends AbstractDsfService implements ISourceLookup { + + private Map fDirectors = new HashMap(); + + public CSourceLookup(DsfSession session) { + super(session); + } + + @Override + protected BundleContext getBundleContext() { + return MIPlugin.getBundleContext(); + } + + + public void setSourceLookupDirector(ISourceLookupDMContext ctx, CSourceLookupDirector director) { + fDirectors.put(ctx, director); + } + + @Override + public void initialize(final RequestMonitor requestMonitor) { + super.initialize( + new RequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleOK() { + doInitialize(requestMonitor); + }}); + } + + private void doInitialize(final RequestMonitor requestMonitor) { + // Register this service + register(new String[] { CSourceLookup.class.getName(), ISourceLookup.class.getName() }, new Hashtable()); + requestMonitor.done(); + } + + @Override + public void shutdown(final RequestMonitor requestMonitor) { + unregister(); + super.shutdown(requestMonitor); + } + + public void getDebuggerPath(ISourceLookupDMContext sourceLookupCtx, Object source, final DataRequestMonitor rm) + { + if (! (source instanceof String)) { + // In future if needed other elements such as URIs could be supported. + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.NOT_SUPPORTED, "Only string source element is supported", null)); //$NON-NLS-1$); + rm.done(); + return; + } + final String sourceString = (String) source; + + if (!fDirectors.containsKey(sourceLookupCtx) ){ + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "No source director configured for given context", null)); //$NON-NLS-1$); + rm.done(); + return; + } + final CSourceLookupDirector director = fDirectors.get(sourceLookupCtx); + + new Job("Lookup Debugger Path") { //$NON-NLS-1$ + @Override + protected IStatus run(IProgressMonitor monitor) { + IPath debuggerPath = director.getCompilationPath(sourceString); + if (debuggerPath != null) { + rm.setData(debuggerPath.toString()); + } else { + rm.setData(sourceString); + } + rm.done(); + + return Status.OK_STATUS; + } + }.schedule(); + + } + + public void getSource(ISourceLookupDMContext sourceLookupCtx, final String debuggerPath, final DataRequestMonitor rm) + { + if (!fDirectors.containsKey(sourceLookupCtx) ){ + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "No source director configured for given context", null)); //$NON-NLS-1$); + rm.done(); + return; + } + final CSourceLookupDirector director = fDirectors.get(sourceLookupCtx); + + new Job("Lookup Source") { //$NON-NLS-1$ + @Override + protected IStatus run(IProgressMonitor monitor) { + Object[] sources; + try { + sources = director.findSourceElements(debuggerPath); + if (sources == null || sources.length == 0) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, "No sources found", null)); //$NON-NLS-1$); + } else { + rm.setData(sources[0]); + } + } catch (CoreException e) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, "Source lookup failed", e)); //$NON-NLS-1$); + } finally { + rm.done(); + } + + return Status.OK_STATUS; + } + }.schedule(); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/ExpressionService.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/ExpressionService.java new file mode 100644 index 00000000000..9fb5aec2dcc --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/ExpressionService.java @@ -0,0 +1,898 @@ +/******************************************************************************* + * 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 + * Ericsson - Modified for handling of multiple execution contexts + *******************************************************************************/ +package org.eclipse.dd.mi.service; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Map; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.utils.Addr32; +import org.eclipse.cdt.utils.Addr64; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.AbstractDMContext; +import org.eclipse.dd.dsf.datamodel.AbstractDMEvent; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.IExpressions; +import org.eclipse.dd.dsf.debug.service.IFormattedValues; +import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryChangedEvent; +import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryDMContext; +import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext; +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.command.CommandCache; +import org.eclipse.dd.dsf.service.AbstractDsfService; +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.mi.internal.MIPlugin; +import org.eclipse.dd.mi.service.command.commands.ExprMetaGetAttributes; +import org.eclipse.dd.mi.service.command.commands.ExprMetaGetChildCount; +import org.eclipse.dd.mi.service.command.commands.ExprMetaGetChildren; +import org.eclipse.dd.mi.service.command.commands.ExprMetaGetValue; +import org.eclipse.dd.mi.service.command.commands.ExprMetaGetVar; +import org.eclipse.dd.mi.service.command.commands.MIDataEvaluateExpression; +import org.eclipse.dd.mi.service.command.output.ExprMetaGetAttributesInfo; +import org.eclipse.dd.mi.service.command.output.ExprMetaGetChildCountInfo; +import org.eclipse.dd.mi.service.command.output.ExprMetaGetChildrenInfo; +import org.eclipse.dd.mi.service.command.output.ExprMetaGetValueInfo; +import org.eclipse.dd.mi.service.command.output.ExprMetaGetVarInfo; +import org.eclipse.dd.mi.service.command.output.MIDataEvaluateExpressionInfo; +import org.osgi.framework.BundleContext; + +/** + * This class implements a debugger expression evaluator as a DSF service. The + * primary interface that clients of this class should use is IExpressions. + */ +public class ExpressionService extends AbstractDsfService implements IExpressions { + + /** + * This class represents the two expressions that characterize an Expression Context. + */ + public static class ExpressionInfo { + private final String fullExpression; + private final String relativeExpression; + + public ExpressionInfo(String full, String relative) { + fullExpression = full; + relativeExpression = relative; + } + + public String getFullExpr() { return fullExpression; } + public String getRelExpr() { return relativeExpression; } + + @Override + public boolean equals(Object other) { + if (other instanceof ExpressionInfo) { + if (fullExpression == null ? ((ExpressionInfo) other).fullExpression == null : + fullExpression.equals(((ExpressionInfo) other).fullExpression)) { + if (relativeExpression == null ? ((ExpressionInfo) other).relativeExpression == null : + relativeExpression.equals(((ExpressionInfo) other).relativeExpression)) { + return true; + } + } + } + return false; + } + + @Override + public int hashCode() { + return (fullExpression == null ? 0 : fullExpression.hashCode()) ^ + (relativeExpression == null ? 0 : relativeExpression.hashCode()); + } + + @Override + public String toString() { + return "[" + fullExpression +", " + relativeExpression + "]"; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ + } + } + /** + * This class represents an expression. + */ + protected static class MIExpressionDMC extends AbstractDMContext implements IExpressionDMContext { + /** + * This field holds an expression to be evaluated. + */ + private ExpressionInfo exprInfo; + + /** + * ExpressionDMC Constructor for expression to be evaluated in context of + * a stack frame. + * + * @param sessionId + * The session ID in which this context is created. + * @param expression + * The expression to be described by this ExpressionDMC + * @param relExpr + * The relative expression if this expression was created as a child + * @param frameCtx + * The parent stack frame context for this ExpressionDMC. + */ + public MIExpressionDMC(String sessionId, String expression, String relExpr, IFrameDMContext frameCtx) { + this(sessionId, expression, relExpr, (IDMContext)frameCtx); + } + + /** + * ExpressionDMC Constructor for expression to be evaluated in context of + * an thread. + * + * @param sessionId + * The session ID in which this context is created. + * @param expression + * The expression to be described by this ExpressionDMC + * @param relExpr + * The relative expression if this expression was created as a child + * @param execCtx + * The parent thread context for this ExpressionDMC. + */ + public MIExpressionDMC(String sessionId, String expression, String relExpr, IMIExecutionDMContext execCtx) { + this(sessionId, expression, relExpr, (IDMContext)execCtx); + } + + /** + * ExpressionDMC Constructor for expression to be evaluated in context of + * a memory space. + * + * @param sessionId + * The session ID in which this context is created. + * @param expression + * The expression to be described by this ExpressionDMC + * @param relExpr + * The relative expression if this expression was created as a child + * @param memoryCtx + * The parent memory space context for this ExpressionDMC. + */ + public MIExpressionDMC(String sessionId, String expression, String relExpr, IMemoryDMContext memoryCtx) { + this(sessionId, expression, relExpr, (IDMContext)memoryCtx); + } + + private MIExpressionDMC(String sessionId, String expr, String relExpr, IDMContext parent) { + super(sessionId, new IDMContext[] { parent }); + exprInfo = new ExpressionInfo(expr, relExpr); + } + + /** + * @return True if the two objects are equal, false otherwise. + */ + @Override + public boolean equals(Object other) { + return super.baseEquals(other) && exprInfo.equals(((MIExpressionDMC)other).exprInfo); + } + + /** + * + * @return The hash code of this ExpressionDMC object. + */ + @Override + public int hashCode() { + return super.baseHashCode() + exprInfo.hashCode(); + } + + /** + * + * @return A string representation of this ExpressionDMC (including the + * expression to which it is bound). + */ + @Override + public String toString() { + return baseToString() + ".expr" + exprInfo.toString(); //$NON-NLS-1$ + } + + /** + * @return The full expression string represented by this ExpressionDMC + */ + public String getExpression() { + return exprInfo.getFullExpr(); + } + + /** + * @return The relative expression string represented by this ExpressionDMC + */ + public String getRelativeExpression() { + return exprInfo.getRelExpr(); + } + } + + protected static class InvalidContextExpressionDMC extends AbstractDMContext + implements IExpressionDMContext + { + private final String expression; + + public InvalidContextExpressionDMC(String sessionId, String expr, IDMContext parent) { + super(sessionId, new IDMContext[] { parent }); + expression = expr; + } + + @Override + public boolean equals(Object other) { + return super.baseEquals(other) && + expression == null ? ((InvalidContextExpressionDMC) other).getExpression() == null : expression.equals(((InvalidContextExpressionDMC) other).getExpression()); + } + + @Override + public int hashCode() { + return expression == null ? super.baseHashCode() : super.baseHashCode() ^ expression.hashCode(); + } + + @Override + public String toString() { + return baseToString() + ".invalid_expr[" + expression + "]"; //$NON-NLS-1$ //$NON-NLS-2$ + } + + public String getExpression() { + return expression; + } + } + + + /** + * Contains the address of an expression as well as the size of its type. + */ + protected static class ExpressionDMAddress implements IExpressionDMAddress { + IAddress fAddr; + int fSize; + + public ExpressionDMAddress(IAddress addr, int size) { + fAddr = addr; + fSize = size; + } + + public ExpressionDMAddress(String addrStr, int size) { + fSize = size; + // We must count the "0x" and that + // is why we compare with 10 characters + // instead of 8 + if (addrStr.length() <= 10) { + fAddr = new Addr32(addrStr); + } else { + fAddr = new Addr64(addrStr); + } + } + + public IAddress getAddress() { return fAddr; } + public int getSize() { return fSize; } + + @Override + public boolean equals(Object other) { + if (other instanceof ExpressionDMAddress) { + ExpressionDMAddress otherAddr = (ExpressionDMAddress) other; + return (fSize == otherAddr.getSize()) && + (fAddr == null ? otherAddr.getAddress() == null : fAddr.equals(otherAddr.getAddress())); + } + return false; + } + + @Override + public int hashCode() { + return (fAddr == null ? 0 :fAddr.hashCode()) + fSize; + } + + @Override + public String toString() { + return (fAddr == null ? "null" : "(0x" + fAddr.toString()) + ", " + fSize + ")"; //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$ + } + } + + /** + * This class represents the static data referenced by an instance of ExpressionDMC, + * such as its type and number of children; it does not contain the value or format + * of the expression. + */ + protected static class ExpressionDMData implements IExpressionDMData { + // This is the relative expression, such as the name of a field within a structure, + // in contrast to the fully-qualified expression contained in the ExpressionDMC, + // which refers to the full name, including parent structure. + private final String relativeExpression; + private final String exprType; + private final int numChildren; + private final boolean editable; + + /** + * ExpressionDMData constructor. + */ + public ExpressionDMData(String expr, String type, int num, boolean edit) { + relativeExpression = expr; + exprType = type; + numChildren = num; + editable = edit; + } + + public BasicType getBasicType() { + return null; + } + + public String getEncoding() { + return null; + } + + public Map getEnumerations() { + return new HashMap(); + } + + public String getName() { + return relativeExpression; + } + + public IRegisterDMContext getRegister() { + return null; + } + + // See class VariableVMNode for an example of usage of this method + public String getStringValue() { + return null; + } + + public String getTypeId() { + return null; + } + + public String getTypeName() { + return exprType; + } + + public int getNumChildren() { + return numChildren; + } + + public boolean isEditable() { + return editable; + } + + @Override + public boolean equals(Object other) { + if (other instanceof ExpressionDMData) { + ExpressionDMData otherData = (ExpressionDMData) other; + return (getNumChildren() == otherData.getNumChildren()) && + (getTypeName() == null ? otherData.getTypeName() == null : getTypeName().equals(otherData.getTypeName())) && + (getName() == null ? otherData.getName() == null : getName().equals(otherData.getName())); + } + return false; + } + + @Override + public int hashCode() { + return relativeExpression == null ? 0 : relativeExpression.hashCode() + + exprType == null ? 0 : exprType.hashCode() + numChildren; + } + + @Override + public String toString() { + return "relExpr=" + relativeExpression + ", type=" + exprType + ", numchildren=" + numChildren; //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$ + } + } + + /** + * Event generated every time an expression is changed by the ExpressionService. + * + * A client wishing to receive such events has to register as a service + * event listener and implement the corresponding eventDispatched method. + * + * E.g.: + * + * getSession().addServiceEventListener(listenerObject, null); + * + * @DsfServiceEventHandler + * public void eventDispatched(ExpressionChangedEvent e) { + * IExpressionDMContext context = e.getDMContext(); + * // do something... + * } + */ + protected static class ExpressionChangedEvent extends AbstractDMEvent + implements IExpressionChangedDMEvent { + + public ExpressionChangedEvent(IExpressionDMContext context) { + super(context); + } + } + + // This field holds a reference to to the data model context for this service. + private CommandCache fExpressionCache; + private MIVariableManager varManager; + + + public ExpressionService(DsfSession session) { + super(session); + } + + /** + * This method initializes this service. + * + * @param requestMonitor + * The request monitor indicating the operation is finished + */ + @Override + public void initialize(final RequestMonitor requestMonitor) { + super.initialize(new RequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleOK() { + doInitialize(requestMonitor); + } + }); + } + + /** + * This method initializes this service after our superclass's initialize() + * method succeeds. + * + * @param requestMonitor + * The call-back object to notify when this service's + * initialization is done. + */ + private void doInitialize(RequestMonitor requestMonitor) { + + // Register to receive service events for this session. + getSession().addServiceEventListener(this, null); + + // Register this service. + register(new String[] { IExpressions.class.getName(), + ExpressionService.class.getName() }, + new Hashtable()); + + // Create the expressionService-specific CommandControl which is our + // variable object manager. + // It will deal with the meta-commands, before sending real MI commands + // to the back-end, through the MICommandControl service + // It must be created after the ExpressionService is registered + // since it will need to find it. + varManager = new MIVariableManager(getSession(), getServicesTracker()); + + // Create the meta command cache which will use the variable manager + // to actually send MI commands to the back-end + fExpressionCache = new CommandCache(varManager); + + requestMonitor.done(); + } + + /** + * This method shuts down this service. It unregisters the service, stops + * receiving service events, and calls the superclass shutdown() method to + * finish the shutdown process. + * + * @return void + */ + @Override + public void shutdown(RequestMonitor requestMonitor) { + unregister(); + varManager.shutdown(); + getSession().removeServiceEventListener(this); + super.shutdown(requestMonitor); + } + + /** + * @return The bundle context of the plug-in to which this service belongs. + */ + @Override + protected BundleContext getBundleContext() { + return MIPlugin.getBundleContext(); + } + + /** + * Create an expression context with the same full and relative expression + */ + public IExpressionDMContext createExpression(IDMContext ctx, String expression) { + return createExpression(ctx, expression, expression); + } + + /** + * Create an expression context. + */ + public IExpressionDMContext createExpression(IDMContext ctx, String expression, String relExpr) { + IFrameDMContext frameDmc = DMContexts.getAncestorOfType(ctx, IFrameDMContext.class); + if (frameDmc != null) { + return new MIExpressionDMC(getSession().getId(), expression, relExpr, frameDmc); + } + + IMIExecutionDMContext execCtx = DMContexts.getAncestorOfType(ctx, IMIExecutionDMContext.class); + if (execCtx != null) { + return new MIExpressionDMC(getSession().getId(), expression, relExpr, execCtx); + } + + IMemoryDMContext memoryCtx = DMContexts.getAncestorOfType(ctx, IMemoryDMContext.class); + if (memoryCtx != null) { + return new MIExpressionDMC(getSession().getId(), expression, relExpr, memoryCtx); + } + + // Don't care about the relative expression at this point + return new InvalidContextExpressionDMC(getSession().getId(), expression, ctx); + } + + /** + * @see IFormattedValues.getFormattedValueContext(IFormattedDataDMContext, String) + * + * @param dmc + * The context describing the data for which we want to create + * a Formatted context. + * @param formatId + * The format that will be used to create the Formatted context + * + * @return A FormattedValueDMContext that can be used to obtain the value + * of an expression in a specific format. + */ + + public FormattedValueDMContext getFormattedValueContext( + IFormattedDataDMContext dmc, String formatId) { + return new FormattedValueDMContext(this, dmc, formatId); + } + + /** + * @see IFormattedValues.getAvailableFormats(IFormattedDataDMContext, DataRequestMonitor) + * + * @param dmc + * The context describing the data for which we want to know + * which formats are available. + * @param rm + * The data request monitor for this asynchronous operation. + * + */ + + public void getAvailableFormats(IFormattedDataDMContext dmc, + final DataRequestMonitor rm) { + rm.setData(new String[] { IFormattedValues.BINARY_FORMAT, + IFormattedValues.NATURAL_FORMAT, IFormattedValues.HEX_FORMAT, + IFormattedValues.OCTAL_FORMAT, IFormattedValues.DECIMAL_FORMAT }); + rm.done(); + } + + /** + * This method obtains the model data for a given ExpressionDMC object or + * for a FormattedValueDMC, or for this DSF service. + * + * @param dmc + * The context for which we are requesting the data + * @param rm + * The request monitor that will contain the requested data + */ + @SuppressWarnings("unchecked") + public void getModelData(IDMContext dmc, DataRequestMonitor rm) { + if (dmc instanceof MIExpressionDMC) { + getExpressionData((MIExpressionDMC) dmc, + (DataRequestMonitor) rm); + } else if (dmc instanceof FormattedValueDMContext) { + getFormattedExpressionValue((FormattedValueDMContext) dmc, + (DataRequestMonitor) rm); + } else { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ + rm.done(); + } + } + + /** + * Obtains the static data of an expression represented + * by an ExpressionDMC object (dmc). + * + * @param dmc + * The ExpressionDMC for the expression to be evaluated. + * @param rm + * The data request monitor that will contain the requested data + */ + public void getExpressionData( + final IExpressionDMContext dmc, + final DataRequestMonitor rm) + { + if (dmc instanceof MIExpressionDMC) { + fExpressionCache.execute( + new ExprMetaGetVar(dmc), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + rm.setData(new ExpressionDMData(getData().getExpr(), + getData().getType(), getData().getNumChildren(), getData().getEditable())); + rm.done(); + } + }); + } else if (dmc instanceof InvalidContextExpressionDMC) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context for evaluating expressions.", null)); //$NON-NLS-1$ + rm.done(); + } else { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid expression context.", null)); //$NON-NLS-1$ + rm.done(); + } + } + + /** + * Obtains the address of an expression and the size of its type. + * + * @param dmc + * The ExpressionDMC for the expression. + * @param rm + * The data request monitor that will contain the requested data + */ + public void getExpressionAddressData( + IExpressionDMContext dmc, + final DataRequestMonitor rm) { + + // First create an address expression and a size expression + // to be used in back-end calls + final IExpressionDMContext addressDmc = + createExpression( dmc, "&(" + dmc.getExpression() + ")" );//$NON-NLS-1$//$NON-NLS-2$ + final IExpressionDMContext sizeDmc = + createExpression( dmc, "sizeof(" + dmc.getExpression() + ")" ); //$NON-NLS-1$//$NON-NLS-2$ + + if (addressDmc instanceof InvalidContextExpressionDMC || sizeDmc instanceof InvalidContextExpressionDMC) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context for evaluating expressions.", null)); //$NON-NLS-1$ + rm.done(); + } else { + fExpressionCache.execute( + new MIDataEvaluateExpression(addressDmc), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + final String addrStr = getData().getValue(); + fExpressionCache.execute( + new MIDataEvaluateExpression(sizeDmc), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + try { + int size = Integer.parseInt(getData().getValue()); + rm.setData(new ExpressionDMAddress(addrStr, size)); + } catch (NumberFormatException e) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, + "Unexpected size format from backend: " + getData().getValue(), null)); //$NON-NLS-1$ + } + rm.done(); + } + }); + } + }); + } + } + + /** + * Obtains the value of an expression in a specific format. + * + * @param dmc + * The context for the format of the value requested and + * for the expression to be evaluated. The expression context + * should be a parent of the FormattedValueDMContext. + * @param rm + * The data request monitor that will contain the requested data + */ + public void getFormattedExpressionValue( + final FormattedValueDMContext dmc, + final DataRequestMonitor rm) + { + // We need to make sure the FormattedValueDMContext also holds an ExpressionContext, + // or else this method cannot do its work. + // Note that we look for MIExpressionDMC and not IExpressionDMC, because getting + // looking for IExpressionDMC could yield InvalidContextExpressionDMC which is still + // not what we need to have. + if (DMContexts.getAncestorOfType(dmc, MIExpressionDMC.class) == null ) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context for evaluating expressions.", null)); //$NON-NLS-1$ + rm.done(); + } else { + fExpressionCache.execute( + new ExprMetaGetValue(dmc), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + rm.setData(new FormattedValueDMData(getData().getValue())); + rm.done(); + } + }); + } + } + + /* Not implemented + * + * (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IExpressions#getBaseExpressions(org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) + */ + public void getBaseExpressions(IExpressionDMContext exprContext, + DataRequestMonitor rm) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, + NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$ + rm.done(); + } + + /** + * Retrieves the children expressions of the specified expression + * + * @param exprCtx + * The context for the expression for which the children + * should be retrieved. + * @param rm + * The data request monitor that will contain the requested data + */ + public void getSubExpressions(final IExpressionDMContext dmc, + final DataRequestMonitor rm) + { + if (dmc instanceof MIExpressionDMC) { + fExpressionCache.execute( + new ExprMetaGetChildren(dmc), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + ExpressionInfo[] childrenExpr = getData().getChildrenExpressions(); + IExpressionDMContext[] childArray = new IExpressionDMContext[childrenExpr.length]; + for (int i=0; i rm) { + getSubExpressions( + exprCtx, + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + rm.setData((IExpressionDMContext[])Arrays.asList(getData()).subList(startIndex, startIndex + length).toArray()); + rm.done(); + } + }); + } + + /** + * Retrieves the count of children expressions of the specified expression + * + * @param exprCtx + * The context for the expression for which the children count + * should be retrieved. + * @param rm + * The data request monitor that will contain the requested data + */ + public void getSubExpressionCount(IExpressionDMContext dmc, + final DataRequestMonitor rm) + { + if (dmc instanceof MIExpressionDMC) { + fExpressionCache.execute( + new ExprMetaGetChildCount(dmc), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + rm.setData(getData().getChildNum()); + rm.done(); + } + }); + } else if (dmc instanceof InvalidContextExpressionDMC) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context for evaluating expressions.", null)); //$NON-NLS-1$ + rm.done(); + } else { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid expression context.", null)); //$NON-NLS-1$ + rm.done(); + } + } + + /** + * This method indicates if an expression can be written to. + * + * @param dmc: The data model context representing an expression. + * + * @param rm: Data Request monitor containing True if this expression's value can be edited. False otherwise. + */ + + public void canWriteExpression(IExpressionDMContext dmc, final DataRequestMonitor rm) { + if (dmc instanceof MIExpressionDMC) { + fExpressionCache.execute( + new ExprMetaGetAttributes(dmc), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + rm.setData(getData().getEditable()); + rm.done(); + } + }); + } else if (dmc instanceof InvalidContextExpressionDMC) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context for evaluating expressions.", null)); //$NON-NLS-1$ + rm.done(); + } else { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid expression context.", null)); //$NON-NLS-1$ + rm.done(); + } + } + + + /** + * Changes the value of the specified expression based on the new value and format. + * + * @param expressionContext + * The context for the expression for which the value + * should be changed. + * @param expressionValue + * The new value for the specified expression + * @param formatId + * The format in which the value is specified + * @param rm + * The request monitor that will indicate the completion of the operation + */ + public void writeExpression(final IExpressionDMContext dmc, String expressionValue, + String formatId, final RequestMonitor rm) { + + if (dmc instanceof MIExpressionDMC) { + // This command must not be cached, since it changes the state of the back-end. + // We must send it directly to the variable manager + varManager.writeValue( + dmc, + expressionValue, + formatId, + new RequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + // A value has changed, we should remove any references to that + // value in our cache. Since we don't have such granularity, + // we must clear the entire cache. + // We cannot use the context to do a more-specific reset, because + // the same global variable can be set with different contexts + fExpressionCache.reset(); + + // Issue event that the expression has changed + getSession().dispatchEvent(new ExpressionChangedEvent(dmc), getProperties()); + + rm.done(); + } + }); + } else if (dmc instanceof InvalidContextExpressionDMC) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context for evaluating expressions.", null)); //$NON-NLS-1$ + rm.done(); + } else { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid expression context.", null)); //$NON-NLS-1$ + rm.done(); + } + } + + + @DsfServiceEventHandler + public void eventDispatched(IRunControl.IResumedDMEvent e) { + fExpressionCache.setTargetAvailable(false); + if (e.getReason() != StateChangeReason.STEP) { + fExpressionCache.reset(); + } + } + + @DsfServiceEventHandler + public void eventDispatched(IRunControl.ISuspendedDMEvent e) { + fExpressionCache.setTargetAvailable(true); + fExpressionCache.reset(); + } + + @DsfServiceEventHandler + public void eventDispatched(IMemoryChangedEvent e) { + fExpressionCache.reset(); + // We must also deal with our MIVariableManager since it + // caches variable values, which may now have changed + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/IMIExecutionDMContext.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/IMIExecutionDMContext.java new file mode 100644 index 00000000000..2413909f075 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/IMIExecutionDMContext.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service; + +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; + +/** + * An execution context object. In the GDB/MI protocol, threads are represented + * by an integer identifier, which is the basis for this context. The parent of this + * context should always be a container context. + */ +public interface IMIExecutionDMContext extends IExecutionDMContext +{ + /** + * Returns the GDB/MI thread identifier of this context. + * @return + */ + public int getThreadId(); +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointDMData.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointDMData.java new file mode 100644 index 00000000000..ce595d76bce --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointDMData.java @@ -0,0 +1,267 @@ +/******************************************************************************* + * Copyright (c) 2007 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.utils.Addr64; +import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointDMData; +import org.eclipse.dd.mi.service.command.output.MIBreakpoint; + +public class MIBreakpointDMData implements IBreakpointDMData { + + /** + * MI-specific breakpoint attributes markers. + */ + public static final String DSFMIBREAKPOINT = "org.eclipse.dd.dsf.debug.breakpoint.mi"; //$NON-NLS-1$ + public static final String NUMBER = DSFMIBREAKPOINT + ".number"; //$NON-NLS-1$ + public static final String TYPE = DSFMIBREAKPOINT + ".type"; //$NON-NLS-1$ + public static final String THREAD_ID = DSFMIBREAKPOINT + ".threadId"; //$NON-NLS-1$ + public static final String FULL_NAME = DSFMIBREAKPOINT + ".fullName"; //$NON-NLS-1$ + public static final String HITS = DSFMIBREAKPOINT + ".hits"; //$NON-NLS-1$ + public static final String IS_TEMPORARY = DSFMIBREAKPOINT + ".isTemporary"; //$NON-NLS-1$ + public static final String IS_HARDWARE = DSFMIBREAKPOINT + ".isHardware"; //$NON-NLS-1$ + public static final String LOCATION = DSFMIBREAKPOINT + ".location"; //$NON-NLS-1$ + + // Back-end breakpoint object + private final MIBreakpoint fBreakpoint; + private final Map fProperties; + + // Breakpoint types + public static enum MIBreakpointNature { UNKNOWN, BREAKPOINT, WATCHPOINT, CATCHPOINT }; + private final MIBreakpointNature fNature; + + + /////////////////////////////////////////////////////////////////////////// + // Constructors + /////////////////////////////////////////////////////////////////////////// + + /** + * Copy constructor + * + * @param other + */ + public MIBreakpointDMData(MIBreakpointDMData other) { + + fBreakpoint = new MIBreakpoint(other.fBreakpoint); + fProperties = new HashMap(other.fProperties); + fNature = other.fNature; + } + + /** + * Constructs a DsfMIBreakpoint from a back-end object + * + * @param dsfMIBreakpoint back-end breakpoint + */ + public MIBreakpointDMData(MIBreakpoint dsfMIBreakpoint) { + + // We only support breakpoint and watchpoint (so far) + fBreakpoint = dsfMIBreakpoint; + fNature = dsfMIBreakpoint.isWatchpoint() ? MIBreakpointNature.WATCHPOINT : MIBreakpointNature.BREAKPOINT; + + fProperties = new HashMap(); + switch (fNature) { + + case BREAKPOINT: + { + // Generic breakpoint attributes + fProperties.put(MIBreakpoints.BREAKPOINT_TYPE, MIBreakpoints.BREAKPOINT); + fProperties.put(MIBreakpoints.FILE_NAME, dsfMIBreakpoint.getFile()); + fProperties.put(MIBreakpoints.LINE_NUMBER, dsfMIBreakpoint.getLine()); + fProperties.put(MIBreakpoints.FUNCTION, dsfMIBreakpoint.getFunction()); + fProperties.put(MIBreakpoints.ADDRESS, dsfMIBreakpoint.getAddress()); + fProperties.put(MIBreakpoints.CONDITION, dsfMIBreakpoint.getCondition()); + fProperties.put(MIBreakpoints.IGNORE_COUNT, dsfMIBreakpoint.getIgnoreCount()); + fProperties.put(MIBreakpoints.IS_ENABLED, new Boolean(dsfMIBreakpoint.isEnabled())); + + // MI-specific breakpoint attributes + fProperties.put(NUMBER, dsfMIBreakpoint.getNumber()); + fProperties.put(TYPE, dsfMIBreakpoint.getType()); + fProperties.put(THREAD_ID, dsfMIBreakpoint.getThreadId()); + fProperties.put(FULL_NAME, dsfMIBreakpoint.getFullName()); + fProperties.put(HITS, dsfMIBreakpoint.getTimes()); + fProperties.put(IS_TEMPORARY, new Boolean(dsfMIBreakpoint.isTemporary())); + fProperties.put(IS_HARDWARE, new Boolean(dsfMIBreakpoint.isHardware())); + fProperties.put(LOCATION, formatLocation()); + break; + } + + case WATCHPOINT: + { + // Generic breakpoint attributes + fProperties.put(MIBreakpoints.BREAKPOINT_TYPE, MIBreakpoints.WATCHPOINT); + fProperties.put(MIBreakpoints.EXPRESSION, dsfMIBreakpoint.getExpression()); + fProperties.put(MIBreakpoints.READ, dsfMIBreakpoint.isAccessWatchpoint() || dsfMIBreakpoint.isReadWatchpoint()); + fProperties.put(MIBreakpoints.WRITE, dsfMIBreakpoint.isAccessWatchpoint() || dsfMIBreakpoint.isWriteWatchpoint()); + + // MI-specific breakpoint attributes + fProperties.put(NUMBER, dsfMIBreakpoint.getNumber()); + break; + } + + // Not reachable + default: + { + fProperties.put(MIBreakpoints.BREAKPOINT_TYPE, null); + break; + } + } + } + + /** + * Formats the LOCATION synthetic property from the existing fields + * + * @return The location string + */ + private String formatLocation() { + + // Unlikely default location + String location = fBreakpoint.getAddress(); + + // Get the relevant parameters + String fileName = fBreakpoint.getFile(); + Integer lineNumber = fBreakpoint.getLine(); + String function = fBreakpoint.getFunction(); + + if (!fileName.equals("")) { //$NON-NLS-1$ + if (lineNumber != -1) { + location = fileName + ":" + lineNumber; //$NON-NLS-1$ + } else { + location = fileName + ":" + function; //$NON-NLS-1$ + } + } + + return location; + } + + /** + * Checks for equality + * + * @param other + * @return + */ + public boolean equals(MIBreakpointDMData other) { + return (fNature == other.fNature) && (fProperties.equals(other.fProperties)); + } + + /////////////////////////////////////////////////////////////////////////// + // IBreakpointDMData + /////////////////////////////////////////////////////////////////////////// + + public String getBreakpointType() { + return (String) fProperties.get(MIBreakpoints.BREAKPOINT_TYPE); + } + + public int getReference() { + return fBreakpoint.getNumber(); + } + + public IAddress[] getAddresses() { + IAddress[] addresses = new IAddress[1]; + addresses[0] = new Addr64(fBreakpoint.getAddress()); + return addresses; + } + + public String getCondition() { + return fBreakpoint.getCondition(); + } + + public String getExpression() { + return fBreakpoint.getExpression(); + } + + public String getFileName() { + return fBreakpoint.getFile(); + } + + public String getFunctionName() { + return fBreakpoint.getFunction(); + } + + public int getIgnoreCount() { + return fBreakpoint.getIgnoreCount(); + } + + public int getLineNumber() { + return fBreakpoint.getLine(); + } + + public boolean isEnabled() { + return fBreakpoint.isEnabled(); + } + + /////////////////////////////////////////////////////////////////////////// + // MIBreakpointDMData + /////////////////////////////////////////////////////////////////////////// + + public int getNumber() { + return fBreakpoint.getNumber(); + } + + public String getThreadId() { + return fBreakpoint.getThreadId(); + } + + public boolean isTemporary() { + return fBreakpoint.isTemporary(); + } + + public boolean isHardware() { + return fBreakpoint.isHardware(); + } + + public String getLocation() { + return (String) fProperties.get(LOCATION); + } + + public int getHits() { + return fBreakpoint.getTimes(); + } + + public String getFullName() { + return fBreakpoint.getFullName(); + } + + public String getType() { + return fBreakpoint.getType(); + } + + public void setCondition(String condition) { + fBreakpoint.setCondition(condition); + fProperties.put(MIBreakpoints.CONDITION, condition); + } + + public void setIgnoreCount(int ignoreCount) { + fBreakpoint.setIgnoreCount(ignoreCount); + fProperties.put(MIBreakpoints.IGNORE_COUNT, ignoreCount); + } + + public void setEnabled(boolean isEnabled) { + fBreakpoint.setEnabled(isEnabled); + fProperties.put(MIBreakpoints.IS_ENABLED, isEnabled); + } + + public boolean isReadWatchpoint() { + return fBreakpoint.isReadWatchpoint(); + } + + public boolean isWriteWatchpoint() { + return fBreakpoint.isWriteWatchpoint(); + } + + public boolean isAccessWatchpoint() { + return fBreakpoint.isAccessWatchpoint(); + } + +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpoints.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpoints.java new file mode 100644 index 00000000000..8f97eb51a53 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpoints.java @@ -0,0 +1,956 @@ +/******************************************************************************* + * Copyright (c) 2007 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service; + +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Map; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.AbstractDMContext; +import org.eclipse.dd.dsf.datamodel.AbstractDMEvent; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.IBreakpoints; +import org.eclipse.dd.dsf.debug.service.command.ICommandControl; +import org.eclipse.dd.dsf.service.AbstractDsfService; +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.mi.internal.MIPlugin; +import org.eclipse.dd.mi.service.command.commands.MIBreakAfter; +import org.eclipse.dd.mi.service.command.commands.MIBreakCondition; +import org.eclipse.dd.mi.service.command.commands.MIBreakDelete; +import org.eclipse.dd.mi.service.command.commands.MIBreakDisable; +import org.eclipse.dd.mi.service.command.commands.MIBreakEnable; +import org.eclipse.dd.mi.service.command.commands.MIBreakInsert; +import org.eclipse.dd.mi.service.command.commands.MIBreakList; +import org.eclipse.dd.mi.service.command.commands.MIBreakWatch; +import org.eclipse.dd.mi.service.command.events.MIGDBExitEvent; +import org.eclipse.dd.mi.service.command.events.MIWatchpointScopeEvent; +import org.eclipse.dd.mi.service.command.output.MIBreakInsertInfo; +import org.eclipse.dd.mi.service.command.output.MIBreakListInfo; +import org.eclipse.dd.mi.service.command.output.MIBreakpoint; +import org.eclipse.dd.mi.service.command.output.MIInfo; +import org.osgi.framework.BundleContext; + +/** + * Initial breakpoint service implementation. + * Implements the IBreakpoints interface. + */ +public class MIBreakpoints extends AbstractDsfService implements IBreakpoints +{ + /** + * Breakpoint attributes markers used in the map parameters of insert/updateBreakpoint(). + * All are optional with the possible exception of TYPE. It is the responsibility of the + * service to ensure that the set of attributes provided is sufficient to create/update + * a valid breakpoint on the back-end. + */ + public static final String PREFIX = "org.eclipse.dd.dsf.debug.breakpoint"; //$NON-NLS-1$ + + // General markers + public static final String BREAKPOINT_TYPE = PREFIX + ".type"; //$NON-NLS-1$ + public static final String BREAKPOINT = "breakpoint"; //$NON-NLS-1$ + public static final String WATCHPOINT = "watchpoint"; //$NON-NLS-1$ + public static final String CATCHPOINT = "catchpoint"; //$NON-NLS-1$ + + // Basic set of breakpoint attribute markers + public static final String FILE_NAME = PREFIX + ".fileName"; //$NON-NLS-1$ + public static final String LINE_NUMBER = PREFIX + ".lineNumber"; //$NON-NLS-1$ + public static final String FUNCTION = PREFIX + ".function"; //$NON-NLS-1$ + public static final String ADDRESS = PREFIX + ".address"; //$NON-NLS-1$ + public static final String CONDITION = PREFIX + ".condition"; //$NON-NLS-1$ + public static final String IGNORE_COUNT = PREFIX + ".ignoreCount"; //$NON-NLS-1$ + public static final String IS_ENABLED = PREFIX + ".isEnabled"; //$NON-NLS-1$ + + // Basic set of watchpoint attribute markers + public static final String EXPRESSION = PREFIX + ".expression"; //$NON-NLS-1$ + public static final String READ = PREFIX + ".read"; //$NON-NLS-1$ + public static final String WRITE = PREFIX + ".write"; //$NON-NLS-1$ + + + // Services + ICommandControl fConnection; + + // Service breakpoints tracking + // The breakpoints are stored per context and keyed on the back-end breakpoint reference + private Map> fBreakpoints = + new HashMap>(); + + // Error messages + final String NULL_STRING = ""; //$NON-NLS-1$ + final String UNKNOWN_EXECUTION_CONTEXT = "Unknown execution context"; //$NON-NLS-1$ + final String UNKNOWN_BREAKPOINT_CONTEXT = "Unknown breakpoint context"; //$NON-NLS-1$ + final String UNKNOWN_BREAKPOINT_TYPE = "Unknown breakpoint type"; //$NON-NLS-1$ + final String UNKNOWN_BREAKPOINT = "Unknown breakpoint"; //$NON-NLS-1$ + final String BREAKPOINT_INSERTION_FAILURE = "Breakpoint insertion failure"; //$NON-NLS-1$ + final String WATCHPOINT_INSERTION_FAILURE = "Watchpoint insertion failure"; //$NON-NLS-1$ + final String INVALID_CONDITION = "Invalid condition"; //$NON-NLS-1$ + + /////////////////////////////////////////////////////////////////////////// + // Breakpoint Events + /////////////////////////////////////////////////////////////////////////// + + public class BreakpointsChangedEvent extends AbstractDMEvent implements IBreakpointsChangedEvent { + private IBreakpointDMContext[] fEventBreakpoints; + + public BreakpointsChangedEvent(IBreakpointDMContext bp) { + super(DMContexts.getAncestorOfType(bp, IBreakpointsTargetDMContext.class)); + fEventBreakpoints = new IBreakpointDMContext[] { bp }; + } + public IBreakpointDMContext[] getBreakpoints() { + return fEventBreakpoints; + } + } + + public class BreakpointAddedEvent extends BreakpointsChangedEvent implements IBreakpointsAddedEvent { + public BreakpointAddedEvent(IBreakpointDMContext context) { + super(context); + } + } + + public class BreakpointUpdatedEvent extends BreakpointsChangedEvent implements IBreakpointsUpdatedEvent { + public BreakpointUpdatedEvent(IBreakpointDMContext context) { + super(context); + } + } + + public class BreakpointRemovedEvent extends BreakpointsChangedEvent implements IBreakpointsRemovedEvent { + public BreakpointRemovedEvent(IBreakpointDMContext context) { + super(context); + } + } + + /////////////////////////////////////////////////////////////////////////// + // IBreakpointDMContext + // Used to hold the back-end breakpoint references. The reference can then + // be used to get the actual DsfMIBreakpoint. + /////////////////////////////////////////////////////////////////////////// + @Immutable + public static final class MIBreakpointDMContext extends AbstractDMContext implements IBreakpointDMContext { + + // The breakpoint reference + private final Integer fReference; + + /** + * @param service the Breakpoint service + * @param parents the parent contexts + * @param reference the DsfMIBreakpoint reference + */ + public MIBreakpointDMContext(MIBreakpoints service, IDMContext[] parents, int reference) { + super(service.getSession().getId(), parents); + fReference = reference; + } + + /* (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IBreakpoints.IDsfBreakpointDMContext#getReference() + */ + public int getReference() { + return fReference; + } + + /* (non-Javadoc) + * @see org.eclipse.dd.dsf.datamodel.AbstractDMContext#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + return baseEquals(obj) && (fReference == ((MIBreakpointDMContext) obj).fReference); + } + + /* (non-Javadoc) + * @see org.eclipse.dd.dsf.datamodel.AbstractDMContext#hashCode() + */ + @Override + public int hashCode() { + return baseHashCode() + fReference.hashCode(); + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return baseToString() + ".reference(" + fReference + ")"; //$NON-NLS-1$//$NON-NLS-2$*/ + } + } + + /////////////////////////////////////////////////////////////////////////// + // AbstractDsfService + /////////////////////////////////////////////////////////////////////////// + + /** + * The service constructor + * + * @param session The debugging session + */ + public MIBreakpoints(DsfSession session) { + super(session); + } + + /* (non-Javadoc) + * @see org.eclipse.dd.dsf.service.AbstractDsfService#initialize(org.eclipse.dd.dsf.concurrent.RequestMonitor) + */ + @Override + public void initialize(final RequestMonitor rm) { + super.initialize(new RequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + doInitialize(rm); + } + }); + } + + /* + * Asynchronous service initialization + */ + private void doInitialize(final RequestMonitor rm) { + + // Get the services references + fConnection = getServicesTracker().getService(ICommandControl.class); + + // Register for the useful events + getSession().addServiceEventListener(this, null); + + // Register this service + register(new String[] { IBreakpoints.class.getName(), MIBreakpoints.class.getName() }, + new Hashtable()); + + rm.done(); + } + + /* (non-Javadoc) + * @see org.eclipse.dd.dsf.service.AbstractDsfService#shutdown(org.eclipse.dd.dsf.concurrent.RequestMonitor) + */ + @Override + public void shutdown(final RequestMonitor rm) { + unregister(); + getSession().removeServiceEventListener(this); + rm.done(); + } + + /* (non-Javadoc) + * @see org.eclipse.dd.dsf.service.AbstractDsfService#getBundleContext() + */ + @Override + protected BundleContext getBundleContext() { + return MIPlugin.getBundleContext(); + } + + /////////////////////////////////////////////////////////////////////////// + // IServiceEventListener + /////////////////////////////////////////////////////////////////////////// + + /* + * When a watchpoint goes out of scope, it is automatically removed from + * the back-end. To keep our internal state synchronized, we have to + * remove it from our breakpoints map. + */ + @DsfServiceEventHandler + public void eventDispatched(MIWatchpointScopeEvent e) { + // PP: + IBreakpointsTargetDMContext bpContext = DMContexts.getAncestorOfType(e.getDMContext(), IBreakpointsTargetDMContext.class); + if (bpContext != null) { + Map contextBps = fBreakpoints.get(bpContext); + if (contextBps != null) { + contextBps.remove(e.getNumber()); + } + } + } + + @DsfServiceEventHandler + public void eventDispatched(MIGDBExitEvent e) { + // TODO: Remove the installed breakpoints from the back-end + } + + /////////////////////////////////////////////////////////////////////////// + // IBreakpoints interface + /////////////////////////////////////////////////////////////////////////// + + //------------------------------------------------------------------------- + // getBreakpoints + //------------------------------------------------------------------------- + + /* (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IBreakpoints#getBreakpoints(org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) + */ + public void getBreakpoints(final IBreakpointsTargetDMContext context, final DataRequestMonitor drm) + { + // Validate the context + if (context == null) { + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_EXECUTION_CONTEXT, null)); + drm.done(); + return; + } + + // Select the breakpoints context map + // If it doesn't exist then no breakpoint was ever inserted for this breakpoint space. + // In that case, return an empty list. + final Map breakpointContext = fBreakpoints.get(context); + if (breakpointContext == null) { + drm.setData(new IBreakpointDMContext[0]); + drm.done(); + return; + } + + // Execute the command + fConnection.queueCommand(new MIBreakList(context), + new DataRequestMonitor(getExecutor(), drm) { + @Override + protected void handleOK() { + // Refresh the breakpoints map and format the result + breakpointContext.clear(); + MIBreakpoint[] breakpoints = getData().getMIBreakpoints(); + IBreakpointDMContext[] result = new IBreakpointDMContext[breakpoints.length]; + for (int i = 0; i < breakpoints.length; i++) { + MIBreakpointDMData breakpoint = new MIBreakpointDMData(breakpoints[i]); + int reference = breakpoint.getReference(); + result[i] = new MIBreakpointDMContext(MIBreakpoints.this, new IDMContext[] { context }, reference); + breakpointContext.put(reference, breakpoint); + } + drm.setData(result); + drm.done(); + } + }); + } + + //------------------------------------------------------------------------- + // getBreakpointDMData + //------------------------------------------------------------------------- + + /* (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IBreakpoints#getBreakpointDMData(org.eclipse.dd.dsf.debug.service.IBreakpoints.IDsfBreakpointDMContext, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) + */ + public void getBreakpointDMData(IBreakpointDMContext dmc, DataRequestMonitor drm) + { + // Validate the breakpoint context + if (dmc == null) { + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); + drm.done(); + return; + } + + // Validate the breakpoint type + MIBreakpointDMContext breakpoint; + if (dmc instanceof MIBreakpointDMContext) { + breakpoint = (MIBreakpointDMContext) dmc; + } + else { + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT_TYPE, null)); + drm.done(); + return; + } + + // Validate the target context + IBreakpointsTargetDMContext context = DMContexts.getAncestorOfType(breakpoint, IBreakpointsTargetDMContext.class); + if (context == null) { + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_EXECUTION_CONTEXT, null)); + drm.done(); + return; + } + + // Select the breakpoints context map + Map contextBreakpoints = fBreakpoints.get(context); + if (contextBreakpoints == null) { + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); + drm.done(); + return; + } + + // No need to go to the back-end for this one + IBreakpointDMData breakpointCopy = new MIBreakpointDMData(contextBreakpoints.get(breakpoint.getReference())); + drm.setData(breakpointCopy); + drm.done(); + } + + //------------------------------------------------------------------------- + // insertBreakpoint + //------------------------------------------------------------------------- + + /* (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IBreakpoints#insertBreakpoint(org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext, java.util.Map, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) + */ + public void insertBreakpoint(IBreakpointsTargetDMContext context, Map attributes, DataRequestMonitor drm) { + + // Validate the context + if (context == null) { + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_EXECUTION_CONTEXT, null)); + drm.done(); + return; + } + + // Select the breakpoints context map. If it doesn't exist, create it. + Map breakpointContext = fBreakpoints.get(context); + if (breakpointContext == null) { + breakpointContext = new HashMap(); + fBreakpoints.put(context, breakpointContext); + } + + // Validate the breakpoint type + String type = (String) attributes.get(BREAKPOINT_TYPE); + if (type == null) { + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT_TYPE, null)); + drm.done(); + return; + } + + // And go... + if (type.equals(BREAKPOINT)) { + addBreakpoint(context, attributes, drm); + } + else if (type.equals(WATCHPOINT)) { + addWatchpoint(context, attributes, drm); + } + else { + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT_TYPE, null)); + drm.done(); + } + } + + /** + * @param map + * @param key + * @param defaultValue + * @return + */ + public Object getProperty(Map map, String key, Object defaultValue) { + return (map.containsKey(key) && (map.get(key) != null)) ? map.get(key) : defaultValue; + } + + /** + * @param attributes + * @return + */ + private String formatLocation(Map attributes) { + + // Unlikely default location + String location = (String) getProperty(attributes, ADDRESS, NULL_STRING); + + // Get the relevant parameters + String fileName = (String) getProperty(attributes, FILE_NAME, NULL_STRING); + Integer lineNumber = (Integer) getProperty(attributes, LINE_NUMBER, -1); + String function = (String) getProperty(attributes, FUNCTION, NULL_STRING); + + if (!fileName.equals(NULL_STRING)) { + if (lineNumber != -1) { + location = fileName + ":" + lineNumber; //$NON-NLS-1$ + } else { + location = fileName + ":" + function; //$NON-NLS-1$ + } + } + + return location; + } + + /** + * Add a breakpoint of type BREAKPOINT + * + * @param context + * @param breakpoint + * @param drm + */ + private void addBreakpoint(final IBreakpointsTargetDMContext context, final Map attributes, final DataRequestMonitor drm) + { + // Select the context breakpoints map + final Map contextBreakpoints = fBreakpoints.get(context); + if (contextBreakpoints == null) { + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); + drm.done(); + return; + } + + // Extract the relevant parameters (providing default values to avoid potential NPEs) + String location = formatLocation(attributes); + Boolean isTemporary = (Boolean) getProperty(attributes, MIBreakpointDMData.IS_TEMPORARY, false); + Boolean isHardware = (Boolean) getProperty(attributes, MIBreakpointDMData.IS_HARDWARE, false); + final String condition = (String) getProperty(attributes, CONDITION, NULL_STRING); + Integer ignoreCount = (Integer) getProperty(attributes, IGNORE_COUNT, 0 ); + String threadId = (String) getProperty(attributes, MIBreakpointDMData.THREAD_ID, "0"); //$NON-NLS-1$ + int tid = Integer.parseInt(threadId); + + // The DataRequestMonitor for the add request + DataRequestMonitor addBreakpointDRM = + new DataRequestMonitor(getExecutor(), drm) { + @Override + protected void handleOK() { + + // With MI, an invalid location won't generate an error + if (getData().getMIBreakpoints().length == 0) { + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, BREAKPOINT_INSERTION_FAILURE, null)); + drm.done(); + return; + } + + // Create a breakpoint object and store it in the map + final MIBreakpointDMData newBreakpoint = new MIBreakpointDMData(getData().getMIBreakpoints()[0]); + int reference = newBreakpoint.getNumber(); + if (reference == -1) { + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, BREAKPOINT_INSERTION_FAILURE, null)); + drm.done(); + return; + } + contextBreakpoints.put(reference, newBreakpoint); + + // Format the return value + MIBreakpointDMContext dmc = new MIBreakpointDMContext(MIBreakpoints.this, new IDMContext[] { context }, reference); + drm.setData(dmc); + + // Flag the event + getSession().dispatchEvent(new BreakpointAddedEvent(dmc), getProperties()); + + // By default the breakpoint is enabled at creation + // If it wasn't supposed to be, then disable it right away + Map delta = new HashMap(); + delta.put(IS_ENABLED, getProperty(attributes, IS_ENABLED, true)); + modifyBreakpoint(dmc, delta, drm, false); + } + + @Override + protected void handleError() { + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, BREAKPOINT_INSERTION_FAILURE, null)); + drm.done(); + } + }; + + // Execute the command + fConnection.queueCommand( + new MIBreakInsert(context, isTemporary, isHardware, condition, ignoreCount, location, tid), addBreakpointDRM); + } + + /** + * Add a breakpoint of type WATCHPOINT + * + * @param context + * @param watchpoint + * @param drm + */ + private void addWatchpoint(final IBreakpointsTargetDMContext context, final Map attributes, final DataRequestMonitor drm) + { + // Pick the context breakpoints map + final Map contextBreakpoints = fBreakpoints.get(context); + if (contextBreakpoints == null) { + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); + drm.done(); + return; + } + + // Extract the relevant parameters (providing default values to avoid potential NPEs) + String expression = (String) getProperty(attributes, EXPRESSION, NULL_STRING); + boolean isRead = (Boolean) getProperty(attributes, READ, false); + boolean isWrite = (Boolean) getProperty(attributes, WRITE, false); + + // The DataRequestMonitor for the add request + DataRequestMonitor addWatchpointDRM = + new DataRequestMonitor(getExecutor(), drm) { + @Override + protected void handleOK() { + + // With MI, an invalid location won't generate an error + if (getData().getMIBreakpoints().length == 0) { + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, WATCHPOINT_INSERTION_FAILURE, null)); + drm.done(); + return; + } + + // Create a breakpoint object and store it in the map + final MIBreakpointDMData newBreakpoint = new MIBreakpointDMData(getData().getMIBreakpoints()[0]); + int reference = newBreakpoint.getNumber(); + if (reference == -1) { + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, WATCHPOINT_INSERTION_FAILURE, null)); + drm.done(); + return; + } + contextBreakpoints.put(reference, newBreakpoint); + + // Format the return value + IBreakpointDMContext dmc = new MIBreakpointDMContext(MIBreakpoints.this, new IDMContext[] { context }, reference); + drm.setData(dmc); + + // Flag the event + getSession().dispatchEvent(new BreakpointAddedEvent(dmc), getProperties()); + + // Condition, ignore count and state can not be specified at watchpoint creation time. + // Therefore, we have to update the watchpoint if any of these is present + Map delta = new HashMap(); + delta.put(CONDITION, getProperty(attributes, CONDITION, NULL_STRING)); + delta.put(IGNORE_COUNT, getProperty(attributes, IGNORE_COUNT, 0 )); + delta.put(IS_ENABLED, getProperty(attributes, IS_ENABLED, true)); + modifyBreakpoint(dmc, delta, drm, false); + } + + @Override + protected void handleError() { + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, WATCHPOINT_INSERTION_FAILURE, null)); + drm.done(); + } + }; + + // Execute the command + fConnection.queueCommand(new MIBreakWatch(context, isRead, isWrite, expression), addWatchpointDRM); + } + + //------------------------------------------------------------------------- + // removeBreakpoint + //------------------------------------------------------------------------- + + /* (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IBreakpoints#removeBreakpoint(org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointDMContext, org.eclipse.dd.dsf.concurrent.RequestMonitor) + */ + public void removeBreakpoint(final IBreakpointDMContext dmc, final RequestMonitor rm) { + + // Validate the breakpoint context + if (dmc == null) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); + rm.done(); + return; + } + + // Validate the breakpoint type + MIBreakpointDMContext breakpointCtx; + if (dmc instanceof MIBreakpointDMContext) { + breakpointCtx = (MIBreakpointDMContext) dmc; + } + else { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT_TYPE, null)); + rm.done(); + return; + } + + // Validate the target context + IBreakpointsTargetDMContext context = DMContexts.getAncestorOfType(dmc, IBreakpointsTargetDMContext.class); + if (context == null) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_EXECUTION_CONTEXT, null)); + rm.done(); + return; + } + + // Pick the context breakpoints map + final Map contextBreakpoints = fBreakpoints.get(context); + if (contextBreakpoints == null) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); + rm.done(); + return; + } + + // Validate the breakpoint + final int reference = breakpointCtx.getReference(); + MIBreakpointDMData breakpoint = contextBreakpoints.get(reference); + if (breakpoint == null) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); + rm.done(); + return; + } + + // Queue the command + fConnection.queueCommand( + new MIBreakDelete(context, new int[] { reference }), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + getSession().dispatchEvent(new BreakpointRemovedEvent(dmc), getProperties()); + contextBreakpoints.remove(reference); + } + rm.done(); + } + }); + } + + // ------------------------------------------------------------------------- + // updateBreakpoint + //------------------------------------------------------------------------- + + /* (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IBreakpoints#updateBreakpoint(org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointDMContext, java.util.Map, org.eclipse.dd.dsf.concurrent.RequestMonitor) + */ + public void updateBreakpoint(IBreakpointDMContext dmc, Map properties, RequestMonitor rm) + { + // Validate the breakpoint context + if (dmc == null) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); + rm.done(); + return; + } + + // Validate the breakpoint type + MIBreakpointDMContext breakpointCtx; + if (dmc instanceof MIBreakpointDMContext) { + breakpointCtx = (MIBreakpointDMContext) dmc; + } + else { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT_TYPE, null)); + rm.done(); + return; + } + + // Validate the context + IBreakpointsTargetDMContext context = DMContexts.getAncestorOfType(dmc, IBreakpointsTargetDMContext.class); + if (context == null) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_EXECUTION_CONTEXT, null)); + rm.done(); + return; + } + + // Pick the context breakpoints map + final Map contextBreakpoints = fBreakpoints.get(context); + if (contextBreakpoints == null) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); + rm.done(); + return; + } + + // Validate the breakpoint + final int reference = breakpointCtx.getReference(); + MIBreakpointDMData breakpoint = contextBreakpoints.get(reference); + if (breakpoint == null) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); + rm.done(); + return; + } + + modifyBreakpoint(dmc, properties, rm, true); + } + + /** + * @param dmc + * @param properties + * @param rm + * @param generateUpdateEvent + */ + private void modifyBreakpoint(final IBreakpointDMContext dmc, Map attributes, final RequestMonitor rm, final boolean generateUpdateEvent) + { + // Use a working copy of the attributes since we are going to tamper happily with them + Map properties = new HashMap(attributes); + + // Retrieve the breakpoint parameters + // At this point, we know their are OK so there is no need to re-validate + MIBreakpointDMContext breakpointCtx = (MIBreakpointDMContext) dmc; + IBreakpointsTargetDMContext context = DMContexts.getAncestorOfType(dmc, IBreakpointsTargetDMContext.class); + final Map contextBreakpoints = fBreakpoints.get(context); + final int reference = breakpointCtx.getReference(); + MIBreakpointDMData breakpoint = contextBreakpoints.get(reference); + + // Track the number of change requests + int numberOfChanges = 0; + final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + if (generateUpdateEvent) + getSession().dispatchEvent(new BreakpointUpdatedEvent(dmc), getProperties()); + rm.done(); + } + }; + + // Determine if the breakpoint condition changed + String conditionAttribute = CONDITION; + if (properties.containsKey(conditionAttribute)) { + String oldValue = breakpoint.getCondition(); + String newValue = (String) properties.get(conditionAttribute); + if (newValue == null) newValue = NULL_STRING; + if (!oldValue.equals(newValue)) { + changeCondition(context, reference, newValue, countingRm); + numberOfChanges++; + } + properties.remove(conditionAttribute); + } + + // Determine if the breakpoint ignore count changed + String ignoreCountAttribute = IGNORE_COUNT; + if (properties.containsKey(ignoreCountAttribute)) { + Integer oldValue = breakpoint.getIgnoreCount(); + Integer newValue = (Integer) properties.get(ignoreCountAttribute); + if (newValue == null) newValue = 0; + if (!oldValue.equals(newValue)) { + changeIgnoreCount(context, reference, newValue, countingRm); + numberOfChanges++; + } + properties.remove(ignoreCountAttribute); + } + + // Determine if the breakpoint state changed + String enableAttribute = IS_ENABLED; + if (properties.containsKey(enableAttribute)) { + Boolean oldValue = breakpoint.isEnabled(); + Boolean newValue = (Boolean) properties.get(enableAttribute); + if (newValue == null) newValue = false; + if (!oldValue.equals(newValue)) { + numberOfChanges++; + if (newValue) + enableBreakpoint(context, reference, countingRm); + else + disableBreakpoint(context, reference, countingRm); + } + properties.remove(enableAttribute); + } + + // Set the number of completions required + countingRm.setDoneCount(numberOfChanges); + } + + /** + * Update the breakpoint condition + * + * @param context + * @param dmc + * @param condition + * @param rm + */ + private void changeCondition(IBreakpointsTargetDMContext context, + final int reference, final String condition, final RequestMonitor rm) + { + // Pick the context breakpoints map + final Map contextBreakpoints = fBreakpoints.get(context); + if (contextBreakpoints == null) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); + rm.done(); + return; + } + + // Queue the command + fConnection.queueCommand( + new MIBreakCondition(context, reference, condition), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleCompleted() { + MIBreakpointDMData breakpoint = contextBreakpoints.get(reference); + if (breakpoint == null) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); + rm.done(); + return; + } + if (getStatus().isOK()) { + breakpoint.setCondition(condition); + } + else { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, INVALID_CONDITION, null)); + breakpoint.setCondition(NULL_STRING); + } + rm.done(); + } + }); + } + + + /** + * Update the breakpoint ignoreCount + * + * @param context + * @param reference + * @param ignoreCount + * @param rm + */ + private void changeIgnoreCount(IBreakpointsTargetDMContext context, + final int reference, final int ignoreCount, final RequestMonitor rm) + { + // Pick the context breakpoints map + final Map contextBreakpoints = fBreakpoints.get(context); + if (contextBreakpoints == null) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); + rm.done(); + return; + } + + // Queue the command + fConnection.queueCommand( + new MIBreakAfter(context, reference, ignoreCount), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + MIBreakpointDMData breakpoint = contextBreakpoints.get(reference); + if (breakpoint == null) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); + rm.done(); + return; + } + breakpoint.setIgnoreCount(ignoreCount); + rm.done(); + } + }); + } + + /** + * Enable the breakpoint + * + * @param context + * @param reference + * @param rm + */ + private void enableBreakpoint(IBreakpointsTargetDMContext context, + final int reference, final RequestMonitor rm) + { + // Pick the context breakpoints map + final Map contextBreakpoints = fBreakpoints.get(context); + if (contextBreakpoints == null) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); + rm.done(); + return; + } + + // Queue the command + fConnection.queueCommand( + new MIBreakEnable(context, new int[] { reference }), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + MIBreakpointDMData breakpoint = contextBreakpoints.get(reference); + if (breakpoint == null) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); + rm.done(); + return; + } + breakpoint.setEnabled(true); + rm.done(); + } + }); + } + + /** + * Disable the breakpoint + * + * @param context + * @param dmc + * @param rm + */ + private void disableBreakpoint(IBreakpointsTargetDMContext context, + final int reference, final RequestMonitor rm) + { + // Pick the context breakpoints map + final Map contextBreakpoints = fBreakpoints.get(context); + if (contextBreakpoints == null) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); + rm.done(); + return; + } + + // Queue the command + fConnection.queueCommand( + new MIBreakDisable(context, new int[] { reference }), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + MIBreakpointDMData breakpoint = contextBreakpoints.get(reference); + if (breakpoint == null) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); + rm.done(); + return; + } + breakpoint.setEnabled(false); + rm.done(); + } + }); + } + +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointsActionManager.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointsActionManager.java new file mode 100644 index 00000000000..9cc46e6c481 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointsActionManager.java @@ -0,0 +1,185 @@ +/******************************************************************************* + * Copyright (c) 2007 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service; + +import java.io.StringReader; +import java.util.ArrayList; +import java.util.Iterator; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.eclipse.cdt.debug.core.CDebugCorePlugin; +import org.eclipse.cdt.debug.core.breakpointactions.IBreakpointAction; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.debug.core.model.IBreakpoint; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.helpers.DefaultHandler; + +public class MIBreakpointsActionManager { + + public static final String BREAKPOINT_ACTION_ATTRIBUTE = "BREAKPOINT_ACTIONS"; //$NON-NLS-1$ + private static final String BREAKPOINT_ACTION_DATA = "BreakpointActionManager.actionData"; //$NON-NLS-1$ + + private ArrayList breakpointActions = null; + + public MIBreakpointsActionManager() { + } + + public void executeActions(final IBreakpoint breakpoint, final IAdaptable context) { + if (breakpoint != null) { + IMarker marker = breakpoint.getMarker(); + String actionNames = marker.getAttribute(BREAKPOINT_ACTION_ATTRIBUTE, ""); //$NON-NLS-1$ + final String[] actions = actionNames.split(","); + if (actions.length > 0){ + Job job = new Job("Execute breakpoint actions") { + public IStatus run(final IProgressMonitor monitor) { + return doExecuteActions(breakpoint, context, actions, monitor); + } + }; + job.schedule(); + try { + // wait for actions to execute + job.join(); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } + + private IStatus doExecuteActions(final IBreakpoint breakpoint, final IAdaptable context, String[] actions, IProgressMonitor monitor) { + try { + for (int i = 0; i < actions.length && !monitor.isCanceled(); i++) { + String actionName = actions[i]; + IBreakpointAction action = findBreakpointAction(actionName); + if (action != null) { + monitor.setTaskName(action.getSummary()); + IStatus status = action.execute(breakpoint, context, monitor); + if (status.getCode() != IStatus.OK) { + // do not log status if user canceled. + if (status.getCode() != IStatus.CANCEL) + CDebugCorePlugin.log(status); + return status; + } + } + monitor.worked(1); + } + } catch (Exception e) { + return new Status( IStatus.ERROR, CDebugCorePlugin.getUniqueIdentifier(), CDebugCorePlugin.INTERNAL_ERROR, "Internal Error", e ); + } + return monitor.isCanceled() ? Status.CANCEL_STATUS : Status.OK_STATUS; + } + + public IBreakpointAction findBreakpointAction(String name) { + for (Iterator iter = getBreakpointActions().iterator(); iter.hasNext();) { + IBreakpointAction action = (IBreakpointAction) iter.next(); + if (action.getName().equals(name)) + return action; + } + return null; + } + + public ArrayList getBreakpointActions() { + if (breakpointActions == null) { + breakpointActions = new ArrayList(); + loadActionData(); + } + return breakpointActions; + } + + private void loadActionData() { + + String actionData = CDebugCorePlugin.getDefault().getPluginPreferences().getString(BREAKPOINT_ACTION_DATA); + + if (actionData == null || actionData.length() == 0) + return; + + Element root = null; + DocumentBuilder parser; + try { + parser = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + parser.setErrorHandler(new DefaultHandler()); + root = parser.parse(new InputSource(new StringReader(actionData))).getDocumentElement(); + + NodeList nodeList = root.getChildNodes(); + int entryCount = nodeList.getLength(); + + for (int i = 0; i < entryCount; i++) { + Node node = nodeList.item(i); + short type = node.getNodeType(); + if (type == Node.ELEMENT_NODE) { + Element subElement = (Element) node; + String nodeName = subElement.getNodeName(); + if (nodeName.equalsIgnoreCase("actionEntry")) { //$NON-NLS-1$ + String name = subElement.getAttribute("name"); //$NON-NLS-1$ + if (name == null) + throw new Exception(); + String value = subElement.getAttribute("value"); //$NON-NLS-1$ + if (value == null) + throw new Exception(); + String className = subElement.getAttribute("class"); //$NON-NLS-1$ + if (className == null) + throw new Exception(); + + IBreakpointAction action = createActionFromClassName(name, className); + action.initializeFromMemento(value); + } + } + } + + } catch (Exception e) { + e.printStackTrace(); + } + } + + private IBreakpointAction createActionFromClassName(String name, String className) { + + IBreakpointAction action = null; + IExtension[] actionExtensions = CDebugCorePlugin.getDefault().getBreakpointActionManager().getBreakpointActionExtensions(); + + try { + + for (int i = 0; i < actionExtensions.length && action == null; i++) { + IConfigurationElement[] elements = actionExtensions[i].getConfigurationElements(); + for (int j = 0; j < elements.length && action == null; j++) { + IConfigurationElement element = elements[j]; + if (element.getName().equals(CDebugCorePlugin.ACTION_TYPE_ELEMENT)) { + if (element.getAttribute("class").equals(className)) { //$NON-NLS-1$ + action = (IBreakpointAction) element.createExecutableExtension("class"); //$NON-NLS-1$ + action.setName(name); + CDebugCorePlugin.getDefault().getBreakpointActionManager().addAction(action); + } + } + } + } + + } catch (CoreException e) { + e.printStackTrace(); + } + + return action; + } + +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointsManager.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointsManager.java new file mode 100644 index 00000000000..a4faefb1d5c --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointsManager.java @@ -0,0 +1,1484 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River 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 - Initial API and implementation + * Ericsson - High-level breakpoints integration + * Ericsson - Added breakpoint filter support + * Ericsson - Re-factored the service and put a few comments + *******************************************************************************/ + +package org.eclipse.dd.mi.service; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Vector; +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.cdt.debug.core.model.ICBreakpoint; +import org.eclipse.cdt.debug.core.model.ICBreakpointExtension; +import org.eclipse.cdt.debug.core.model.ICLineBreakpoint; +import org.eclipse.cdt.debug.core.model.ICWatchpoint; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IMarkerDelta; +import org.eclipse.core.resources.IWorkspaceRunnable; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +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.core.runtime.jobs.MultiRule; +import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.IBreakpoints; +import org.eclipse.dd.dsf.debug.service.IDsfBreakpointExtension; +import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.ISourceLookup; +import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointDMContext; +import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.dsf.debug.service.ISourceLookup.ISourceLookupDMContext; +import org.eclipse.dd.dsf.debug.service.command.ICommandControl; +import org.eclipse.dd.dsf.service.AbstractDsfService; +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.mi.internal.MIPlugin; +import org.eclipse.dd.mi.service.MIRunControl.MIExecutionDMC; +import org.eclipse.dd.mi.service.command.events.MIGDBExitEvent; +import org.eclipse.dd.mi.service.command.events.MIWatchpointScopeEvent; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.IBreakpointListener; +import org.eclipse.debug.core.IBreakpointManager; +import org.eclipse.debug.core.IBreakpointManagerListener; +import org.eclipse.debug.core.model.IBreakpoint; +import org.osgi.framework.BundleContext; + +/** + * Breakpoint service interface. The breakpoint service tracks CDT breakpoint + * objects, and based on those, it manages breakpoints in the debugger back end. + * + * It relies on MIBreakpoints for the actual back-end interface. + */ +public class MIBreakpointsManager extends AbstractDsfService implements IBreakpointManagerListener, IBreakpointListener +{ + // Note: Find a way to import this (careful of circular dependencies) + public final static String GDB_DEBUG_MODEL_ID = "org.eclipse.dd.dsf.gdb"; //$NON-NLS-1$ + + // Extra breakpoint attributes + private static final String ATTR_DEBUGGER_PATH = MIPlugin.PLUGIN_ID + ".debuggerPath"; //$NON-NLS-1$ + private static final String ATTR_THREAD_FILTER = MIPlugin.PLUGIN_ID + ".threadFilter"; //$NON-NLS-1$ + private static final String ATTR_THREAD_ID = MIPlugin.PLUGIN_ID + ".threadID"; //$NON-NLS-1$ + + // Services + ICommandControl fConnection; + IRunControl fRunControl; + ISourceLookup fSourceLookup; + IBreakpoints fBreakpoints; + IBreakpointManager fBreakpointManager; // Platform breakpoint manager (not this!) + // FIXME: MIBreakpointsActionManager fBreakpointActionManager; + + /////////////////////////////////////////////////////////////////////////// + // Breakpoints tracking + /////////////////////////////////////////////////////////////////////////// + + private String fDebugModelId; + + // Holds the set of platform breakpoints with their corresponding back-end + // breakpoint attributes, per context (i.e. each platform breakpoint is + // replicated for each execution context). + // - Context entry added/removed on start/stopTrackingBreakpoints() + // - Augmented on breakpointAdded() + // - Modified on breakpointChanged() + // - Diminished on breakpointRemoved() + private Map>> fPlatformBPs = + new HashMap>>(); + + // Holds the set of target breakpoints, per execution context, and their + // mapping to the corresponding platform breakpoint. In a given execution + // context there can only be one platform breakpoint per target breakpoint. + // Acts as a mapping from target (low-level) BP to the corresponding platform + // (high-level) BP. + // Updated when: + // - We start/stop tracking an execution context + // - A platform breakpoint is added/removed + // - A thread filter is applied/removed + private Map> fTargetBPs = + new HashMap>(); + + // Holds the mapping from platform breakpoint to the corresponding target + // breakpoint(s), per context. There can be multiple back-end BPs for a + // single platform BP in the case of [1] multiple target contexts, and/or + // [2] thread filtering. + // Updated when: + // - We start/stop tracking an execution context + // - A platform breakpoint is added/removed + // - A thread filter is applied/removed + private Map>> fBreakpointIDs = + new HashMap>>(); + + // Holds the mapping from platform breakpoint to the corresponding target + // breakpoint threads, per context. + // Updated when: + // - We start/stop tracking an execution context + // - A platform breakpoint is added/removed + // - A thread filter is applied/removed + private Map>> fBreakpointThreads = + new HashMap>>(); + + // Due to the very asynchronous nature of DSF, a new breakpoint request can + // pop up at any time before an ongoing one is completed. The following set + // is used to store requests until the ongoing operation completes. + private Set fPendingRequests = new HashSet(); + private Set fPendingBreakpoints = new HashSet(); + + /////////////////////////////////////////////////////////////////////////// + // String constants + // FIXME: Extract to some centralized location + /////////////////////////////////////////////////////////////////////////// + + private static final String NULL_STRING = ""; //$NON-NLS-1$ + + static final String CONTEXT_ALREADY_INITIALIZED = "Context already initialized"; //$NON-NLS-1$ + static final String INVALID_CONTEXT_TYPE = "Invalid context type"; //$NON-NLS-1$ + static final String INVALID_CONTEXT = "Invalid context"; //$NON-NLS-1$ + + static final String UNABLE_TO_READ_BREAKPOINT = "Unable to read initial breakpoint attributes"; //$NON-NLS-1$ + static final String BREAKPOINT_NOT_INSTALLED = "Breakpoints not installed for given context"; //$NON-NLS-1$ + static final String BREAKPOINT_ALREADY_INSTALLED = "Breakpoint already installed"; //$NON-NLS-1$ + static final String BREAKPOINT_ALREADY_REMOVED = "Breakpoint already removed"; //$NON-NLS-1$ + + static final String INVALID_BREAKPOINT = "Invalid breakpoint"; //$NON-NLS-1$ + static final String UNKNOWN_BREAKPOINT = "Unknown breakpoint"; //$NON-NLS-1$ + static final String INVALID_PARAMETER = "Invalid breakpoint parameter(s)"; //$NON-NLS-1$ + + static final String NO_DEBUGGER_PATH = "No debugger path for breakpoint"; //$NON-NLS-1$ + static final String NO_MARKER_FOR_BREAKPOINT = "No marker associated with breakpoint"; //$NON-NLS-1$ + + /////////////////////////////////////////////////////////////////////////// + // AbstractDsfService + /////////////////////////////////////////////////////////////////////////// + + /** + * The service constructor. + * Performs basic instantiation (method initialize() performs the real + * service initialization asynchronously). + * + * @param session the debugging session + * @param debugModelId the debugging model + */ + public MIBreakpointsManager(DsfSession session, String debugModelId) { + super(session); + fDebugModelId = debugModelId; + } + + //------------------------------------------------------------------------- + // initialize + //------------------------------------------------------------------------- + // - Collect references for the services we interact with + // - Register to interesting events + // - Obtain the list of platform breakpoints + // - Register the service for interested parties + //------------------------------------------------------------------------- + + /* (non-Javadoc) + * @see org.eclipse.dd.dsf.service.AbstractDsfService#initialize(org.eclipse.dd.dsf.concurrent.RequestMonitor) + */ + @Override + public void initialize(final RequestMonitor rm) { + super.initialize( + new RequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + doInitialize(rm); + }}); + } + + /** + * @param rm + */ + private void doInitialize(RequestMonitor rm) { + + // Get the required services references from central repository + fConnection = getServicesTracker().getService(ICommandControl.class); + fRunControl = getServicesTracker().getService(IRunControl.class); + fSourceLookup = getServicesTracker().getService(ISourceLookup.class); + fBreakpoints = getServicesTracker().getService(IBreakpoints.class); + fBreakpointManager = DebugPlugin.getDefault().getBreakpointManager(); + // FIXME: fBreakpointActionManager = new MIBreakpointsActionManager(); + + // Register to the useful events + getSession().addServiceEventListener(this, null); + fBreakpointManager.addBreakpointListener(this); + fBreakpointManager.addBreakpointManagerListener(this); + + // And register this service + register(new String[] { MIBreakpointsManager.class.getName() }, + new Hashtable()); + rm.done(); + } + + //------------------------------------------------------------------------- + // shutdown + //------------------------------------------------------------------------- + // - Un-register the service + // - Stop listening to events + // - Remove the breakpoints installed by this service + // + // Since we are shutting down, there is no overwhelming need + // to keep the maps coherent... + //------------------------------------------------------------------------- + + /* (non-Javadoc) + * @see org.eclipse.dd.dsf.service.AbstractDsfService#shutdown(org.eclipse.dd.dsf.concurrent.RequestMonitor) + */ + @Override + public void shutdown(final RequestMonitor rm) { + + // Stop accepting requests and events + unregister(); + getSession().removeServiceEventListener(this); + fBreakpointManager.removeBreakpointListener(this); + fBreakpointManager.removeBreakpointManagerListener(this); + + // Cleanup the breakpoints that are still installed by the service. + // Use a counting monitor which will call mom to complete the shutdown + // after the breakpoints are un-installed (successfully or not). + CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm) { + @Override + protected void handleCompleted() { + MIBreakpointsManager.super.shutdown(rm); + } + }; + + List targetBPKeys = new ArrayList(fTargetBPs.size()); + targetBPKeys.addAll(0, fTargetBPs.keySet()); + for (IBreakpointsTargetDMContext dmc : targetBPKeys) { + stopTrackingBreakpoints(dmc, countingRm); + } + countingRm.setDoneCount(targetBPKeys.size()); + } + + //------------------------------------------------------------------------- + // getBundleContext + //------------------------------------------------------------------------- + + /* (non-Javadoc) + * @see org.eclipse.dd.dsf.service.AbstractDsfService#getBundleContext() + */ + @Override + protected BundleContext getBundleContext() { + return MIPlugin.getBundleContext(); + } + + /////////////////////////////////////////////////////////////////////////// + // IBreakpointsManager + /////////////////////////////////////////////////////////////////////////// + + //------------------------------------------------------------------------- + // startTrackingBreakpoints + //------------------------------------------------------------------------- + // - Augment the maps with the new execution context + // - Install the platform breakpoints on the selected target + //------------------------------------------------------------------------- + + /** + * Install and begin tracking breakpoints for given context. The service + * will keep installing new breakpoints that appear in the IDE for this + * context until {@link #uninstallBreakpoints(IDMContext)} is called for that + * context. + * @param dmc Context to start tracking breakpoints for. + * @param rm Completion callback. + */ + public void startTrackingBreakpoints(final IBreakpointsTargetDMContext dmc, final RequestMonitor rm) { + + // Validate the execution context + if (dmc == null) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, INVALID_CONTEXT, null)); + rm.done(); + return; + } + + // Make sure a mapping for this execution context does not already exist + Map> platformBPs = fPlatformBPs.get(dmc); + Map> breakpointIDs = fBreakpointIDs.get(dmc); + Map targetIDs = fTargetBPs.get(dmc); + Map> threadIDs = fBreakpointThreads.get(dmc); + if ((platformBPs != null) || (breakpointIDs != null) || (targetIDs != null) || (threadIDs != null)) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INTERNAL_ERROR, CONTEXT_ALREADY_INITIALIZED, null)); + rm.done(); + return; + } + + // Create entries in the breakpoint tables for the new context. These entries should only + // be removed when this service stops tracking breakpoints for the given context. + fPlatformBPs.put(dmc, new HashMap>()); + fBreakpointIDs.put(dmc, new HashMap>()); + fTargetBPs.put(dmc, new HashMap()); + fBreakpointThreads.put(dmc, new HashMap>()); + + // Install the platform breakpoints (stored in fPlatformBPs) on the target. + // FIXME: Why bother with a Job? + new Job("DSF BreakpointsManager: Install initial breakpoints on target") { //$NON-NLS-1$ + @Override + protected IStatus run(IProgressMonitor monitor) { + // Submit the runnable to plant the breakpoints on dispatch thread. + getExecutor().submit(new Runnable() { + public void run() { + installInitialBreakpoints(dmc, rm); + } + }); + + return Status.OK_STATUS; + } + }.schedule(); + } + + /** + * Installs the breakpoints that existed prior to the activation of this + * execution context. + * + * @param dmc + * @param initialPlatformBPs + * @param rm + */ + private void installInitialBreakpoints(final IBreakpointsTargetDMContext dmc, final RequestMonitor rm) + { + // Retrieve the set of platform breakpoints for this context + final Map> platformBPs = fPlatformBPs.get(dmc); + if (platformBPs == null) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INTERNAL_ERROR, INVALID_CONTEXT, null)); + rm.done(); + return; + } + + // Read current breakpoints from platform and copy their augmented + // attributes into the local reference map + try { + IBreakpoint[] breakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints(fDebugModelId); + for (IBreakpoint breakpoint : breakpoints) { + if (supportsBreakpoint(breakpoint)) { + @SuppressWarnings("unchecked") + Map attributes = breakpoint.getMarker().getAttributes(); + attributes.put(ATTR_DEBUGGER_PATH, NULL_STRING); + attributes.put(ATTR_THREAD_FILTER, extractThreads(dmc, (ICBreakpoint) breakpoint)); + attributes.put(ATTR_THREAD_ID, NULL_STRING); + platformBPs.put((ICBreakpoint) breakpoint, attributes); + } + } + } catch (CoreException e) { + IStatus status = new Status( + IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, UNABLE_TO_READ_BREAKPOINT, e); + rm.setStatus(status); + rm.done(); + } + + // Install the individual breakpoints on the dispatcher thread + // Requires a counting monitor to know when we are done + final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm); + countingRm.setDoneCount(platformBPs.size()); + + for (final ICBreakpoint breakpoint : platformBPs.keySet()) { + final Map attributes = platformBPs.get(breakpoint); + // Upon determining the debuggerPath, the breakpoint is installed + determineDebuggerPath(dmc, attributes, new RequestMonitor(getExecutor(), countingRm) { + @Override + protected void handleOK() { + installBreakpoint(dmc, breakpoint, attributes, new RequestMonitor(getExecutor(), countingRm)); + } + }); + } + } + + //------------------------------------------------------------------------- + // stopTrackingBreakpoints + //------------------------------------------------------------------------- + // - Remove the target breakpoints for the given execution context + // - Update the maps + //------------------------------------------------------------------------- + + /** + * Uninstall and stop tracking breakpoints for the given context. + * @param dmc Context to start tracking breakpoints for. + * @param rm Completion callback. + */ + public void stopTrackingBreakpoints(final IBreakpointsTargetDMContext dmc, final RequestMonitor rm) { + + // Validate the context + if (dmc == null) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INTERNAL_ERROR, INVALID_CONTEXT, null)); + rm.done(); + return; + } + + // Retrieve the set of platform breakpoints for this context + final Map> platformBPs = fPlatformBPs.get(dmc); + if (platformBPs == null) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INTERNAL_ERROR, INVALID_CONTEXT, null)); + rm.done(); + return; + } + + // Un-install the individual breakpoints on the dispatcher thread + // (requires a counting monitor to know when we are done). + // On completion (success or failure), update the maps. + final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm) { + @Override + protected void handleCompleted() { + fPlatformBPs.remove(dmc); + fBreakpointIDs.remove(dmc); + fTargetBPs.remove(dmc); + fBreakpointThreads.remove(dmc); + rm.done(); + } + }; + countingRm.setDoneCount(platformBPs.size()); + + for (final ICBreakpoint breakpoint : platformBPs.keySet()) { + uninstallBreakpoint(dmc, breakpoint, + new RequestMonitor(getExecutor(), countingRm) { + @Override + protected void handleCompleted() { + countingRm.done(); + } + }); + } + } + + /////////////////////////////////////////////////////////////////////////// + // Back-end interface functions + /////////////////////////////////////////////////////////////////////////// + + //------------------------------------------------------------------------- + // installBreakpoint + //------------------------------------------------------------------------- + + /** + * Install a platform breakpoint on the back-end. For a given context, a + * platform breakpoint can resolve into multiple back-end breakpoints when + * threads are taken into account. + * + * @param dmc + * @param breakpoint + * @param attributes + * @param rm + */ + private void installBreakpoint(IBreakpointsTargetDMContext dmc, final ICBreakpoint breakpoint, + final Map attributes, final RequestMonitor rm) + { + // Retrieve the breakpoint maps + final Map> platformBPs = fPlatformBPs.get(dmc); + assert platformBPs != null; + + final Map> breakpointIDs = fBreakpointIDs.get(dmc); + assert breakpointIDs != null; + + final Map targetBPs = fTargetBPs.get(dmc); + assert targetBPs != null; + + final Map> threadsIDs = fBreakpointThreads.get(dmc); + assert threadsIDs != null; + + // Minimal validation + if (breakpointIDs.containsKey(breakpoint) || targetBPs.containsValue(breakpoint)) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INTERNAL_ERROR, BREAKPOINT_ALREADY_INSTALLED, null)); + rm.done(); + return; + } + + // Ensure the breakpoint has a valid debugger source path + if (!(breakpoint instanceof ICWatchpoint)) { + String debuggerPath = (String) attributes.get(ATTR_DEBUGGER_PATH); + if (debuggerPath == null || debuggerPath == NULL_STRING) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, NO_DEBUGGER_PATH, null)); + rm.done(); + return; + } + } + + // A back-end breakpoint needs to be installed for each specified thread + // Note: This is a bit academic since [1] thread info is not kept by the + // BreakpointManager (so it can not possibly be restored when a target is + // started), and [2] the standard GUI doesn't allow to specify thread at + // breakpoint creation. However, it is conceivable that an enhanced Editor + // would permit it. + final Set threads = getThreads(attributes); + + // Update the breakpoint state when all back-end breakpoints have been installed + final CountingRequestMonitor installRM = new CountingRequestMonitor(getExecutor(), rm) { + @Override + protected void handleCompleted() { + // Store the platform breakpoint + platformBPs.put(breakpoint, attributes); + threadsIDs.put(breakpoint, threads); + rm.done(); + } + }; + installRM.setDoneCount(threads.size()); + + // Install the back-end breakpoint(s) + for (final String thread : threads) { + DataRequestMonitor drm = + new DataRequestMonitor(getExecutor(), installRM) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + // Add the new back-end breakpoint to the map + Vector list = breakpointIDs.get(breakpoint); + if (list == null) + list = new Vector(); + IBreakpointDMContext targetBP = getData(); + list.add(targetBP); + breakpointIDs.put(breakpoint, list); + + // Add the reverse mapping + targetBPs.put(targetBP, breakpoint); + + // And update the corresponding thread list + Set thrds = threadsIDs.get(breakpoint); + if (thrds == null) + thrds = new HashSet(); + thrds.add(thread); + threadsIDs.put(breakpoint, thrds); + + // Finally, update the platform breakpoint + attributes.remove(ATTR_THREAD_ID); + try { + breakpoint.incrementInstallCount(); + } catch (CoreException e) { + } + } + installRM.done(); + } + }; + + // Convert the breakpoint attributes for the back-end + attributes.put(ATTR_THREAD_ID, thread); + Map targetAttributes = convertToTargetBreakpoint(breakpoint, attributes); + fBreakpoints.insertBreakpoint(dmc, targetAttributes, drm); + } + } + + //------------------------------------------------------------------------- + // uninstallBreakpoint + //------------------------------------------------------------------------- + + /** + * Un-install an individual breakpoint on the back-end. For one platform + * breakpoint in a given execution context, there could be multiple + * corresponding back-end breakpoints (one per thread). + * + * @param dmc + * @param breakpoint + * @param rm + */ + private void uninstallBreakpoint(final IBreakpointsTargetDMContext dmc, + final ICBreakpoint breakpoint, final RequestMonitor rm) + { + // Retrieve the breakpoint maps + final Map> platformBPs = fPlatformBPs.get(dmc); + assert platformBPs != null; + + final Map> breakpointIDs = fBreakpointIDs.get(dmc); + assert breakpointIDs != null; + + final Map targetBPs = fTargetBPs.get(dmc); + assert targetBPs != null; + + final Map> threadsIDs = fBreakpointThreads.get(dmc); + assert threadsIDs != null; + + // Minimal validation + if (!platformBPs.containsKey(breakpoint) || !breakpointIDs.containsKey(breakpoint) || !targetBPs.containsValue(breakpoint)) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INTERNAL_ERROR, BREAKPOINT_ALREADY_REMOVED, null)); + rm.done(); + return; + } + + // Remove completion monitor + // Upon completion, update the mappings + CountingRequestMonitor removeRM = new CountingRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + // Update the mappings + platformBPs.remove(breakpoint); + threadsIDs.remove(breakpoint); + + Vector contexts = breakpointIDs.get(breakpoint); + if (contexts != null) { + for (IBreakpointDMContext context : contexts) + targetBPs.remove(context); + } + + breakpointIDs.get(breakpoint).clear(); + breakpointIDs.remove(breakpoint); + + fPendingRequests.remove(breakpoint); + + rm.done(); + } + }; + + // Remove the back-end breakpoints + Vector list = breakpointIDs.get(breakpoint); + int count = 0; + if (list != null) { + for (IBreakpointDMContext bp : list) { + fBreakpoints.removeBreakpoint(bp, removeRM); + try { + breakpoint.decrementInstallCount(); + } catch (CoreException e) { + } + } + count = list.size(); + } + removeRM.setDoneCount(count); + } + + //------------------------------------------------------------------------- + // modifyBreakpoint + //------------------------------------------------------------------------- + + /** + * Modify a platform breakpoint which can translate to quite a few updates + * on the target... + * + * @param dmc + * @param breakpoint + * @param attributes + * @param oldValues + * @param rm + */ + private void modifyBreakpoint(final IBreakpointsTargetDMContext dmc, final ICBreakpoint breakpoint, + final Map attributes, final IMarkerDelta oldValues, final RequestMonitor rm) + { + // Retrieve the breakpoint maps + final Map> platformBPs = fPlatformBPs.get(dmc); + assert platformBPs != null; + + final Map> breakpointIDs = fBreakpointIDs.get(dmc); + assert breakpointIDs != null; + + final Map targetBPs = fTargetBPs.get(dmc); + assert targetBPs != null; + + final Map> threadsIDs = fBreakpointThreads.get(dmc); + assert threadsIDs != null; + + // Minimal validation + if (!platformBPs.containsKey(breakpoint) || !breakpointIDs.containsKey(breakpoint) || !targetBPs.containsValue(breakpoint)) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INTERNAL_ERROR, BREAKPOINT_NOT_INSTALLED, null)); + rm.done(); + return; + } + + // Get the original breakpoint attributes + final Map original_attributes = platformBPs.get(breakpoint); + if (original_attributes == null) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, INVALID_BREAKPOINT, null)); + rm.done(); + return; + } + + // Determine the attributes delta + final Map oldAttributes = new HashMap(original_attributes); + oldAttributes.put(ATTR_THREAD_FILTER, threadsIDs.get(breakpoint)); + + final Set newThreads = extractThreads(dmc, breakpoint); + Map newAttributes = new HashMap(attributes); + newAttributes.put(ATTR_THREAD_FILTER, newThreads); + + final Map attributesDelta = determineAttributesDelta(oldAttributes, newAttributes); + + // Get the list of back-end breakpoints + final Vector oldTargetBPs = new Vector(breakpointIDs.get(breakpoint)); + if (oldTargetBPs == null) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, INVALID_BREAKPOINT, null)); + rm.done(); + return; + } + + // We're all set for the breakpoint update. + // + // The path for a simple update is straightforward: + // - For each back-end BP corresponding to a platform BP + // - Send an update command to the back-end + // - If the operation succeeded, update the data structures + // - If the operation failed, try to roll-back + // + // In cases where the the back-end breakpoint cannot be + // simply updated (e.g. thread filter modification), the old + // breakpoint has to be removed and new one(s) inserted. + // + // The path for such an update is: + // - Install the updated breakpoint + // - In the operation succeeded + // - Remove the old breakpoint(s) + // - perform any pending update + + // Update completion monitor + final CountingRequestMonitor updateRM = new CountingRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + // Success: simply store the new attributes + platformBPs.put(breakpoint, attributes); + rm.done(); + } + + @Override + protected void handleError() { + // Reset the breakpoint attributes. This will trigger a + // breakpoint change event and the correct delta will be + // computed, resulting in a correctly restored breakpoint + // at the back-end. + rollbackAttributes(breakpoint, oldValues); + platformBPs.put(breakpoint, attributes); + + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, INVALID_PARAMETER, null)); + rm.done(); + } + }; + + // Everything OK: remove the old back-end breakpoints + final Vector newTargetBPs = new Vector(); + final CountingRequestMonitor removeRM = new CountingRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + // All right! Save the new list and perform the final update + Map> breakpointIDs = fBreakpointIDs.get(dmc); + if (breakpointIDs == null) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, INVALID_BREAKPOINT, null)); + rm.done(); + return; + } + breakpointIDs.put(breakpoint, newTargetBPs); + for (IBreakpointDMContext ref : newTargetBPs) { + fBreakpoints.updateBreakpoint(ref, attributesDelta, updateRM); + } + updateRM.setDoneCount(newTargetBPs.size()); + }}; + + // New back-end breakpoints insertion monitor + // Holds the list of new back-end breakpoint contexts of the platform breakpoint + final DataRequestMonitor> insertRM = + new DataRequestMonitor>(getExecutor(), null) { + + @Override + // In theory, we could have had a partial success and the original threads + // list would be invalid. We think it is highly unlikely so we assume that + // either everything went fine or else everything failed. + protected void handleOK() { + // Get the list of new back-end breakpoints contexts + newTargetBPs.addAll(getData()); + threadsIDs.put(breakpoint, newThreads); + for (IBreakpointDMContext ref : oldTargetBPs) { + fBreakpoints.removeBreakpoint(ref, removeRM); + try { + breakpoint.decrementInstallCount(); // A tad early but it should work... + } catch (CoreException e) { + } + } + removeRM.setDoneCount(oldTargetBPs.size()); + } + + @Override + protected void handleError() { + // Keep the old threads list and reset the attributes + // (bad attributes are the likely cause of failure) + updateRM.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, INVALID_PARAMETER, null)); + updateRM.setDoneCount(0); + } + }; + + // If the changes in the breakpoint attributes justify it, install a + // new set of back-end breakpoint(s) and then update them + if (needsResinstallation(attributesDelta)) { + reinstallBreakpoint(dmc, breakpoint, attributes, newThreads, insertRM); + } + else { + // Update the back-end breakpoint(s) state + for (IBreakpointDMContext ref : oldTargetBPs) { + fBreakpoints.updateBreakpoint(ref, attributesDelta, updateRM); + } + updateRM.setDoneCount(oldTargetBPs.size()); + } + } + + /** + * Re-install the back-end breakpoints + * + * @param context the target context + * @param breakpoint the platform breakpoint + * @param attributes breakpoint augmented attributes + * @param threads list of threads where breakpoint is to be installed + * @param drm will contain the list of successfully installed back-end breakpoints + */ + private void reinstallBreakpoint(final IBreakpointsTargetDMContext context, final ICBreakpoint breakpoint, + final Map attributes, Set threads, final DataRequestMonitor> drm) + { + // Our new list of back-end breakpoints. Built as we go. + final Vector breakpointList = new Vector(); + + // Counting monitor for the new back-end breakpoints to install + // Once we're done, return the new list of back-end breakpoints contexts + final CountingRequestMonitor installRM = new CountingRequestMonitor(getExecutor(), drm) { + @Override + protected void handleOK() { + // Report whatever we have managed to install + // It is very likely installation either succeeded or failed for all + drm.setData(breakpointList); + drm.done(); + } + }; + installRM.setDoneCount(threads.size()); + + // And install the new back-end breakpoints + for (String thread : threads) { + // Convert the breakpoint attributes for the back-end + // Refresh the set of attributes at each iteration just in case... + Map attrs = convertToTargetBreakpoint(breakpoint, attributes); + if (!fBreakpointManager.isEnabled()) { + attrs.put(MIBreakpoints.IS_ENABLED, false); + } + // Add the secret ingredient.. + attrs.put(MIBreakpointDMData.THREAD_ID, thread); + + // Then install the spiked breakpoint + fBreakpoints.insertBreakpoint(context, attrs, + new DataRequestMonitor(getExecutor(), installRM) { + @Override + protected void handleOK() { + // Add the new back-end breakpoint context to the list + breakpointList.add(getData()); + try { + breakpoint.incrementInstallCount(); + } catch (CoreException e) { + } + installRM.done(); + } + + @Override + protected void handleError() { + // Add the new back-end breakpoint context to the list + installRM.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, INVALID_PARAMETER, null)); + installRM.done(); + } + }); + } + } + + /////////////////////////////////////////////////////////////////////////// + // IBreakpointManagerListener implementation + /////////////////////////////////////////////////////////////////////////// + + /* (non-Javadoc) + * @see org.eclipse.debug.core.IBreakpointManagerListener#breakpointManagerEnablementChanged(boolean) + */ + public void breakpointManagerEnablementChanged(boolean enabled) { + + // Only modify enabled breakpoints + for (IBreakpointsTargetDMContext context : fBreakpointIDs.keySet()) { + for (ICBreakpoint breakpoint : fBreakpointIDs.get(context).keySet()) { + try { + if (breakpoint.isEnabled()) { + for (IBreakpointDMContext ref : fBreakpointIDs.get(context).get(breakpoint)) { + Map delta = new HashMap(); + delta.put(MIBreakpoints.IS_ENABLED, enabled); + fBreakpoints.updateBreakpoint(ref, delta, new RequestMonitor(getExecutor(), null)); + } + } + } catch (CoreException e) { + } + } + } + } + + /////////////////////////////////////////////////////////////////////////// + // IBreakpointListener implementation + /////////////////////////////////////////////////////////////////////////// + + /* (non-Javadoc) + * @see org.eclipse.debug.core.IBreakpointListener#breakpointAdded(org.eclipse.debug.core.model.IBreakpoint) + */ + @ThreadSafe + public void breakpointAdded(final IBreakpoint breakpoint) { + + if (supportsBreakpoint(breakpoint)) { + try { + // Retrieve the breakpoint attributes + @SuppressWarnings("unchecked") + final Map attrs = breakpoint.getMarker().getAttributes(); + + getExecutor().execute(new DsfRunnable() { + public void run() { + final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), null) { + @Override + protected void handleError() { + if (getStatus().getSeverity() == IStatus.ERROR) { + MIPlugin.getDefault().getLog().log(getStatus()); + } + } + }; + countingRm.setDoneCount(fPlatformBPs.size()); + + // Install the breakpoint in all the execution contexts + for (final IBreakpointsTargetDMContext dmc : fPlatformBPs.keySet()) { + determineDebuggerPath(dmc, attrs, + new RequestMonitor(getExecutor(), countingRm) { + @Override + protected void handleOK() { + installBreakpoint(dmc, (ICBreakpoint) breakpoint, + attrs, new RequestMonitor(getExecutor(), countingRm)); + } + }); + } + } + }); + } catch (CoreException e) { + } catch (RejectedExecutionException e) { + } + } + } + + /** + * @param bp + * @return + * @throws CoreException + */ + private IDsfBreakpointExtension getFilterExtension(ICBreakpoint bp) throws CoreException { + return (IDsfBreakpointExtension) bp.getExtension(GDB_DEBUG_MODEL_ID, ICBreakpointExtension.class); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.IBreakpointListener#breakpointChanged(org.eclipse.debug.core.model.IBreakpoint, org.eclipse.core.resources.IMarkerDelta) + */ + public void breakpointChanged(final IBreakpoint breakpoint, final IMarkerDelta delta) { + + if (supportsBreakpoint(breakpoint)) { + + try { + // Retrieve the breakpoint attributes + @SuppressWarnings("unchecked") + final Map attrs = breakpoint.getMarker().getAttributes(); + if (!fBreakpointManager.isEnabled()) { + attrs.put(ICBreakpoint.ENABLED, false); + } + + // Modify the breakpoint in all the target contexts + getExecutor().execute( new DsfRunnable() { + public void run() { + + // If the breakpoint is currently being updated, queue the request and exit + if (fPendingRequests.contains(breakpoint)) { + fPendingBreakpoints.add(breakpoint); + return; + } + + // Keep track of the updates + final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), null) { + @Override + protected void handleCompleted() { + + if (!getStatus().isOK()) { + if (getStatus().getSeverity() == IStatus.ERROR) { + MIPlugin.getDefault().getLog().log(getStatus()); + } + } + + // Indicate that the pending request has completed + fPendingRequests.remove(breakpoint); + + // Process the next pending update for this breakpoint + if (fPendingBreakpoints.contains(breakpoint)) { + fPendingBreakpoints.remove(breakpoint); + breakpointChanged(breakpoint, delta); + } + } + }; + countingRm.setDoneCount(fPlatformBPs.size()); + + // Mark the breakpoint as being updated and go + fPendingRequests.add(breakpoint); + + // Modify the breakpoint in all the execution contexts + for (final IBreakpointsTargetDMContext dmc : fPlatformBPs.keySet()) { + determineDebuggerPath(dmc, attrs, + new RequestMonitor(getExecutor(), countingRm) { + @Override + protected void handleOK() { + modifyBreakpoint(dmc, (ICBreakpoint) breakpoint, attrs, delta, new RequestMonitor(getExecutor(), countingRm)); + } + }); + } + } + }); + } catch (CoreException e) { + } catch (RejectedExecutionException e) { + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.IBreakpointListener#breakpointRemoved(org.eclipse.debug.core.model.IBreakpoint, org.eclipse.core.resources.IMarkerDelta) + */ + public void breakpointRemoved(final IBreakpoint breakpoint, IMarkerDelta delta) { + + if (supportsBreakpoint(breakpoint)) { + try { + getExecutor().execute(new DsfRunnable() { + public void run() { + CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), null) { + @Override + protected void handleError() { + if (getStatus().getSeverity() == IStatus.ERROR) { + MIPlugin.getDefault().getLog().log(getStatus()); + } + } + }; + countingRm.setDoneCount(fPlatformBPs.size()); + + // Remove the breakpoint in all the execution contexts + for (IBreakpointsTargetDMContext dmc : fPlatformBPs.keySet()) { + if (fPlatformBPs.get(dmc).containsKey(breakpoint)) { + uninstallBreakpoint(dmc, (ICBreakpoint) breakpoint, countingRm); + } else { + // Breakpoint not installed for given context, do nothing. + } + } + } + }); + } catch (RejectedExecutionException e) { + } + } + } + + /////////////////////////////////////////////////////////////////////////// + // IServiceEventListener + /////////////////////////////////////////////////////////////////////////// + +// /* +// * When a breakpoint is hit, handle associated actions (if any) +// */ +// @DsfServiceEventHandler +// public void eventDispatched(DsfMIBreakpointHitEvent e) { +// IExecutionDMContext context = e.getDMContext(); +// int breakpointNumber = e.getNumber(); +//// IBreakpoint breakpoint = +//// fBreakpointActionManager. +// } + + /* + * When a watchpoint goes out of scope, it is automatically removed from + * the back-end. To keep our internal state synchronized, we have to + * remove it from our breakpoints maps. + * Unfortunately, GDB doesn't generate the correct event... + */ + @DsfServiceEventHandler + public void eventDispatched(MIWatchpointScopeEvent e) { +// fBreakpoints.remove(e.getNumber()); + } + + @DsfServiceEventHandler + public void eventDispatched(MIGDBExitEvent e) { + terminated(); + } + + private void terminated() { + clearBreakpointStatus(fPlatformBPs.keySet().toArray(new ICBreakpoint[fPlatformBPs.size()])); + fPlatformBPs.clear(); + } + + /////////////////////////////////////////////////////////////////////////// + // Breakpoint status handling functions + /////////////////////////////////////////////////////////////////////////// + + /** + * @param bps + */ + private void clearBreakpointStatus(final ICBreakpoint[] bps) + { + new Job("Clear Breakpoints Status") { //$NON-NLS-1$ + @Override + protected IStatus run(IProgressMonitor monitor) { + IWorkspaceRunnable wr = new IWorkspaceRunnable() { + public void run(IProgressMonitor monitor) throws CoreException { + for (ICBreakpoint breakpoint : bps) { + breakpoint.resetInstallCount(); + } + } + }; + + // Create the scheduling rule to clear all bp planted. + ISchedulingRule rule = null; + List markerRules = new ArrayList(); + for (ICBreakpoint bp : bps) { + IMarker marker = bp.getMarker(); + if (marker != null) { + ISchedulingRule markerRule = + ResourcesPlugin.getWorkspace().getRuleFactory().markerRule( + marker.getResource()); + if (markerRule == null) { + markerRules = null; + break; + } else { + markerRules.add(markerRule); + } + } + } + if (markerRules != null) { + rule = MultiRule.combine(markerRules.toArray(new ISchedulingRule[markerRules.size()])); + } + + try { + ResourcesPlugin.getWorkspace().run(wr, rule, 0, null); + } catch (CoreException e) { + return e.getStatus(); + } + return Status.OK_STATUS; + } + }.schedule(); + } + + /////////////////////////////////////////////////////////////////////////// + // Support functions + /////////////////////////////////////////////////////////////////////////// + + /** + * supportsBreakpoint + * + * Indicates if it is breakpoint we can deal with. For now, it boils down + * to a CDI breakpoint... + * + * @param bp + * @return + */ + private boolean supportsBreakpoint(IBreakpoint bp) { + if (bp instanceof ICBreakpoint && bp.getModelIdentifier().equals(fDebugModelId)) { + IMarker marker = bp.getMarker(); + if (marker != null) { + return true; + } + } + return false; + } + + /** + * determineDebuggerPath + * + * Adds the path to the source file to the set of attributes + * (for the debugger). + * + * @param dmc + * @param attributes + * @param rm + */ + private void determineDebuggerPath(IBreakpointsTargetDMContext dmc, + final Map attributes, final RequestMonitor rm) + { + String hostPath = (String) attributes.get(ICBreakpoint.SOURCE_HANDLE); + + if (hostPath != null) { + ISourceLookupDMContext srcDmc = DMContexts.getAncestorOfType(dmc, ISourceLookupDMContext.class); + if (srcDmc != null) { + fSourceLookup.getDebuggerPath(srcDmc, hostPath, + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + attributes.put(ATTR_DEBUGGER_PATH, getData()); + rm.done(); + } + }); + } else { + // Source lookup not available for given context, use the host + // path for the debugger path. + attributes.put(ATTR_DEBUGGER_PATH, hostPath); + rm.done(); + } + } else { + // Some types of breakpoints do not require a path + // (e.g. watchpoints) + rm.done(); + } + } + + /** + * Determine the set of modified attributes. + * Elementary set operations in full action :-) + * + * @param oldAttributes + * @param newAttributes + * @return + */ + private Map determineAttributesDelta(Map oldAttributes, Map newAttributes) { + + Map delta = new HashMap(); + + Set oldKeySet = oldAttributes.keySet(); + Set newKeySet = newAttributes.keySet(); + + Set commonKeys = new HashSet(newKeySet); commonKeys.retainAll(oldKeySet); + Set addedKeys = new HashSet(newKeySet); addedKeys.removeAll(oldKeySet); + Set removedKeys = new HashSet(oldKeySet); removedKeys.removeAll(newKeySet); + + // Add the modified attributes + for (String key : commonKeys) { + if (!(oldAttributes.get(key).equals(newAttributes.get(key)))) + delta.put(key, newAttributes.get(key)); + } + + // Add the new attributes + for (String key : addedKeys) { + delta.put(key, newAttributes.get(key)); + } + + // Remove the deleted attributes + for (String key : removedKeys) { + delta.put(key, null); + } + + return convertedAttributes(delta); + } + + /** + * Converts ICBreakpoint attributes to IBreakpoints attributes. + * + * @param cdt_attributes + * @return + */ + private Map convertedAttributes(Map cdt_attributes) { + + Map result = new HashMap(); + + // IBreakpoint attributes + if (cdt_attributes.containsKey(ATTR_DEBUGGER_PATH)) + result.put(MIBreakpoints.FILE_NAME, cdt_attributes.get(ATTR_DEBUGGER_PATH)); + + if (cdt_attributes.containsKey(IMarker.LINE_NUMBER)) + result.put(MIBreakpoints.LINE_NUMBER, cdt_attributes.get(IMarker.LINE_NUMBER)); + + // ICLineBreakpoint attributes + if (cdt_attributes.containsKey(ICLineBreakpoint.FUNCTION)) + result.put(MIBreakpoints.FUNCTION, cdt_attributes.get(ICLineBreakpoint.FUNCTION)); + + if (cdt_attributes.containsKey(ICLineBreakpoint.ADDRESS)) + result.put(MIBreakpoints.ADDRESS, cdt_attributes.get(ICLineBreakpoint.ADDRESS)); + + // ICBreakpoint attributes + if (cdt_attributes.containsKey(ICBreakpoint.CONDITION)) + result.put(MIBreakpoints.CONDITION, cdt_attributes.get(ICBreakpoint.CONDITION)); + + if (cdt_attributes.containsKey(ICBreakpoint.IGNORE_COUNT)) + result.put(MIBreakpoints.IGNORE_COUNT, cdt_attributes.get(ICBreakpoint.IGNORE_COUNT)); + + if (cdt_attributes.containsKey(ICBreakpoint.ENABLED)) + result.put(MIBreakpoints.IS_ENABLED, cdt_attributes.get(ICBreakpoint.ENABLED)); + + // ICWatchpoint attributes + if (cdt_attributes.containsKey(ICWatchpoint.EXPRESSION)) + result.put(MIBreakpoints.EXPRESSION, cdt_attributes.get(ICWatchpoint.EXPRESSION)); + + if (cdt_attributes.containsKey(ICWatchpoint.READ)) + result.put(MIBreakpoints.READ, cdt_attributes.get(ICWatchpoint.READ)); + + if (cdt_attributes.containsKey(ICWatchpoint.WRITE)) + result.put(MIBreakpoints.WRITE, cdt_attributes.get(ICWatchpoint.WRITE)); + + // Threads + if (cdt_attributes.containsKey(ATTR_THREAD_FILTER)) + result.put(ATTR_THREAD_FILTER, cdt_attributes.get(ATTR_THREAD_FILTER)); + + return result; + } + + /** + * Figure out the corresponding number of back-end breakpoints + * Even though the thread IDs are usually integers, they are + * stored as strings in CBreakpoints. + * + * @param attributes + * @return + */ + @SuppressWarnings("unchecked") + private Set getThreads(Map attributes) { + Set threads = (Set) attributes.get(ATTR_THREAD_FILTER); + if (threads == null) { + threads = new HashSet(); + threads.add("0"); // Thread 0 means all threads //$NON-NLS-1$ + } + return threads; + } + + /** + * Get the list of threads from the platform breakpoint attributes + * + * @param breakpoint + * @return + */ + private Set extractThreads(IBreakpointsTargetDMContext context, ICBreakpoint breakpoint) { + + // Find the ancestor + IContainerDMContext targetContext = DMContexts.getAncestorOfType(context, IContainerDMContext.class); + IExecutionDMContext[] threads = null; + + try { + // Retrieve the targets + IDsfBreakpointExtension filterExtension = getFilterExtension(breakpoint); + IContainerDMContext[] targets = filterExtension.getTargetFilters(); + + // If no target is present, plant one... + if (targets.length == 0) { + for (IBreakpointsTargetDMContext dmc : fPlatformBPs.keySet()) { + IContainerDMContext ctx = DMContexts.getAncestorOfType(dmc, IContainerDMContext.class); + if (ctx == targetContext) { + filterExtension.setTargetFilter(ctx); + targets = filterExtension.getTargetFilters(); + } + } + } + + // Extract the thread IDs (if there is none, we are covered) + for (IContainerDMContext ctxt : targets) { + if (ctxt == targetContext) { + threads = filterExtension.getThreadFilters(ctxt); + } + } + } catch (CoreException e1) { + } + + Set results = new HashSet(); + if ((threads != null) && (supportsThreads(breakpoint))) { + for (IExecutionDMContext thread : threads) { + if (thread instanceof MIExecutionDMC) { + MIExecutionDMC dmc = (MIExecutionDMC) thread; + results.add(((Integer) dmc.getThreadId()).toString()); + } + } + } else { + results.add("0"); //$NON-NLS-1$ + } + + return results; + } + + /////////////////////////////////////////////////////////////////////////// + // Non-generic (MI-specific) functions + /////////////////////////////////////////////////////////////////////////// + + /** + * Create a target breakpoint from an ICBreakpoint + * + * @param breakpoint + * @param attributes + * @return + */ + protected Map convertToTargetBreakpoint(ICBreakpoint breakpoint, Map attributes) { + + Map properties = new HashMap(); + + if (breakpoint instanceof ICWatchpoint) { + // Convert the CDI watchpoint to an IBreakpoint + properties.put(MIBreakpoints.BREAKPOINT_TYPE, MIBreakpoints.WATCHPOINT); + properties.put(MIBreakpoints.EXPRESSION, attributes.get(ICWatchpoint.EXPRESSION)); + properties.put(MIBreakpoints.READ, attributes.get(ICWatchpoint.READ)); + properties.put(MIBreakpoints.WRITE, attributes.get(ICWatchpoint.WRITE)); + } + else { + // Convert the CDI breakpoint to an IBreakpoint + properties.put(MIBreakpoints.BREAKPOINT_TYPE, MIBreakpoints.BREAKPOINT); + properties.put(MIBreakpoints.FILE_NAME, attributes.get(ATTR_DEBUGGER_PATH)); + properties.put(MIBreakpoints.LINE_NUMBER, attributes.get(IMarker.LINE_NUMBER)); + properties.put(MIBreakpoints.FUNCTION, attributes.get(ICLineBreakpoint.FUNCTION)); + properties.put(MIBreakpoints.ADDRESS, attributes.get(ICLineBreakpoint.ADDRESS)); + } + + // Common fields + properties.put(MIBreakpoints.CONDITION, attributes.get(ICBreakpoint.CONDITION)); + properties.put(MIBreakpoints.IGNORE_COUNT, attributes.get(ICBreakpoint.IGNORE_COUNT)); + properties.put(MIBreakpoints.IS_ENABLED, attributes.get(ICBreakpoint.ENABLED)); + properties.put(MIBreakpointDMData.THREAD_ID, attributes.get(ATTR_THREAD_ID)); + + // Adjust for "skip-all" + if (!fBreakpointManager.isEnabled()) { + properties.put(MIBreakpoints.IS_ENABLED, false); + } + + return properties; + } + + /** + * Determine if the modified attributes necessitate + * a breakpoint removal/re-installation + * + * @param delta + * @return + */ + protected boolean needsResinstallation(Map delta) { + + // Check if there is any modified attribute + if (delta == null) + return false; + + // Check the "critical" attributes + if (delta.containsKey(ATTR_DEBUGGER_PATH) // File name + || delta.containsKey(IMarker.LINE_NUMBER) // Line number + || delta.containsKey(ICLineBreakpoint.FUNCTION) // Function name + || delta.containsKey(ICLineBreakpoint.ADDRESS) // Absolute address + || delta.containsKey(ATTR_THREAD_FILTER) // Thread ID + || delta.containsKey(ICWatchpoint.EXPRESSION) // Watchpoint expression + || delta.containsKey(ICWatchpoint.READ) // Watchpoint type + || delta.containsKey(ICWatchpoint.WRITE)) { // Watchpoint type + return true; + } + + return false; + } + + /** + * @param breakpoint + * @param oldValues + */ + protected void rollbackAttributes(ICBreakpoint breakpoint, IMarkerDelta oldValues) { + + try { + String new_condition = breakpoint.getCondition(); + if (new_condition == null) + new_condition = NULL_STRING; + String old_condition = (oldValues != null) ? oldValues.getAttribute(ICBreakpoint.CONDITION, NULL_STRING) : NULL_STRING; + if (!old_condition.equals(new_condition)) { + breakpoint.setCondition(old_condition); + } + else { + breakpoint.setCondition(NULL_STRING); + } + } catch (CoreException e) { + } + } + + /** + * Indicates if the back-end supports multiple threads for + * this type of breakpoint + * + * @param breakpoint + */ + protected boolean supportsThreads(ICBreakpoint breakpoint) { + + return !(breakpoint instanceof ICWatchpoint); + } + +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIFormat.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIFormat.java new file mode 100644 index 00000000000..3a2c7ee31b1 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIFormat.java @@ -0,0 +1,109 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service; + +import java.math.BigInteger; + +/** + * Help class to specify formats. + */ +public final class MIFormat { + public final static int HEXADECIMAL = 0; + public final static int OCTAL = 1; + public final static int BINARY = 2; + public final static int DECIMAL = 3; + public final static int RAW = 4; + public final static int NATURAL = 5; + + public final static int FLOAT = 10; + public final static int ADDRESS = 11; + public final static int INSTRUCTION = 12; + public final static int CHAR = 13; + public final static int STRING = 14; + public final static int UNSIGNED = 15; + + // no instanciation. + private MIFormat() { + } + + /** + * We are assuming that GDB will print the address in hex format + * like: + * 0xbfffe5f0 "hello" + * (int *) 0xbfffe2b8 + * + * @param buffer + * @return + */ + public static BigInteger decodeAdress(String buffer) { + int radix = 10; + int cursor = 0; + int offset = 0; + int len = buffer.length(); + + if ((offset = buffer.indexOf("0x")) != -1 || //$NON-NLS-1$ + (offset = buffer.indexOf("0X")) != -1) { //$NON-NLS-1$ + radix = 16; + cursor = offset + 2; + } + + while (cursor < len && Character.digit(buffer.charAt(cursor), radix) != -1) { + cursor++; + } + + String s = buffer.substring(offset, cursor); + return getBigInteger(s); + } + + public static BigInteger getBigInteger(String address) { + int index = 0; + int radix = 10; + boolean negative = false; + + // Handle zero length + address = address.trim(); + if (address.length() == 0) { + return BigInteger.ZERO; + } + + // Handle minus sign, if present + if (address.startsWith("-")) { //$NON-NLS-1$ + negative = true; + index++; + } + if (address.startsWith("0x", index) || address.startsWith("0X", index)) { //$NON-NLS-1$ //$NON-NLS-2$ + index += 2; + radix = 16; + } else if (address.startsWith("#", index)) { //$NON-NLS-1$ + index ++; + radix = 16; + } else if (address.startsWith("0", index) && address.length() > 1 + index) { //$NON-NLS-1$ + index ++; + radix = 8; + } + + if (index > 0) { + address = address.substring(index); + } + if (negative) { + address = "-" + address; //$NON-NLS-1$ + } + try { + return new BigInteger(address, radix); + } catch (NumberFormatException e) { + // ... + // What can we do ??? + } + return BigInteger.ZERO; + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIMemory.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIMemory.java new file mode 100644 index 00000000000..d900414065d --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIMemory.java @@ -0,0 +1,895 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + * Ericsson AB - expanded from initial stub + * Ericsson AB - added support for event handling + * Ericsson AB - added memory cache + *******************************************************************************/ +package org.eclipse.dd.mi.service; + +import java.util.Hashtable; +import java.util.LinkedList; +import java.util.ListIterator; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.utils.Addr64; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.AbstractDMEvent; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.IExpressions; +import org.eclipse.dd.dsf.debug.service.IMemory; +import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMAddress; +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason; +import org.eclipse.dd.dsf.debug.service.command.CommandCache; +import org.eclipse.dd.dsf.debug.service.command.ICommandControl; +import org.eclipse.dd.dsf.service.AbstractDsfService; +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.mi.internal.MIPlugin; +import org.eclipse.dd.mi.service.ExpressionService.ExpressionChangedEvent; +import org.eclipse.dd.mi.service.command.commands.MIDataReadMemory; +import org.eclipse.dd.mi.service.command.commands.MIDataWriteMemory; +import org.eclipse.dd.mi.service.command.output.MIDataReadMemoryInfo; +import org.eclipse.dd.mi.service.command.output.MIDataWriteMemoryInfo; +import org.eclipse.debug.core.model.MemoryByte; +import org.osgi.framework.BundleContext; + +/** + * Memory service implementation + */ +public class MIMemory extends AbstractDsfService implements IMemory { + + public class MemoryChangedEvent extends AbstractDMEvent + implements IMemoryChangedEvent + { + IAddress[] fAddresses; + IDMContext fContext; + + public MemoryChangedEvent(IMemoryDMContext context, IAddress[] addresses) { + super(context); + fAddresses = addresses; + } + + public IAddress[] getAddresses() { + return fAddresses; + } + } + + @SuppressWarnings("unused") + private MIRunControl fRunControl; + private MIMemoryCache fMemoryCache; + + /** + * Constructor + */ + public MIMemory(DsfSession session) { + super(session); + } + + /////////////////////////////////////////////////////////////////////////// + // AbstractDsfService overrides + /////////////////////////////////////////////////////////////////////////// + + /* (non-Javadoc) + * @see org.eclipse.dd.dsf.service.AbstractDsfService#initialize(org.eclipse.dd.dsf.concurrent.RequestMonitor) + * + * This function is called during the launch sequence (where the service is + * instantiated). See LaunchSequence.java. + */ + @Override + public void initialize(final RequestMonitor requestMonitor) { + super.initialize(new RequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleOK() { + doInitialize(requestMonitor); + } + }); + } + + /* + * Initialization function: + * - Register the service + * - Create the command cache + * - Register self to service events + * + * @param requestMonitor + */ + private void doInitialize(final RequestMonitor requestMonitor) { + + // Register this service + register(new String[] { MIMemory.class.getName(), IMemory.class.getName() }, new Hashtable()); + + // Get the RunControl so we can retrieve the current Execution context + fRunControl = getServicesTracker().getService(MIRunControl.class); + + // Create the memory requests cache + fMemoryCache = new MIMemoryCache(); + + // Register as service event listener + getSession().addServiceEventListener(this, null); + + // Done + requestMonitor.done(); + } + + /* (non-Javadoc) + * @see org.eclipse.dd.dsf.service.AbstractDsfService#shutdown(org.eclipse.dd.dsf.concurrent.RequestMonitor) + */ + @Override + public void shutdown(final RequestMonitor requestMonitor) { + + // Unregister this service + unregister(); + + // Remove event listener + getSession().removeServiceEventListener(this); + + // Clear the cache + fMemoryCache.reset(); + + // Complete the shutdown + super.shutdown(requestMonitor); + } + + /* (non-Javadoc) + * @see org.eclipse.dd.dsf.service.AbstractDsfService#getBundleContext() + */ + @Override + protected BundleContext getBundleContext() { + return MIPlugin.getBundleContext(); + } + + /////////////////////////////////////////////////////////////////////////// + // IMemory + /////////////////////////////////////////////////////////////////////////// + + /* (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IMemory#getMemory(org.eclipse.dd.dsf.datamodel.IDMContext, org.eclipse.cdt.core.IAddress, long, int, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) + */ + public void getMemory(IMemoryDMContext memoryDMC, IAddress address, long offset, + int word_size, int count, DataRequestMonitor drm) + { + // Validate the context + if (memoryDMC == null) { + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown context type", null)); //$NON-NLS-1$); + drm.done(); + return; + } + + // Validate the word size + // NOTE: We only accept 1 byte words for this implementation + if (word_size != 1) { + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.NOT_SUPPORTED, "Word size not supported (!= 1)", null)); //$NON-NLS-1$ + drm.done(); + return; + } + + // Validate the byte count + if (count < 0) { + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Invalid word count (< 0)", null)); //$NON-NLS-1$ + drm.done(); + return; + } + + // All is clear: go for it + fMemoryCache.getMemory(memoryDMC, address.add(offset), word_size, count, drm); + } + + /* (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IMemory#setMemory(org.eclipse.dd.dsf.datamodel.IDMContext, org.eclipse.cdt.core.IAddress, long, int, byte[], org.eclipse.dd.dsf.concurrent.RequestMonitor) + */ + public void setMemory(IMemoryDMContext memoryDMC, IAddress address, long offset, + int word_size, int count, byte[] buffer, RequestMonitor rm) + { + // Validate the context + if (memoryDMC == null) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown context type", null)); //$NON-NLS-1$); + rm.done(); + return; + } + + // Validate the word size + // NOTE: We only accept 1 byte words for this implementation + if (word_size != 1) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.NOT_SUPPORTED, "Word size not supported (!= 1)", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + // Validate the byte count + if (count < 0) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Invalid word count (< 0)", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + // Validate the buffer size + if (buffer.length < count) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Buffer too short", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + // All is clear: go for it + fMemoryCache.setMemory(memoryDMC, address, offset, word_size, count, buffer, rm); + } + + /* (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IMemory#fillMemory(org.eclipse.dd.dsf.datamodel.IDMContext, org.eclipse.cdt.core.IAddress, long, int, byte[], org.eclipse.dd.dsf.concurrent.RequestMonitor) + */ + public void fillMemory(IMemoryDMContext memoryDMC, IAddress address, long offset, + int word_size, int count, byte[] pattern, RequestMonitor rm) + { + // Validate the context + if (memoryDMC == null) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown context type", null)); //$NON-NLS-1$); + rm.done(); + return; + } + + // Validate the word size + // NOTE: We only accept 1 byte words for this implementation + if (word_size != 1) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.NOT_SUPPORTED, "Word size not supported (!= 1)", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + // Validate the repeat count + if (count < 0) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Invalid repeat count (< 0)", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + // Validate the pattern + if (pattern.length < 1) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Empty pattern", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + // Create an aggregate buffer so we can write in 1 shot + int length = pattern.length; + byte[] buffer = new byte[count * length]; + for (int i = 0; i < count; i++) { + System.arraycopy(pattern, 0, buffer, i * length, length); + } + + // All is clear: go for it + fMemoryCache.setMemory(memoryDMC, address, offset, word_size, count * length, buffer, rm); + } + + ////////////////////////////////////////////////////////////////////////// + // Event handlers + ////////////////////////////////////////////////////////////////////////// + + @DsfServiceEventHandler + public void eventDispatched(IRunControl.IResumedDMEvent e) { + fMemoryCache.setTargetAvailable(false); + if (e.getReason() != StateChangeReason.STEP) { + fMemoryCache.reset(); + } + } + + @DsfServiceEventHandler + public void eventDispatched(IRunControl.ISuspendedDMEvent e) { + fMemoryCache.setTargetAvailable(true); + fMemoryCache.reset(); + } + + @DsfServiceEventHandler + public void eventDispatched(ExpressionChangedEvent e) { + + // Get the context and expression service handle + final IExpressionDMContext context = e.getDMContext(); + IExpressions expressionService = getServicesTracker().getService(IExpressions.class); + + // Get the variable information and update the corresponding memory locations + if (expressionService != null) { + expressionService.getExpressionAddressData(context, + new DataRequestMonitor(getExecutor(), null) { + @Override + protected void handleOK() { + // Figure out which memory area was modified + IExpressionDMAddress expression = getData(); + final int count = expression.getSize(); + IAddress expAddress = expression.getAddress(); + final Addr64 address; + if (expAddress instanceof Addr64) + address = (Addr64) expAddress; + else + address = new Addr64(expAddress.getValue()); + + final IMemoryDMContext memoryDMC = DMContexts.getAncestorOfType(context, IMemoryDMContext.class); + fMemoryCache.refreshMemory(memoryDMC, address, 0, 1, count, + new RequestMonitor(getExecutor(), null)); + } + }); + } + } + + /////////////////////////////////////////////////////////////////////////// + // SortedLinkedlist + /////////////////////////////////////////////////////////////////////////// + + // This class is really the equivalent of a C struct (old habits die hard...) + // For simplicity, everything is public. + private class MemoryBlock { + public IAddress fAddress; + public long fLength; + public MemoryByte[] fBlock; + public MemoryBlock(IAddress address, long length, MemoryByte[] block) { + fAddress = address; + fLength = length; + fBlock = block; + } + } + + // Address-ordered data structure to cache the memory blocks. + // Contiguous blocks are merged if possible. + @SuppressWarnings("serial") + private class SortedMemoryBlockList extends LinkedList { + + public SortedMemoryBlockList() { + super(); + } + + // Insert the block in the sorted linked list and merge contiguous + // blocks if necessary + @Override + @SuppressWarnings("unchecked") + public boolean add(MemoryBlock block) { + + // If the list is empty, just store the block + if (isEmpty()) { + addFirst(block); + return true; + } + + // Insert the block at the correct location and then + // merge the blocks if possible + ListIterator it = listIterator(); + while (it.hasNext()) { + int index = it.nextIndex(); + MemoryBlock item = it.next(); + if (block.fAddress.compareTo(item.fAddress) < 0) { + add(index, block); + compact(index); + return true; + } + } + + // Put at the end of the list and merge if necessary + addLast(block); + compact(size() - 1); + return true; + } + + // Merge this block with its contiguous neighbors (if any) + // Note: Merge is not performed if resulting block size would exceed MAXINT + private void compact(int index) { + + MemoryBlock newBlock = get(index); + + // Case where the block is to be merged with the previous block + if (index > 0) { + MemoryBlock prevBlock = get(index - 1); + IAddress endOfPreviousBlock = prevBlock.fAddress.add(prevBlock.fLength); + if (endOfPreviousBlock.distanceTo(newBlock.fAddress).longValue() == 0) { + long newLength = prevBlock.fLength + newBlock.fLength; + if (newLength <= Integer.MAX_VALUE) { + MemoryByte[] block = new MemoryByte[(int) newLength] ; + System.arraycopy(prevBlock.fBlock, 0, block, 0, (int) prevBlock.fLength); + System.arraycopy(newBlock.fBlock, 0, block, (int) prevBlock.fLength, (int) newBlock.fLength); + newBlock = new MemoryBlock(prevBlock.fAddress, newLength, block); + remove(index); + index -= 1; + set(index, newBlock); + } + } + } + + // Case where the block is to be merged with the following block + int lastIndex = size() - 1; + if (index < lastIndex) { + MemoryBlock nextBlock = get(index + 1); + IAddress endOfNewBlock = newBlock.fAddress.add(newBlock.fLength); + if (endOfNewBlock.distanceTo(nextBlock.fAddress).longValue() == 0) { + long newLength = newBlock.fLength + nextBlock.fLength; + if (newLength <= Integer.MAX_VALUE) { + MemoryByte[] block = new MemoryByte[(int) newLength] ; + System.arraycopy(newBlock.fBlock, 0, block, 0, (int) newBlock.fLength); + System.arraycopy(nextBlock.fBlock, 0, block, (int) newBlock.fLength, (int) nextBlock.fLength); + newBlock = new MemoryBlock(newBlock.fAddress, newLength, block); + set(index, newBlock); + remove(index + 1); + } + } + } + } + } + + /////////////////////////////////////////////////////////////////////////// + // MIMemoryCache + /////////////////////////////////////////////////////////////////////////// + + private class MIMemoryCache { + + // Back-end commands cache + private CommandCache fCommandCache; + + // The memory cache data structure + private SortedMemoryBlockList fMemoryBlockList; + + public MIMemoryCache() { + // Create the command cache + fCommandCache = new CommandCache(getServicesTracker().getService(ICommandControl.class)); + // Create the memory block cache + fMemoryBlockList = new SortedMemoryBlockList(); + } + + public void reset() { + // Clear the command cache + fCommandCache.reset(); + // Clear the memory cache + fMemoryBlockList.clear(); + } + + public void setTargetAvailable(boolean isAvailable) { + fCommandCache.setTargetAvailable(isAvailable); + } + + public boolean isTargetAvailable() { + return fCommandCache.isTargetAvailable(); + } + + /** + * This function walks the address-sorted memory block list to identify + * the 'missing' blocks (i.e. the holes) that need to be fetched on the target. + * + * The idea is fairly simple but an illustration could perhaps help. + * Assume the cache holds a number of cached memory blocks with gaps i.e. + * there is un-cached memory areas between blocks A, B and C: + * + * +---------+ +---------+ +---------+ + * + A + + B + + C + + * +---------+ +---------+ +---------+ + * : : : : : : + * [a] : : [b] : : [c] : : [d] + * : : : : : : + * [e---+--] : [f--+---------+--] : : + * [g---+---------+------+---------+------+---------+----] + * : : : : : : + * : [h] : : [i----+--] : : + * + * + * We have the following cases to consider.The requested block [a-i] either: + * + * [1] Fits entirely before A, in one of the gaps, or after C + * with no overlap and no contiguousness (e.g. [a], [b], [c] and [d]) + * -> Add the requested block to the list of blocks to fetch + * + * [2] Starts before an existing block but overlaps part of it, possibly + * spilling in the gap following the cached block (e.g. [e], [f] and [g]) + * -> Determine the length of the missing part (< count) + * -> Add a request to fill the gap before the existing block + * -> Update the requested block for the next iteration: + * - Start address to point just after the end of the cached block + * - Count reduced by cached block length (possibly becoming negative, e.g. [e]) + * At this point, the updated requested block starts just beyond the cached block + * for the next iteration. + * + * [3] Starts at or into an existing block and overlaps part of it ([h] and [i]) + * -> Update the requested block for the next iteration: + * - Start address to point just after the end of the cached block + * - Count reduced by length to end of cached block (possibly becoming negative, e.g. [h]) + * At this point, the updated requested block starts just beyond the cached block + * for the next iteration. + * + * We iterate over the cached blocks list until there is no entry left or until + * the remaining requested block count is <= 0, meaning the result list contains + * only the sub-blocks needed to fill the gap(s), if any. + * + * (As is often the case, it takes much more typing to explain it than to just do it :-) + * + * @param reqBlockStart The address of the requested block + * @param count Its length + * @return A list of the sub-blocks to fetch in order to fill enough gaps in the memory cache + * to service the request + */ + private LinkedList getListOfMissingBlocks(IAddress reqBlockStart, int count) { + + LinkedList list = new LinkedList(); + ListIterator it = fMemoryBlockList.listIterator(); + + // Look for holes in the list of memory blocks + while (it.hasNext() && count > 0) { + MemoryBlock cachedBlock = it.next(); + IAddress cachedBlockStart = cachedBlock.fAddress; + IAddress cachedBlockEnd = cachedBlock.fAddress.add(cachedBlock.fLength); + + // Case where we miss a block before the cached block + if (reqBlockStart.distanceTo(cachedBlockStart).longValue() >= 0) { + int length = (int) Math.min(reqBlockStart.distanceTo(cachedBlockStart).longValue(), count); + // If both blocks start at the same location, no need to create a new cached block + if (length > 0) { + MemoryBlock newBlock = new MemoryBlock(reqBlockStart, length, new MemoryByte[0]); + list.add(newBlock); + } + // Adjust request block start and length for the next iteration + reqBlockStart = cachedBlockEnd; + count -= length + cachedBlock.fLength; + } + + // Case where the requested block starts somewhere in the cached block + else if (cachedBlockStart.distanceTo(reqBlockStart).longValue() > 0 + && reqBlockStart.distanceTo(cachedBlockEnd).longValue() >= 0) + { + // Start of the requested block already in cache + // Adjust request block start and length for the next iteration + count -= reqBlockStart.distanceTo(cachedBlockEnd).longValue(); + reqBlockStart = cachedBlockEnd; + } + } + + // Case where we miss a block at the end of the cache + if (count > 0) { + MemoryBlock newBlock = new MemoryBlock(reqBlockStart, count, new MemoryByte[0]); + list.add(newBlock); + } + + return list; + } + + /** + * This function walks the address-sorted memory block list to get the + * cached memory bytes (possibly from multiple contiguous blocks). + * This function is called *after* the missing blocks have been read from + * the back end i.e. the requested memory is all cached. + * + * Again, this is fairly simple. As we loop over the address-ordered list, + * There are really only 2 cases: + * + * [1] The requested block fits entirely in the cached block ([a] or [b]) + * [2] The requested block starts in a cached block and ends in the + * following (contiguous) one ([c]) in which case it is treated + * as 2 contiguous requests ([c'] and [c"]) + * + * +--------------+--------------+ + * + A + B + + * +--------------+--------------+ + * : [a----] : [b-----] : + * : : : + * : [c-----+------] : + * : [c'---]+[c"---] : + * + * @param reqBlockStart The address of the requested block + * @param count Its length + * @return The cached memory content + */ + private MemoryByte[] getMemoryBlockFromCache(IAddress reqBlockStart, int count) { + + IAddress reqBlockEnd = reqBlockStart.add(count); + MemoryByte[] resultBlock = new MemoryByte[count]; + ListIterator iter = fMemoryBlockList.listIterator(); + + while (iter.hasNext()) { + MemoryBlock cachedBlock = iter.next(); + IAddress cachedBlockStart = cachedBlock.fAddress; + IAddress cachedBlockEnd = cachedBlock.fAddress.add(cachedBlock.fLength); + + // Case where the cached block overlaps completely the requested memory block + if (cachedBlockStart.distanceTo(reqBlockStart).longValue() >= 0 + && reqBlockEnd.distanceTo(cachedBlockEnd).longValue() >= 0) + { + int pos = (int) cachedBlockStart.distanceTo(reqBlockStart).longValue(); + System.arraycopy(cachedBlock.fBlock, pos, resultBlock, 0, count); + } + + // Case where the beginning of the cached block is within the requested memory block + else if (reqBlockStart.distanceTo(cachedBlockStart).longValue() >= 0 + && cachedBlockStart.distanceTo(reqBlockEnd).longValue() > 0) + { + int pos = (int) reqBlockStart.distanceTo(cachedBlockStart).longValue(); + int length = (int) Math.min(cachedBlock.fLength, count - pos); + System.arraycopy(cachedBlock.fBlock, 0, resultBlock, pos, length); + } + + // Case where the end of the cached block is within the requested memory block + else if (cachedBlockStart.distanceTo(reqBlockStart).longValue() >= 0 + && reqBlockStart.distanceTo(cachedBlockEnd).longValue() > 0) + { + int pos = (int) cachedBlockStart.distanceTo(reqBlockStart).longValue(); + int length = (int) Math.min(cachedBlock.fLength - pos, count); + System.arraycopy(cachedBlock.fBlock, pos, resultBlock, 0, length); + } + } + return resultBlock; + } + + /** + * This function walks the address-sorted memory block list and updates + * the content with the actual memory just read from the target. + * + * @param modBlockStart + * @param count + * @param modBlock + */ + private void updateMemoryCache(IAddress modBlockStart, int count, MemoryByte[] modBlock) { + + IAddress modBlockEnd = modBlockStart.add(count); + ListIterator iter = fMemoryBlockList.listIterator(); + + while (iter.hasNext()) { + MemoryBlock cachedBlock = iter.next(); + IAddress cachedBlockStart = cachedBlock.fAddress; + IAddress cachedBlockEnd = cachedBlock.fAddress.add(cachedBlock.fLength); + + // For now, we only bother to update bytes already cached. + // Note: In a better implementation (v1.1), we would augment + // the cache with the missing memory blocks since we went + // through the pains of reading them in the first place. + // (this is left as an exercise to the reader :-) + + // Case where the modified block is completely included in the cached block + if (cachedBlockStart.distanceTo(modBlockStart).longValue() >= 0 + && modBlockEnd.distanceTo(cachedBlockEnd).longValue() >= 0) + { + int pos = (int) cachedBlockStart.distanceTo(modBlockStart).longValue(); + System.arraycopy(modBlock, 0, cachedBlock.fBlock, pos, count); + } + + // Case where the beginning of the modified block is within the cached block + else if (cachedBlockStart.distanceTo(modBlockStart).longValue() >= 0 + && modBlockStart.distanceTo(cachedBlockEnd).longValue() > 0) + { + int pos = (int) cachedBlockStart.distanceTo(modBlockStart).longValue(); + int length = (int) cachedBlockStart.distanceTo(modBlockEnd).longValue(); + System.arraycopy(modBlock, 0, cachedBlock.fBlock, pos, length); + } + + // Case where the end of the modified block is within the cached block + else if (cachedBlockStart.distanceTo(modBlockEnd).longValue() > 0 + && modBlockEnd.distanceTo(cachedBlockEnd).longValue() >= 0) + { + int pos = (int) modBlockStart.distanceTo(cachedBlockStart).longValue(); + int length = (int) cachedBlockStart.distanceTo(modBlockEnd).longValue(); + System.arraycopy(modBlock, pos, cachedBlock.fBlock, 0, length); + } + } + return; + } + + /** + * @param memoryDMC + * @param address the memory block address (on the target) + * @param word_size the size, in bytes, of an addressable item + * @param count the number of bytes to read + * @param drm the asynchronous data request monitor + */ + public void getMemory(IMemoryDMContext memoryDMC, final IAddress address, final int word_size, + final int count, final DataRequestMonitor drm) + { + // Determine the number of read requests to issue + LinkedList missingBlocks = getListOfMissingBlocks(address, count); + int numberOfRequests = missingBlocks.size(); + + // A read request will be issued for each block needed + // so we need to keep track of the count + final CountingRequestMonitor countingRM = + new CountingRequestMonitor(getExecutor(), drm) { + @Override + protected void handleOK() { + // We received everything so read the result from the memory cache + drm.setData(getMemoryBlockFromCache(address, count)); + drm.done(); + } + }; + countingRM.setDoneCount(numberOfRequests); + + // Issue the read requests + for (int i = 0; i < numberOfRequests; i++) { + MemoryBlock block = missingBlocks.get(i); + final IAddress startAddress = block.fAddress; + final int length = (int) block.fLength; + readMemoryBlock(memoryDMC, startAddress, 0, word_size, length, + new DataRequestMonitor(getSession().getExecutor(), drm) { + @Override + protected void handleOK() { + MemoryByte[] block = new MemoryByte[count]; + block = getData(); + MemoryBlock memoryBlock = new MemoryBlock(startAddress, length, block); + fMemoryBlockList.add(memoryBlock); + countingRM.done(); + } + }); + } + } + + /** + * @param memoryDMC + * @param address the memory block address (on the target) + * @param offset the offset from the start address + * @param word_size the size, in bytes, of an addressable item + * @param count the number of bytes to write + * @param buffer the source buffer + * @param rm the asynchronous request monitor + */ + public void setMemory(final IMemoryDMContext memoryDMC, final IAddress address, + final long offset, final int word_size, final int count, final byte[] buffer, + final RequestMonitor rm) + { + writeMemoryBlock( + memoryDMC, address, offset, word_size, count, buffer, + new RequestMonitor(getSession().getExecutor(), rm) { + @Override + protected void handleOK() { + // Clear the command cache (otherwise we can't guarantee + // that the subsequent memory read will be correct) + fCommandCache.reset(); + + // Asynchronous update of the memory cache + final DataRequestMonitor drm = + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + updateMemoryCache(address.add(offset), count, getData()); + // Send the MemoryChangedEvent + IAddress[] addresses = new IAddress[count]; + for (int i = 0; i < count; i++) { + addresses[i] = address.add(offset + i); + } + getSession().dispatchEvent(new MemoryChangedEvent(memoryDMC, addresses), getProperties()); + // Finally... + rm.done(); + } + }; + + // Re-read the modified memory block + readMemoryBlock(memoryDMC, address, offset, word_size, count, + new DataRequestMonitor(getExecutor(), drm) { + @Override + public void handleOK() { + drm.setData(getData()); + drm.done(); + } + }); + } + }); + } + + /** + * @param memoryDMC + * @param address + * @param offset + * @param word_size + * @param count + * @param rm + */ + public void refreshMemory(final IMemoryDMContext memoryDMC, final IAddress address, + final long offset, final int word_size, final int count, final RequestMonitor rm) + { + // Check if we already cache part of this memory area (which means it + // is used by a memory service client that will have to be updated) + LinkedList list = fMemoryCache.getListOfMissingBlocks(address, count); + int sizeToRead = 0; + for (MemoryBlock block : list) { + sizeToRead += block.fLength; + } + + // If none of the requested memory is in cache, just get out + if (sizeToRead == count) { + rm.done(); + return; + } + + // Prepare the data for the MemoryChangedEvent + final IAddress[] addresses = new IAddress[count]; + for (int i = 0; i < count; i++) { + addresses[i] = address.add(i); + } + + // Read the corresponding memory block + fMemoryCache.fCommandCache.reset(); + fMemoryCache.readMemoryBlock(memoryDMC, address, 0, 1, count, + new DataRequestMonitor(getExecutor(), rm) { + @Override + public void handleOK() { + fMemoryCache.updateMemoryCache(address, count, getData()); + getSession().dispatchEvent(new MemoryChangedEvent(memoryDMC, addresses), getProperties()); + rm.done(); + } + }); + } + + /////////////////////////////////////////////////////////////////////// + // Back-end functions + /////////////////////////////////////////////////////////////////////// + + /** + * @param memoryDMC + * @param address + * @param offset + * @param word_size + * @param count + * @param drm + */ + private void readMemoryBlock(IMemoryDMContext memoryDMC, IAddress address, final long offset, + final int word_size, final int count, final DataRequestMonitor drm) + { + /* To simplify the parsing of the MI result, we request the output to + * be on 1 row of [count] columns, no char interpretation. + */ + int mode = MIFormat.HEXADECIMAL; + int nb_rows = 1; + int nb_cols = count; + Character asChar = null; + + fCommandCache.execute( + new MIDataReadMemory(memoryDMC, offset, address.toString(), mode, word_size, nb_rows, nb_cols, asChar), + new DataRequestMonitor(getExecutor(), drm) { + @Override + protected void handleOK() { + // Retrieve the memory block + drm.setData(getData().getMIMemoryBlock()); + drm.done(); + } + } + ); + } + + /** + * @param memoryDMC + * @param address + * @param offset + * @param word_size + * @param count + * @param buffer + * @param rm + */ + private void writeMemoryBlock(final IMemoryDMContext memoryDMC, final IAddress address, final long offset, + final int word_size, final int count, final byte[] buffer, final RequestMonitor rm) + { + // Each byte is written individually (GDB power...) + // so we need to keep track of the count + final CountingRequestMonitor countingRM = + new CountingRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + rm.done(); + } + }; + countingRM.setDoneCount(count); + + // We will format the individual bytes in decimal + int format = MIFormat.DECIMAL; + String baseAddress = address.toString(); + + // Issue an MI request for each byte to write + for (int i = 0; i < count; i++) { + String value = new Byte(buffer[i]).toString(); + fCommandCache.execute( + new MIDataWriteMemory(memoryDMC, offset + i, baseAddress, format, word_size, value), + new DataRequestMonitor(getExecutor(), countingRM) + ); + } + } + + } + +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIModules.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIModules.java new file mode 100644 index 00000000000..64a8a86b291 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIModules.java @@ -0,0 +1,217 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + * Ericsson AB - Modules implementation for GDB + *******************************************************************************/ +package org.eclipse.dd.mi.service; + +import java.math.BigInteger; +import java.util.Hashtable; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.AbstractDMContext; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.IModules; +import org.eclipse.dd.dsf.debug.service.command.CommandCache; +import org.eclipse.dd.dsf.debug.service.command.ICommandControl; +import org.eclipse.dd.dsf.service.AbstractDsfService; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.mi.internal.MIPlugin; +import org.eclipse.dd.mi.service.command.commands.CLIInfoSharedLibrary; +import org.eclipse.dd.mi.service.command.output.CLIInfoSharedLibraryInfo; +import org.eclipse.dd.mi.service.command.output.CLIInfoSharedLibraryInfo.DsfMISharedInfo; +import org.osgi.framework.BundleContext; + +/** + * + */ +public class MIModules extends AbstractDsfService implements IModules { + private CommandCache fModulesCache; + + public MIModules(DsfSession session) { + super(session); + } + + @Override + protected BundleContext getBundleContext() { + return MIPlugin.getBundleContext(); + } + + @Override + public void initialize(final RequestMonitor requestMonitor) { + super.initialize( + new RequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleOK() { + doInitialize(requestMonitor); + }}); + } + + private void doInitialize(RequestMonitor requestMonitor) { + // Cache for holding Modules data + fModulesCache = new CommandCache(getServicesTracker().getService(ICommandControl.class)); + /* + * Make ourselves known so clients can use us. + */ + register(new String[]{IModules.class.getName(), MIModules.class.getName()}, new Hashtable()); + + requestMonitor.done(); + } + + @Override + public void shutdown(RequestMonitor requestMonitor) { + unregister(); + super.shutdown(requestMonitor); + } + + static class ModuleDMContext extends AbstractDMContext implements IModuleDMContext { + private final String fFile; + ModuleDMContext(MIModules service, IDMContext[] parents, String file) { + super(service, parents); + fFile = file; + } + + @Override + public boolean equals(Object obj) { + return baseEquals(obj) && fFile.equals(((ModuleDMContext)obj).fFile); + } + + @Override + public int hashCode() { + return baseHashCode() + fFile.hashCode(); + } + } + + static class ModuleDMData implements IModuleDMData { + private final String fFile; + private final String fFromAddress; + private final String fToAddress; + private final boolean fIsSymbolsRead; + + public ModuleDMData(ModuleDMContext dmc) { + fFile = dmc.fFile; + fFromAddress = null; + fToAddress = null; + fIsSymbolsRead = false; + } + + public ModuleDMData(String fileName, String fromAddress, String toAddress, boolean isSymsRead){ + fFile = fileName; + fFromAddress = fromAddress; + fToAddress = toAddress; + fIsSymbolsRead = isSymsRead; + } + + public String getFile() { + return fFile; + } + + public String getName() { + return fFile; + } + + public long getTimeStamp() { + return 0; + } + + public String getBaseAddress() { + return fFromAddress; + } + + public String getToAddress() { + return fToAddress; + } + + public boolean isSymbolsLoaded() { + return fIsSymbolsRead; + } + + public long getSize() { + long result = 0; + if(getBaseAddress() == null || getToAddress() == null) + return result; + BigInteger start = MIFormat.getBigInteger(getBaseAddress()); + BigInteger end = MIFormat.getBigInteger(getToAddress()); + if ( end.compareTo( start ) > 0 ) + result = end.subtract( start ).longValue(); + return result; + } + + } + + public void getModules(final ISymbolDMContext symCtx, final DataRequestMonitor rm) { + if(symCtx != null){ + fModulesCache.execute(new CLIInfoSharedLibrary(symCtx), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + rm.setData(makeModuleContexts(symCtx, getData())); + rm.done(); + } + }); + } + else{ + rm.setData(new IModuleDMContext[] { new ModuleDMContext(this, DMContexts.EMPTY_CONTEXTS_ARRAY, "example module 1"), new ModuleDMContext(this, DMContexts.EMPTY_CONTEXTS_ARRAY, "example module 2") }); //$NON-NLS-1$ //$NON-NLS-2$ + rm.done(); + } + } + + private IModuleDMContext[] makeModuleContexts(IDMContext symCtxt, CLIInfoSharedLibraryInfo info){ + + DsfMISharedInfo[] sharedInfos = info.getMIShared(); + ModuleDMContext[] modules = new ModuleDMContext[sharedInfos.length]; + int i = 0; + for(DsfMISharedInfo shared : sharedInfos){ + modules[i++] = new ModuleDMContext(this, new IDMContext[]{symCtxt}, shared.getName()); + } + return modules; + } + + public void getModuleData(final IModuleDMContext dmc, final DataRequestMonitor rm) { + assert dmc != null; + if (dmc instanceof ModuleDMContext) { + fModulesCache.execute(new CLIInfoSharedLibrary(dmc), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + rm.setData( createSharedLibInfo((ModuleDMContext)dmc, getData()) ); + rm.done(); + } + }); + } else { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown DM Context", null)); //$NON-NLS-1$ + rm.done(); + } + } + + private IModuleDMData createSharedLibInfo(ModuleDMContext dmc, CLIInfoSharedLibraryInfo info){ + for (CLIInfoSharedLibraryInfo.DsfMISharedInfo shared : info.getMIShared()) { + if(shared.getName().equals(dmc.fFile)){ + return new ModuleDMData(shared.getName(), shared.getFrom(), shared.getTo(), shared.isRead()); + } + } + return new ModuleDMData("","", "", false); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + } + + public void calcAddressInfo(ISymbolDMContext symCtx, String file, int line, int col, DataRequestMonitor rm) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, "Functionality not supported", null)); //$NON-NLS-1$ + rm.done(); + } + + public void calcLineInfo(ISymbolDMContext symCtx, IAddress address, DataRequestMonitor rm) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, "Functionality not supported", null)); //$NON-NLS-1$ + rm.done(); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRegisters.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRegisters.java new file mode 100644 index 00000000000..56c17b4eb45 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRegisters.java @@ -0,0 +1,583 @@ +/******************************************************************************* + * 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 + * Ericsson - Modified for additional features in DSF Reference Implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service; + +import java.util.Hashtable; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.AbstractDMContext; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.IRegisters; +import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMData; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason; +import org.eclipse.dd.dsf.debug.service.command.CommandCache; +import org.eclipse.dd.dsf.debug.service.command.ICommandControl; +import org.eclipse.dd.dsf.service.AbstractDsfService; +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.mi.internal.MIPlugin; +import org.eclipse.dd.mi.service.command.commands.MIDataListRegisterNames; +import org.eclipse.dd.mi.service.command.commands.MIDataListRegisterValues; +import org.eclipse.dd.mi.service.command.output.MIDataListRegisterNamesInfo; +import org.eclipse.dd.mi.service.command.output.MIDataListRegisterValuesInfo; +import org.eclipse.dd.mi.service.command.output.MIInfo; +import org.eclipse.dd.mi.service.command.output.MIRegisterValue; +import org.osgi.framework.BundleContext; + + +/** + * + *

    + * Implementation note: + * This class implements event handlers for the events that are generated by + * this service itself. When the event is dispatched, these handlers will + * be called first, before any of the clients. These handlers update the + * service's internal state information to make them consistent with the + * events being issued. Doing this in the handlers as opposed to when + * the events are generated, guarantees that the state of the service will + * always be consistent with the events. + */ + +public class MIRegisters extends AbstractDsfService implements IRegisters { + private static final String BLANK_STRING = ""; //$NON-NLS-1$ + /* + * Support class used to construct Register Group DMCs. + */ + + public static class MIRegisterGroupDMC extends AbstractDMContext implements IRegisterGroupDMContext { + private int fGroupNo; + private String fGroupName; + + public MIRegisterGroupDMC(MIRegisters service, IContainerDMContext contDmc, int groupNo, String groupName) { + super(service.getSession().getId(), new IDMContext[] { contDmc }); + fGroupNo = groupNo; + fGroupName = groupName; + } + + public int getGroupNo() { return fGroupNo; } + public String getName() { return fGroupName; } + + @Override + public boolean equals(Object other) { + return ((super.baseEquals(other)) && (((MIRegisterGroupDMC) other).fGroupNo == fGroupNo) && + (((MIRegisterGroupDMC) other).fGroupName.equals(fGroupName))); + } + + @Override + public int hashCode() { return super.baseHashCode() ^ fGroupNo; } + @Override + public String toString() { return baseToString() + ".group[" + fGroupNo + "]"; } //$NON-NLS-1$ //$NON-NLS-2$ + } + + /* + * Support class used to construct Register DMCs. + */ + + public static class MIRegisterDMC extends AbstractDMContext implements IRegisterDMContext { + private int fRegNo; + private String fRegName; + + public MIRegisterDMC(MIRegisters service, MIRegisterGroupDMC group, int regNo, String regName) { + super(service.getSession().getId(), + new IDMContext[] { group }); + fRegNo = regNo; + fRegName = regName; + } + + public MIRegisterDMC(MIRegisters service, MIRegisterGroupDMC group, IMIExecutionDMContext execDmc, int regNo, String regName) { + super(service.getSession().getId(), + new IDMContext[] { execDmc, group }); + fRegNo = regNo; + fRegName = regName; + } + + public int getRegNo() { return fRegNo; } + public String getName() { return fRegName; } + + @Override + public boolean equals(Object other) { + return ((super.baseEquals(other)) && (((MIRegisterDMC) other).fRegNo == fRegNo) && + (((MIRegisterDMC) other).fRegName.equals(fRegName))); + } + + @Override + public int hashCode() { return super.baseHashCode() ^ fRegNo; } + @Override + public String toString() { return baseToString() + ".register[" + fRegNo + "]"; } //$NON-NLS-1$ //$NON-NLS-2$ + } + + /* + * Event class to notify register value is changed + */ + public static class RegisterChangedDMEvent implements IRegisters.IRegisterChangedDMEvent { + + private final IRegisterDMContext fRegisterDmc; + + RegisterChangedDMEvent(IRegisterDMContext registerDMC) { + fRegisterDmc = registerDMC; + } + + public IRegisterDMContext getDMContext() { + return fRegisterDmc; + } + } + + /* + * Internal control variables. + */ + + private MIRegisterGroupDMC fGeneralRegistersGroupDMC; + private CommandCache fRegisterNameCache; // Cache for holding the Register Names in the single Group + private CommandCache fRegisterValueCache; // Cache for holding the Register Values + + public MIRegisters(DsfSession session) + { + super(session); + } + + @Override + protected BundleContext getBundleContext() + { + return MIPlugin.getBundleContext(); + } + + @Override + public void initialize(final RequestMonitor requestMonitor) { + super.initialize( + new RequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleOK() { + doInitialize(requestMonitor); + }}); + } + + private void doInitialize(RequestMonitor requestMonitor) { + /* + * Create the lower level register cache. + */ + fRegisterValueCache = new CommandCache(getServicesTracker().getService(ICommandControl.class)); + fRegisterNameCache = new CommandCache(getServicesTracker().getService(ICommandControl.class)); + + /* + * Signup so we see events. We use these events to decide how to manage + * any local caches we are providing as well as the lower level register + * cache we create to get/set registers on the target. + */ + getSession().addServiceEventListener(this, null); + + /* + * Make ourselves known so clients can use us. + */ + register(new String[]{IRegisters.class.getName(), MIRegisters.class.getName()}, new Hashtable()); + + requestMonitor.done(); + } + + @Override + public void shutdown(RequestMonitor requestMonitor) + { + unregister(); + getSession().removeServiceEventListener(this); + super.shutdown(requestMonitor); + } + + public boolean isValid() { return true; } + + @SuppressWarnings("unchecked") + public void getModelData(IDMContext dmc, DataRequestMonitor rm) { + /* + * This is the method which is called when actual results need to be returned. We + * can be called either with a service DMC for which we return oureslves or we can + * be called with the DMC's we have handed out. If the latter is the case then we + * datamine by talking to the Debug Engine. + */ + + if (dmc instanceof MIRegisterGroupDMC) { + getRegisterGroupData((MIRegisterGroupDMC)dmc, (DataRequestMonitor)rm); + } else if (dmc instanceof MIRegisterDMC) { + getRegisterData((MIRegisterDMC)dmc, (DataRequestMonitor)rm); + } else if (dmc instanceof FormattedValueDMContext) { + getFormattedExpressionValue((FormattedValueDMContext)dmc, (DataRequestMonitor)rm); + } else { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, -1, "Unknown DMC type", null)); //$NON-NLS-1$ + rm.done(); + } + } + + public void getFormattedExpressionValue(FormattedValueDMContext dmc, DataRequestMonitor rm) { + if (dmc.getParents().length == 1 && dmc.getParents()[0] instanceof MIRegisterDMC) { + getRegisterDataValue( (MIRegisterDMC) dmc.getParents()[0], dmc.getFormatID(), rm); + } else { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ + rm.done(); + } + } + + public void getRegisterGroupData(IRegisterGroupDMContext regGroupDmc, DataRequestMonitor rm) { + /** + * For the GDB GDBMI implementation there is only on group. The GPR and FPU registers are grouped into + * one set. We are going to hard wire this set as the "General Registers". + */ + class RegisterGroupData implements IRegisterGroupDMData { + public String getName() { return "General Registers"; } //$NON-NLS-1$ + public String getDescription() { return "General Purpose and FPU Register Group"; } //$NON-NLS-1$ + } + + rm.setData( new RegisterGroupData() ) ; + rm.done(); + } + + public void getBitFieldData(IBitFieldDMContext dmc, DataRequestMonitor rm) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, "Bit fields not yet supported", null)); //$NON-NLS-1$ + rm.done(); + } + + /** + * For the GDB GDBMI implementation there is only on group. We represent + * this group as a single list we maintain within this service. So we + * need to search this list to see if we have a current value. + */ + public void getRegisterData(IRegisterDMContext regDmc , final DataRequestMonitor rm) { + if (regDmc instanceof MIRegisterDMC) { + final MIRegisterDMC miRegDmc = (MIRegisterDMC)regDmc; + IMIExecutionDMContext execDmc = DMContexts.getAncestorOfType(regDmc, IMIExecutionDMContext.class); + // Create register DMC with name if execution DMC is not present. + if(execDmc == null){ + rm.setData(new RegisterData(miRegDmc.getName(), BLANK_STRING, false)); + rm.done(); + return; + } + + int[] regnos = {miRegDmc.getRegNo()}; + fRegisterValueCache.execute( + new MIDataListRegisterValues(execDmc, MIFormat.HEXADECIMAL, regnos), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + // Retrieve the register value. + MIRegisterValue[] regValue = getData().getMIRegisterValues(); + + // If the list is empty just return empty handed. + if (regValue.length == 0) { + assert false : "Backend protocol error"; //$NON-NLS-1$ + //done.setStatus(new Status(IStatus.ERROR, IDsfService.INTERNAL_ERROR ,)); + rm.done(); + return; + } + + // We can determine if the register is floating point because + // GDB returns this additional information as part of the value. + MIRegisterValue reg = regValue[0]; + boolean isFloat = false; + + if ( reg.getValue().contains("float")) { //$NON-NLS-1$ + isFloat = true; + } + + // Return the new register attributes. + rm.setData(new RegisterData(miRegDmc.getName(), BLANK_STRING, isFloat)); + rm.done(); + } + }); + } else { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown DMC type", null)); //$NON-NLS-1$ + rm.done(); + } + } + + private void getRegisterDataValue( final MIRegisterDMC regDmc, final String formatId, final DataRequestMonitor rm) { + IMIExecutionDMContext miExecDmc = DMContexts.getAncestorOfType(regDmc, IMIExecutionDMContext.class); + if(miExecDmc == null){ + // Set value to blank if execution dmc is not present + rm.setData( new FormattedValueDMData( BLANK_STRING ) ); + rm.done(); + return; + } + + // Select the format to be shown + int NumberFormat = MIFormat.HEXADECIMAL; + + if ( HEX_FORMAT.equals ( formatId ) ) { NumberFormat = MIFormat.HEXADECIMAL; } + if ( OCTAL_FORMAT.equals ( formatId ) ) { NumberFormat = MIFormat.OCTAL; } + if ( NATURAL_FORMAT.equals( formatId ) ) { NumberFormat = MIFormat.NATURAL; } + if ( BINARY_FORMAT.equals ( formatId ) ) { NumberFormat = MIFormat.BINARY; } + if ( DECIMAL_FORMAT.equals( formatId ) ) { NumberFormat = MIFormat.DECIMAL; } + + int[] regnos = {regDmc.getRegNo()}; + fRegisterValueCache.execute( + new MIDataListRegisterValues(miExecDmc, NumberFormat, regnos), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + // Retrieve the register value. + MIRegisterValue[] regValue = getData().getMIRegisterValues(); + + // If the list is empty just return empty handed. + if (regValue.length == 0) { + assert false : "Backend protocol error"; //$NON-NLS-1$ + //done.setStatus(new Status(IStatus.ERROR, IDsfService.INTERNAL_ERROR ,)); + rm.done(); + return; + } + + MIRegisterValue reg = regValue[0]; + + // Return the new register value. + rm.setData( new FormattedValueDMData( reg.getValue() ) ); + rm.done(); + } + }); + } + + static class RegisterData implements IRegisterDMData { + + final private String fRegName; + final private String fRegDesc; + final private boolean fIsFloat; + + public RegisterData(String regName, String regDesc, boolean isFloat ) { + + fRegName = regName; + fRegDesc = regDesc; + fIsFloat = isFloat; + } + + public boolean isReadable() { return true; } + public boolean isReadOnce() { return false; } + public boolean isWriteable() { return true; } + public boolean isWriteOnce() { return false; } + public boolean hasSideEffects() { return false; } + public boolean isVolatile() { return true; } + + public boolean isFloat() { return fIsFloat; } + public String getName() { return fRegName; } + public String getDescription() { return fRegDesc; } + } + + // Wraps a list of registers in DMContexts. + private MIRegisterDMC[] makeRegisterDMCs(MIRegisterGroupDMC groupDmc, String[] regNames) { + return makeRegisterDMCs(groupDmc, null, regNames); + } + + // Wraps a list of registers in DMContexts. + private MIRegisterDMC[] makeRegisterDMCs(MIRegisterGroupDMC groupDmc, IMIExecutionDMContext execDmc, String[] regNames) { + MIRegisterDMC[] regDmcList = new MIRegisterDMC[regNames.length]; + int regNo = 0 ; + for (String regName : regNames) { + if(execDmc != null) + regDmcList[regNo] = new MIRegisterDMC(this, groupDmc, execDmc, regNo, regName); + else + regDmcList[regNo] = new MIRegisterDMC(this, groupDmc, regNo, regName); + regNo++; + } + + return regDmcList; + } + + /* + * Event handling section. These event handlers control the caching state of the + * register caches. This service creates several cache objects. Not all of which + * need to be flushed. These handlers maintain the state of the caches. + */ + + @DsfServiceEventHandler public void eventDispatched(IRunControl.IResumedDMEvent e) { + fRegisterValueCache.setTargetAvailable(false); + if (e.getReason() != StateChangeReason.STEP) { + fRegisterValueCache.reset(); + } + } + + @DsfServiceEventHandler public void eventDispatched( + IRunControl.ISuspendedDMEvent e) { + fRegisterValueCache.setTargetAvailable(true); + fRegisterValueCache.reset(); + } + + @DsfServiceEventHandler + public void eventDispatched(final IRegisters.IRegisterChangedDMEvent e) { + fRegisterValueCache.reset(); + } + + /* + * These are the public interfaces for this service. + * + * (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IRegisters#getRegisterGroups(org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext, org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) + */ + public void getRegisterGroups(IDMContext ctx, DataRequestMonitor rm ) { + IContainerDMContext contDmc = DMContexts.getAncestorOfType(ctx, IContainerDMContext.class); + if (contDmc == null) { + rm.setStatus( new Status( IStatus.ERROR , MIPlugin.PLUGIN_ID , INVALID_HANDLE , "Container context not found", null ) ) ; //$NON-NLS-1$ + rm.done(); + return; + } + + if (fGeneralRegistersGroupDMC == null) { + fGeneralRegistersGroupDMC = new MIRegisterGroupDMC( this , contDmc, 0 , "General Registers" ) ; //$NON-NLS-1$ + } + MIRegisterGroupDMC[] groupDMCs = new MIRegisterGroupDMC[] { fGeneralRegistersGroupDMC }; + rm.setData(groupDMCs) ; + rm.done() ; + } + + + /* + * (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IRegisters#getRegisters(org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) + */ + public void getRegisters(final IDMContext dmc, final DataRequestMonitor rm) { + final MIRegisterGroupDMC groupDmc = DMContexts.getAncestorOfType(dmc, MIRegisterGroupDMC.class); + if ( groupDmc == null ) { + rm.setStatus( new Status( IStatus.ERROR , MIPlugin.PLUGIN_ID , INVALID_HANDLE , "RegisterGroup context not found", null ) ) ; //$NON-NLS-1$ + rm.done(); + return; + } + + final IContainerDMContext containerDmc = DMContexts.getAncestorOfType(dmc, IContainerDMContext.class); + if ( containerDmc == null ) { + rm.setStatus( new Status( IStatus.ERROR , MIPlugin.PLUGIN_ID , INVALID_HANDLE , "Container context not found" , null ) ) ; //$NON-NLS-1$ + rm.done(); + return; + } + + // There is only one group and its number must be 0. + if ( groupDmc.getGroupNo() == 0 ) { + final IMIExecutionDMContext executionDmc = DMContexts.getAncestorOfType(dmc, IMIExecutionDMContext.class); + fRegisterNameCache.execute( + new MIDataListRegisterNames(containerDmc), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + // Retrieve the register names. + String[] regNames = getData().getRegisterNames() ; + + // If the list is empty just return empty handed. + if ( regNames.length == 0 ) { + rm.done(); + return; + } + // Create DMContexts for each of the register names. + if(executionDmc == null) + rm.setData(makeRegisterDMCs(groupDmc, regNames)); + else + rm.setData(makeRegisterDMCs(groupDmc, executionDmc, regNames)); + rm.done(); + } + }); + } else { + rm.setStatus(new Status(IStatus.ERROR , MIPlugin.PLUGIN_ID , INTERNAL_ERROR , "Invalid group = " + groupDmc , null)); //$NON-NLS-1$ + rm.done(); + } + } + + /* + * (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IRegisters#getBitFields(org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) + */ + public void getBitFields( IRegisterDMContext regDmc , DataRequestMonitor rm ) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, "BitField not supported", null)); //$NON-NLS-1$ + rm.done(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IRegisters#writeRegister(org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext, java.lang.String, java.lang.String, org.eclipse.dd.dsf.concurrent.RequestMonitor) + */ + public void writeRegister(IRegisterDMContext regCtx, final String regValue, final String formatId, final RequestMonitor rm) { + MIRegisterGroupDMC grpDmc = DMContexts.getAncestorOfType(regCtx, MIRegisterGroupDMC.class); + if ( grpDmc == null ) { + rm.setStatus( new Status( IStatus.ERROR , MIPlugin.PLUGIN_ID , INVALID_HANDLE , "RegisterGroup context not found" , null ) ) ; //$NON-NLS-1$ + rm.done(); + return; + } + + final MIRegisterDMC regDmc = (MIRegisterDMC)regCtx; + // There is only one group and its number must be 0. + if ( grpDmc.getGroupNo() == 0 ) { + final ExpressionService exprService = getServicesTracker().getService(ExpressionService.class); + String regName = regDmc.getName(); + final IExpressionDMContext exprCtxt = exprService.createExpression(regCtx, "$" + regName); //$NON-NLS-1$ + exprService.getModelData(exprCtxt, new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + // Evaluate the expression - request HEX since it works in every case + final FormattedValueDMContext valueDmc = exprService.getFormattedValueContext(exprCtxt, formatId); + exprService.getModelData( + valueDmc, + new DataRequestMonitor(getExecutor(), null) { + @Override + protected void handleOK() { + if(! regValue.equals(getData().getFormattedValue()) || ! valueDmc.getFormatID().equals(formatId)){ + exprService.writeExpression(exprCtxt, regValue, formatId, new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + generateRegisterChangedEvent(regDmc); + } + }); + }//if + rm.done(); + }//handleOK + } + ); + } + }); + } + else { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, "Invalid group = " + grpDmc, null)); //$NON-NLS-1$ + rm.done(); + } + } + + /* + * (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IRegisters#writeBitField(org.eclipse.dd.dsf.debug.service.IRegisters.IBitFieldDMContext, java.lang.String, java.lang.String, org.eclipse.dd.dsf.concurrent.RequestMonitor) + */ + public void writeBitField(IBitFieldDMContext bitFieldCtx, String bitFieldValue, String formatId, RequestMonitor rm) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, "Writing bit field not supported", null)); //$NON-NLS-1$ + rm.done(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IRegisters#writeBitField(org.eclipse.dd.dsf.debug.service.IRegisters.IBitFieldDMContext, org.eclipse.dd.dsf.debug.service.IRegisters.IMnemonic, org.eclipse.dd.dsf.concurrent.RequestMonitor) + */ + public void writeBitField(IBitFieldDMContext bitFieldCtx, IMnemonic mnemonic, RequestMonitor rm) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, "Writing bit field not supported", null)); //$NON-NLS-1$ + rm.done(); + } + + public void getAvailableFormats(IFormattedDataDMContext dmc, DataRequestMonitor rm) { + + rm.setData(new String[] { HEX_FORMAT, DECIMAL_FORMAT, OCTAL_FORMAT, BINARY_FORMAT, NATURAL_FORMAT }); + rm.done(); + } + + public FormattedValueDMContext getFormattedValueContext(IFormattedDataDMContext dmc, String formatId) { + if ( dmc instanceof MIRegisterDMC ) { + MIRegisterDMC regDmc = (MIRegisterDMC) dmc; + return( new FormattedValueDMContext( this, regDmc, formatId)); + } + return null; + } + + private void generateRegisterChangedEvent(IRegisterDMContext dmc ) { + getSession().dispatchEvent(new RegisterChangedDMEvent(dmc), getProperties()); + } + +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java new file mode 100644 index 00000000000..644182278e4 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java @@ -0,0 +1,668 @@ +/******************************************************************************* + * 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 + * Ericsson AB - Modified for handling of multiple threads + *******************************************************************************/ +package org.eclipse.dd.mi.service; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.AbstractDMContext; +import org.eclipse.dd.dsf.datamodel.AbstractDMEvent; +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.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; +import org.eclipse.dd.dsf.debug.service.command.CommandCache; +import org.eclipse.dd.dsf.debug.service.command.ICommandControl; +import org.eclipse.dd.dsf.service.AbstractDsfService; +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.mi.internal.MIPlugin; +import org.eclipse.dd.mi.service.command.commands.MIExecContinue; +import org.eclipse.dd.mi.service.command.commands.MIExecFinish; +import org.eclipse.dd.mi.service.command.commands.MIExecInterrupt; +import org.eclipse.dd.mi.service.command.commands.MIExecNext; +import org.eclipse.dd.mi.service.command.commands.MIExecStep; +import org.eclipse.dd.mi.service.command.commands.MIExecUntil; +import org.eclipse.dd.mi.service.command.commands.MIThreadListIds; +import org.eclipse.dd.mi.service.command.events.MIBreakpointHitEvent; +import org.eclipse.dd.mi.service.command.events.MIErrorEvent; +import org.eclipse.dd.mi.service.command.events.MIEvent; +import org.eclipse.dd.mi.service.command.events.MIGDBExitEvent; +import org.eclipse.dd.mi.service.command.events.MIRunningEvent; +import org.eclipse.dd.mi.service.command.events.MISharedLibEvent; +import org.eclipse.dd.mi.service.command.events.MISignalEvent; +import org.eclipse.dd.mi.service.command.events.MISteppingRangeEvent; +import org.eclipse.dd.mi.service.command.events.MIStoppedEvent; +import org.eclipse.dd.mi.service.command.events.MIThreadCreatedEvent; +import org.eclipse.dd.mi.service.command.events.MIThreadExitEvent; +import org.eclipse.dd.mi.service.command.events.MIWatchpointTriggerEvent; +import org.eclipse.dd.mi.service.command.output.MIInfo; +import org.eclipse.dd.mi.service.command.output.MIThreadListIdsInfo; +import org.osgi.framework.BundleContext; + + +/** + * + *

    + * Implementation note: + * This class implements event handlers for the events that are generated by + * this service itself. When the event is dispatched, these handlers will + * be called first, before any of the clients. These handlers update the + * service's internal state information to make them consistent with the + * events being issued. Doing this in the handlers as opposed to when + * the events are generated, guarantees that the state of the service will + * always be consistent with the events. + * The purpose of this pattern is to allow clients that listen to service + * events and track service state, to be perfectly in sync with the service + * state. + */ +public class MIRunControl extends AbstractDsfService implements IRunControl +{ + protected class MIExecutionDMC extends AbstractDMContext + implements IMIExecutionDMContext + { + /** + * Integer ID that is used to identify the thread in the GDB/MI protocol. + */ + private final int fThreadId; + + /** + * Constructor for the context. It should not be called directly by clients. + * Instead clients should call {@link MIRunControl#createMIExecutionContext(IContainerDMContext, int)} + * to create instances of this context based on the thread ID. + *

    + * Classes extending {@link MIRunControl} may also extend this class to include + * additional information in the context. + * + * @param sessionId Session that this context belongs to. + * @param containerDmc The container that this context belongs to. + * @param threadId GDB/MI thread identifier. + */ + protected MIExecutionDMC(String sessionId, IContainerDMContext containerDmc, int threadId) { + super(sessionId, containerDmc != null ? new IDMContext[] { containerDmc } : new IDMContext[0]); + fThreadId = threadId; + } + + /** + * Returns the GDB/MI thread identifier of this context. + * @return + */ + public int getThreadId(){ + return fThreadId; + } + + @Override + public String toString() { return baseToString() + ".thread[" + fThreadId + "]"; } //$NON-NLS-1$ //$NON-NLS-2$ + + @Override + public boolean equals(Object obj) { + return super.baseEquals(obj) && ((MIExecutionDMC)obj).fThreadId == fThreadId; + } + + @Override + public int hashCode() { return super.baseHashCode() ^ fThreadId; } + } + + @Immutable + private static class ExecutionData implements IExecutionDMData { + private final StateChangeReason fReason; + ExecutionData(StateChangeReason reason) { + fReason = reason; + } + public StateChangeReason getStateChangeReason() { return fReason; } + } + + /** + * Base class for events generated by the MI Run Control service. Most events + * generated by the MI Run Control service are directly caused by some MI event. + * Other services may need access to the extended MI data carried in the event. + * + * @param DMC that this event refers to + * @param MIInfo object that is the direct cause of this event + * @see MIRunControl + */ + @Immutable + protected static class RunControlEvent> extends AbstractDMEvent + implements IDMEvent + { + final private T fMIInfo; + public RunControlEvent(V dmc, T miInfo) { + super(dmc); + fMIInfo = miInfo; + } + + public T getMIEvent() { return fMIInfo; } + } + + /** + * Indicates that the given thread has been suspended. + */ + @Immutable + protected static class SuspendedEvent extends RunControlEvent + implements ISuspendedDMEvent + { + SuspendedEvent(IExecutionDMContext ctx, MIStoppedEvent miInfo) { + super(ctx, miInfo); + } + + public StateChangeReason getReason() { + if (getMIEvent() instanceof MIBreakpointHitEvent) { + return StateChangeReason.BREAKPOINT; + } else if (getMIEvent() instanceof MISteppingRangeEvent) { + return StateChangeReason.STEP; + } else if (getMIEvent() instanceof MISharedLibEvent) { + return StateChangeReason.SHAREDLIB; + }else if (getMIEvent() instanceof MISignalEvent) { + return StateChangeReason.SIGNAL; + }else if (getMIEvent() instanceof MIWatchpointTriggerEvent) { + return StateChangeReason.WATCHPOINT; + }else if (getMIEvent() instanceof MIErrorEvent) { + return StateChangeReason.ERROR; + }else { + return StateChangeReason.USER_REQUEST; + } + } + } + + @Immutable + protected static class ContainerSuspendedEvent extends SuspendedEvent + implements IContainerSuspendedDMEvent + { + final IExecutionDMContext triggeringDmc; + ContainerSuspendedEvent(IContainerDMContext containerDmc, MIStoppedEvent miInfo, IExecutionDMContext triggeringDmc) { + super(containerDmc, miInfo); + this.triggeringDmc = triggeringDmc; + } + + public IExecutionDMContext getTriggeringContext() { + return triggeringDmc; + } + } + + @Immutable + protected static class ResumedEvent extends RunControlEvent + implements IResumedDMEvent + { + ResumedEvent(IExecutionDMContext ctx, MIRunningEvent miInfo) { + super(ctx, miInfo); + } + + public StateChangeReason getReason() { + switch(getMIEvent().getType()) { + case MIRunningEvent.CONTINUE: + return StateChangeReason.USER_REQUEST; + case MIRunningEvent.NEXT: + case MIRunningEvent.NEXTI: + return StateChangeReason.STEP; + case MIRunningEvent.STEP: + case MIRunningEvent.STEPI: + return StateChangeReason.STEP; + case MIRunningEvent.FINISH: + return StateChangeReason.STEP; + case MIRunningEvent.UNTIL: + case MIRunningEvent.RETURN: + break; + } + return StateChangeReason.UNKNOWN; + } + } + + @Immutable + protected static class ContainerResumedEvent extends ResumedEvent + implements IContainerResumedDMEvent + { + final IExecutionDMContext triggeringDmc; + + ContainerResumedEvent(IContainerDMContext containerDmc, MIRunningEvent miInfo, IExecutionDMContext triggeringDmc) { + super(containerDmc, miInfo); + this.triggeringDmc = triggeringDmc; + } + + public IExecutionDMContext getTriggeringContext() { + return triggeringDmc; + } + } + + @Immutable + protected static class StartedDMEvent extends RunControlEvent + implements IStartedDMEvent{ + + private final IMIExecutionDMContext fExecutionDmc; + + StartedDMEvent(IContainerDMContext containerDmc, IMIExecutionDMContext executionDmc, MIThreadCreatedEvent miInfo) { + super(containerDmc, miInfo); + fExecutionDmc = executionDmc; + } + + public IExecutionDMContext getExecutionContext(){ + return fExecutionDmc; + } + + } + + @Immutable + protected static class ExitedDMEvent extends RunControlEvent + implements IExitedDMEvent{ + + private final IMIExecutionDMContext fExecutionDmc; + + ExitedDMEvent(IContainerDMContext containerDmc, IMIExecutionDMContext executionDmc, MIThreadExitEvent miInfo) { + super(containerDmc, miInfo); + fExecutionDmc = executionDmc; + } + + public IExecutionDMContext getExecutionContext(){ + return fExecutionDmc; + } + } + + private ICommandControl fConnection; + private CommandCache fMICommandCache; + + // state flags + private boolean fSuspended = true; + private boolean fResumePending = false; + private boolean fStepping = false; + private boolean fTerminated = false; + + private StateChangeReason fStateChangeReason; + private IExecutionDMContext fStateChangeTriggeringContext; + + private static final int NO_THREAD_ID = 0; + + public MIRunControl(DsfSession session) { + super(session); + } + + @Override + public void initialize(final RequestMonitor rm) { + super.initialize( + new RequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + doInitialize(rm); + }}); + } + + private void doInitialize(final RequestMonitor rm) { + fConnection = getServicesTracker().getService(ICommandControl.class); + fMICommandCache = new CommandCache(fConnection); + getSession().addServiceEventListener(this, null); + + //register(new String[]{IRunControl.class.getName(), MIRunControl.class.getName()}, new Hashtable()); + + rm.done(); + } + + @Override + public void shutdown(final RequestMonitor rm) { + getSession().removeServiceEventListener(this); + fMICommandCache.reset(); + super.shutdown(rm); + } + + public boolean isValid() { return true; } + + @SuppressWarnings("unchecked") + public void getModelData(IDMContext dmc, DataRequestMonitor rm) { + if (dmc instanceof IExecutionDMContext) { + getExecutionData((IExecutionDMContext)dmc, (DataRequestMonitor)rm); + } else { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ + rm.done(); + } + } + + public CommandCache getCache() { return fMICommandCache; } + + public IMIExecutionDMContext createMIExecutionContext(IContainerDMContext container, int threadId) { + return new MIExecutionDMC(getSession().getId(), container, threadId); + } + + // + // Running event handling + // + @DsfServiceEventHandler + public void eventDispatched(final MIRunningEvent e) { + IDMEvent event = null; + // Find the container context, which is used in multi-threaded debugging. + IContainerDMContext containerDmc = DMContexts.getAncestorOfType(e.getDMContext(), IContainerDMContext.class); + if (containerDmc != null) { + // Set the triggering context only if it's different than the container context. + IExecutionDMContext triggeringCtx = !e.getDMContext().equals(containerDmc) ? e.getDMContext() : null; + event = new ContainerResumedEvent(containerDmc, e, triggeringCtx); + } else { + event = new ResumedEvent(e.getDMContext(), e); + } + getSession().dispatchEvent(event, getProperties()); + } + + // + // Suspended event handling + // + @DsfServiceEventHandler + public void eventDispatched(final MIStoppedEvent e) { + IDMEvent event = null; + // Find the container context, which is used in multi-threaded debugging. + IContainerDMContext containerDmc = DMContexts.getAncestorOfType(e.getDMContext(), IContainerDMContext.class); + if (containerDmc != null) { + // Set the triggering context only if it's different than the container context. + IExecutionDMContext triggeringCtx = !e.getDMContext().equals(containerDmc) ? e.getDMContext() : null; + event = new ContainerSuspendedEvent(containerDmc, e, triggeringCtx); + } else { + event = new SuspendedEvent(e.getDMContext(), e); + } + getSession().dispatchEvent(event, getProperties()); + } + + // + // Thread Created event handling + // When a new thread is created - OOB Event fired ~"[New Thread 1077300144 (LWP 7973)]\n" + // + @DsfServiceEventHandler + public void eventDispatched(final MIThreadCreatedEvent e) { + IContainerDMContext containerDmc = e.getDMContext(); + IMIExecutionDMContext executionCtx = e.getId() != -1 ? new MIExecutionDMC(getSession().getId(), containerDmc, e.getId()) : null; + getSession().dispatchEvent(new StartedDMEvent(containerDmc, executionCtx, e), getProperties()); + } + + // + // Thread exit event handling + // When a new thread is destroyed - OOB Event fired " + // + @DsfServiceEventHandler + public void eventDispatched(final MIThreadExitEvent e) { + IContainerDMContext containerDmc = e.getDMContext(); + IMIExecutionDMContext executionCtx = e.getId() != -1 ? new MIExecutionDMC(getSession().getId(), containerDmc, e.getId()) : null; + getSession().dispatchEvent(new ExitedDMEvent(containerDmc, executionCtx, e), getProperties()); + } + + @DsfServiceEventHandler + public void eventDispatched(ContainerResumedEvent e) { + fSuspended = false; + fResumePending = false; + fStateChangeReason = e.getReason(); + fMICommandCache.setTargetAvailable(false); + //fStateChangeTriggeringContext = e.getTriggeringContext(); + if (e.getReason().equals(StateChangeReason.STEP)) { + fStepping = true; + } else { + fMICommandCache.reset(); + } + } + + + @DsfServiceEventHandler + public void eventDispatched(ContainerSuspendedEvent e) { + fMICommandCache.setTargetAvailable(true); + fMICommandCache.reset(); + fStateChangeReason = e.getReason(); + fStateChangeTriggeringContext = e.getTriggeringContext(); + fSuspended = true; + fStepping = false; + } + + + @DsfServiceEventHandler + public void eventDispatched(MIGDBExitEvent e) { + fTerminated = true; + } + + + // Event handler when New thread is created + @DsfServiceEventHandler + public void eventDispatched(StartedDMEvent e) { + + } + + // Event handler when a thread is destroyed + @DsfServiceEventHandler + public void eventDispatched(ExitedDMEvent e) { + fMICommandCache.reset(e.getExecutionContext()); + + } + + /////////////////////////////////////////////////////////////////////////// + // AbstractService + @Override + protected BundleContext getBundleContext() { + return MIPlugin.getBundleContext(); + } + + /////////////////////////////////////////////////////////////////////////// + // IRunControl + public boolean canResume(IExecutionDMContext context) { + return !fTerminated && isSuspended(context) && !fResumePending; + } + + public boolean canSuspend(IExecutionDMContext context) { + return !fTerminated && !isSuspended(context); + } + + public boolean isSuspended(IExecutionDMContext context) { + return !fTerminated && fSuspended; + } + + public boolean isStepping(IExecutionDMContext context) { + return !fTerminated && fStepping; + } + + public void resume(IExecutionDMContext context, final RequestMonitor rm) { + assert context != null; + + if (canResume(context)) { + fResumePending = true; + // Cygwin GDB will accept commands and execute them after the step + // which is not what we want, so mark the target as unavailable + // as soon as we send a resume command. + fMICommandCache.setTargetAvailable(false); + MIExecContinue cmd = null; + if(context instanceof IContainerDMContext) + cmd = new MIExecContinue(context); + else{ + IMIExecutionDMContext dmc = DMContexts.getAncestorOfType(context, IMIExecutionDMContext.class); + if (dmc == null){ + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Given context: " + context + " is not an execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$ + rm.done(); + return; + } + cmd = new MIExecContinue(dmc);//, new String[0]); + } + fConnection.queueCommand( + cmd, + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + rm.done(); + } + } + ); + }else { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Given context: " + context + ", is already running.", null)); //$NON-NLS-1$ //$NON-NLS-2$ + rm.done(); + } + } + + public void suspend(IExecutionDMContext context, final RequestMonitor rm){ + assert context != null; + + if (canSuspend(context)) { + MIExecInterrupt cmd = null; + if(context instanceof IContainerDMContext){ + cmd = new MIExecInterrupt(context); + } + else { + IMIExecutionDMContext dmc = DMContexts.getAncestorOfType(context, IMIExecutionDMContext.class); + if (dmc == null){ + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Given context: " + context + " is not an execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$ + rm.done(); + return; + } + cmd = new MIExecInterrupt(dmc); + } + fConnection.queueCommand( + cmd, + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + rm.done(); + } + } + ); + } else { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Given context: " + context + ", is already suspended.", null)); //$NON-NLS-1$ //$NON-NLS-2$ + rm.done(); + } + } + + public boolean canStep(IExecutionDMContext context) { + return canResume(context); + } + + public void step(IExecutionDMContext context, StepType stepType, final RequestMonitor rm) { + assert context != null; + + IMIExecutionDMContext dmc = DMContexts.getAncestorOfType(context, IMIExecutionDMContext.class); + if (dmc == null){ + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Given context: " + context + " is not an execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$ + rm.done(); + return; + } + + if (!canResume(context)) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_STATE, "Cannot resume context", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + fResumePending = true; + fStepping = true; + fMICommandCache.setTargetAvailable(false); + switch(stepType) { + case STEP_INTO: + fConnection.queueCommand( + new MIExecStep(dmc, 1), new DataRequestMonitor(getExecutor(), rm) {} + ); + break; + case STEP_OVER: + fConnection.queueCommand( + new MIExecNext(dmc), new DataRequestMonitor(getExecutor(), rm) {}); + break; + case STEP_RETURN: + // The -exec-finish command operates on the selected stack frame, but here we always + // want it to operate on the stop stack frame. So we manually create a top-frame + // context to use with the MI command. + // We get a local instance of the stack service because the stack service can be shut + // down before the run control service is shut down. So it is possible for the + // getService() reqeust below to return null. + MIStack stackService = getServicesTracker().getService(MIStack.class); + if (stackService != null) { + IFrameDMContext topFrameDmc = stackService.createFrameDMContext(dmc, 0); + fConnection.queueCommand( + new MIExecFinish(topFrameDmc), new DataRequestMonitor(getExecutor(), rm) {}); + } else { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Cannot create context for command, stack service not available.", null)); //$NON-NLS-1$ + rm.done(); + } + break; + default: + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Given step type not supported", null)); //$NON-NLS-1$ + rm.done(); + } + } + + public boolean canInstructionStep(IExecutionDMContext context) { + return false; + } + + public void instructionStep(IExecutionDMContext context, StepType stepType, RequestMonitor rm) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, "Operation not implemented", null)); //$NON-NLS-1$ + rm.done(); + } + + public void getExecutionContexts(final IContainerDMContext containerDmc, final DataRequestMonitor rm) { + fMICommandCache.execute( + new MIThreadListIds(containerDmc), + new DataRequestMonitor( + getExecutor(), rm) { + @Override + protected void handleOK() { + rm.setData(makeExecutionDMCs(containerDmc, getData())); + rm.done(); + } + }); + } + + + private IExecutionDMContext[] makeExecutionDMCs(IContainerDMContext containerCtx, MIThreadListIdsInfo info) { + if (info.getThreadIds().length == 0) { + //Main thread always exist even if it is not reported by GDB. + //So create thread-id= 0 when no thread is reported + return new IMIExecutionDMContext[]{new MIExecutionDMC(getSession().getId(), containerCtx, NO_THREAD_ID)}; + } else { + IExecutionDMContext[] executionDmcs = new IMIExecutionDMContext[info.getThreadIds().length]; + for (int i = 0; i < info.getThreadIds().length; i++) { + executionDmcs[i] = new MIExecutionDMC(getSession().getId(), containerCtx, info.getThreadIds()[i]); + } + return executionDmcs; + } + } + + public void getExecutionData(IExecutionDMContext dmc, DataRequestMonitor rm){ + if (dmc instanceof IContainerDMContext) { + rm.setData( new ExecutionData(fStateChangeReason) ); + } else if (dmc instanceof IMIExecutionDMContext) { + StateChangeReason reason = dmc.equals(fStateChangeTriggeringContext) ? fStateChangeReason : StateChangeReason.CONTAINER; + rm.setData(new ExecutionData(reason)); + } else { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Given context: " + dmc + " is not an execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$ + } + rm.done(); + } + + /* + * Run selected execution thread to a given line number. + */ + // Later add support for Address and function. + // skipBreakpoints is not used at the moment. Implement later + public void runToLine(IExecutionDMContext context, String fileName, String lineNo, boolean skipBreakpoints, final DataRequestMonitor rm){ + assert context != null; + + IMIExecutionDMContext dmc = DMContexts.getAncestorOfType(context, IMIExecutionDMContext.class); + if (dmc == null){ + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Given context: " + context + " is not an execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$ + rm.done(); + return; + } + + if (canResume(context)) { + fResumePending = true; + fMICommandCache.setTargetAvailable(false); + fConnection.queueCommand(new MIExecUntil(dmc, fileName + ":" + lineNo), //$NON-NLS-1$ + new DataRequestMonitor( + getExecutor(), rm) { + @Override + protected void handleOK() { + rm.done(); + } + }); + } else { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, + "Cannot resume given DMC.", null)); //$NON-NLS-1$ + rm.done(); + } + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIStack.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIStack.java new file mode 100644 index 00000000000..f18f53765ac --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIStack.java @@ -0,0 +1,559 @@ +/******************************************************************************* + * 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 + * Ericsson - Modified for handling of multiple execution contexts + *******************************************************************************/ +package org.eclipse.dd.mi.service; + +import java.util.Hashtable; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.utils.Addr32; +import org.eclipse.cdt.utils.Addr64; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.AbstractDMContext; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.IStack; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason; +import org.eclipse.dd.dsf.service.AbstractDsfService; +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.mi.internal.MIPlugin; +import org.eclipse.dd.mi.service.command.commands.MIStackInfoDepth; +import org.eclipse.dd.mi.service.command.commands.MIStackListArguments; +import org.eclipse.dd.mi.service.command.commands.MIStackListFrames; +import org.eclipse.dd.mi.service.command.commands.MIStackListLocals; +import org.eclipse.dd.mi.service.command.events.MIStoppedEvent; +import org.eclipse.dd.mi.service.command.output.MIArg; +import org.eclipse.dd.mi.service.command.output.MIFrame; +import org.eclipse.dd.mi.service.command.output.MIStackInfoDepthInfo; +import org.eclipse.dd.mi.service.command.output.MIStackListArgumentsInfo; +import org.eclipse.dd.mi.service.command.output.MIStackListFramesInfo; +import org.eclipse.dd.mi.service.command.output.MIStackListLocalsInfo; +import org.osgi.framework.BundleContext; + +public class MIStack extends AbstractDsfService + implements IStack +{ + protected static class MIFrameDMC extends AbstractDMContext + implements IFrameDMContext + { + private final int fLevel; + // public MIFrameDMC(MIStack service, int level) { + public MIFrameDMC(String sessionId, IExecutionDMContext execDmc, int level) { + super(sessionId, new IDMContext[] { execDmc }); + fLevel = level; + } + + public int getLevel() { return fLevel; } + + @Override + public boolean equals(Object other) { + return super.baseEquals(other) && ((MIFrameDMC)other).fLevel == fLevel; + } + + @Override + public int hashCode() { + return super.baseHashCode() ^ fLevel; + } + + @Override + public String toString() { + return baseToString() + ".frame[" + fLevel + "]"; //$NON-NLS-1$ //$NON-NLS-2$ + } + } + + protected static class MIVariableDMC extends AbstractDMContext + implements IVariableDMContext + { + public enum Type { ARGUMENT, LOCAL } + final private Type fType; + final private int fIndex; + + public MIVariableDMC(MIStack service, IFrameDMContext frame, Type type, int index) { + super(service, new IDMContext[] { frame }); + fIndex = index; + fType = type; + } + + public int getIndex() { return fIndex; } + public Type getType() { return fType; } + + @Override + public boolean equals(Object other) { + return super.baseEquals(other) && + ((MIVariableDMC)other).fType == fType && + ((MIVariableDMC)other).fIndex == fIndex; + } + + @Override + public int hashCode() { + int typeFactor = 0; + if (fType == Type.LOCAL) typeFactor = 2; + else if (fType == Type.ARGUMENT) typeFactor = 3; + return super.baseHashCode() ^ typeFactor ^ fIndex; + } + + @Override + public String toString() { + return baseToString() + ".variable(" + fType + ")[" + fIndex + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + } + + private MIRunControl fRunControl; + private MIStoppedEvent fCachedStoppedEvent; + + public MIStack(DsfSession session) + { + super(session); + } + + @Override + protected BundleContext getBundleContext() + { + return MIPlugin.getBundleContext(); + } + + @Override + public void initialize(final RequestMonitor rm) { + super.initialize( + new RequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + doInitialize(rm); + } + }); + } + + private void doInitialize(RequestMonitor rm) { + fRunControl = getServicesTracker().getService(MIRunControl.class); + getSession().addServiceEventListener(this, null); + register(new String[]{IStack.class.getName(), MIStack.class.getName()}, new Hashtable()); + rm.done(); + } + + @Override + public void shutdown(RequestMonitor rm) + { + unregister(); + getSession().removeServiceEventListener(this); + super.shutdown(rm); + } + + @SuppressWarnings("unchecked") + public void getModelData(IDMContext dmc, DataRequestMonitor rm) { + if (dmc instanceof MIFrameDMC) { + getFrameData((MIFrameDMC)dmc, (DataRequestMonitor)rm); + // getFrameData invokes rm + } else if (dmc instanceof MIVariableDMC) { + getVariableData((MIVariableDMC)dmc, (DataRequestMonitor)rm); + // getVariablesData invokes rm + } else { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ + rm.done(); + } + } + + /** + * Creates a frame context. This method is intended to be used by other MI + * services and sub-classes which need to create a frame context directly. + *

    + * Sub-classes can override this method to provide custom stack frame + * context implementation. + *

    + * @param execDmc Execution context that this frame is to be a child of. + * @param level Level of the new context. + * @return A new frame context. + */ + public IFrameDMContext createFrameDMContext(IExecutionDMContext execDmc, int level) { + return new MIFrameDMC(getSession().getId(), execDmc, level); + } + + + public boolean isStackAvailable(IDMContext context) { + IExecutionDMContext execCtx = DMContexts.getAncestorOfType(context, IExecutionDMContext.class); + return execCtx != null && (fRunControl.isSuspended(execCtx) || (fRunControl.isStepping(execCtx))); + } + + public void getFrames(final IDMContext ctx, final DataRequestMonitor rm) { + + final IMIExecutionDMContext execDmc = DMContexts.getAncestorOfType(ctx, IMIExecutionDMContext.class); + + if (execDmc == null) { + //rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, -1, "No frame context found in " + ctx, null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context" + ctx, null)); //$NON-NLS-1$ + rm.done(); + return; + } + fRunControl.getCache().execute( + new MIStackListFrames(execDmc), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + rm.setData(getFrames(execDmc, getData())); + rm.done(); + } + }); + } + + public void getTopFrame(final IDMContext ctx, final DataRequestMonitor rm) { + final IMIExecutionDMContext execDmc = DMContexts.getAncestorOfType(ctx, IMIExecutionDMContext.class); + if (execDmc == null) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context" + ctx, null)); //$NON-NLS-1$ + rm.done(); + return; + } + + // Try to retrieve the top stack frame from the cached stopped event. + if (fCachedStoppedEvent != null && + fCachedStoppedEvent.getFrame() != null && + execDmc.equals(fCachedStoppedEvent.getDMContext())) + { + rm.setData(createFrameDMContext(execDmc, fCachedStoppedEvent.getFrame().getLevel())); + rm.done(); + return; + } + + // If stopped event is not available or doesn't contain frame info, + // query the full list of frames. + getFrames( + ctx, + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + rm.setData(getData()[0]); + rm.done(); + } + }); + } + + //private MIFrameDMC[] getFrames(DsfMIStackListFramesInfo info) { + private IFrameDMContext[] getFrames(IMIExecutionDMContext execDmc, MIStackListFramesInfo info) { + IFrameDMContext[] frameDMCs = new MIFrameDMC[info.getMIFrames().length]; + for (int i = 0; i < info.getMIFrames().length; i++) { + //frameDMCs[i] = new MIFrameDMC(this, info.getMIFrames()[i].getLevel()); + frameDMCs[i] = createFrameDMContext(execDmc, info.getMIFrames()[i].getLevel()); + } + return frameDMCs; + } + + + + public void getFrameData(final IFrameDMContext frameDmc, final DataRequestMonitor rm) { + if (!(frameDmc instanceof MIFrameDMC)) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context type " + frameDmc, null)); //$NON-NLS-1$ + rm.done(); + return; + } + + final MIFrameDMC miFrameDmc = (MIFrameDMC)frameDmc; + + IMIExecutionDMContext execDmc = DMContexts.getAncestorOfType(frameDmc, IMIExecutionDMContext.class); + if (execDmc == null) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "No execution context found in " + frameDmc, null)); //$NON-NLS-1$ + rm.done(); + return; + } + + /** + * Base class for the IFrameDMData object that uses an MIFrame object to + * provide the data. Sub-classes must provide the MIFrame object + */ + abstract class FrameData implements IFrameDMData + { + abstract protected MIFrame getMIFrame(); + + public IAddress getAddress() { + String addr = getMIFrame().getAddress(); + if (addr.startsWith("0x")) { //$NON-NLS-1$ + addr = addr.substring(2); + } + if (addr.length() <= 8) { + return new Addr32(getMIFrame().getAddress()); + } else { + return new Addr64(getMIFrame().getAddress()); + } + } + + public int getColumn() { return 0; } + + public String getFile() { return getMIFrame().getFile(); } + public int getLine() { return getMIFrame().getLine(); } + public String getFunction() { return getMIFrame().getFunction(); } + + @Override + public String toString() { return getMIFrame().toString(); } + } + + // If requested frame is the top stack frame, try to retrieve it from + // the stopped event data. + class FrameDataFromStoppedEvent extends FrameData { + private final MIStoppedEvent fEvent; + FrameDataFromStoppedEvent(MIStoppedEvent event) { fEvent = event; } + @Override + protected MIFrame getMIFrame() { return fEvent.getFrame(); } + } + + // Retrieve the top stack frame from the stopped event only if the selected thread is the one on which stopped event + // is raised + if (fCachedStoppedEvent != null && + execDmc.equals(fCachedStoppedEvent.getDMContext()) && + miFrameDmc.fLevel == 0 && + fCachedStoppedEvent.getFrame() != null) + { + rm.setData(new FrameDataFromStoppedEvent(fCachedStoppedEvent)); + rm.done(); + return; + } + + // If not, retrieve the full list of frame data. + class FrameDataFromMIStackFrameListInfo extends FrameData { + private MIStackListFramesInfo fFrameDataCacheInfo; + private int fFrameIndex; + + FrameDataFromMIStackFrameListInfo(MIStackListFramesInfo info, int index) { + fFrameDataCacheInfo = info; + fFrameIndex = index; + } + + @Override + protected MIFrame getMIFrame() { return fFrameDataCacheInfo.getMIFrames()[fFrameIndex]; } + } + + fRunControl.getCache().execute( + new MIStackListFrames(execDmc), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + // Find the index to the correct MI frame object. + int idx = findFrameIndex(getData().getMIFrames(), miFrameDmc.fLevel); + if (idx == -1) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid frame " + frameDmc, null)); //$NON-NLS-1$ + rm.done(); + return; + } + + // Create the data object. + rm.setData(new FrameDataFromMIStackFrameListInfo(getData(), idx)); + rm.done(); + } + }); + } + + public void getArguments(final IFrameDMContext frameDmc, final DataRequestMonitor rm) { + final IMIExecutionDMContext execDmc = DMContexts.getAncestorOfType(frameDmc, IMIExecutionDMContext.class); + if (execDmc == null) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "No execution context found in " + frameDmc, null)); //$NON-NLS-1$ + rm.done(); + return; + } + + + // If requested frame is the top stack frame, try to retrieve it from + // the stopped event data. + if (frameDmc.getLevel() == 0 && + fCachedStoppedEvent != null && + fCachedStoppedEvent.getFrame() != null && + execDmc.equals(fCachedStoppedEvent.getDMContext()) && + fCachedStoppedEvent.getFrame().getArgs() != null) + { + rm.setData(makeVariableDMCs( + frameDmc, MIVariableDMC.Type.ARGUMENT, fCachedStoppedEvent.getFrame().getArgs().length)); + rm.done(); + return; + } + + // If not, retrieve the full list of frame data. + fRunControl.getCache().execute( + new MIStackListArguments(execDmc, true), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + // Find the index to the correct MI frame object. + // Note: this is a short-cut, but it won't work once we implement retrieving + // partial lists of stack frames. + int idx = frameDmc.getLevel(); + if (idx == -1) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_STATE, "Invalid frame " + frameDmc, null)); //$NON-NLS-1$ + rm.done(); + return; + } + + // Create the variable array out of MIArg array. + MIArg[] args = getData().getMIFrames()[idx].getArgs(); + if (args == null) args = new MIArg[0]; + rm.setData(makeVariableDMCs(frameDmc, MIVariableDMC.Type.ARGUMENT, args.length)); + rm.done(); + } + }); + } + + public void getVariableData(IVariableDMContext variableDmc, final DataRequestMonitor rm) { + if (!(variableDmc instanceof MIVariableDMC)) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context type " + variableDmc, null)); //$NON-NLS-1$ + rm.done(); + return; + } + final MIVariableDMC miVariableDmc = (MIVariableDMC)variableDmc; + + // Extract the frame DMC from the variable DMC. + final MIFrameDMC frameDmc = DMContexts.getAncestorOfType(variableDmc, MIFrameDMC.class); + if (frameDmc == null) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "No frame context found in " + variableDmc, null)); //$NON-NLS-1$ + rm.done(); + return; + } + + final IMIExecutionDMContext execDmc = DMContexts.getAncestorOfType(frameDmc, IMIExecutionDMContext.class); + if (execDmc == null) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "No execution context found in " + frameDmc, null)); //$NON-NLS-1$ + rm.done(); + return; + } + + /** + * Same as with frame objects, this is a base class for the IVariableDMData object that uses an MIArg object to + * provide the data. Sub-classes must supply the MIArg object. + */ + class VariableData implements IVariableDMData { + private MIArg dsfMIArg; + VariableData(MIArg arg){ + dsfMIArg = arg; + } + public String getName() { return dsfMIArg.getName(); } + public String getValue() { return dsfMIArg.getValue(); } + @Override + public String toString() { return dsfMIArg.toString(); } + } + + // Check if the stopped event can be used to extract the variable value. + if (execDmc != null && miVariableDmc.fType == MIVariableDMC.Type.ARGUMENT && + frameDmc.fLevel == 0 && fCachedStoppedEvent != null && fCachedStoppedEvent.getFrame() != null && + execDmc.equals(fCachedStoppedEvent.getDMContext()) && + fCachedStoppedEvent.getFrame().getArgs() != null) + { + if (miVariableDmc.fIndex >= fCachedStoppedEvent.getFrame().getArgs().length) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, -1, "Invalid variable " + miVariableDmc, null)); //$NON-NLS-1$ + rm.done(); + return; + } + + rm.setData(new VariableData(fCachedStoppedEvent.getFrame().getArgs()[miVariableDmc.fIndex])); + rm.done(); + return; + } + + if (miVariableDmc.fType == MIVariableDMC.Type.ARGUMENT){ + fRunControl.getCache().execute( + new MIStackListArguments(execDmc, true), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + // Find the correct frame and argument + if ( frameDmc.fLevel >= getData().getMIFrames().length || + miVariableDmc.fIndex >= getData().getMIFrames()[frameDmc.fLevel].getArgs().length ) + { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid variable " + miVariableDmc, null)); //$NON-NLS-1$ + rm.done(); + return; + } + + // Create the data object. + rm.setData(new VariableData(getData().getMIFrames()[frameDmc.fLevel].getArgs()[miVariableDmc.fIndex])); + rm.done(); + }}); + }//if + if (miVariableDmc.fType == MIVariableDMC.Type.LOCAL){ + fRunControl.getCache().execute( + new MIStackListLocals(frameDmc, true), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + + // Create the data object. + rm.setData(new VariableData(getData().getLocals()[miVariableDmc.fIndex])); + rm.done(); + } + }); + + }//if + + } + + private MIVariableDMC[] makeVariableDMCs(IFrameDMContext frame, MIVariableDMC.Type type, int count) { + MIVariableDMC[] variables = new MIVariableDMC[count]; + for (int i = 0; i < count; i++) { + variables[i]= new MIVariableDMC(this, frame, type, i); + } + return variables; + } + + private int findFrameIndex(MIFrame[] frames, int level) { + for (int idx = 0; idx < frames.length; idx++) { + if (frames[idx].getLevel() == level) { + return idx; + } + } + return -1; + } + + + public void getLocals(final IFrameDMContext frameDmc, final DataRequestMonitor rm) { + fRunControl.getCache().execute( + new MIStackListLocals(frameDmc, true), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + rm.setData(makeVariableDMCs(frameDmc, MIVariableDMC.Type.LOCAL, getData().getLocals().length)); + rm.done(); + } + }); + } + + public void getStackDepth(IDMContext dmc, final int maxDepth, final DataRequestMonitor rm) { + IMIExecutionDMContext execDmc = DMContexts.getAncestorOfType(dmc, IMIExecutionDMContext.class); + if (execDmc != null) { + MIStackInfoDepth depthCommand = null; + if (maxDepth > 0) depthCommand = new MIStackInfoDepth(execDmc, maxDepth); + else depthCommand = new MIStackInfoDepth(execDmc); + + fRunControl.getCache().execute( + depthCommand, + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + rm.setData(getData().getDepth()); + rm.done(); + } + }); + } else { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ + rm.done(); + } + } + // IServiceEventListener + @DsfServiceEventHandler public void eventDispatched(IRunControl.IResumedDMEvent e) { + if (e.getReason() != StateChangeReason.STEP) { + fCachedStoppedEvent = null; + } + } + + // @DsfServiceEventHandler public void eventDispatched(MIRunControl.SuspendedEvent e) { + @DsfServiceEventHandler public void eventDispatched(MIRunControl.ContainerSuspendedEvent e) { + fCachedStoppedEvent = e.getMIEvent(); + } + +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java new file mode 100644 index 00000000000..3227e81206f --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java @@ -0,0 +1,1648 @@ +/******************************************************************************* + * Copyright (c) 2008 Monta Vista 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: + * Monta Vista - initial API and implementation + * Ericsson - Modified for handling of multiple execution contexts + * Ericsson - Major updates for GDB/MI implementation + * Ericsson - Major re-factoring to deal with children + *******************************************************************************/ +package org.eclipse.dd.mi.service; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.debug.service.IExpressions; +import org.eclipse.dd.dsf.debug.service.IFormattedValues; +import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.IStack; +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData; +import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; +import org.eclipse.dd.dsf.debug.service.command.ICommand; +import org.eclipse.dd.dsf.debug.service.command.ICommandControl; +import org.eclipse.dd.dsf.debug.service.command.ICommandListener; +import org.eclipse.dd.dsf.debug.service.command.ICommandResult; +import org.eclipse.dd.dsf.debug.service.command.IEventListener; +import org.eclipse.dd.dsf.service.AbstractDsfService; +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.mi.internal.MIPlugin; +import org.eclipse.dd.mi.service.ExpressionService.ExpressionInfo; +import org.eclipse.dd.mi.service.ExpressionService.MIExpressionDMC; +import org.eclipse.dd.mi.service.command.AbstractMIControl; +import org.eclipse.dd.mi.service.command.MIControlDMContext; +import org.eclipse.dd.mi.service.command.commands.ExprMetaGetAttributes; +import org.eclipse.dd.mi.service.command.commands.ExprMetaGetChildCount; +import org.eclipse.dd.mi.service.command.commands.ExprMetaGetChildren; +import org.eclipse.dd.mi.service.command.commands.ExprMetaGetValue; +import org.eclipse.dd.mi.service.command.commands.ExprMetaGetVar; +import org.eclipse.dd.mi.service.command.commands.MIDataEvaluateExpression; +import org.eclipse.dd.mi.service.command.commands.MIVarAssign; +import org.eclipse.dd.mi.service.command.commands.MIVarCreate; +import org.eclipse.dd.mi.service.command.commands.MIVarDelete; +import org.eclipse.dd.mi.service.command.commands.MIVarEvaluateExpression; +import org.eclipse.dd.mi.service.command.commands.MIVarInfoPathExpression; +import org.eclipse.dd.mi.service.command.commands.MIVarListChildren; +import org.eclipse.dd.mi.service.command.commands.MIVarSetFormat; +import org.eclipse.dd.mi.service.command.commands.MIVarShowAttributes; +import org.eclipse.dd.mi.service.command.commands.MIVarUpdate; +import org.eclipse.dd.mi.service.command.output.ExprMetaGetAttributesInfo; +import org.eclipse.dd.mi.service.command.output.ExprMetaGetChildCountInfo; +import org.eclipse.dd.mi.service.command.output.ExprMetaGetChildrenInfo; +import org.eclipse.dd.mi.service.command.output.ExprMetaGetValueInfo; +import org.eclipse.dd.mi.service.command.output.ExprMetaGetVarInfo; +import org.eclipse.dd.mi.service.command.output.MIVar; +import org.eclipse.dd.mi.service.command.output.MIVarAssignInfo; +import org.eclipse.dd.mi.service.command.output.MIVarChange; +import org.eclipse.dd.mi.service.command.output.MIVarCreateInfo; +import org.eclipse.dd.mi.service.command.output.MIVarDeleteInfo; +import org.eclipse.dd.mi.service.command.output.MIVarEvaluateExpressionInfo; +import org.eclipse.dd.mi.service.command.output.MIVarInfoPathExpressionInfo; +import org.eclipse.dd.mi.service.command.output.MIVarListChildrenInfo; +import org.eclipse.dd.mi.service.command.output.MIVarSetFormatInfo; +import org.eclipse.dd.mi.service.command.output.MIVarShowAttributesInfo; +import org.eclipse.dd.mi.service.command.output.MIVarUpdateInfo; +import org.osgi.framework.BundleContext; + +/** + * Manages a list of variable objects as created through GDB/MI commands. + * + * Note that for the moment, this class is inheriting from AbstractDsfService, + * although it does not register as a service. This class is only used by the Expression + * Service, and therefore, need not be a service of its own. + * However, to be able to implement ICommandControl, we automatically must implement + * IDsfService, so, that is why we extend AbstractDsfService. We must implement + * ICommandControl service, to be able to interface properly with the MICommandCache which + * is using this class. + * + * This class is passed expression-meta-commands which have their own cache. + * Therefore, we don't use the standard MICommandCache in this class. + * In fact, we can't even use it, because many variableObject MI commands, + * should not be cached as they alter the state of the back-end. + * + * Design details: + * ============== + * + * GDB variable object information + * ------------------------------- + * o Variable objects are recursively hierarchical, where children can be created through + * the parent. + * o A varObject created with -var-create is a ROOT + * o A varObject created with -var-list-children, is not a root + * o Only varObject with no children or varObjects that are pointers can change values + * and therefore + * those objects can be used with -var-assign + * o After a program stops, a varObject must be 'updated' before used + * o Only root varObject can be updated with -var-update, which will trigger all + * of the root's descendants to be updated. + * o Once updated, a varObject need not be updated until the program resumes again; + * this is true even after -var-assign is used (because it does an implicit -var-update) + * o -var-update will return the list of all modifiable descendants of the udpated root which + * have changed + * o -var-update will indicate if a root is out-of-scope (which implies that all + * its descendants are out-of-scope) + * o if a varObject is out-of-scope, another varObject may be valid for the same + * expression as the out-of-scope varObject + * o deleting a varObject will delete all its descendants, therefore, it is only + * necessary to delete roots + * + * + * Class details + * ------------- + * - We have an MIVariableObject class which represents a variable object in GDB + * + * - MIVariableObject includes a buffered value for each allowed format. + * + * - We have an MIRootVariableObject class inheriting from MIVariableObject to describe + * root varObjects created with -var-create. Objects created with -var-list-children + * are MIVariableObjects only. The root class will keep track of if the root object + * needs to be updated, if the root object is out-of-scope, and of a list of all + * modifiable descendants of this root. The list of modifiable descendants is + * accessed using the gdb-given name to allow quick updates from the -var-update + * result (see below.) + * + * - we do not use -var-list-children for arrays, but create them manually + * + * - when the program stops, we should mark all roots as needing to be updated. + * To achieve this efficiently, we have a dedicated list of roots that are updated. + * When the program stops, we go through this list, remove each element and mark it + * as needing to be updated. + * + * - when a varObject is accessed, if its root must be updated, the var-update + * command shall be used. The result of that command will indicate all + * modifiable descendants that have changed. We also use --all-values with -var-update + * to get the new value (in the current format) for each modified descendant. Using the list of modifiable + * descendants of the root, we can quickly update the changed ones to invalidate their buffered + * values and store the new current format value. + * + * - all values of non-modifiable varObjects (except arrays) will be set to {...} + * without going to the back-end + * + * - requesting the value of an array varObject will trigger the creation of a new + * varObject for the array's address. Note that we must still use a variable + * object and not the command -data-evaluate-expression, because we still need to get + * the array address in multiple formats. + * + * - we keep an LRU (Least Recently Used) structure of all variable objects. This LRU + * will be bounded to a maximum allowed number of variable objects. Whenever we get an + * object from the LRU cleanup will be done if the maximum size has been reached. + * The LRU will not delete a parent varObject until all its children are deleted; this is + * achieved by touching each of the parents of an object whenever that object is put or get + * + * - It may happen that when accessing a varObject we find its root to be + * out-of-scope. The expression for which we are trying to access a varObject + * could still be valid, and therefore we should try to create a new varObject for + * that expression. This can happen for example if two methods use the same name + * for a variable. In the case when we find that a varObject is out-of-scope (when + * its root is out-of-scope) the following should be done: + * - replace the varObject in the LRU with a newly created one in GDB + * - if the old object was a root, delete it in GDB. + * + * - In GDB, -var-update will only report a change if -var-evaluate-expression has + * changed -- in the current format--. This means that situations like + * double z = 1.2; + * z = 1.4; + * Will not report a change if the format is anything else than natural. + * This is because 1.2 and 1.4 are both printed as 1, 0x1, etc + * Since we cache the values of every format, we must know if the value has + * change in -any- format, not just the current one. + * To solve this, we always keep the display format of variable objects (and their + * children) to the natural format; we believe that if the value changes in any + * format, it guarantees that it will change in the natural format. + * The simplest way to do this is that whenever we change the format + * of a variable object, we immediately set it back to natural with a second + * var-set-format command. + * Note that versions of GDB after 6.7 will allows to issue -var-evaluate-expression + * with a specified format, therefore allowing us to never use -var-set-format, and + * consequently, to easily keep the display format of all variable objects to natural. + */ +public class MIVariableManager extends AbstractDsfService implements ICommandControl { + + + /** + * Utility class to track the progress and information of MI variable objects + */ + public class MIVariableObject { + + // Don't use an enumeration to allow subclasses to extend this + protected static final int STATE_READY = 0; + protected static final int STATE_UPDATING = 1; + + protected int currentState; + + // This is the lock used when we must run multiple + // operations at once. This lock should be independent of the + // UPDATING state, which is why we don't make it part of the state + private boolean locked = false; + + // This id is the one used to search for this object in our hash-map + private final VariableObjectId internalId; + // This is the name of the variable object, as given by GDB (e.g., var1 or var1.public.x) + private String gdbName = null; + // The current format of this variable object, within GDB + private String format = IFormattedValues.NATURAL_FORMAT; + + // The full expression that can be used to characterize this object + private String fullExp = null; + private String type = null; + private int numChildren = 0; + private Boolean editable = null; + + // The current values of the expression for each format. (null if not known yet) + private Map valueMap = null; + + // A queue of request monitors waiting for this object to be ready + private LinkedList operationsPending; + + // A queue of request monitors that requested an update + protected LinkedList> updatesPending; + + // The relative expressions of the children of this variable, if any. + // Null means we didn't fetch them yet, while an empty array means no children + private ExpressionInfo[] children = null; + + // The parent of this variable object within GDB. Null if this object has no parent + private MIVariableObject parent = null; + + // The root parent that must be used to issue -var-update. + // If this object is a root, then the rootToUpdate is itself + private MIRootVariableObject rootToUpdate = null; + + protected boolean outOfScope = false; + + public MIVariableObject(VariableObjectId id, MIVariableObject parentObj) { + currentState = STATE_READY; + + operationsPending = new LinkedList(); + updatesPending = new LinkedList>(); + + internalId = id; + setParent(parentObj); + + // No values are available yet + valueMap = new HashMap(); + resetValues(); + } + + public VariableObjectId getInternalId() { return internalId; } + public String getGdbName() { return gdbName; } + public String getCurrentFormat() { return format; } + public MIVariableObject getParent() { return parent; } + public MIRootVariableObject getRootToUpdate() { return rootToUpdate; } + + public String getExpression() { return fullExp; } + public String getType() { return type; } + public int getNumChildren() { return numChildren; } + public String getValue(String format) { return valueMap.get(format); } + + public ExpressionInfo[] getChildren() { return children; } + + + //FIX replace these methods with CDT's GDBTypeParser (see bug 200897 comment #5) + // int(*)[5] is a pointer to an array (so it is a pointer but not an array) (e.g., &b where int b[5]) + // int *[5] is an array of pointers (so it is an array but not a pointer) (e.g., int *b[5]) + public boolean isArray() { return (getType() == null) ? false : getType().endsWith("]") && !getType().contains("(*)") ; }//$NON-NLS-1$//$NON-NLS-2$ + public boolean isPointer() { return (getType() == null) ? false : getType().contains("*")&& !isArray(); }//$NON-NLS-1$ + public boolean isMethod() { return (getType() == null) ? false : getType().contains("()"); }//$NON-NLS-1$ + // A complex variable is one with children. However, it must not be a pointer since a pointer has one child + // according to GDB, but is still a 'simple' variable + public boolean isComplex() { return (getType() == null) ? false : getNumChildren() > 0 && !isPointer(); } + + public void setGdbName(String n) { gdbName = n; } + public void setCurrentFormat(String f) { format = f; } + + public void setExpressionData(String fullExpression, String t, int num) { + fullExp = fullExpression; + type = t; + numChildren = num; + } + + public void setValue(String format, String val) { valueMap.put(format, val); } + + public void resetValues(String valueInCurrentFormat) { + resetValues(); + setValue(getCurrentFormat(), valueInCurrentFormat); + } + + public void resetValues() { + valueMap.put(IFormattedValues.NATURAL_FORMAT, null); + valueMap.put(IFormattedValues.BINARY_FORMAT, null); + valueMap.put(IFormattedValues.HEX_FORMAT, null); + valueMap.put(IFormattedValues.OCTAL_FORMAT, null); + valueMap.put(IFormattedValues.DECIMAL_FORMAT, null); + } + + public void setChildren(ExpressionInfo[] c) { children = c; } + public void setParent(MIVariableObject p) { + parent = p; + rootToUpdate = (p == null ? (MIRootVariableObject)this : p.getRootToUpdate()); + } + + public void executeWhenNotUpdating(RequestMonitor rm) { + getRootToUpdate().executeWhenNotUpdating(rm); + } + + private void lock() { + locked = true; + } + + private void unlock() { + locked = false; + + while (operationsPending.size() > 0) { + operationsPending.poll().done(); + } + } + + public boolean isOutOfScope() { return outOfScope; } + + /** + * This method updates the variable object. + * Updating a variable object is done by updating its root. + */ + public void update(final DataRequestMonitor rm) { + + // We check to see if we are already out-of-scope + // We must do this to avoid the risk of re-creating this object + // twice, due to race conditions + if (isOutOfScope()) { + rm.setData(false); + rm.done(); + } else if (currentState == STATE_UPDATING) { + // If we were already updating, we just queue the request monitor + // until the on-going update finishes. + updatesPending.add(rm); + } else { + currentState = STATE_UPDATING; + getRootToUpdate().update(new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleCompleted() { + currentState = STATE_READY; + + if (getStatus().isOK()) { + outOfScope = getRootToUpdate().isOutOfScope(); + // This request monitor is the one that should re-create + // the variable object if the old one was out-of-scope + rm.setData(outOfScope); + rm.done(); + + // All the other request monitors must be notified but must + // not re-create the object, even if it is out-of-scope + while (updatesPending.size() > 0) { + DataRequestMonitor pendingRm = updatesPending.poll(); + pendingRm.setData(false); + pendingRm.done(); + } + } else { + rm.setStatus(getStatus()); + rm.done(); + + while (updatesPending.size() > 0) { + DataRequestMonitor pendingRm = updatesPending.poll(); + pendingRm.setStatus(getStatus()); + pendingRm.done(); + } + } + } + }); + } + } + + /** + * Variable objects need not be deleted unless they are root. + * This method is specialized in the MIRootVariableObject class. + */ + public void deleteInGdb() {} + + /** + * This method returns the value of the variable object attributes by + * using -var-show-attributes. + * Currently, the only attribute available is 'editable'. + * + * @param rm + * The data request monitor that will hold the value returned + */ + private void getAttributes(final DataRequestMonitor rm) { + if (editable != null) { + rm.setData(editable); + rm.done(); + } if (isComplex()) { + editable = false; + rm.setData(editable); + rm.done(); + } else { + fCommandControl.queueCommand( + new MIVarShowAttributes(fControlDmc, getGdbName()), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + editable = getData().isEditable(); + + rm.setData(editable); + rm.done(); + } + }); + } + } + + /** + * This method returns the value of the variable object. + * This operation translates to multiple MI commands which affect the state of the + * variable object in the back-end; therefore, we must make sure the object is not + * locked doing another operation, and we must lock the object once it is our turn + * to use it. + * + * @param dmc + * The context containing the format to be used for the evaluation + * @param rm + * The data request monitor that will hold the value returned + */ + private void getValue(final FormattedValueDMContext dmc, + final DataRequestMonitor rm) { + + // We might already know the value + String value = getValue(dmc.getFormatID()); + if (value != null) { + rm.setData(new FormattedValueDMData(value)); + rm.done(); + return; + } + + // If the variable is a complex structure, there is no need to ask the back-end for a value, + // we can give it the {...} ourselves + // Unless we are dealing with an array, in which case, we want to get the address of it + if (isComplex()) { + if (isArray()) { + // Figure out the address + IExpressionDMContext exprCxt = DMContexts.getAncestorOfType(dmc, IExpressionDMContext.class); + IExpressionDMContext addrCxt = fExpressionService.createExpression(exprCxt, "&(" + exprCxt.getExpression() + ")"); //$NON-NLS-1$//$NON-NLS-2$ + + final FormattedValueDMContext formatCxt = new FormattedValueDMContext( + fExpressionService.getSession().getId(), + addrCxt, + dmc.getFormatID() + ); + + getVariable( + addrCxt, + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + getData().getValue(formatCxt, rm); + + } + }); + } else { + // Other complex structure + String complexValue = "{...}"; //$NON-NLS-1$ + setValue(dmc.getFormatID(), complexValue); + rm.setData(new FormattedValueDMData(complexValue)); + rm.done(); + } + + return; + } + + if (locked) { + operationsPending.add(new RequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + getValue(dmc, rm); + } + }); + } else { + lock(); + + // If the format is already the one set for this variable object, + // we don't need to set it again + if (dmc.getFormatID().equals(getCurrentFormat())) { + evaluate(rm); + } else { + // We must first set the new format and then evaluate the variable + fCommandControl.queueCommand( + new MIVarSetFormat(fControlDmc, getGdbName(), dmc.getFormatID()), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + setCurrentFormat(dmc.getFormatID()); + + // If set-format returned the value, no need to evaluate + // This is only valid after GDB 6.7 + if (getData().getValue() != null) { + setValue(dmc.getFormatID(), getData().getValue()); + rm.setData(new FormattedValueDMData(getData().getValue())); + rm.done(); + + // Unlock is done within this method + resetFormatToNatural(); + } else { + evaluate(rm); + } + } else { + rm.setStatus(getStatus()); + rm.done(); + + unlock(); + } + } + }); + } + } + } + + /** + * This method evaluates a variable object + */ + private void evaluate(final DataRequestMonitor rm) { + fCommandControl.queueCommand( + new MIVarEvaluateExpression(fControlDmc, getGdbName()), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + setValue(getCurrentFormat(), getData().getValue()); + rm.setData(new FormattedValueDMData(getData().getValue())); + rm.done(); + } else { + rm.setStatus(getStatus()); + rm.done(); + } + + // Unlock is done within this method + resetFormatToNatural(); + } + }); + } + + // In GDB, var-update will only report a change if -var-evaluate-expression has + // changed -- in the current format--. This means that situations like + // double z = 1.2; + // z = 1.4; + // Will not report a change if the format is anything else than natural. + // This is because 1.2 and 1.4 are both printed as 1, 0x1, etc + // Since we cache the values of every format, we must know if -any- format has + // changed, not just the current one. + // To solve this, we always do an update in the natural format; I am not aware + // of any case where the natural format would stay the same, but another format + // would change. However, since a var-update update all children as well, + // we must make sure these children are also in the natural format + // The simplest way to do this is that whenever we change the format + // of a variable object, we immediately set it back to natural with a second + // var-set-format command. + private void resetFormatToNatural() { + if (!getCurrentFormat().equals(IFormattedValues.NATURAL_FORMAT)) { + fCommandControl.queueCommand( + new MIVarSetFormat(fControlDmc, getGdbName(), IFormattedValues.NATURAL_FORMAT), + new DataRequestMonitor(getExecutor(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + setCurrentFormat(IFormattedValues.NATURAL_FORMAT); + } + unlock(); + } + }); + } else { + unlock(); + } + } + + /** + * This method returns the list of children of the variable object passed as a parameter. + * + * @param rm + * The data request monitor that will hold the children returned + */ + private void getChildren(final MIExpressionDMC exprDmc, final DataRequestMonitor rm) { + + // If we already know the children, no need to go to the back-end + ExpressionInfo[] childrenArray = getChildren(); + if (childrenArray != null) { + rm.setData(childrenArray); + rm.done(); + return; + } + + // If the variable does not have children, we can return an empty list right away + if (getNumChildren() == 0) { + // First store the empty list, for the next time + setChildren(new ExpressionInfo[0]); + rm.setData(getChildren()); + rm.done(); + return; + } + + // For arrays (which could be very large), we create the children ourselves. This is + // to avoid creating an enormous amount of children variable objects that the view may + // never need. Using -var-list-children will create a variable object for every child + // immediately, that is why won't don't want to use it for arrays. + if (isArray()) { + ExpressionInfo[] childrenOfArray = new ExpressionInfo[getNumChildren()]; + for (int i= 0; i < childrenOfArray.length; i++) { + String indexStr = "[" + i + "]";//$NON-NLS-1$//$NON-NLS-2$ + String fullExpr = exprDmc.getExpression() + indexStr; + String relExpr = exprDmc.getRelativeExpression() + indexStr; + + childrenOfArray[i] = new ExpressionInfo(fullExpr, relExpr); + } + + // First store these children, for the next time + setChildren(childrenOfArray); + rm.setData(getChildren()); + rm.done(); + return; + } + + // No need to wait for the object to be ready since listing children can be performed + // at any time, as long as the object is created, which we know it is, since we can only + // be called here with a fully created object. + // Also no need to lock the object, since getting the children won't affect other operations + fCommandControl.queueCommand( + new MIVarListChildren(fControlDmc, getGdbName()), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + MIVar[] children = getData().getMIVars(); + final List realChildren = new ArrayList(); + + final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + // Store the children in our variable object cache + setChildren(realChildren.toArray(new ExpressionInfo[realChildren.size()])); + rm.setData(getChildren()); + rm.done(); + } + }; + + int numSubRequests = 0; + for (final MIVar child : children) { + // These children get created automatically as variable objects in GDB, so we should + // add them to the LRU. + // Note that if this variable object already exists, we can be in three scenarios: + // 1- the existing object is the same variable object in GDB. In this case, + // the existing and new one are identical so we can keep either one. + // 2- the existing object is out-of-scope and should be replaced by the new one. + // This can happen if a root was found to be out-of-scope, but this child + // had not been accessed and therefore had not been removed. + // 3- the existing object is an in-scope root object representing the same expression. + // In this case, either object can be kept and the other one can be deleted. + // The existing root could currently be in-use by another operation and may + // not be deleted; but since we can only have one entry in the LRU, we are + // forced to keep the existing root. Note that we need not worry about + // the newly created child since it will automatically be deleted when + // its root is deleted. + + numSubRequests++; + + final DataRequestMonitor childPathRm = + new DataRequestMonitor(getExecutor(), countingRm) { + @Override + protected void handleOK() { + String childFullExpression = getData(); + + // For children that do not map to a real expression (such as f.public) + // GDB returns an empty string. In this case, we can use another unique + // name, such as the variable name + boolean fakeChild = false; + if (childFullExpression.length() == 0) { + fakeChild = true; + childFullExpression = child.getVarName(); + } + + // Now try to see if we already have this variable object in our Map + // Since our map names use the expression, and not the GDB given + // name, we must determine the correct map name from the varName + VariableObjectId childId = new VariableObjectId(); + childId.generateId(childFullExpression, getInternalId()); + MIVariableObject childVar = lruVariableList.get(childId); + + // Note that we must check the root to know if it is out-of-scope. + // We cannot check the child as it has not be updated and its + // outOfScope variable is not updated either. + if (childVar != null && childVar.getRootToUpdate().isOutOfScope()) { + childVar.deleteInGdb(); + childVar = null; + } + + if (childVar == null) { + childVar = new MIVariableObject(childId, MIVariableObject.this); + childVar.setGdbName(child.getVarName()); + childVar.setExpressionData( + childFullExpression, + child.getType(), + child.getNumChild()); + + // This will replace any existing entry + lruVariableList.put(childId, childVar); + + // Is this new child a modifiable descendant of the root? + if (childVar.isModifiable()) { + getRootToUpdate().addModifiableDescendant(child.getVarName(), childVar); + } + } + + if (fakeChild) { + // This is just a qualifier level of C++, and we must + // get the children of this child to get the real children + childVar.getChildren( + exprDmc, + new DataRequestMonitor(getExecutor(), countingRm) { + @Override + protected void handleOK() { + ExpressionInfo[] vars = getData(); + for (ExpressionInfo realChild : vars) { + realChildren.add(realChild); + } + countingRm.done(); + } + }); + } else { + // This is a real child + realChildren.add(new ExpressionInfo(childFullExpression, child.getExp())); + countingRm.done(); + } + } + }; + + + if (isAccessQualifier(child.getExp())) { + // This is just a qualifier level of C++, so we don't need + // to call -var-info-path-expression for real, but just pretend we did. + childPathRm.setData(""); //$NON-NLS-1$ + childPathRm.done(); + } else { + // To build the child id, we need the fully qualified expression which we + // can get from -var-info-path-expression starting from GDB 6.7 + fCommandControl.queueCommand( + new MIVarInfoPathExpression(fControlDmc, child.getVarName()), + new DataRequestMonitor(getExecutor(), childPathRm) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + childPathRm.setData(getData().getFullExpression()); + } else { + // If we don't have var-info-path-expression + // build the expression ourselves + // Note that this does not work well yet + childPathRm.setData(buildChildExpression(exprDmc.getExpression(), child.getExp())); + } + childPathRm.done(); + } + }); + } + } + + countingRm.setDoneCount(numSubRequests); + } + }); + } + + /** + * This method builds a child expression based on its parent's expression. + * + * Currently, this does not support inherited class such as + * class foo : bar { + * ... + * } + * because we'll create foo.bar instead of (bar)foo. + */ + private String buildChildExpression(String parentExp, String childExp) { + return parentExp + "." + childExp; //$NON-NLS-1$ + // No need for a special case for arrays since we deal with arrays differently + // and don't call this method for them + } + + /** + * This method returns the count of children of the variable object passed as a parameter. + * + * @param rm + * The data request monitor that will hold the count of children returned + */ + private void getChildrenCount(final DataRequestMonitor rm) { + // No need to lock the object or wait for it to be ready since this operation does not + // affect other operations + rm.setData(getNumChildren()); + rm.done(); + } + + + + /** + * This method request the back-end to change the value of the variable object. + * + * @param value + * The new value. + * @param formatId + * The format the new value is specified in. + * @param rm + * The request monitor to indicate the operation is finished + */ + private void writeValue(String value, final String formatId, final RequestMonitor rm) { + + // If the variable is a complex structure (including an array), then we cannot write to it + if (isComplex()) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, + "Cannot change the value of a complex expression", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + // First deal with the format. For GDB, the way to specify a format is to prefix the value with + // 0x for hex, 0 for octal etc So we need to make sure that 'value' has this prefix. + // Note that there is no way to specify a binary format for GDB so we convert 'value' + // into a decimal format. + // If the formatId is NATURAL, we do nothing for now because it is more complicated. + // For example for a bool, a value of "true" is correct and should be left as is, + // but for a pointer a value of 16 should be sent to GDB as 0x16. To figure this out, + // we need to know the type of the variable, which we don't have yet. + + if (formatId.equals(IFormattedValues.HEX_FORMAT)) { + if (!value.startsWith("0x")) value = "0x" + value; //$NON-NLS-1$ //$NON-NLS-2$ + } + else if (formatId.equals(IFormattedValues.OCTAL_FORMAT)) { + if (!value.startsWith("0")) value = "0" + value; //$NON-NLS-1$ //$NON-NLS-2$ + } + else if (formatId.equals(IFormattedValues.BINARY_FORMAT)) { + // convert from binary to decimal + if (value.startsWith("0b")) value = value.substring(2, value.length()); //$NON-NLS-1$ + try { + value = Integer.toString(Integer.parseInt(value, 2)); + } catch (NumberFormatException e) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, + "Invalid binary number: " + value, e)); //$NON-NLS-1$ + rm.done(); + return; + } + } + else if (formatId.equals(IFormattedValues.DECIMAL_FORMAT)) { + // nothing to do + } + else if (formatId.equals(IFormattedValues.NATURAL_FORMAT)) { + // we do nothing for now and let the user have put in the proper value + } + else { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, + "Unknown format: " + formatId, null)); //$NON-NLS-1$ + rm.done(); + return; + } + + // No need to be in ready state or to lock the object + fCommandControl.queueCommand( + new MIVarAssign(fControlDmc, getGdbName(), value), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + resetValues(getData().getValue()); + rm.done(); + } + }); + } + + private boolean isAccessQualifier(String str) { + return str.equals("private") || str.equals("public") || str.equals("protected"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + public boolean isModifiable() { + if (!isComplex()) return true; + return false; + } + } + + private class MIRootVariableObject extends MIVariableObject { + + // Only root variables go through the GDB creation process + protected static final int STATE_NOT_CREATED = 10; + protected static final int STATE_CREATING = 11; + + private boolean outOfDate = false; + + // Modifiable descendants are any variable object that is a descendant or itself for + // which the value can change. + private Map modifiableDescendants; + + public MIRootVariableObject(VariableObjectId id) { + super(id, null); + currentState = STATE_NOT_CREATED; + modifiableDescendants = new HashMap(); + } + + public boolean isUpdating() { return currentState == STATE_UPDATING; } + + public boolean isOutOfDate() { return outOfDate; } + public void markAsOutOfDate() { outOfDate = true; } + + // Remember that we must add ourself as a modifiable descendant if our value can change + public void addModifiableDescendant(String gdbName, MIVariableObject descendant) { + modifiableDescendants.put(gdbName, descendant); + } + + public void processChanges(MIVarChange[] updates) { + for (MIVarChange update : updates) { + MIVariableObject descendant = modifiableDescendants.get(update.getVarName()); + // Descendant should never be null, but just to be safe + if (descendant != null) descendant.resetValues(update.getValue()); + } + } + + public void create(final IExpressionDMContext exprCtx, + final RequestMonitor rm) { + + if (currentState == STATE_NOT_CREATED) { + + currentState = STATE_CREATING; + + fCommandControl.queueCommand( + new MIVarCreate(exprCtx, exprCtx.getExpression()), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + setGdbName(getData().getName()); + setExpressionData( + exprCtx.getExpression(), + getData().getType(), + getData().getNumChildren()); + + // Store the value returned at create (available in GDB 6.7) + // Don't store if it is an array, since we want to show + // the address of an array as its value + if (getData().getValue() != null && !isArray()) { + setValue(getCurrentFormat(), getData().getValue()); + } + + // If we are modifiable, we should be in our modifiable list + if (isModifiable()) { + addModifiableDescendant(getData().getName(), MIRootVariableObject.this); + } + + rm.done(); + + // Object can now be used by others + creationCompleted(true); + } else { + rm.setStatus(getStatus()); + rm.done(); + // Object must tell any waiting monitors that it failed + creationCompleted(false); + } + } + }); + } else { + assert false; + } + } + + private void creationCompleted(boolean success) { + // A creation completed we must be up-to-date, so we + // can tell any pending monitors that updates are done + if (success) { + currentState = STATE_READY; + while (updatesPending.size() > 0) { + DataRequestMonitor rm = updatesPending.poll(); + // Nothing to be re-created + rm.setData(false); + rm.done(); + } + } else { + currentState = STATE_NOT_CREATED; + + // Creation failed, inform anyone waiting. + while (updatesPending.size() > 0) { + RequestMonitor rm = updatesPending.poll(); + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, + "Unable to create variable object", null)); //$NON-NLS-1$ + rm.done(); + } + } + } + + @Override + public void update(final DataRequestMonitor rm) { + + if (isOutOfScope()) { + rm.setData(false); + rm.done(); + } else if (currentState != STATE_READY) { + // Object is not fully created or is being updated + // so add RequestMonitor to pending queue + updatesPending.add(rm); + } else if (outOfDate == false) { + rm.setData(false); + rm.done(); + } else { + // Object needs to be updated in the back-end + currentState = STATE_UPDATING; + + // In GDB, var-update will only report a change if -var-evaluate-expression has + // changed -- in the current format--. This means that situations like + // double z = 1.2; + // z = 1.4; + // Will not report a change if the format is anything else than natural. + // This is because 1.2 and 1.4 are both printed as 1, 0x1, etc + // Since we cache the values of every format, we must know if -any- format has + // changed, not just the current one. + // To solve this, we always do an update in the natural format; I am not aware + // of any case where the natural format would stay the same, but another format + // would change. However, since a var-update update all children as well, + // we must make sure these children are also in the natural format + // The simplest way to do this is that whenever we change the format + // of a variable object, we immediately set it back to natural with a second + // var-set-format command. This is done in the getValue() method + fCommandControl.queueCommand( + new MIVarUpdate(fControlDmc, getGdbName()), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleCompleted() { + currentState = STATE_READY; + + if (getStatus().isOK()) { + outOfDate = false; + + MIVarChange[] changes = getData().getMIVarChanges(); + if (changes.length > 0 && changes[0].isInScope() == false) { + // Object is out-of-scope + outOfScope = true; + + // We can delete this root in GDB right away. This is safe, even + // if the root has children, because they are also out-of-scope. + // We -must- also remove this entry from our LRU. If we don't + // we can end-up with a race condition that create this object + // twice, or have an infinite loop while never re-creating the object. + // The can happen if we update a child first then we request + // the root later, + lruVariableList.remove(getInternalId()); + + rm.setData(true); + rm.done(); + } else { + // The root object is now up-to-date, we must parse the changes, if any. + processChanges(changes); + + // We only mark this root as updated in our list if it is in-scope. + // For out-of-scope object, we don't ever need to re-update them so + // we don't need to add them to this list. + updatedRootList.add(MIRootVariableObject.this); + + rm.setData(false); + rm.done(); + } + + while (updatesPending.size() > 0) { + DataRequestMonitor pendingRm = updatesPending.poll(); + pendingRm.setData(false); + pendingRm.done(); + } + } else { + // We were not able to update for some reason + rm.setData(false); + rm.done(); + + while (updatesPending.size() > 0) { + DataRequestMonitor pendingRm = updatesPending.poll(); + pendingRm.setStatus(getStatus()); + pendingRm.done(); + } + } + } + }); + } + } + + /** + * This method request the back-end to delete a variable object. + * We check if the GDB name has been filled to confirm that this object + * was actually successfully created on the back-end. + * Only root variable objects are deleted, while children are left in GDB + * to be deleted automatically when their root is deleted. + */ + @Override + public void deleteInGdb() { + if (getGdbName() != null) { + fCommandControl.queueCommand( + new MIVarDelete(fControlDmc, getGdbName()), + new DataRequestMonitor(getExecutor(), null)); + // Nothing to do in the requestMonitor, since the object was already + // removed from our list before calling this method. + + // Set the GDB name to null to make sure we don't attempt to delete + // this variable a second time. This can happen if the LRU triggers + // an automatic delete. + setGdbName(null); + } else { + // Variable was never created or was already deleted, no need to do anything. + } + } + + + } + + /** + * This class represents an unique identifier for a variable object. + * + * The following must be considered to obtain a unique name: + * - the expression itself + * - the threadId specified in the execution context + * - relative depth of frame based on the frame context and the total depth of the stack + * + * Note that if no frameContext is specified (only Execution, or even only Container), which can + * characterize a global variable for example, we will only use the available information. + */ + private class VariableObjectId { + String fExpression = null; + Integer fThreadId = null; + Integer fFrameId = null; + + @Override + public boolean equals(Object other) { + if (other instanceof VariableObjectId) { + VariableObjectId otherId = (VariableObjectId) other; + return (fExpression == null ? otherId.fExpression == null : fExpression.equals(otherId.fExpression)) && + (fThreadId == null ? otherId.fThreadId == null : fThreadId.equals(otherId.fThreadId)) && + (fFrameId == null ? otherId.fFrameId == null : fFrameId.equals(otherId.fFrameId)); + } + return false; + } + + @Override + public int hashCode() { + return (fExpression == null ? 0 : fExpression.hashCode()) + + (fThreadId == null ? 0 : fThreadId.hashCode()) + + (fFrameId == null ? 0 : fFrameId.hashCode()); + } + + public void generateId(IExpressionDMContext exprCtx, final RequestMonitor rm) { + fExpression = exprCtx.getExpression(); + + IMIExecutionDMContext execCtx = DMContexts.getAncestorOfType(exprCtx, IMIExecutionDMContext.class); + if (execCtx == null) { + rm.done(); + return; + } + + fThreadId = new Integer(execCtx.getThreadId()); + + final IFrameDMContext frameCtx = DMContexts.getAncestorOfType(exprCtx, IFrameDMContext.class); + if (frameCtx == null) { + rm.done(); + return; + } + + // We need the current stack depth to be able to make a unique and reproducible name + // for this expression. This is pretty efficient since the stackDepth will be retrieved + // from the StackService command cache after the first time. + fStackService.getStackDepth( + execCtx, 0, + new DataRequestMonitor(getExecutor(), rm) { + @Override + public void handleOK() { + fFrameId = new Integer(getData() - frameCtx.getLevel()); + rm.done(); + } + }); + } + + public void generateId(String childFullExp, VariableObjectId parentId) { + // The thread and frame are the same as the parent + fThreadId = parentId.fThreadId; + fFrameId = parentId.fFrameId; + // The expression here must be the one that is part of IExpressionContext for this child + // This will allow us to find a variable object directly + fExpression = childFullExp; + } + } + + /** + * This is the real work horse of managing our objects. Not only must every + * value be unique to get inserted, this also creates an LRU (least recently + * used). When we hit our size limitation, the LRUsed will be removed to + * make space. Removing means that a GDB request to delete the object is + * generated. We must also take into consideration the fact that GDB will + * automatically delete children of a variable object, when deleting the parent + * variable object. Our solution to that is to tweak the LRU to make sure that + * children are always older than their parents, to guarantee the children will + * always be delete before their parents. + * + */ + private class LRUVariableCache extends LinkedHashMap { + public static final long serialVersionUID = 0; + + // Maximum allowed concurrent variables + private static final int MAX_VARIABLE_LIST = 1000; + + public LRUVariableCache() { + super(0, // Initial load capacity + 0.75f, // Load factor as defined in JAVA 1.5 + true); // Order is dictated by access, not insertion + } + + // We never remove doing put operations. Instead, we rely on our get() operations + // to trigger the remove. See bug 200897 + @Override + public boolean removeEldestEntry(Map.Entry eldest) { + return false; + } + + @Override + public MIVariableObject get(Object key) { + MIVariableObject varObj = super.get(key); + touchAncestors(varObj); + + // If we're over our max size, attempt to remove eldest entry. + if (size() > MAX_VARIABLE_LIST) { + Map.Entry eldest = entrySet().iterator().next(); + // First make sure we are not deleting ourselves! + if (!eldest.getValue().equals(varObj)) { + if (eldest.getValue().currentState == MIVariableObject.STATE_READY) { + remove(eldest.getKey()); + } + } + } + return varObj; + } + + private void touchAncestors(MIVariableObject varObj) { + while (varObj != null) { + varObj = varObj.getParent(); + // If there is a parent, touch it + if (varObj != null) super.get(varObj.getInternalId()); + } + } + + @Override + public MIVariableObject put(VariableObjectId key, MIVariableObject varObj) { + MIVariableObject retVal = super.put(key, varObj); + + // Touch all parents of this element so as + // to guarantee they are not deleted before their children. + touchAncestors(varObj); + + return retVal; + } + + @Override + public MIVariableObject remove(Object key) { + MIVariableObject varObj = super.remove(key); + varObj.deleteInGdb(); + return varObj; + } + } + + /** Provides access to the GDB/MI back-end */ + private final ICommandControl fCommandControl; + // The stack service needs to be used to get information such + // as the stack depth to differentiate between expressions that have the + // same name but refer to a different context + private final IStack fStackService; + private IExpressions fExpressionService; + + // The top level context. It is used to operate on variable objects + // that have already been created, since those objects are referenced + // by name, irrespective of context. + // We do need a context, for when we will have multiple MIRunControls (multiple GDBs) + private final MIControlDMContext fControlDmc; + + // Typically, there will only be one listener, since only the ExpressionService will use this class + private final List fCommandProcessors = new ArrayList(); + + /** Our least recently used cache */ + private final LRUVariableCache lruVariableList; + + /** The list of root variable objects that have been updated */ + private final LinkedList updatedRootList = new LinkedList(); + + /** + * MIVariableManager constructor + * + * @param session + * The session we are working with + * @param tracker + * The service tracker that can be used to find other services + */ + public MIVariableManager(DsfSession session, DsfServicesTracker tracker) { + super(session); + lruVariableList = new LRUVariableCache(); + fCommandControl = tracker.getService(ICommandControl.class); + fStackService = tracker.getService(IStack.class); + fExpressionService = tracker.getService(IExpressions.class); + fControlDmc = ((AbstractMIControl)fCommandControl).getControlDMContext(); + + // Register to receive service events for this session. + getSession().addServiceEventListener(this, null); + } + + public void shutdown() { + getSession().removeServiceEventListener(this); + } + + /** + * This method returns a variable object based on the specified + * ExpressionDMC, creating it in GDB if it was not created already. + * The method guarantees that the variable is finished creating and that + * is it not out-of-scope. + * + * @param exprCtx + * The expression context to which the variable object is applied to. + * + * @param rm + * The data request monitor that will contain the requested variable object + */ + private void getVariable(final IExpressionDMContext exprCtx, + final DataRequestMonitor rm) { + // Generate an id for this expression so that we can determine if we already + // have a variable object tracking it. If we don't we'll need to create one. + final VariableObjectId id = new VariableObjectId(); + id.generateId( + exprCtx, + new RequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + getVariable(id, exprCtx, rm); + } + }); + } + + private void getVariable(final VariableObjectId id, + final IExpressionDMContext exprCtx, + final DataRequestMonitor rm) { + + final MIVariableObject varObj = lruVariableList.get(id); + + if (varObj == null) { + // We do not have this varObject, so we create it + createVariable(id, exprCtx, rm); + } else { + // We have found a varObject, but it may not be updated yet. + // Updating the object will also tell us if it is out-of-scope + // and if we should re-create it. + varObj.update(new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + + boolean shouldCreateNew = getData().booleanValue(); + + if (varObj.isOutOfScope()) { + // The variable object is out-of-scope and we + // should not use it. + if (shouldCreateNew) { + /** + * It may happen that when accessing a varObject we find it to be + * out-of-scope. The expression for which we are trying to access a varObject + * could still be valid, and therefore we should try to create a new varObject for + * that expression. This can happen for example if two methods use the same name + * for a variable. In the case when we find that a varObject is out-of-scope (when + * its root is out-of-scope) the following should be done: + * + * - create a new varObject for the expression (as a root varObject) and insert it + * in the LRU. Make sure that when creating children of this new varObject, they + * will replace any old children with the same name in the LRU (this is ok since the + * children being replaced are also out-of-scope). + */ + + createVariable(id, exprCtx, rm); + } else { + // Just request the variable object again + // We must use this call to handle the fact that + // the new object might be in the middle of being + // created. + getVariable(id, exprCtx, rm); + } + } else { + // The variable object is up-to-date and valid + rm.setData(varObj); + rm.done(); + } + } + }); + } + } + + + + /** + * This method creates a variable object in GDB. + */ + private void createVariable(final VariableObjectId id, + final IExpressionDMContext exprCtx, + final DataRequestMonitor rm) { + + // Variable objects that are created directly like this, are considered ROOT variable objects + // in comparison to variable objects that are children of other variable objects. + final MIRootVariableObject newVarObj = new MIRootVariableObject(id); + + // We must put this object in our map right away, in case it is + // requested again, before it completes its creation. + // Note that this will replace any old entry with the same id. + lruVariableList.put(id, newVarObj); + + newVarObj.create(exprCtx, new RequestMonitor(getExecutor(), rm) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + // Also store the object as a varObj that is up-to-date + updatedRootList.add(newVarObj); + + rm.setData(newVarObj); + rm.done(); + } else { + // Object was not created, remove it from our list + lruVariableList.remove(id); + + rm.setStatus(getStatus()); + rm.done(); + } + } + }); + } + + /** + * This method requests the back-end to change the value of an expression. + * + * @param expressionContext + * The context of the expression we want to change + * @param expressionValue + * The new value of the expression + * @param formatId + * The format in which the expressionValue is specified in + * @param rm + * The request monitor to indicate the operation is finished + */ + // This method can be called directly from the ExpressionService, since it cannot be cached + public void writeValue(final IExpressionDMContext ctx, final String expressionValue, + final String formatId, final RequestMonitor rm) { + + getVariable( + ctx, + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + getData().writeValue(expressionValue, formatId, rm); + } + }); + } + + public void queueCommand(final ICommand command, DataRequestMonitor rm) { + + // The MIVariableManager does not buffer commands itself, but sends them directly to the real + // MICommandControl service. Therefore, we must immediately tell our calling cache that the command + // has been sent, since we can never cancel it. Note that this removes any option of coalescing, + // but coalescing was not applicable to variableObjects anyway. + processCommandSent(command); + + if (command instanceof ExprMetaGetVar) { + @SuppressWarnings("unchecked") + final DataRequestMonitor drm = (DataRequestMonitor)rm; + final MIExpressionDMC exprCtx = (MIExpressionDMC)(command.getContext()); + + getVariable( + exprCtx, + new DataRequestMonitor(getExecutor(), drm) { + @Override + protected void handleOK() { + drm.setData( + new ExprMetaGetVarInfo( + exprCtx.getRelativeExpression(), + getData().getNumChildren(), + getData().getType(), + !getData().isComplex())); + drm.done(); + } + }); + } else if (command instanceof ExprMetaGetAttributes) { + @SuppressWarnings("unchecked") + final DataRequestMonitor drm = (DataRequestMonitor)rm; + final IExpressionDMContext exprCtx = (IExpressionDMContext)(command.getContext()); + + getVariable( + exprCtx, + new DataRequestMonitor(getExecutor(), drm) { + @Override + protected void handleOK() { + getData().getAttributes( + new DataRequestMonitor(getExecutor(), drm) { + @Override + protected void handleOK() { + drm.setData(new ExprMetaGetAttributesInfo(getData())); + drm.done(); + } + }); + } + }); + + + } else if (command instanceof ExprMetaGetValue) { + @SuppressWarnings("unchecked") + final DataRequestMonitor drm = (DataRequestMonitor)rm; + final FormattedValueDMContext valueCtx = (FormattedValueDMContext)(command.getContext()); + final IExpressionDMContext exprCtx = DMContexts.getAncestorOfType(valueCtx, IExpressionDMContext.class); + + getVariable( + exprCtx, + new DataRequestMonitor(getExecutor(), drm) { + @Override + protected void handleOK() { + getData().getValue( + valueCtx, + new DataRequestMonitor(getExecutor(), drm) { + @Override + protected void handleOK() { + drm.setData( + new ExprMetaGetValueInfo(getData().getFormattedValue())); + drm.done(); + } + }); + } + }); + + } else if (command instanceof ExprMetaGetChildren) { + @SuppressWarnings("unchecked") + final DataRequestMonitor drm = (DataRequestMonitor)rm; + final MIExpressionDMC exprCtx = (MIExpressionDMC)(command.getContext()); + + getVariable( + exprCtx, + new DataRequestMonitor(getExecutor(), drm) { + @Override + protected void handleOK() { + getData().getChildren( + exprCtx, + new DataRequestMonitor(getExecutor(), drm) { + @Override + protected void handleOK() { + drm.setData(new ExprMetaGetChildrenInfo(getData())); + drm.done(); + } + }); + } + }); + + } else if (command instanceof ExprMetaGetChildCount) { + @SuppressWarnings("unchecked") + final DataRequestMonitor drm = (DataRequestMonitor)rm; + final IExpressionDMContext exprCtx = (IExpressionDMContext)(command.getContext()); + + getVariable( + exprCtx, + new DataRequestMonitor(getExecutor(), drm) { + @Override + protected void handleOK() { + getData().getChildrenCount( + new DataRequestMonitor(getExecutor(), drm) { + @Override + protected void handleOK() { + drm.setData(new ExprMetaGetChildCountInfo(getData())); + drm.done(); + } + }); + } + }); + + } else if (command instanceof MIDataEvaluateExpression) { + // This does not use the variable objects but sends the command directly to the back-end + fCommandControl.queueCommand(command, rm); + } else { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, + "Unexpected Expression Meta command", null)); //$NON-NLS-1$ + rm.done(); + } + } + + /* + * This is the command which allows the user to retract a previously issued command. The + * state of the command is that it is in the waiting queue and has not yet been handed + * to the back-end yet. + * + * (non-Javadoc) + * @see org.eclipse.dd.mi.service.command.IDebuggerControl#removeCommand(org.eclipse.dd.mi.service.command.commands.ICommand) + */ + public void removeCommand(ICommand command) { + // It is impossible to remove a command from the MIVariableManager. + // This should never be called, if we did things right. + assert false; + } + + /* + * This command allows the user to try and cancel commands which have been handed off to the + * back-end. Some back-ends support this with extended GDB/MI commands. If the support is there + * then we will attempt it. Because of the bidirectional nature of the GDB/MI command stream + * there is no guarantee that this will work. The response to the command could be on its way + * back when the cancel command is being issued. + * + * (non-Javadoc) + * @see org.eclipse.dd.mi.service.command.IDebuggerControl#cancelCommand(org.eclipse.dd.mi.service.command.commands.ICommand) + */ + public void cancelCommand(ICommand command) {} + public void addCommandListener(ICommandListener processor) { fCommandProcessors.add(processor); } + public void removeCommandListener(ICommandListener processor) { fCommandProcessors.remove(processor); } + public void addEventListener(IEventListener processor) {} + public void removeEventListener(IEventListener processor) {} + + + private void processCommandSent(ICommand command) { + for (ICommandListener processor : fCommandProcessors) { + processor.commandSent(command); + } + } + + @Override + protected BundleContext getBundleContext() { + return MIPlugin.getBundleContext(); + } + + @DsfServiceEventHandler + public void eventDispatched(IRunControl.IResumedDMEvent e) { + // Program has resumed, all variable objects need to be updated. + // Since only roots can actually be updated in GDB, we only need + // to deal with those. Also, to optimize this operation, we have + // a list of all roots that have been updated, so we only have to + // set those to needing to be updated. + MIRootVariableObject root; + while ((root = updatedRootList.poll()) != null) { + root.markAsOutOfDate(); + } + } + + @DsfServiceEventHandler + public void eventDispatched(IRunControl.ISuspendedDMEvent e) { + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractCLIProcess.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractCLIProcess.java new file mode 100644 index 00000000000..c4fd26db62c --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractCLIProcess.java @@ -0,0 +1,320 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + * Ericsson - Modified for additional features in DSF Reference implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.core.runtime.ILog; +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.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.command.ICommand; +import org.eclipse.dd.dsf.debug.service.command.ICommandListener; +import org.eclipse.dd.dsf.debug.service.command.ICommandResult; +import org.eclipse.dd.dsf.debug.service.command.IEventListener; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.mi.internal.MIPlugin; +import org.eclipse.dd.mi.service.command.commands.CLICommand; +import org.eclipse.dd.mi.service.command.commands.MIInterpreterExecConsole; +import org.eclipse.dd.mi.service.command.commands.RawCommand; +import org.eclipse.dd.mi.service.command.output.MIConsoleStreamOutput; +import org.eclipse.dd.mi.service.command.output.MIInfo; +import org.eclipse.dd.mi.service.command.output.MILogStreamOutput; +import org.eclipse.dd.mi.service.command.output.MIOOBRecord; +import org.eclipse.dd.mi.service.command.output.MIOutput; + +/** + * This Process implementation tracks the process the GDB process. This + * process object is displayed in Debug view and is used to + * accept CLI commands and to write their output to the console. + * + * @see org.eclipse.debug.core.model.IProcess + */ +@ThreadSafe +public abstract class AbstractCLIProcess extends Process + implements IEventListener, ICommandListener +{ + public static final String PRIMARY_PROMPT = "(gdb)"; //$NON-NLS-1$ + public static final String SECONDARY_PROMPT = ">"; //$NON-NLS-1$ + + private final DsfSession fSession; + private final AbstractMIControl fCommandControl; + private final OutputStream fOutputStream = new CLIOutputStream(); + + // Client process console stream. + private final PipedInputStream fMIInConsolePipe; + private final PipedOutputStream fMIOutConsolePipe; + private final PipedInputStream fMIInLogPipe; + private final PipedOutputStream fMIOutLogPipe; + + private final boolean fUseExecConsole; + + private boolean fDisposed = false; + + /** + * Counter for tracking console commands sent by services. + * + * Services may issue console commands when the available MI commands are + * not sufficient. However, these commands may produce console and log + * output which should not be written to the user CLI terminal. + * + * This counter is incremented any time a console command is seen which was + * not generated by this class. It is decremented whenever a service CLI + * command is finished. When counter value is 0, the CLI process writes + * the console output. + */ + private int fSuppressConsoleOutputCounter = 0; + + private int fPrompt = 1; // 1 --> Primary prompt "(gdb)"; 2 --> Secondary Prompt ">" + + @ConfinedToDsfExecutor("fSession#getExecutor") + public AbstractCLIProcess(AbstractMIControl commandControl, boolean useExecConsole) throws IOException { + fSession = commandControl.getSession(); + fCommandControl = commandControl; + fUseExecConsole = useExecConsole; + + commandControl.addEventListener(this); + commandControl.addCommandListener(this); + + PipedInputStream miInConsolePipe = null; + PipedOutputStream miOutConsolePipe = null; + PipedInputStream miInLogPipe = null; + PipedOutputStream miOutLogPipe = null; + + try { + miOutConsolePipe = new PipedOutputStream(); + miInConsolePipe = new PipedInputStream(miOutConsolePipe); + miOutLogPipe = new PipedOutputStream(); + miInLogPipe = new PipedInputStream(miOutLogPipe); + } catch (IOException e) { + ILog log = MIPlugin.getDefault().getLog(); + if (log != null) { + log.log(new Status( + IStatus.ERROR, MIPlugin.PLUGIN_ID, -1, "Error when creating log pipes", e)); //$NON-NLS-1$ + } + } + // Must initialize these outside of the try block because they are final. + fMIOutConsolePipe = miOutConsolePipe; + fMIInConsolePipe = miInConsolePipe; + fMIOutLogPipe = miOutLogPipe; + fMIInLogPipe = miInLogPipe; + } + + protected DsfSession getSession() { return fSession; } + + protected AbstractMIControl getCommandControl() { return fCommandControl; } + + protected boolean isDisposed() { return fDisposed; } + + @ConfinedToDsfExecutor("fSession#getExecutor") + public void dispose() { + fCommandControl.removeEventListener(this); + fCommandControl.removeCommandListener(this); + + closeIO(); + fDisposed = true; + } + + private void closeIO() { + try { + fMIOutConsolePipe.close(); + } catch (IOException e) {} + try { + fMIInConsolePipe.close(); + } catch (IOException e) {} + try { + fMIOutLogPipe.close(); + } catch (IOException e) {} + try { + fMIInLogPipe.close(); + } catch (IOException e) {} + + } + + /** + * @see java.lang.Process#getErrorStream() + */ + @Override + public InputStream getErrorStream() { + return fMIInLogPipe; + } + + /** + * @see java.lang.Process#getInputStream() + */ + @Override + public InputStream getInputStream() { + return fMIInConsolePipe; + } + + /** + * @see java.lang.Process#getOutputStream() + */ + @Override + public OutputStream getOutputStream() { + return fOutputStream; + } + + + public void eventReceived(Object output) { + if (fSuppressConsoleOutputCounter > 0) return; + for (MIOOBRecord oobr : ((MIOutput)output).getMIOOBRecords()) { + if (oobr instanceof MIConsoleStreamOutput) + { + MIConsoleStreamOutput out = (MIConsoleStreamOutput) oobr; + String str = out.getString(); + // Process the console stream too. + setPrompt(str); + try { + fMIOutConsolePipe.write(str.getBytes()); + fMIOutConsolePipe.flush(); + } catch (IOException e) { + } + } else if (oobr instanceof MILogStreamOutput) { + MILogStreamOutput out = (MILogStreamOutput) oobr; + String str = out.getString(); + if (str != null) { + try { + fMIOutLogPipe.write(str.getBytes()); + fMIOutLogPipe.flush(); + } catch (IOException e) { + } + } + } + } + } + + public void commandQueued(ICommand command) { + // Ignore + } + + public void commandSent(ICommand command) { + // Check if the command is a CLI command and if it did not originate from this class. + if (command instanceof CLICommand && + !(command instanceof ProcessCLICommand || command instanceof ProcessMIInterpreterExecConsole)) + { + fSuppressConsoleOutputCounter++; + } + } + + public void commandRemoved(ICommand command) { + // Ignore + } + + public void commandDone(ICommand command, ICommandResult result) { + if (command instanceof CLICommand && + !(command instanceof ProcessCLICommand || command instanceof ProcessMIInterpreterExecConsole)) + { + fSuppressConsoleOutputCounter--; + } + } + + void setPrompt(String line) { + fPrompt = 0; + // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=109733 + if (line == null) + return; + line = line.trim(); + if (line.equals(PRIMARY_PROMPT)) { + fPrompt = 1; + } else if (line.equals(SECONDARY_PROMPT)) { + fPrompt = 2; + } + } + + public boolean inPrimaryPrompt() { + return fPrompt == 1; + } + + public boolean inSecondaryPrompt() { + return fPrompt == 2; + } + + private class CLIOutputStream extends OutputStream { + private final StringBuffer buf = new StringBuffer(); + + @Override + public void write(int b) throws IOException { + buf.append((char)b); + if (b == '\n') { + // Throw away the newline. + final String bufString = buf.toString().trim(); + buf.setLength(0); + try { + fSession.getExecutor().execute(new DsfRunnable() { public void run() { + try { + post(bufString); + } catch (IOException e) { + // Pipe closed. + } + }}); + } catch (RejectedExecutionException e) { + // Session disposed. + } + } + } + + // Encapsulate the string sent to gdb in a fake + // command and post it to the TxThread. + public void post(String str) throws IOException { + if (isDisposed()) return; + ICommand cmd = null; + // 1- + // if We have the secondary prompt it means + // that GDB is waiting for more feedback, use a RawCommand + // 2- + // Do not use the interpreterexec for stepping operation + // the UI will fall out of step. + // 3- + // Normal Command Line Interface. + boolean secondary = inSecondaryPrompt(); + if (secondary) { + cmd = new RawCommand(getCommandControl().getControlDMContext(), str); + } + else if (fUseExecConsole && ! CLIEventProcessor.isSteppingOperation(str)) + { + cmd = new ProcessMIInterpreterExecConsole(getCommandControl().getControlDMContext(), str); + } + else { + cmd = new ProcessCLICommand(getCommandControl().getControlDMContext(), str); + } + final ICommand finalCmd = cmd; + fSession.getExecutor().execute(new DsfRunnable() { public void run() { + if (isDisposed()) return; + // Do not wait around for the answer. + getCommandControl().queueCommand(finalCmd, null); + }}); + } + } + + private class ProcessCLICommand extends CLICommand { + public ProcessCLICommand(IDMContext ctx, String oper) { + super(ctx, oper); + } + } + + private class ProcessMIInterpreterExecConsole extends MIInterpreterExecConsole { + public ProcessMIInterpreterExecConsole(IDMContext ctx, String cmd) { + super(ctx, cmd); + } + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java new file mode 100644 index 00000000000..96758120a14 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java @@ -0,0 +1,736 @@ +/******************************************************************************* + * 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 + * Ericsson - Modified for handling of multiple stacks and threads + *******************************************************************************/ +package org.eclipse.dd.mi.service.command; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; +import org.eclipse.dd.dsf.debug.service.command.ICommand; +import org.eclipse.dd.dsf.debug.service.command.ICommandControl; +import org.eclipse.dd.dsf.debug.service.command.ICommandListener; +import org.eclipse.dd.dsf.debug.service.command.ICommandResult; +import org.eclipse.dd.dsf.debug.service.command.IEventListener; +import org.eclipse.dd.dsf.service.AbstractDsfService; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.mi.internal.MIPlugin; +import org.eclipse.dd.mi.service.IMIExecutionDMContext; +import org.eclipse.dd.mi.service.command.commands.MICommand; +import org.eclipse.dd.mi.service.command.commands.MIStackSelectFrame; +import org.eclipse.dd.mi.service.command.commands.MIThreadSelect; +import org.eclipse.dd.mi.service.command.output.MIConst; +import org.eclipse.dd.mi.service.command.output.MIInfo; +import org.eclipse.dd.mi.service.command.output.MIList; +import org.eclipse.dd.mi.service.command.output.MIOOBRecord; +import org.eclipse.dd.mi.service.command.output.MIOutput; +import org.eclipse.dd.mi.service.command.output.MIParser; +import org.eclipse.dd.mi.service.command.output.MIResult; +import org.eclipse.dd.mi.service.command.output.MIResultRecord; +import org.eclipse.dd.mi.service.command.output.MIValue; + +/** + * Base implementation of an MI control service. It provides basic handling + * of input/output channels, and processing of the commands. + *

    + * Extending classes need to implement the initialize() and shutdown() methods. + */ +public abstract class AbstractMIControl extends AbstractDsfService + implements ICommandControl +{ + final static String PROP_INSTANCE_ID = MIPlugin.PLUGIN_ID + ".miControlInstanceId"; //$NON-NLS-1$ + + /* + * Thread control variables for the transmit and receive threads. + */ + + private TxThread fTxThread; + private RxThread fRxThread; + + private int fCurrentStackLevel = -1; + private int fCurrentThreadId = -1; + + + private final BlockingQueue fTxCommands = new LinkedBlockingQueue(); + private final Map fRxCommands = Collections.synchronizedMap(new HashMap()); + + /* + * Various listener control variables used to keep track of listeners who want to monitor + * what the control object is doing. + */ + + private final List fCommandProcessors = new ArrayList(); + private final List fEventProcessors = new ArrayList(); + + /** + * Current command which have not been handed off to the backend yet. + */ + + private final List fCommandQueue = new ArrayList(); + + /** + * Flag indicating that the command control has stopped processing commands. + */ + private boolean fStoppedCommandProcessing = false; + + /* + * Public constructor. + */ + + public AbstractMIControl(DsfSession session) { + super(session); + } + + /** + * Starts the threads that process the debugger input/output channels. + * To be invoked by the initialization routine of the extending class. + * + * @param inStream + * @param outStream + */ + + protected void startCommandProcessing(InputStream inStream, OutputStream outStream) { + + fTxThread = new TxThread(outStream); + fRxThread = new RxThread(inStream); + fTxThread.start(); + fRxThread.start(); + } + + /** + * Stops the threads that process the debugger input/output channels, and notifies the + * results of the outstanding commands. To be invoked by the shutdown routine of the + * extending class. + * + * @param inStream + * @param outStream + */ + + private Status genStatus(String str) { + return new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, str, null); + } + + protected void stopCommandProcessing() { + fStoppedCommandProcessing = true; + + /* + * First go through the commands which have been queueud and not yet sent to the backend. + */ + for (CommandHandle commandHandle : fCommandQueue) { + if (commandHandle.getRequestMonitor() == null) continue; + commandHandle.getRequestMonitor().setStatus(genStatus("Connection is shut down")); //$NON-NLS-1$ + commandHandle.getRequestMonitor().done(); + } + + /* + * Now go through the commands which are outstanding in that they have been sent to the backend. + */ + synchronized(fRxCommands) { + for (CommandHandle commandHandle : fRxCommands.values()) { + if (commandHandle.getRequestMonitor() == null) continue; + commandHandle.getRequestMonitor().setStatus(genStatus( "Connection is shut down")); //$NON-NLS-1$ + commandHandle.getRequestMonitor().done(); + } + fRxCommands.clear(); + } + + /* + * Now handle any requests which have not been transmitted, but weconsider them handed off. + */ + List txCommands = new ArrayList(); + fTxCommands.drainTo(txCommands); + for (CommandHandle commandHandle : txCommands) { + if (commandHandle.getRequestMonitor() == null) continue; + commandHandle.getRequestMonitor().setStatus(genStatus("Connection is shut down")); //$NON-NLS-1$ + commandHandle.getRequestMonitor().done(); + } + } + + /** + * Queues the given MI command to be sent to the debugger back end. + * + * @param command Command to be executed. This parameter must be an + * instance of DsfMICommand, otherwise a ClassCastException will be + * thrown. + * @param rm Request completion monitor + * + * @see org.eclipse.dd.dsf.debug.service.command.ICommandControl#addCommand(org.eclipse.dd.dsf.debug.service.command.ICommand, org.eclipse.dd.dsf.concurrent.RequestMonitor) + */ + + public void queueCommand(ICommand command, DataRequestMonitor rm) { + + // If the command control stopped processing commands, just return an error immediately. + if (fStoppedCommandProcessing) { + rm.setStatus(genStatus("Connection is shut down")); //$NON-NLS-1$ + rm.done(); + return; + } + + // Cast the command to MI Command type. This will cause a cast exception to be + // thrown if the client did not give an MI command as an argument. + @SuppressWarnings("unchecked") + MICommand miCommand = (MICommand) command; + + // Cast the return token to match the result type of MI Command. This is checking + // against an erased type so it should never throw any exceptions. + @SuppressWarnings("unchecked") + DataRequestMonitor miDone = (DataRequestMonitor)rm; + + final CommandHandle handle = new CommandHandle(miCommand, miDone); + + if ( fRxCommands.size() > 3 ) { + + /* + * We only allow three outstanding commands to be on the wire to the backend + * at any one time. This allows for coalesence as well as allowing for canceling + * existing commands on a state change. So we add it to the waiting list and let + * the user know they can now work with this item if need be. + */ + fCommandQueue.add(handle); + processCommandQueued(handle); + } else { + + /* + * We are putting this one on the wire. We need to add it to the waiting list so + * the user has the chance to cancel it when we tell them we are acknowleding it + * has been officially accepted. They could choose to cancel it before we go and + * send it. That is why we put it into the QUEUE and then check to see if it is + * still there. + */ + fCommandQueue.add(handle); + processCommandQueued(handle); + + if ( fCommandQueue.remove(handle) ) { + processCommandSent(handle); + + // Before the command is sent, Check the Thread Id and send it to + // the queue only if the id has been changed. + if( handle.getThreadId()!= null && + handle.getThreadId().intValue() != fCurrentThreadId && handle.getThreadId().intValue() != 0) + { + // Re-set the level + fCurrentThreadId = handle.getThreadId().intValue(); + CommandHandle cmdHandle = new CommandHandle( + new MIThreadSelect(handle.fCommand.getContext(), fCurrentThreadId), null); + fTxCommands.add(cmdHandle); + MIPlugin.debug(MIPlugin.getDebugTime() + " " + cmdHandle.getCommand()); //$NON-NLS-1$ + } + + // Before the command is sent, Check the Stack level and send it to + // the queue only if the level has been changed. + if( handle.getStackFrameId()!= null && + handle.getStackFrameId().intValue() != fCurrentStackLevel) + { + // Re-set the level + fCurrentStackLevel = handle.getStackFrameId().intValue(); + CommandHandle cmdHandle = new CommandHandle( + new MIStackSelectFrame(handle.fCommand.getContext(), fCurrentStackLevel), null); + fTxCommands.add(cmdHandle); + MIPlugin.debug(MIPlugin.getDebugTime() + " " + cmdHandle.getCommand()); //$NON-NLS-1$ + } + fTxCommands.add(handle); + } + } + + } + + /* + * This is the command which allows the user to retract a previously issued command. The + * state of the command is that it is in the waiting queue and has not yet been handed + * to the backend yet. + * + * (non-Javadoc) + * @see org.eclipse.dd.mi.service.command.IDebuggerControl#removeCommand(org.eclipse.dd.mi.service.command.commands.ICommand) + */ + public void removeCommand(ICommand command) { + + synchronized(fCommandQueue) { + + for ( CommandHandle handle : fCommandQueue ) { + if ( handle.getCommand().equals(command)) { + fCommandQueue.remove(handle); + + final CommandHandle finalHandle = handle; + getExecutor().execute(new DsfRunnable() { + public void run() { + processCommandRemoved(finalHandle); + } + }); + break; + } + } + } + } + + /* + * This command allows the user to try and cancel commands which have been handed off to the + * backend. Some backends support this with extended GDB/MI commands. If the support is there + * then we will attempt it. Because of the bidirectional nature of the GDB/MI command stream + * there is no guarantee that this will work. The response to the command could be on its way + * back when the cancel command is being issued. + * + * (non-Javadoc) + * @see org.eclipse.dd.mi.service.command.IDebuggerControl#cancelCommand(org.eclipse.dd.mi.service.command.commands.ICommand) + */ + public void cancelCommand(ICommand command) {} + + /* + * Allows a user ( typically a cache manager ) to sign up a listener to monitor command queue + * activity. + * + * (non-Javadoc) + * @see org.eclipse.dd.mi.service.command.IDebuggerControl#addCommandListener(org.eclipse.dd.mi.service.command.IDebuggerControl.ICommandListener) + */ + public void addCommandListener(ICommandListener processor) { fCommandProcessors.add(processor); } + + /* + * Allows a user ( typically a cache manager ) to remove a monitoring listener. + * (non-Javadoc) + * @see org.eclipse.dd.mi.service.command.IDebuggerControl#removeCommandListener(org.eclipse.dd.mi.service.command.IDebuggerControl.ICommandListener) + */ + public void removeCommandListener(ICommandListener processor) { fCommandProcessors.remove(processor); } + + /* + * Allows a user to sign up to a listener which handles out of band messages ( events ). + * + * (non-Javadoc) + * @see org.eclipse.dd.mi.service.command.IDebuggerControl#addEventListener(org.eclipse.dd.mi.service.command.IDebuggerControl.IEventListener) + */ + public void addEventListener(IEventListener processor) { fEventProcessors.add(processor); } + + /* + * Allows a user to remove a event monitoring listener. + * + * (non-Javadoc) + * @see org.eclipse.dd.mi.service.command.IDebuggerControl#removeEventListener(org.eclipse.dd.mi.service.command.IDebuggerControl.IEventListener) + */ + public void removeEventListener(IEventListener processor) { fEventProcessors.remove(processor); } + + abstract public MIControlDMContext getControlDMContext(); + + /* + * These are the service routines which perform the various callouts back to the listeners. + */ + + private void processCommandQueued(CommandHandle commandHandle) { + for (ICommandListener processor : fCommandProcessors) { + processor.commandQueued(commandHandle.getCommand()); + } + } + private void processCommandRemoved(CommandHandle commandHandle) { + for (ICommandListener processor : fCommandProcessors) { + processor.commandRemoved(commandHandle.getCommand()); + } + } + + private void processCommandSent(CommandHandle commandHandle) { + MIPlugin.debug(MIPlugin.getDebugTime() + " " + commandHandle.getToken() + commandHandle.getCommand()); //$NON-NLS-1$ + for (ICommandListener processor : fCommandProcessors) { + processor.commandSent(commandHandle.getCommand()); + } + } + + private void processCommandDone(CommandHandle commandHandle, ICommandResult result) { + + /* + * Provide tracking for out processing. + */ + if ( result != null ) { + MIInfo cmdResult = (MIInfo) result ; + MIOutput output = cmdResult.getMIOutput(); + MIPlugin.debug(MIPlugin.getDebugTime() + " " + output + "\n"); //$NON-NLS-1$ //$NON-NLS-2$ + } + else + { + MIPlugin.debug(MIPlugin.getDebugTime() + " result output not available\n"); //$NON-NLS-1$ + } + + /* + * Tell the listeners we have completed this one. + */ + for (ICommandListener processor : fCommandProcessors) { + processor.commandDone(commandHandle == null ? null : commandHandle.getCommand(), result); + } + } + + private void processEvent(MIOutput output) { + MIPlugin.debug(MIPlugin.getDebugTime() + " " + output + "\n"); //$NON-NLS-1$ //$NON-NLS-2$ + for (IEventListener processor : fEventProcessors) { + processor.eventReceived(output); + } + } + + /* + * A global counter for all command, the token will be use to identify uniquely a command. + * Unless the value wraps around which is unlikely. + */ + + private static int globalCounter = 0 ; + + private static synchronized int getUniqToken() { + int count = ++globalCounter; + // If we ever wrap around. + if (count <= 0) { + count = globalCounter = 1; + } + return count; + } + + /* + * Support class which creates a convenient wrapper for holding all information about an + * individual request. + */ + + public static class CommandHandle { + + private MICommand fCommand; + private DataRequestMonitor fRequestMonitor; + private int fTokenId ; + + CommandHandle(MICommand c, DataRequestMonitor d) { + fCommand = c; + fRequestMonitor = d; + fTokenId = getUniqToken() ; + } + + public MICommand getCommand() { return fCommand; } + public DataRequestMonitor getRequestMonitor() { return fRequestMonitor; } + public Integer getToken() { return fTokenId; } + //public String getThreadId() { return null; } + public Integer getStackFrameId() { + IFrameDMContext frameCtx = DMContexts.getAncestorOfType(fCommand.getContext(), IFrameDMContext.class); + if(frameCtx != null) + return frameCtx.getLevel(); + return null; + } + + public Integer getThreadId() { + IMIExecutionDMContext execCtx = DMContexts.getAncestorOfType(fCommand.getContext(), IMIExecutionDMContext.class); + if(execCtx != null) + return execCtx.getThreadId(); + return null; + } + } + + /* + * This is the transmitter thread. When a command is given to this thread it has been + * considered to be sent, even if it has not actually been sent yet. This assumption + * makes it easier from state management. Whomever fill this pipeline handles all of + * the required state notofication ( callbacks ). This thread simply physically gives + * the message to the backend. + */ + + private class TxThread extends Thread { + + final private OutputStream fOutputStream; + + public TxThread(OutputStream outStream) { + super("MI TX Thread"); //$NON-NLS-1$ + fOutputStream = outStream; + } + + @Override + public void run () { + while (true) { + CommandHandle commandHandle = null; + + /* + * Note: Acquiring locks for both fRxCommands and fTxCommands collections. + */ + synchronized(fTxCommands) { + try { + commandHandle = fTxCommands.take(); + } catch (InterruptedException e) { + break; // Shutting down. + } + + if (commandHandle == null) { + + break; // Null command is an indicator that we're shutting down. + } + + /* + * We note that this is an outstanding request at this point. + */ + fRxCommands.put(commandHandle.getToken(), commandHandle); + } + + /* + * Construct the new command and push this command out the pipeline. + */ + + String str = commandHandle.getToken() + commandHandle.getCommand().constructCommand(); + + try { + if (fOutputStream != null) { + fOutputStream.write(str.getBytes()); + fOutputStream.flush(); + } + } catch (IOException e) { + // Shutdown thread in case of IO error. + break; + } + } + } + } + + private class RxThread extends Thread { + private final InputStream fInputStream; + private final MIParser fMiParser = new MIParser(); + + /** + * List of out of band records since the last result record. Out of band records are + * required for processing the results of CLI commands. + */ + private final List fAccumulatedOOBRecords = new ArrayList(); + public RxThread(InputStream inputStream) { + super("MI RX Thread"); //$NON-NLS-1$ + fInputStream = inputStream; + } + + @Override + public void run() { + BufferedReader reader = new BufferedReader(new InputStreamReader(fInputStream)); + try { + String line; + while ((line = reader.readLine()) != null) { + if (line.length() != 0) { + processMIOutput(line); + } + } + } catch (IOException e) { + // Socket is shut down. + } catch (RejectedExecutionException e) { + // Dispatch thread is down. + } + } + + private MIResult findResultRecord(MIResult[] results, String variable) { + for (int i = 0; i < results.length; i++) { + if (variable.equals(results[i].getVariable())) { + return results[i]; + } + } + return null; + } + + private String getStatusString(MICommand origCommand, MIOutput response ) { + + // Attempt to extract a message from the result record: + String message = null; + String[] parameters = null; + if (response != null && response.getMIResultRecord() != null) { + MIResult[] results = response.getMIResultRecord().getMIResults(); + + // Extract the parameters + MIResult paramsRes = findResultRecord(results, "parameters"); //$NON-NLS-1$ + if (paramsRes != null && paramsRes.getMIValue() instanceof MIList) { + MIValue[] paramValues = ((MIList)paramsRes.getMIValue()).getMIValues(); + parameters = new String[paramValues.length]; + for (int i = 0; i < paramValues.length; i++) { + if (paramValues[i] instanceof MIConst) { + parameters[i] = ((MIConst)paramValues[i]).getString(); + } else { + parameters[i] = ""; //$NON-NLS-1$ + } + } + } + MIResult messageRes = findResultRecord(results, "message"); //$NON-NLS-1$ + if (messageRes != null && messageRes.getMIValue() instanceof MIConst) { + message = ((MIConst)messageRes.getMIValue()).getString(); + } + // FRCH: I believe that the actual string is "msg" ... + // FRCH: (at least for the version of gdb I'm using) + else { + messageRes = findResultRecord(results, "msg"); //$NON-NLS-1$ + if (messageRes != null && messageRes.getMIValue() instanceof MIConst) { + message = ((MIConst)messageRes.getMIValue()).getString(); + } + } + } + StringBuilder clientMsg = new StringBuilder(); + clientMsg.append("Failed to execute MI command:\n"); //$NON-NLS-1$ + clientMsg.append(origCommand.toString()); + if (message != null) { + clientMsg.append("Error message from debugger back end:\n"); //$NON-NLS-1$ + if (parameters != null) { + try { + clientMsg.append(MessageFormat.format(message, (Object[])parameters)); + } catch(IllegalArgumentException e2) { + // Message format string invalid. Fallback to just appending the strings. + clientMsg.append(message); + clientMsg.append(parameters); + } + } else { + clientMsg.append(message); + } + } + return clientMsg.toString(); + } + + void processMIOutput(String line) { + MIParser.RecordType recordType = fMiParser.getRecordType(line); + + if (recordType == MIParser.RecordType.ResultRecord) { + final MIResultRecord rr = fMiParser.parseMIResultRecord(line); + final MIOutput response = new MIOutput(rr, + fAccumulatedOOBRecords.toArray(new MIOOBRecord[fAccumulatedOOBRecords.size()]) ); + fAccumulatedOOBRecords.clear(); + + + /* + * Find the command in the current output list. If we cannot then this is + * some form of asynchronous notification. Or perhaps general IO. + */ + int id = rr.getToken(); + final CommandHandle commandHandle = fRxCommands.remove(id); + + if (commandHandle != null) { + + MIInfo result = commandHandle.getCommand().getResult(response); + DataRequestMonitor rm = commandHandle.getRequestMonitor(); + + /* + * Not all users want to get there results. They indicate so by not having + * a completion object. + */ + if ( rm != null ) { + rm.setData(result); + + /* + * We need to indicate if this request had an error or not. + */ + String errorResult = rr.getResultClass(); + + if ( errorResult.equals(MIResultRecord.ERROR) ) { + String status = getStatusString(commandHandle.getCommand(),response); + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, status, null)); + } + + /* + * We need to complete the command on the DSF thread for data security. + */ + final ICommandResult finalResult = result; + getExecutor().execute(new DsfRunnable() { + public void run() { + /* + * Complete the specific command. + */ + if (commandHandle.getRequestMonitor() != null) { + commandHandle.getRequestMonitor().done(); + } + + /* + * Now tell the generic listeners about it. + */ + processCommandDone(commandHandle, finalResult); + } + @Override + public String toString() { + return "MI command output received for: " + commandHandle.getCommand(); //$NON-NLS-1$ + } + }); + } else { + /* + * While the specific requestor did not care about the completion we + * need to call any listeners. This could have been a CLI command for + * example and the CommandDone listeners there handle the IO as part + * of the work. + */ + + final ICommandResult finalResult = result; + getExecutor().execute(new DsfRunnable() { + public void run() { + processCommandDone(commandHandle, finalResult); + } + @Override + public String toString() { + return "MI command output received for: " + commandHandle.getCommand(); //$NON-NLS-1$ + } + }); + } + } else { + /* + * GDB apparently can sometimes send multiple responses to the same command. In those cases, + * the command handle is gone, so post the result as an event. Again this must be done on the + * DSF thread for integrity. + */ + getExecutor().execute(new DsfRunnable() { + public void run() { + processEvent(response); + } + @Override + public String toString() { + return "MI asynchronous output received: " + response; //$NON-NLS-1$ + } + }); + } + //} else { + } else if (recordType == MIParser.RecordType.OOBRecord) { + // Process OOBs + final MIOOBRecord oob = fMiParser.parseMIOOBRecord(line); + fAccumulatedOOBRecords.add(oob); + final MIOutput response = new MIOutput(oob); + + + + /* + * OOBS are events. So we pass them to any event listeners who want to see them. Again this must + * be done on the DSF thread for integrity. + */ + getExecutor().execute(new DsfRunnable() { + public void run() { + processEvent(response); + } + @Override + public String toString() { + return "MI asynchronous output received: " + response; //$NON-NLS-1$ + } + }); + } + + getExecutor().execute(new DsfRunnable() { + public void run() { + if ( fCommandQueue.size() > 0 ) { + CommandHandle comHandle = fCommandQueue.remove(0); + if ( comHandle != null ) { + processCommandQueued(comHandle); + processCommandSent(comHandle); + fTxCommands.add(comHandle); + } + } + } + }); + } + } + + public void resetCurrentThreadLevel(){ + fCurrentThreadId = -1; + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/CLIEventProcessor.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/CLIEventProcessor.java new file mode 100644 index 00000000000..c2af69c36d4 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/CLIEventProcessor.java @@ -0,0 +1,353 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + * Ericsson AB - Additional handling of events + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command; + +import java.util.LinkedList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.dd.dsf.debug.service.ISignals.ISignalsDMContext; +import org.eclipse.dd.dsf.debug.service.command.ICommand; +import org.eclipse.dd.dsf.debug.service.command.ICommandListener; +import org.eclipse.dd.dsf.debug.service.command.ICommandResult; +import org.eclipse.dd.dsf.debug.service.command.IEventListener; +import org.eclipse.dd.mi.service.command.commands.CLICommand; +import org.eclipse.dd.mi.service.command.commands.MIInterpreterExecConsole; +import org.eclipse.dd.mi.service.command.events.MIBreakpointChangedEvent; +import org.eclipse.dd.mi.service.command.events.MIDetachedEvent; +import org.eclipse.dd.mi.service.command.events.MIErrorEvent; +import org.eclipse.dd.mi.service.command.events.MIEvent; +import org.eclipse.dd.mi.service.command.events.MIRunningEvent; +import org.eclipse.dd.mi.service.command.events.MISignalChangedEvent; +import org.eclipse.dd.mi.service.command.events.MIThreadCreatedEvent; +import org.eclipse.dd.mi.service.command.output.MIConsoleStreamOutput; +import org.eclipse.dd.mi.service.command.output.MIOOBRecord; +import org.eclipse.dd.mi.service.command.output.MIOutput; +import org.eclipse.dd.mi.service.command.output.MIResultRecord; + +/** + * GDB debugger output listener. + */ +@ConfinedToDsfExecutor("fConnection#getExecutor") +public class CLIEventProcessor + implements ICommandListener, IEventListener +{ + private final AbstractMIControl fCommandControl; + private final MIInferiorProcess fInferior; + private final IContainerDMContext fContainerDmc; + private final List fEventList = new LinkedList(); + + // Last Thread ID created + private static int fLastThreadId; + + + public CLIEventProcessor(AbstractMIControl connection, IContainerDMContext containerDmc, MIInferiorProcess inferior) { + fCommandControl = connection; + fInferior = inferior; + fContainerDmc = containerDmc; + connection.addCommandListener(this); + connection.addEventListener(this); + // Re-set the counter + fLastThreadId = 0; + } + + public void dispose() { + fCommandControl.removeCommandListener(this); + fCommandControl.removeEventListener(this); + } + + public void commandSent(ICommand command) { + if (command instanceof CLICommand) { + processStateChanges( (CLICommand)command ); + } + else if (command instanceof MIInterpreterExecConsole) { + processStateChanges( (MIInterpreterExecConsole)command ); + } + } + + public void commandDone(ICommand command, ICommandResult result) { + if (command instanceof CLICommand) { + processSettingChanges( (CLICommand)command ); + } + else if (command instanceof MIInterpreterExecConsole) { + processSettingChanges( (MIInterpreterExecConsole)command ); + } + fEventList.clear(); + } + + public void commandQueued(ICommand command) { + // No action + } + + public void commandRemoved(ICommand command) { + // No action + } + + public void eventReceived(Object output) { + for (MIOOBRecord oobr : ((MIOutput)output).getMIOOBRecords()) { + fEventList.add(oobr); + + if (oobr instanceof MIConsoleStreamOutput) { + // Process Events of type DsfMIConsoleStreamOutput here + MIConsoleStreamOutput exec = (MIConsoleStreamOutput) oobr; + + // Look for events with Pattern ^[New Thread 1077300144 (LWP 7973) + Pattern pattern = Pattern.compile("(^\\[New Thread.*LWP\\s*)(\\d*)", Pattern.MULTILINE); //$NON-NLS-1$ + Matcher matcher = pattern.matcher(exec.getCString()); + if (matcher.find()) { + //fMapThreadIds.put(matcher.group(2), Integer.valueOf(++fLastThreadId)); + //DsfMIEvent e = new DsfMIThreadCreatedEvent(Integer.valueOf(matcher.group(2))); + MIEvent e = new MIThreadCreatedEvent(fContainerDmc, ++fLastThreadId); + // Dispatch DsfMIThreadCreatedEvent + fCommandControl.getSession().dispatchEvent(e, fCommandControl.getProperties()); + } + // HACK - For GDB thread exit events, we won't use the events generated by GDB. This event is + // raised in GDBRunControl class by polling and comparing the ExecutionContexts returned by + // -thread-list-ids command. This is done as threads reported by exit event are still reported till + // they completely exit the system. + // Look for Thread Exited Event with Pattern [Thread 1077300144 (LWP 23832) exited]\n + // See bug 200615 for details. +// pattern = Pattern.compile("(^\\[Thread.*LWP\\s)(\\d*)(.*exited.*$)", Pattern.MULTILINE); //$NON-NLS-1$ +// matcher = pattern.matcher(exec.getCString()); +// if (matcher.find()) { +// DsfMIEvent e = new DsfMIThreadExitEvent(fMapThreadIds.get(matcher.group(2)).intValue()); +// // Dispatch DsfMIThreadExitEvent +// fConnection.getSession().dispatchEvent(e, fConnection.getProperties()); +// } + } + } + + // GDB can send an error result following sending an OK result. + // In this case the error is routed as an event. + MIResultRecord rr = ((MIOutput)output).getMIResultRecord(); + if (rr != null) { + // Check if the state changed. + String state = rr.getResultClass(); + if (fInferior != null && "error".equals(state)) { //$NON-NLS-1$ + if (fInferior.getState() == MIInferiorProcess.State.RUNNING) { + fInferior.setState(MIInferiorProcess.State.RUNNING); + fCommandControl.getSession().dispatchEvent( + MIErrorEvent.parse(fContainerDmc, rr.getToken(), rr.getMIResults(), null), + fCommandControl.getProperties()); + } + } + } + } + + + private void processStateChanges(CLICommand cmd) { + String operation = cmd.getOperation().trim(); + // In refactoring we are no longer genwerating the token id as + // part of the command. It is passed here and stored away and + // then never really used. So it has just been changed to 0. + processStateChanges(0, operation); + } + + private void processStateChanges(MIInterpreterExecConsole exec) { + String[] operations = exec.getParameters(); + if (operations != null && operations.length > 0) { + // In refactoring we are no longer genwerating the token id as + // part of the command. It is passed here and stored away and + // then never really used. So it has just been changed to 0. + processStateChanges(0, operations[0]); + } + } + + private void processStateChanges(int token, String operation) { + // Get the command name. + int indx = operation.indexOf(' '); + if (indx != -1) { + operation = operation.substring(0, indx).trim(); + } else { + operation = operation.trim(); + } + + // Check the type of command + + int type = getSteppingOperationKind(operation); + if (type != -1) { + // if it was a step instruction set state running + MIEvent event = new MIRunningEvent(fContainerDmc, token, type); + fCommandControl.getSession().dispatchEvent(event, fCommandControl.getProperties()); + } + } + + /** + * An attempt to discover the command type and + * fire an event if necessary. + */ + private void processSettingChanges(CLICommand cmd) { + String operation = cmd.getOperation().trim(); + // In refactoring we are no longer genwerating the token id as + // part of the command. It is passed here and stored away and + // then never really used. So it has just been changed to 0. + processSettingChanges(cmd.getContext(), 0, operation); + } + + private void processSettingChanges(MIInterpreterExecConsole exec) { + String[] operations = exec.getParameters(); + if (operations != null && operations.length > 0) { + // In refactoring we are no longer genwerating the token id as + // part of the command. It is passed here and stored away and + // then never really used. So it has just been changed to 0. + processSettingChanges(exec.getContext(), 0, operations[0]); + } + } + + private void processSettingChanges(IDMContext dmc, int token, String operation) { + // Get the command name. + int indx = operation.indexOf(' '); + if (indx != -1) { + operation = operation.substring(0, indx).trim(); + } else { + operation = operation.trim(); + } + + // Check the type of command + + if (isSettingBreakpoint(operation) || + isSettingWatchpoint(operation) || + isChangeBreakpoint(operation) || + isDeletingBreakpoint(operation)) + { + // We know something change, we just do not know what. + // So the easiest way is to let the top layer handle it. + MIEvent event = new MIBreakpointChangedEvent( + DMContexts.getAncestorOfType(dmc, IBreakpointsTargetDMContext.class), 0); + fCommandControl.getSession().dispatchEvent(event, fCommandControl.getProperties()); + } else if (isSettingSignal(operation)) { + // We do no know which signal let the upper layer find it. + MIEvent event = new MISignalChangedEvent( + DMContexts.getAncestorOfType(dmc, ISignalsDMContext.class), ""); //$NON-NLS-1$ + fCommandControl.getSession().dispatchEvent(event, fCommandControl.getProperties()); + } else if (isDetach(operation)) { + // if it was a "detach" command change the state. + MIEvent event = new MIDetachedEvent(DMContexts.getAncestorOfType(dmc, MIControlDMContext.class), token); + fCommandControl.getSession().dispatchEvent(event, fCommandControl.getProperties()); + } + } + + private static int getSteppingOperationKind(String operation) { + int type = -1; + /* execution commands: n, next, s, step, si, stepi, u, until, finish, + c, continue, fg */ + if (operation.equals("n") || operation.equals("next")) { //$NON-NLS-1$ //$NON-NLS-2$ + type = MIRunningEvent.NEXT; + } else if (operation.equals("ni") || operation.equals("nexti")) { //$NON-NLS-1$ //$NON-NLS-2$ + type = MIRunningEvent.NEXTI; + } else if (operation.equals("s") || operation.equals("step")) { //$NON-NLS-1$ //$NON-NLS-2$ + type = MIRunningEvent.STEP; + } else if (operation.equals("si") || operation.equals("stepi")) { //$NON-NLS-1$ //$NON-NLS-2$ + type = MIRunningEvent.STEPI; + } else if (operation.equals("u") || //$NON-NLS-1$ + (operation.startsWith("unt") && "until".indexOf(operation) != -1)) { //$NON-NLS-1$ //$NON-NLS-2$ + type = MIRunningEvent.UNTIL; + } else if (operation.startsWith("fin") && "finish".indexOf(operation) != -1) { //$NON-NLS-1$ //$NON-NLS-2$ + type = MIRunningEvent.FINISH; + } else if (operation.equals("c") || operation.equals("fg") || //$NON-NLS-1$ //$NON-NLS-2$ + (operation.startsWith("cont") && "continue".indexOf(operation) != -1)) { //$NON-NLS-1$ //$NON-NLS-2$ + type = MIRunningEvent.CONTINUE; + } else if (operation.startsWith("sig") && "signal".indexOf(operation) != -1) { //$NON-NLS-1$ //$NON-NLS-2$ + type = MIRunningEvent.CONTINUE; + } else if (operation.startsWith("j") && "jump".indexOf(operation) != -1) { //$NON-NLS-1$ //$NON-NLS-2$ + type = MIRunningEvent.CONTINUE; + } else if (operation.equals("r") || operation.equals("run")) { //$NON-NLS-1$ //$NON-NLS-2$ + type = MIRunningEvent.CONTINUE; + } + return type; + } + + /** + * Return true if the operation is a stepping operation. + * + * @param operation + * @return + */ + public static boolean isSteppingOperation(String operation) { + int type = getSteppingOperationKind(operation); + return type != -1; + } + + private boolean isSettingBreakpoint(String operation) { + boolean isbreak = false; + /* breakpoints: b, break, hbreak, tbreak, rbreak, thbreak */ + /* watchpoints: watch, rwatch, awatch, tbreak, rbreak, thbreak */ + if ((operation.startsWith("b") && "break".indexOf(operation) != -1) || //$NON-NLS-1$ //$NON-NLS-2$ + (operation.startsWith("tb") && "tbreak".indexOf(operation) != -1) || //$NON-NLS-1$ //$NON-NLS-2$ + (operation.startsWith("hb") && "hbreak".indexOf(operation) != -1) || //$NON-NLS-1$ //$NON-NLS-2$ + (operation.startsWith("thb") && "thbreak".indexOf(operation) != -1) || //$NON-NLS-1$ //$NON-NLS-2$ + (operation.startsWith("rb") && "rbreak".indexOf(operation) != -1)) { //$NON-NLS-1$ //$NON-NLS-2$ + isbreak = true; + } + return isbreak; + } + + private boolean isSettingWatchpoint(String operation) { + boolean isWatch = false; + /* watchpoints: watch, rwatch, awatch, tbreak, rbreak, thbreak */ + if ((operation.startsWith("wa") && "watch".indexOf(operation) != -1) || //$NON-NLS-1$ //$NON-NLS-2$ + (operation.startsWith("rw") && "rwatch".indexOf(operation) != -1) || //$NON-NLS-1$ //$NON-NLS-2$ + (operation.startsWith("aw") && "awatch".indexOf(operation) != -1)) { //$NON-NLS-1$ //$NON-NLS-2$ + isWatch = true; + } + return isWatch; + } + + private boolean isDeletingBreakpoint(String operation) { + boolean isDelete = false; + /* deleting breaks: clear, delete */ + if ((operation.startsWith("cl") && "clear".indexOf(operation) != -1) || //$NON-NLS-1$ //$NON-NLS-2$ + (operation.equals("d") || (operation.startsWith("del") && "delete".indexOf(operation) != -1))) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + isDelete = true; + } + return isDelete; + } + + private boolean isChangeBreakpoint(String operation) { + boolean isChange = false; + /* changing breaks: enable, disable */ + if ((operation.equals("dis") || operation.equals("disa") || //$NON-NLS-1$ //$NON-NLS-2$ + (operation.startsWith("disa") && "disable".indexOf(operation) != -1)) || //$NON-NLS-1$ //$NON-NLS-2$ + (operation.equals("en") || (operation.startsWith("en") && "enable".indexOf(operation) != -1)) || //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + (operation.startsWith("ig") && "ignore".indexOf(operation) != -1) || //$NON-NLS-1$ //$NON-NLS-2$ + (operation.startsWith("cond") && "condition".indexOf(operation) != -1)) { //$NON-NLS-1$ //$NON-NLS-2$ + isChange = true; + } + return isChange; + } + + private boolean isSettingSignal(String operation) { + boolean isChange = false; + /* changing signal: handle, signal */ + if (operation.startsWith("ha") && "handle".indexOf(operation) != -1) { //$NON-NLS-1$ //$NON-NLS-2$ + isChange = true; + } + return isChange; + } + + /** + * @param operation + * @return + */ + private boolean isDetach(String operation) { + return (operation.startsWith("det") && "detach".indexOf(operation) != -1); //$NON-NLS-1$ //$NON-NLS-2$ + } + +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIControlDMContext.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIControlDMContext.java new file mode 100644 index 00000000000..bee6c4174d2 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIControlDMContext.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command; + +import org.eclipse.dd.dsf.datamodel.AbstractDMContext; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.command.ICommandControl; +import org.eclipse.dd.dsf.service.IDsfService; +import org.osgi.framework.Constants; + +/** + * + */ +public class MIControlDMContext extends AbstractDMContext { + + private final String fCommandControlFilter; + private final String fCommandControlId; + + public MIControlDMContext(String sessionId, String commandControlId) { + this(sessionId, DMContexts.EMPTY_CONTEXTS_ARRAY, commandControlId); + } + + public MIControlDMContext(String sessionId, IDMContext[] parents, String commandControlId) { + super(sessionId, parents); + + fCommandControlId = commandControlId; + fCommandControlFilter = + "(&" + //$NON-NLS-1$ + "(" + Constants.OBJECTCLASS + "=" + ICommandControl.class.getName() + ")" + //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ + "(" + IDsfService.PROP_SESSION_ID + "=" + sessionId + ")" + //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ + "(" + AbstractMIControl.PROP_INSTANCE_ID + "=" + commandControlId + ")" + //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ + ")"; //$NON-NLS-1$ + } + + public String getCommandControlFilter() { + return fCommandControlFilter; + } + + @Override + public boolean equals(Object obj) { + return baseEquals(obj) && fCommandControlFilter.equals(((MIControlDMContext)obj).fCommandControlFilter); + } + + @Override + public int hashCode() { + return baseHashCode() + fCommandControlFilter.hashCode(); + } + + @Override + public String toString() { + return baseToString() + ".control(" + fCommandControlId + ")"; //$NON-NLS-1$//$NON-NLS-2$*/ + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIInferiorProcess.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIInferiorProcess.java new file mode 100644 index 00000000000..9cbe94eaa20 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIInferiorProcess.java @@ -0,0 +1,396 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Hewlett-Packard Development Company - fix for bug 109733 + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.cdt.utils.pty.PTY; +import org.eclipse.core.runtime.CoreException; +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.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; +import org.eclipse.dd.dsf.concurrent.Query; +import org.eclipse.dd.dsf.debug.service.command.ICommand; +import org.eclipse.dd.dsf.debug.service.command.ICommandListener; +import org.eclipse.dd.dsf.debug.service.command.ICommandResult; +import org.eclipse.dd.dsf.debug.service.command.IEventListener; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.mi.internal.MIPlugin; +import org.eclipse.dd.mi.service.command.commands.CLIExecAbort; +import org.eclipse.dd.mi.service.command.commands.MIGDBShowExitCode; +import org.eclipse.dd.mi.service.command.output.MIConst; +import org.eclipse.dd.mi.service.command.output.MIExecAsyncOutput; +import org.eclipse.dd.mi.service.command.output.MIGDBShowExitCodeInfo; +import org.eclipse.dd.mi.service.command.output.MIInfo; +import org.eclipse.dd.mi.service.command.output.MIOOBRecord; +import org.eclipse.dd.mi.service.command.output.MIOutput; +import org.eclipse.dd.mi.service.command.output.MIResult; +import org.eclipse.dd.mi.service.command.output.MIResultRecord; +import org.eclipse.dd.mi.service.command.output.MITargetStreamOutput; +import org.eclipse.dd.mi.service.command.output.MIValue; + +/** + * This Process implementation tracks the process that is being debugged + * by GDB. The process object is displayed in Debug view and is used to + * channel the STDIO of the interior process to the console view. + * + * @see org.eclipse.debug.core.model.IProcess + */ +public class MIInferiorProcess extends Process + implements IEventListener, ICommandListener +{ + public enum State { RUNNING, STOPPED, TERMINATED } + + private final OutputStream fOutputStream; + private final InputStream fInputStream; + + private final PipedOutputStream fInputStreamPiped; + + private final PipedInputStream fErrorStream; + private final PipedOutputStream fErrorStreamPiped; + + private final DsfSession fSession; + private final PTY fPty; + + private final AbstractMIControl fCommandControl; + + @ConfinedToDsfExecutor("fSession#getExecutor") + private boolean fDisposed = false; + + Integer fExitCode = null; + + private State fState = State.RUNNING; + + int inferiorPID; + + @ConfinedToDsfExecutor("fSession#getExecutor") + public MIInferiorProcess(AbstractMIControl commandControl, OutputStream gdbOutputStream) { + this(commandControl, gdbOutputStream, null); + } + + @ConfinedToDsfExecutor("fSession#getExecutor") + public MIInferiorProcess(AbstractMIControl commandControl, PTY p) { + this(commandControl, null, p); + } + + @ConfinedToDsfExecutor("fSession#getExecutor") + private MIInferiorProcess(AbstractMIControl commandControl, final OutputStream gdbOutputStream, PTY p) { + fCommandControl = commandControl; + fSession = commandControl.getSession(); + + commandControl.addEventListener(this); + commandControl.addCommandListener(this); + + fPty = p; + if (fPty != null) { + fOutputStream = fPty.getOutputStream(); + fInputStream = fPty.getInputStream(); + fInputStreamPiped = null; + } else { + fOutputStream = new OutputStream() { + @Override + public void write(int b) throws IOException { + // Have to re-dispatch to dispatch thread to check state + if (getState() != State.RUNNING) { + throw new IOException("Target is not running"); //$NON-NLS-1$ + } + gdbOutputStream.write(b); + } + }; + + fInputStreamPiped = new PipedOutputStream(); + PipedInputStream inputStream = null; + try { + inputStream = new PipedInputStream(fInputStreamPiped); + } catch (IOException e) { + } + fInputStream = inputStream; + + } + + // Note: We do not have any err stream from gdb/mi so this gdb + // err channel instead. + fErrorStreamPiped = new PipedOutputStream(); + PipedInputStream errorStream = null; + try { + errorStream = new PipedInputStream(fErrorStreamPiped); + } catch (IOException e) { + } + fErrorStream = errorStream; + } + + @ConfinedToDsfExecutor("fSession#getExecutor") + public void dispose() { + fCommandControl.removeEventListener(this); + fCommandControl.removeCommandListener(this); + + closeIO(); + + setState(State.TERMINATED); + + fDisposed = true; + } + + protected DsfSession getSession() { + return fSession; + } + + protected AbstractMIControl getCommandControl() { return fCommandControl; } + + protected boolean isDisposed() { return fDisposed; } + + @Override + public OutputStream getOutputStream() { + return fOutputStream; + } + + @Override + public InputStream getInputStream() { + return fInputStream; + } + + @Override + public InputStream getErrorStream() { + return fErrorStream; + } + + public synchronized void waitForSync() throws InterruptedException { + while (getState() != State.TERMINATED) { + wait(100); + } + } + + /** + * @see java.lang.Process#waitFor() + */ + @Override + public int waitFor() throws InterruptedException { + waitForSync(); + return exitValue(); + } + + /** + * @see java.lang.Process#exitValue() + */ + @Override + public int exitValue() { + if (fExitCode != null) { + return fExitCode; + } + + try { + Query exitCodeQuery = new Query() { + @Override + protected void execute(final DataRequestMonitor rm) { + // Guard against session disposed. + if (!DsfSession.isSessionActive(fSession.getId())) { + cancel(false); + return; + } + + if (isDisposed()) { + rm.setData(0); + rm.done(); + } else if (getState() != State.TERMINATED) { + // This will cause ExecutionException to be thrown with a CoreException, + // which will in turn contain the IllegalThreadStateException. + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "GDB is still running.", new IllegalThreadStateException())); //$NON-NLS-1$ + rm.done(); + } else { + getCommandControl().queueCommand( + new MIGDBShowExitCode(getCommandControl().getControlDMContext()), + new DataRequestMonitor(fSession.getExecutor(), rm) { + @Override + protected void handleOK() { + rm.setData(getData().getCode()); + rm.done(); + } + }); + + } + } + }; + fSession.getExecutor().execute(exitCodeQuery); + fExitCode = exitCodeQuery.get(); + return fExitCode; + } catch (RejectedExecutionException e) { + } catch (InterruptedException e) { + } catch (CancellationException e) { + } catch (ExecutionException e) { + // Che + if (e.getCause() instanceof CoreException && + ((CoreException)e.getCause()).getStatus().getException() instanceof RuntimeException ) + { + throw (RuntimeException)((CoreException)e.getCause()).getStatus().getException(); + } + } + return 0; + } + + /** + * @see java.lang.Process#destroy() + */ + @Override + public void destroy() { + try { + fSession.getExecutor().execute(new DsfRunnable() { + public void run() { + doDestroy(); + } + }); + } catch (RejectedExecutionException e) { + // Session disposed. + } + closeIO(); + } + + private void closeIO() { + try { + fOutputStream.close(); + } catch (IOException e) {} + try { + fInputStream.close(); + } catch (IOException e) {} + try { + fInputStreamPiped.close(); + } catch (IOException e) {} + try { + fErrorStream.close(); + } catch (IOException e) {} + try { + fErrorStreamPiped.close(); + } catch (IOException e) {} + } + + @ConfinedToDsfExecutor("fSession#getExecutor") + private void doDestroy() { + if (isDisposed() || !fSession.isActive() || getState() == State.TERMINATED) return; + + // To avoid a RejectedExecutionException, use an executor that + // immediately executes in the same dispatch cycle. + CLIExecAbort cmd = new CLIExecAbort(getCommandControl().getControlDMContext()); + getCommandControl().queueCommand( + cmd, + new DataRequestMonitor(ImmediateExecutor.getInstance(), null) { + @Override + protected void handleCompleted() { + setState(MIInferiorProcess.State.TERMINATED); + } + } + ); + } + + public State getState() { + return fState; + } + + synchronized void setState(State state) { + if (fState == State.TERMINATED) return; + fState = state; + if (fState == State.TERMINATED) { + closeIO(); + } + notifyAll(); + } + + public OutputStream getPipedOutputStream() { + return fInputStreamPiped; + } + + public OutputStream getPipedErrorStream() { + return fErrorStreamPiped; + } + + public PTY getPTY() { + return fPty; + } + + public void eventReceived(Object output) { + for (MIOOBRecord oobr : ((MIOutput)output).getMIOOBRecords()) { + if (oobr instanceof MIExecAsyncOutput) { + MIExecAsyncOutput async = (MIExecAsyncOutput)oobr; + + String state = async.getAsyncClass(); + if ("stopped".equals(state)) { //$NON-NLS-1$ + boolean handled = false; + MIResult[] results = async.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + if (var.equals("reason")) { //$NON-NLS-1$ + MIValue value = results[i].getMIValue(); + if (value instanceof MIConst) { + String reason = ((MIConst) value).getString(); + if ("exited-signalled".equals(reason) || "exited-normally".equals(reason) || "exited".equals(reason)) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + setState(State.TERMINATED); + } else { + setState(State.STOPPED); + } + handled = true; + } + } + } + + if (!handled) { + setState(State.STOPPED); + } + } + } else if (oobr instanceof MITargetStreamOutput) { + MITargetStreamOutput tgtOut = (MITargetStreamOutput)oobr; + if (fInputStreamPiped != null && tgtOut.getString() != null) { + try { + fInputStreamPiped.write(tgtOut.getString().getBytes()); + fInputStreamPiped.flush(); + } catch (IOException e) { + } + } + } + } + } + + public void commandQueued(ICommand command) { + // No action + } + + public void commandSent(ICommand command) { + // No action + } + + public void commandRemoved(ICommand command) { + // No action + } + + public void commandDone(ICommand cmd, ICommandResult result) { + MIInfo cmdResult = (MIInfo) result ; + MIOutput output = cmdResult.getMIOutput(); + MIResultRecord rr = output.getMIResultRecord(); + + // Check if the state changed. + String state = rr.getResultClass(); + + if ("running".equals(state)) { setState(State.RUNNING); }//$NON-NLS-1$ + else if ("exit".equals(state)) { setState(State.TERMINATED); }//$NON-NLS-1$ + else if ("error".equals(state)) { setState(State.STOPPED); }//$NON-NLS-1$ + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIRunControlEventProcessor.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIRunControlEventProcessor.java new file mode 100644 index 00000000000..c64069a42d9 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIRunControlEventProcessor.java @@ -0,0 +1,225 @@ +/******************************************************************************* + * 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 + * Ericsson - Additional handling of events + *******************************************************************************/ +package org.eclipse.dd.mi.service.command; + +import java.util.LinkedList; +import java.util.List; + +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.dd.dsf.debug.service.command.ICommand; +import org.eclipse.dd.dsf.debug.service.command.ICommandListener; +import org.eclipse.dd.dsf.debug.service.command.ICommandResult; +import org.eclipse.dd.dsf.debug.service.command.IEventListener; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.mi.internal.MIPlugin; +import org.eclipse.dd.mi.service.MIRunControl; +import org.eclipse.dd.mi.service.command.commands.MIExecContinue; +import org.eclipse.dd.mi.service.command.commands.MIExecFinish; +import org.eclipse.dd.mi.service.command.commands.MIExecNext; +import org.eclipse.dd.mi.service.command.commands.MIExecNextInstruction; +import org.eclipse.dd.mi.service.command.commands.MIExecReturn; +import org.eclipse.dd.mi.service.command.commands.MIExecStep; +import org.eclipse.dd.mi.service.command.commands.MIExecStepInstruction; +import org.eclipse.dd.mi.service.command.commands.MIExecUntil; +import org.eclipse.dd.mi.service.command.events.MIBreakpointHitEvent; +import org.eclipse.dd.mi.service.command.events.MIEvent; +import org.eclipse.dd.mi.service.command.events.MIFunctionFinishedEvent; +import org.eclipse.dd.mi.service.command.events.MIInferiorExitEvent; +import org.eclipse.dd.mi.service.command.events.MIInferiorSignalExitEvent; +import org.eclipse.dd.mi.service.command.events.MILocationReachedEvent; +import org.eclipse.dd.mi.service.command.events.MIRunningEvent; +import org.eclipse.dd.mi.service.command.events.MISignalEvent; +import org.eclipse.dd.mi.service.command.events.MISteppingRangeEvent; +import org.eclipse.dd.mi.service.command.events.MIStoppedEvent; +import org.eclipse.dd.mi.service.command.events.MIWatchpointScopeEvent; +import org.eclipse.dd.mi.service.command.events.MIWatchpointTriggerEvent; +import org.eclipse.dd.mi.service.command.output.MIConst; +import org.eclipse.dd.mi.service.command.output.MIExecAsyncOutput; +import org.eclipse.dd.mi.service.command.output.MIInfo; +import org.eclipse.dd.mi.service.command.output.MINotifyAsyncOutput; +import org.eclipse.dd.mi.service.command.output.MIOOBRecord; +import org.eclipse.dd.mi.service.command.output.MIOutput; +import org.eclipse.dd.mi.service.command.output.MIResult; +import org.eclipse.dd.mi.service.command.output.MIResultRecord; +import org.eclipse.dd.mi.service.command.output.MIStatusAsyncOutput; +import org.eclipse.dd.mi.service.command.output.MIValue; + +/** + * MI debugger output listener that listens for the parsed MI output, and + * generates corresponding MI events. The generated MI events are then + * received by other services and clients. + */ +public class MIRunControlEventProcessor + implements IEventListener, ICommandListener +{ + /** + * The connection service that this event processor is registered with. + */ + private final AbstractMIControl fCommandControl; + + /** + * Container context used as the context for the run control events generated + * by this processor. + */ + private final IContainerDMContext fContainerDmc; + + /** + * Services tracker used to retrieve the MIRunControl service. + */ + private final DsfServicesTracker fServicesTracker; + + /** + * Creates the event processor and registers it as listener with the debugger + * control. + * @param connection + * @param inferior + */ + public MIRunControlEventProcessor(AbstractMIControl connection, IContainerDMContext containerDmc) { + fCommandControl = connection; + fContainerDmc = containerDmc; + fServicesTracker = new DsfServicesTracker(MIPlugin.getBundleContext(), fCommandControl.getSession().getId()); + connection.addEventListener(this); + connection.addCommandListener(this); + } + + /** + * This processor must be disposed before the control service is un-registered. + */ + public void dispose() { + fCommandControl.removeEventListener(this); + fCommandControl.removeCommandListener(this); + fServicesTracker.dispose(); + } + + public void eventReceived(Object output) { + for (MIOOBRecord oobr : ((MIOutput)output).getMIOOBRecords()) { + if (oobr instanceof MIExecAsyncOutput) { + MIExecAsyncOutput exec = (MIExecAsyncOutput) oobr; + // Change of state. + String state = exec.getAsyncClass(); + if ("stopped".equals(state)) { //$NON-NLS-1$ + // Re-set the thread level to -1 when stopped event is recvd. + // This is to synchronize the state between GDB back-end and AbstractMIControl. + fCommandControl.resetCurrentThreadLevel(); + + List> events = new LinkedList>(); + MIResult[] results = exec.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + MIValue val = results[i].getMIValue(); + if (var.equals("reason")) { //$NON-NLS-1$ + if (val instanceof MIConst) { + String reason = ((MIConst) val).getString(); + MIEvent e = createEvent(reason, exec); + if (e != null) { + events.add(e); + continue; + } + } + } + } + + // We were stopped for some unknown reason, for example + // GDB for temporary breakpoints will not send the + // "reason" ??? still fire a stopped event. + if (events.isEmpty()) { + MIEvent e = MIStoppedEvent.parse( + fServicesTracker.getService(MIRunControl.class), fContainerDmc, exec.getToken(), exec.getMIResults()); + events.add(e); + } + for (MIEvent event : events) { + fCommandControl.getSession().dispatchEvent(event, fCommandControl.getProperties()); + } + } + } + else if (oobr instanceof MIStatusAsyncOutput) { + // Nothing done .. but what about +download?? + } else if (oobr instanceof MINotifyAsyncOutput) { + // Nothing + } + } + } + + protected MIEvent createEvent(String reason, MIExecAsyncOutput exec) { + MIRunControl runControl = fServicesTracker.getService(MIRunControl.class); + MIEvent event = null; + if ("breakpoint-hit".equals(reason)) { //$NON-NLS-1$ + event = MIBreakpointHitEvent.parse(runControl, fContainerDmc, exec.getToken(), exec.getMIResults()); + } else if ( + "watchpoint-trigger".equals(reason) //$NON-NLS-1$ + || "read-watchpoint-trigger".equals(reason) //$NON-NLS-1$ + || "access-watchpoint-trigger".equals(reason)) { //$NON-NLS-1$ + event = MIWatchpointTriggerEvent.parse(runControl, fContainerDmc, exec.getToken(), exec.getMIResults()); + } else if ("watchpoint-scope".equals(reason)) { //$NON-NLS-1$ + event = MIWatchpointScopeEvent.parse(runControl, fContainerDmc, exec.getToken(), exec.getMIResults()); + } else if ("end-stepping-range".equals(reason)) { //$NON-NLS-1$ + event = MISteppingRangeEvent.parse(runControl, fContainerDmc, exec.getToken(), exec.getMIResults()); + } else if ("signal-received".equals(reason)) { //$NON-NLS-1$ + event = MISignalEvent.parse(runControl, fContainerDmc, exec.getToken(), exec.getMIResults()); + } else if ("location-reached".equals(reason)) { //$NON-NLS-1$ + event = MILocationReachedEvent.parse(runControl, fContainerDmc, exec.getToken(), exec.getMIResults()); + } else if ("function-finished".equals(reason)) { //$NON-NLS-1$ + event = MIFunctionFinishedEvent.parse(runControl, fContainerDmc, exec.getToken(), exec.getMIResults()); + } else if ("exited-normally".equals(reason) || "exited".equals(reason)) { //$NON-NLS-1$ //$NON-NLS-2$ + event = MIInferiorExitEvent.parse(fCommandControl.getControlDMContext(), exec.getToken(), exec.getMIResults()); + } else if ("exited-signalled".equals(reason)) { //$NON-NLS-1$ + event = MIInferiorSignalExitEvent.parse(fCommandControl.getControlDMContext(), exec.getToken(), exec.getMIResults()); + } + return event; + } + + public void commandQueued(ICommand command) { + // Do nothing. + } + + public void commandSent(ICommand command) { + // Do nothing. + } + + public void commandRemoved(ICommand command) { + // Do nothing. + } + + public void commandDone(ICommand cmd, ICommandResult result) { + MIInfo cmdResult = (MIInfo) result ; + MIOutput output = cmdResult.getMIOutput(); + MIResultRecord rr = output.getMIResultRecord(); + if (rr != null) { + int id = rr.getToken(); + // Check if the state changed. + String state = rr.getResultClass(); + if ("running".equals(state)) { //$NON-NLS-1$ + int type = 0; + // Check the type of command + // if it was a step instruction set state stepping + + if (cmd instanceof MIExecNext) { type = MIRunningEvent.NEXT; } + else if (cmd instanceof MIExecNextInstruction) { type = MIRunningEvent.NEXTI; } + else if (cmd instanceof MIExecStep) { type = MIRunningEvent.STEP; } + else if (cmd instanceof MIExecStepInstruction) { type = MIRunningEvent.STEPI; } + else if (cmd instanceof MIExecUntil) { type = MIRunningEvent.UNTIL; } + else if (cmd instanceof MIExecFinish) { type = MIRunningEvent.FINISH; } + else if (cmd instanceof MIExecReturn) { type = MIRunningEvent.RETURN; } + else if (cmd instanceof MIExecContinue) { type = MIRunningEvent.CONTINUE; } + else { type = MIRunningEvent.CONTINUE; } + + fCommandControl.getSession().dispatchEvent( + new MIRunningEvent(fContainerDmc, id, type), fCommandControl.getProperties()); + } else if ("exit".equals(state)) { //$NON-NLS-1$ + // No need to do anything, terminate() will. + // Send exited? + } else if ("connected".equals(state)) { //$NON-NLS-1$ + } else if ("error".equals(state)) { //$NON-NLS-1$ + } + } + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLICommand.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLICommand.java new file mode 100644 index 00000000000..d817934babe --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLICommand.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; + +/** + * Represents a CLI command. + */ +public class CLICommand extends MICommand +{ + public CLICommand(IDMContext ctx, String oper) { + super(ctx, oper); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLIExecAbort.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLIExecAbort.java new file mode 100644 index 00000000000..7963bb09921 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLIExecAbort.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.mi.service.command.MIControlDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; + +/** + * + * kill + * + * Terminates the user (MI inferior) process + * + */ +public class CLIExecAbort extends CLICommand +{ + public CLIExecAbort(MIControlDMContext ctx) { + super(ctx, "kill"); //$NON-NLS-1$ + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLIInfoSharedLibrary.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLIInfoSharedLibrary.java new file mode 100644 index 00000000000..88591e704d4 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLIInfoSharedLibrary.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Ericsson - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + + +import org.eclipse.dd.dsf.debug.service.IModules.IModuleDMContext; +import org.eclipse.dd.dsf.debug.service.IModules.ISymbolDMContext; +import org.eclipse.dd.mi.service.command.output.CLIInfoSharedLibraryInfo; +import org.eclipse.dd.mi.service.command.output.MIInfo; +import org.eclipse.dd.mi.service.command.output.MIOutput; + +/** + * + * info sharedlibrary + * + */ +public class CLIInfoSharedLibrary extends CLICommand { + + public CLIInfoSharedLibrary(ISymbolDMContext ctx) { + super(ctx, "info sharedlibrary"); //$NON-NLS-1$ + } + public CLIInfoSharedLibrary(IModuleDMContext ctx) { + super(ctx, "info sharedlibrary"); //$NON-NLS-1$ + } + @Override + public CLIInfoSharedLibraryInfo getResult(MIOutput output) { + return (CLIInfoSharedLibraryInfo)getMIInfo(output); + } + + public MIInfo getMIInfo(MIOutput out) { + MIInfo info = null; + if (out != null) { + info = new CLIInfoSharedLibraryInfo(out); + } + return info; + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLIInfoThreads.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLIInfoThreads.java new file mode 100644 index 00000000000..c3cfecb8009 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLIInfoThreads.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Ericsson - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + + + +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.dd.mi.service.command.output.CLIInfoThreadsInfo; +import org.eclipse.dd.mi.service.command.output.MIInfo; +import org.eclipse.dd.mi.service.command.output.MIOutput; + +/** + * + * info threads + * + */ +public class CLIInfoThreads extends CLICommand { + + public CLIInfoThreads(IContainerDMContext ctx) { + super(ctx, "info threads"); //$NON-NLS-1$ + } + + @Override + public CLIInfoThreadsInfo getResult(MIOutput output) { + return (CLIInfoThreadsInfo)getMIInfo(output); + } + + public MIInfo getMIInfo(MIOutput out) { + MIInfo info = null; + if (out != null) { + info = new CLIInfoThreadsInfo(out); + } + return info; + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/ExprMetaCommand.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/ExprMetaCommand.java new file mode 100644 index 00000000000..e20403d2061 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/ExprMetaCommand.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2007 Ericsson 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: + * Ericsson - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.command.ICommand; +import org.eclipse.dd.dsf.debug.service.command.ICommandResult; + +public class ExprMetaCommand implements ICommand { + + private final IDMContext fCtx; + + public ExprMetaCommand(IDMContext ctx) { + fCtx = ctx; + } + + /* + * Takes the supplied command and coalesces it with this one. + * The result is a new third command which represent the two + * original command. + */ + public ICommand coalesceWith( ICommand command ) { + return null ; + } + + public IDMContext getContext(){ + return fCtx; + } + + @Override + public boolean equals(Object other) { + if (other == null) return false; + if (!(other.getClass().equals(getClass()))) return false; + + // Since other is the same class is this, we are sure it is of type DsfExprMetaCommand also + ExprMetaCommand otherCmd = (ExprMetaCommand)other; + return fCtx == null ? otherCmd.fCtx == null : fCtx.equals(otherCmd.fCtx); + } + + @Override + public int hashCode() { + return fCtx == null ? getClass().hashCode() : getClass().hashCode() ^ fCtx.hashCode(); + } + + @Override + public String toString() { + return getClass().toString() + fCtx == null ? "null" : fCtx.toString(); //$NON-NLS-1$ + } + + public String getCommandControlFilter() { + return null; + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/ExprMetaGetAttributes.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/ExprMetaGetAttributes.java new file mode 100644 index 00000000000..60063bdc8dc --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/ExprMetaGetAttributes.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2008 Ericsson 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: + * Ericsson - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.dd.mi.service.command.output.ExprMetaGetAttributesInfo; + +public class ExprMetaGetAttributes extends ExprMetaCommand { + + public ExprMetaGetAttributes(IExpressionDMContext ctx) { + super(ctx); + } +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/ExprMetaGetChildCount.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/ExprMetaGetChildCount.java new file mode 100644 index 00000000000..f5233d074f8 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/ExprMetaGetChildCount.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2007 Ericsson 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: + * Ericsson - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.dd.mi.service.command.output.ExprMetaGetChildCountInfo; + +public class ExprMetaGetChildCount extends ExprMetaCommand { + + public ExprMetaGetChildCount(IExpressionDMContext ctx) { + super(ctx); + } +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/ExprMetaGetChildren.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/ExprMetaGetChildren.java new file mode 100644 index 00000000000..7b12ab71d2a --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/ExprMetaGetChildren.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2007 Ericsson 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: + * Ericsson - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.dd.mi.service.command.output.ExprMetaGetChildrenInfo; + +public class ExprMetaGetChildren extends ExprMetaCommand { + + public ExprMetaGetChildren(IExpressionDMContext ctx) { + super(ctx); + } +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/ExprMetaGetValue.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/ExprMetaGetValue.java new file mode 100644 index 00000000000..582a3414072 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/ExprMetaGetValue.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2007 Ericsson 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: + * Ericsson - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext; +import org.eclipse.dd.mi.service.command.output.ExprMetaGetValueInfo; + +public class ExprMetaGetValue extends ExprMetaCommand { + + public ExprMetaGetValue(FormattedValueDMContext ctx) { + super(ctx); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/ExprMetaGetVar.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/ExprMetaGetVar.java new file mode 100644 index 00000000000..342597f7281 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/ExprMetaGetVar.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2007 Ericsson 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: + * Ericsson - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.dd.mi.service.command.output.ExprMetaGetVarInfo; + +public class ExprMetaGetVar extends ExprMetaCommand { + + public ExprMetaGetVar(IExpressionDMContext ctx) { + super(ctx); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIBreakAfter.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIBreakAfter.java new file mode 100644 index 00000000000..d4cdbcf414e --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIBreakAfter.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2007 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; + +/** + * + * -break-after NUMBER COUNT + * + * The breakpoint number NUMBER is not in effect until it has been hit + * COUNT times. The count becomes part of the `-break-list' output + * (see the description of the DsfMIBreakList). + */ + +public class MIBreakAfter extends MICommand +{ + public MIBreakAfter(IBreakpointsTargetDMContext ctx, int breakpoint, int ignoreCount) { + super(ctx, "-break-after"); //$NON-NLS-1$ + setParameters(new String[] { Integer.toString(breakpoint), Integer.toString(ignoreCount) }); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIBreakCondition.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIBreakCondition.java new file mode 100644 index 00000000000..9592b9a06b4 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIBreakCondition.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2007 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; + +/** + * + * -break-condition NUMBER EXPR + * + * Breakpoint NUMBER will stop the program only if the condition in + * EXPR is true. The condition becomes part of the `-break-list' output + * (see the description of the DsfMIBreakList). + */ + +public class MIBreakCondition extends MICommand +{ + // In this particular case, because of a GDB peculiarity, setParameters() is + // not used and the whole command is formatted on the parent's constructor. + // See bug 213076 for more information. + + public MIBreakCondition(IBreakpointsTargetDMContext ctx, int breakpoint, String condition) { + super(ctx, "-break-condition " + Integer.toString(breakpoint) + " " + condition); //$NON-NLS-1$ //$NON-NLS-2$ +// setParameters(new String[] { Integer.toString(breakpoint), condition }); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIBreakDelete.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIBreakDelete.java new file mode 100644 index 00000000000..35446b72d22 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIBreakDelete.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; + +/** + * + * -break-delete ( BREAKPOINT )+ + * + * Delete the breakpoint(s) whose number(s) are specified in the + * argument list. This is obviously reflected in the breakpoint list. + * + * Result: + * ^done + * + */ + +public class MIBreakDelete extends MICommand +{ + public MIBreakDelete (IBreakpointsTargetDMContext ctx, int[] array) { + super(ctx, "-break-delete"); //$NON-NLS-1$ + if (array != null && array.length > 0) { + String[] brkids = new String[array.length]; + for (int i = 0; i < array.length; i++) { + brkids[i] = Integer.toString(array[i]); + } + setParameters(brkids); + } + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIBreakDisable.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIBreakDisable.java new file mode 100644 index 00000000000..a71e068cd76 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIBreakDisable.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; + +/** + * + * -break-disable ( BREAKPOINT )+ + * + * Disable the named BREAKPOINT(s). The field `enabled' in the break + * list is now set to `n' for the named BREAKPOINT(s). + * + * Result: + * ^done + */ + +public class MIBreakDisable extends MICommand +{ + public MIBreakDisable (IBreakpointsTargetDMContext ctx, int[] array) { + super(ctx, "-break-disable"); //$NON-NLS-1$ + if (array != null && array.length > 0) { + String[] brkids = new String[array.length]; + for (int i = 0; i < array.length; i++) { + brkids[i] = Integer.toString(array[i]); + } + setParameters(brkids); + } + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIBreakEnable.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIBreakEnable.java new file mode 100644 index 00000000000..7a0c9eb6d0b --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIBreakEnable.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; + +/** + * + * -break-enable ( BREAKPOINT )+ + * + * Enable (previously disabled) BREAKPOINT(s). + * + * Result: + * ^done + */ + +public class MIBreakEnable extends MICommand +{ + public MIBreakEnable (IBreakpointsTargetDMContext ctx, int[] array) { + super(ctx, "-break-enable"); //$NON-NLS-1$ + if (array != null && array.length > 0) { + String[] brkids = new String[array.length]; + for (int i = 0; i < array.length; i++) { + brkids[i] = Integer.toString(array[i]); + } + setParameters(brkids); + } + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIBreakInsert.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIBreakInsert.java new file mode 100644 index 00000000000..79446d9b165 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIBreakInsert.java @@ -0,0 +1,120 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; +import org.eclipse.dd.mi.service.command.output.MIBreakInsertInfo; +import org.eclipse.dd.mi.service.command.output.MIOutput; + +/** + * -break-insert [ -t ] [ -h ] [ -r ] + * [ -c CONDITION ] [ -i IGNORE-COUNT ] + * [ -p THREAD ] [ LINE | ADDR ] + * + * If specified, LINE, can be one of: + * * function + * * filename:linenum + * * filename:function + * * *address + * + * The possible optional parameters of this command are: + * + * '-t' + * Insert a temporary breakpoint. + * + * '-h' + * Insert a hardware breakpoint. + * + * '-r' + * Insert a regular breakpoint in all the functions whose names match + * the given regular expression. Other flags are not applicable to + * regular expression. + * + * '-c CONDITION' + * Make the breakpoint conditional on CONDITION. + * + * '-i IGNORE-COUNT' + * Initialize the IGNORE-COUNT (number of breakpoint hits before breaking). + * + * '-p THREAD' + * THREAD on which to apply the breakpoint + */ +public class MIBreakInsert extends MICommand +{ + public MIBreakInsert(IBreakpointsTargetDMContext ctx, String func) { + this(ctx, false, false, null, 0, func, 0); + } + + public MIBreakInsert(IBreakpointsTargetDMContext ctx, boolean isTemporary, boolean isHardware, + String condition, int ignoreCount, String line, int tid) { + super(ctx, "-break-insert"); //$NON-NLS-1$ + + // Determine the number of optional parameters that are present + // and allocate a corresponding string array + int i = 0; + if (isTemporary) { + i++; + } + if (isHardware) { + i++; + } + if (condition != null && condition.length() > 0) { + i += 2; + } + if (ignoreCount > 0) { + i += 2; + } + if (tid > 0) { + i += 2; + } + String[] opts = new String[i]; + + // Fill in the optional parameters + i = 0; + if (isTemporary) { + opts[i] = "-t"; //$NON-NLS-1$ + i++; + } + if (isHardware) { + opts[i] = "-h"; //$NON-NLS-1$ + i++; + } + if (condition != null && condition.length() > 0) { + opts[i] = "-c"; //$NON-NLS-1$ + i++; + opts[i] = condition; + i++; + } + if (ignoreCount > 0) { + opts[i] = "-i"; //$NON-NLS-1$ + i++; + opts[i] = Integer.toString(ignoreCount); + i++; + } + if (tid > 0) { + opts[i] = "-p"; //$NON-NLS-1$ + i++; + opts[i] = Integer.toString(tid); + } + + if (opts.length > 0) { + setOptions(opts); + } + setParameters(new String[]{line}); + } + + @Override + public MIBreakInsertInfo getResult(MIOutput output) { + return new MIBreakInsertInfo(output); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIBreakList.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIBreakList.java new file mode 100644 index 00000000000..b3472ca9f50 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIBreakList.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; +import org.eclipse.dd.mi.service.command.output.MIBreakListInfo; +import org.eclipse.dd.mi.service.command.output.MIOutput; + +/** + * + * -break-list + * + * Displays the list of inserted breakpoints, showing the following + * fields: + * + * `Number' + * number of the breakpoint + * + * `Type' + * type of the breakpoint: `breakpoint' or `watchpoint' + * + * `Disposition' + * should the breakpoint be deleted or disabled when it is hit: `keep' + * or `nokeep' + * + * `Enabled' + * is the breakpoint enabled or no: `y' or `n' + * + * `Address' + * memory location at which the breakpoint is set + * + * `What' + * logical location of the breakpoint, expressed by function name, + * + * `Times' + * number of times the breakpoint has been hit + * + * If there are no breakpoints or watchpoints, the `BreakpointTable' + * `body' field is an empty list. + * + */ +public class MIBreakList extends MICommand +{ + public MIBreakList (IBreakpointsTargetDMContext ctx) { + super(ctx, "-break-list"); //$NON-NLS-1$ + } + + @Override + public MIBreakListInfo getResult(MIOutput output) { + return new MIBreakListInfo(output); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIBreakWatch.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIBreakWatch.java new file mode 100644 index 00000000000..18aa0c94b06 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIBreakWatch.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2007 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; +import org.eclipse.dd.mi.service.command.output.MIBreakInsertInfo; +import org.eclipse.dd.mi.service.command.output.MIOutput; + +/** + * -break-watch [ -a | -r ] LOCATION + * + * Create a watchpoint on LOCATION. Without either of the options, the watchpoint + * created is a regular watchpoint, i.e., a watchpoint that triggers when the + * memory LOCATION is accessed for writing. + + * The possible optional parameters of this command are: + * + * '-a' + * Creates an access watchpoint i.e. a watchpoint that triggers either + * on a read from or on a write to the memory location. + * + * '-r' + * Creates a read watchpoint i.e. a watchpoint that triggers only when + * the memory location is accessed for reading. + */ +public class MIBreakWatch extends MICommand +{ + public MIBreakWatch(IBreakpointsTargetDMContext ctx, boolean isRead, boolean isWrite, String expression) + { + super(ctx, "-break-watch"); //$NON-NLS-1$ + + if (isRead) { + if (isWrite) + setOptions(new String[] { "-a" }); //$NON-NLS-1$ + else + setOptions(new String[] { "-r" }); //$NON-NLS-1$ + } + + setParameters(new String[]{ expression }); + } + + @Override + public MIBreakInsertInfo getResult(MIOutput output) { + return new MIBreakInsertInfo(output); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MICommand.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MICommand.java new file mode 100644 index 00000000000..bc85b408536 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MICommand.java @@ -0,0 +1,256 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + * Ericsson - Modified for additional features in DSF Reference implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.command.ICommand; +import org.eclipse.dd.dsf.debug.service.command.ICommandResult; +import org.eclipse.dd.mi.service.command.MIControlDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; +import org.eclipse.dd.mi.service.command.output.MIOutput; + +/** + * Represents any MI command. + */ +public class MICommand implements ICommand { + + /* + * Variables. + */ + final static String[] empty = new String[0]; + + String[] fOptions = empty; + String[] fParameters = empty; + String fOperation = new String(); + IDMContext fCtx; + + /* + * Constructors. + */ + + /*public DsfMICommand(String operation) { + this(operation, empty, empty); + }*/ + + public MICommand(IDMContext ctx, String operation) { + this(ctx, operation, empty, empty); + } + + /*public DsfMICommand(String operation, String[] options) { + this(operation, options, empty); + }*/ + + public MICommand(IDMContext ctx, String operation, String[] options) { + this(ctx, operation, options, empty); + } + + public MICommand(IDMContext ctx, String operation, String[] options, String[] params) { + assert(ctx != null && DMContexts.getAncestorOfType(ctx, MIControlDMContext.class) != null); + fCtx = ctx; + fOperation = operation; + fOptions = options; + fParameters = params; + } + + public String getCommandControlFilter() { + MIControlDMContext controlDmc = DMContexts.getAncestorOfType(getContext(), MIControlDMContext.class); + return controlDmc.getCommandControlFilter(); + } + + /* + * Returns the operation of this command. + */ + public String getOperation() { + return fOperation; + } + + /* + * Returns an array of command's options. An empty collection is + * returned if there are no options. + */ + public String[] getOptions() { + return fOptions; + } + + public void setOptions(String[] options) { + fOptions = options; + } + + /* + * Returns an array of command's parameters. An empty collection is + * returned if there are no parameters. + */ + public String[] getParameters() { + return fParameters; + } + + public void setParameters(String[] params) { + fParameters = params; + } + + /* + * Returns the constructed command. + */ + public String constructCommand() { + StringBuffer command = new StringBuffer(getOperation()); + String opt = optionsToString(); + if (opt.length() > 0) { + command.append(' ').append(opt); + } + String p = parametersToString(); + if (p.length() > 0) { + command.append(' ').append(p); + } + command.append('\n'); + return command.toString(); + } + +// /* +// * Checks to see if the current command can be coalesced with the +// * supplied command. +// */ +// public boolean canCoalesce( ICommand command ) { +// return false ; +// } + + /* + * Takes the supplied command and coalesces it with this one. + * The result is a new third command which represent the two + * original command. + */ + public ICommand coalesceWith( ICommand command ) { + return null ; + } + + + public IDMContext getContext(){ + return fCtx; + } + /** + * Produces the corresponding ICommandResult result for this + * command. + * + * @return result for this command + */ + public MIInfo getResult(MIOutput MIresult) { + return ( new MIInfo(MIresult) ); + } + + protected String optionsToString() { + String[] options = getOptions(); + StringBuffer sb = new StringBuffer(); + if (options != null && options.length > 0) { + for (int i = 0; i < options.length; i++) { + String option = options[i]; + // If the option argument contains " or \ it must be escaped + if (option.indexOf('"') != -1 || option.indexOf('\\') != -1) { + StringBuffer buf = new StringBuffer(); + for (int j = 0; j < option.length(); j++) { + char c = option.charAt(j); + if (c == '"' || c == '\\') { + buf.append('\\'); + } + buf.append(c); + } + option = buf.toString(); + } + + // If the option contains a space according to + // GDB/MI spec we must surround it with double quotes. + if (option.indexOf('\t') != -1 || option.indexOf(' ') != -1) { + sb.append(' ').append('"').append(option).append('"'); + } else { + sb.append(' ').append(option); + } + } + } + return sb.toString().trim(); + } + + protected String parametersToString() { + String[] parameters = getParameters(); + String[] options = getOptions(); + StringBuffer buffer = new StringBuffer(); + if (parameters != null && parameters.length > 0) { + // According to GDB/MI spec + // Add a "--" separator if any parameters start with "-" + if (options != null && options.length > 0) { + for (int i = 0; i < parameters.length; i++) { + if (parameters[i].startsWith("-")) { //$NON-NLS-1$ + buffer.append('-').append('-'); + break; + } + } + } + + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < parameters.length; i++) { + // We need to escape the double quotes and the backslash. + sb.setLength(0); + String param = parameters[i]; + for (int j = 0; j < param.length(); j++) { + char c = param.charAt(j); + if (c == '"' || c == '\\') { + sb.append('\\'); + } + sb.append(c); + } + + // If the string contains spaces instead of escaping + // surround the parameter with double quotes. + if (containsWhitespace(param)) { + sb.insert(0, '"'); + sb.append('"'); + } + buffer.append(' ').append(sb); + } + } + return buffer.toString().trim(); + } + + protected boolean containsWhitespace(String s) { + for (int i = 0; i < s.length(); i++) { + if (Character.isWhitespace(s.charAt(i))) { + return true; + } + } + return false; + } + + + /** + * Compare commands based on the MI command string that they generate, + * without the token. + */ + @Override + public boolean equals(Object obj) { + if(obj instanceof MICommand){ + MICommand otherCmd = (MICommand)obj; + return ((fCtx == null && otherCmd.fCtx == null) || (fCtx != null && fCtx.equals(otherCmd.fCtx))) && + constructCommand().equals(otherCmd.constructCommand()); + } + return false; + } + + @Override + public int hashCode() { + return constructCommand().hashCode(); + } + + @Override + public String toString() { + return constructCommand(); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIDataEvaluateExpression.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIDataEvaluateExpression.java new file mode 100644 index 00000000000..bedf2308805 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIDataEvaluateExpression.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; +import org.eclipse.dd.mi.service.IMIExecutionDMContext; +import org.eclipse.dd.mi.service.command.MIControlDMContext; +import org.eclipse.dd.mi.service.command.output.MIDataEvaluateExpressionInfo; +import org.eclipse.dd.mi.service.command.output.MIOutput; + +/** + * + * -data-evaluate-expression EXPR + * + * Evaluate EXPR as an expression. The expression could contain an + *inferior function call. The function call will execute synchronously. + *If the expression contains spaces, it must be enclosed in double quotes. + * + */ +public class MIDataEvaluateExpression extends MICommand +{ + public MIDataEvaluateExpression(MIControlDMContext ctx, String expr) { + super(ctx, "-data-evaluate-expression", new String[]{expr}); //$NON-NLS-1$ + } + + public MIDataEvaluateExpression(IMIExecutionDMContext execDmc, String expr) { + super(execDmc, "-data-evaluate-expression", new String[]{expr}); //$NON-NLS-1$ + } + + public MIDataEvaluateExpression(IFrameDMContext frameDmc, String expr) { + super(frameDmc, "-data-evaluate-expression", new String[]{expr}); //$NON-NLS-1$ + } + + public MIDataEvaluateExpression(IExpressionDMContext exprDmc) { + super(exprDmc, "-data-evaluate-expression", new String[]{exprDmc.getExpression()}); //$NON-NLS-1$ + } + + @Override + public MIDataEvaluateExpressionInfo getResult(MIOutput output) { + return new MIDataEvaluateExpressionInfo(output); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIDataListRegisterNames.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIDataListRegisterNames.java new file mode 100644 index 00000000000..4152a33006c --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIDataListRegisterNames.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.dd.mi.service.command.output.MIDataListRegisterNamesInfo; +import org.eclipse.dd.mi.service.command.output.MIOutput; + +/** + * + * -data-list-register-names [ ( REGNO )+ ] + * + * Show a list of register names for the current target. If no + * arguments are given, it shows a list of the names of all the registers. + * If integer numbers are given as arguments, it will print a list of the + * names of the registers corresponding to the arguments. To ensure + * consistency between a register name and its number, the output list may + * include empty register names. + * + */ +public class MIDataListRegisterNames extends MICommand +{ + public MIDataListRegisterNames(IContainerDMContext ctx) { + super(ctx, "-data-list-register-names"); //$NON-NLS-1$ + } + + public MIDataListRegisterNames(IContainerDMContext ctx, int [] regnos) { + this(ctx); + if (regnos != null && regnos.length > 0) { + String[] array = new String[regnos.length]; + for (int i = 0; i < regnos.length; i++) { + array[i] = Integer.toString(regnos[i]); + } + setParameters(array); + } + } + + @Override + public MIDataListRegisterNamesInfo getResult(MIOutput output) { + return new MIDataListRegisterNamesInfo(output); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIDataListRegisterValues.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIDataListRegisterValues.java new file mode 100644 index 00000000000..a3d6031bf92 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIDataListRegisterValues.java @@ -0,0 +1,145 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.debug.service.command.ICommand; +import org.eclipse.dd.dsf.debug.service.command.ICommandResult; +import org.eclipse.dd.mi.service.MIFormat; +import org.eclipse.dd.mi.service.IMIExecutionDMContext; +import org.eclipse.dd.mi.service.command.output.MIDataListRegisterValuesInfo; +import org.eclipse.dd.mi.service.command.output.MIOutput; + +/** + * + * -data-list-register-values FMT [ ( REGNO )*] + * + * Display the registers' contents. FMT is the format according to + * which the registers' contents are to be returned, followed by an + * optional list of numbers specifying the registers to display. A + * missing list of numbers indicates that the contents of all the + * registers must be returned. + * + */ +public class MIDataListRegisterValues extends MICommand { + + int[] regnums; + int fFmt; + + public MIDataListRegisterValues(IMIExecutionDMContext ctx, int fmt) { + this(ctx, fmt, null); + } + + public MIDataListRegisterValues(IMIExecutionDMContext ctx, int fmt, int [] regnos) { + super(ctx, "-data-list-register-values"); //$NON-NLS-1$ + regnums = regnos; + + String format = "x"; //$NON-NLS-1$ + switch (fmt) { + case MIFormat.NATURAL: format = "N"; break ; //$NON-NLS-1$ + case MIFormat.RAW: format = "r"; break ; //$NON-NLS-1$ + case MIFormat.DECIMAL: format = "d"; break ; //$NON-NLS-1$ + case MIFormat.BINARY: format = "t"; break ; //$NON-NLS-1$ + case MIFormat.OCTAL: format = "o"; break ; //$NON-NLS-1$ + case MIFormat.HEXADECIMAL: format = "x"; break ; //$NON-NLS-1$ + default: format = "x"; break ; //$NON-NLS-1$ + } + + fFmt = fmt; + + setOptions(new String[]{format}); + + if (regnos != null && regnos.length > 0) { + String[] array = new String[regnos.length]; + for (int i = 0; i < regnos.length; i++) { + array[i] = Integer.toString(regnos[i]); + } + setParameters(array); + } + } + + public int[] getRegList() { + return regnums; + } + + @Override + public MIDataListRegisterValuesInfo getResult(MIOutput output) { + return new MIDataListRegisterValuesInfo(output); + } + + /* + * Takes the supplied command and coalesces it with this one. + * The result is a new third command which represent the two + * original command. + */ + @Override + public MIDataListRegisterValues coalesceWith(ICommand command ) { + /* + * Can coalesce only with other DsfMIDataListRegisterValues commands. + */ + if (! (command instanceof MIDataListRegisterValues) ) return null; + + MIDataListRegisterValues cmd = (MIDataListRegisterValues) command; + + int[] newregnos = new int[ regnums.length + cmd.regnums.length]; + + /* + * We need to add the new register #'s to the list. If one is already there + * then do not add it twice. So copy the original list of this command. + */ + + for ( int idx = 0 ; idx < regnums.length ; idx ++) { + newregnos[ idx ] = regnums[ idx ]; + } + + int curloc = regnums.length; + + for ( int ndx = 0 ; ndx < cmd.regnums.length; ndx ++) { + + int curnum = cmd.regnums[ ndx ] ; + int ldx; + + /* + * Search the current list to see if this entry is in it. + */ + + for ( ldx = 0 ; ldx < regnums.length; ldx ++ ) { + if ( newregnos[ ldx ] == curnum ) { + break ; + } + } + + if ( ldx == regnums.length ) { + + /* + * Since we did not find a match add it at the end of the list. + */ + newregnos[ curloc ] = curnum; + curloc ++; + } + } + + /* + * Create a final proper array set of the new combined list. + */ + int[] finalregnums = new int[ curloc ] ; + + for ( int fdx = 0 ; fdx < curloc ; fdx ++ ) { + finalregnums[ fdx ] = newregnos[ fdx ]; + } + + /* + * Now construct a new one. The format we will use is this command. + */ + return( new MIDataListRegisterValues((IMIExecutionDMContext)getContext(), fFmt, finalregnums)); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIDataReadMemory.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIDataReadMemory.java new file mode 100644 index 00000000000..2a7a8880260 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIDataReadMemory.java @@ -0,0 +1,150 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Ericsson AB - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.mi.service.MIFormat; +import org.eclipse.dd.mi.service.command.output.MIDataReadMemoryInfo; +import org.eclipse.dd.mi.service.command.output.MIOutput; + +/** + * -data-read-memory [ -o BYTE-OFFSET ] + * ADDRESS WORD-FORMAT WORD-SIZE + * NR-ROWS NR-COLS [ ASCHAR ] + * + * where: + * + * 'ADDRESS' + * An expression specifying the address of the first memory word to be + * read. Complex expressions containing embedded white space should + * be quoted using the C convention. + * + * 'WORD-FORMAT' + * The format to be used to print the memory words. The notation is + * the same as for GDB's `print' command (*note Output formats: + * Output Formats.). + * + * 'WORD-SIZE' + * The size of each memory word in bytes. + * + * 'NR-ROWS' + * The number of rows in the output table. + * + * 'NR-COLS' + * The number of columns in the output table. + * + * 'ASCHAR' + * If present, indicates that each row should include an ASCII dump. + * The value of ASCHAR is used as a padding character when a byte is + * not a member of the printable ASCII character set (printable ASCII + * characters are those whose code is between 32 and 126, + * inclusively). + * + * 'BYTE-OFFSET' + * An offset to add to ADDRESS before fetching the memory. + * + */ +public class MIDataReadMemory extends MICommand { + + int fword_size; + + public MIDataReadMemory( + IDMContext ctx, + long offset, + String address, + int word_format, + int word_size, + int rows, + int cols, + Character asChar) + { + super(ctx, "-data-read-memory"); //$NON-NLS-1$ + + // Save this for the result parser + fword_size = word_size; + + if (offset != 0) { + setOptions(new String[] { "-o", Long.toString(offset * word_size)}); //$NON-NLS-1$ + } + + String format = "x"; //$NON-NLS-1$ + switch (word_format) { + case MIFormat.UNSIGNED : + format = "u"; //$NON-NLS-1$ + break; + + case MIFormat.FLOAT : + format = "f"; //$NON-NLS-1$ + break; + + case MIFormat.ADDRESS : + format = "a"; //$NON-NLS-1$ + break; + + case MIFormat.INSTRUCTION : + format = "i"; //$NON-NLS-1$ + break; + + case MIFormat.CHAR : + format = "c"; //$NON-NLS-1$ + break; + + case MIFormat.STRING : + format = "s"; //$NON-NLS-1$ + break; + + case MIFormat.DECIMAL : + case MIFormat.NATURAL : + format = "d"; //$NON-NLS-1$ + break; + + case MIFormat.BINARY : + format = "t"; //$NON-NLS-1$ + break; + + case MIFormat.OCTAL : + format = "o"; //$NON-NLS-1$ + break; + + case MIFormat.HEXADECIMAL : + case MIFormat.RAW : + default : + format = "x"; //$NON-NLS-1$ + break; + } + + if (asChar == null) { + setParameters( + new String[] { + address, + format, + Integer.toString(1), // wordSize + Integer.toString(rows), + Integer.toString(cols * word_size)}); + } else { + setParameters( + new String[] { + address, + format, + Integer.toString(1), // wordSize + Integer.toString(rows), + Integer.toString(cols * word_size), + asChar.toString()}); + } + } + + @Override + public MIDataReadMemoryInfo getResult(MIOutput out) { + return new MIDataReadMemoryInfo(out, fword_size); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIDataWriteMemory.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIDataWriteMemory.java new file mode 100644 index 00000000000..383e94bc60a --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIDataWriteMemory.java @@ -0,0 +1,118 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Ericsson Communication - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.mi.service.MIFormat; +import org.eclipse.dd.mi.service.command.output.MIDataWriteMemoryInfo; +import org.eclipse.dd.mi.service.command.output.MIOutput; + +/** + * -data-write-memory [ -o COLUMN_OFFSET ] + * ADDRESS WORD-FORMAT WORD-SIZE VALUE + * + * where: + * + * 'COLUMN_OFFSET' + * The cell offset from the beginning of the memory grid row + * + * 'ADDRESS' + * Row address of the cell to be written + * + * 'WORD-FORMAT' + * The format to be used to print the memory words + * + * 'WORD-SIZE' + * The size of each memory word in bytes + * + * 'VALUE' + * The value to be written into the cell + * + * Writes VALUE into ADDRESS + (COLUMN_OFFSET * WORD_SIZE). + * + */ +public class MIDataWriteMemory extends MICommand { + + public MIDataWriteMemory( + IDMContext ctx, + long offset, + String address, + int wordFormat, + int wordSize, + String value) + { + super(ctx, "-data-write-memory"); //$NON-NLS-1$ + + if (offset != 0) { + setOptions(new String[] { "-o", Long.toString(offset)}); //$NON-NLS-1$ + } + + String format = "x"; //$NON-NLS-1$ + switch (wordFormat) { + case MIFormat.UNSIGNED : + format = "u"; //$NON-NLS-1$ + break; + + case MIFormat.FLOAT : + format = "f"; //$NON-NLS-1$ + break; + + case MIFormat.ADDRESS : + format = "a"; //$NON-NLS-1$ + break; + + case MIFormat.INSTRUCTION : + format = "i"; //$NON-NLS-1$ + break; + + case MIFormat.CHAR : + format = "c"; //$NON-NLS-1$ + break; + + case MIFormat.STRING : + format = "s"; //$NON-NLS-1$ + break; + + case MIFormat.DECIMAL : + case MIFormat.NATURAL : + format = "d"; //$NON-NLS-1$ + break; + + case MIFormat.BINARY : + format = "t"; //$NON-NLS-1$ + break; + + case MIFormat.OCTAL : + format = "o"; //$NON-NLS-1$ + break; + + case MIFormat.HEXADECIMAL : + case MIFormat.RAW : + default : + format = "x"; //$NON-NLS-1$ + break; + } + + setParameters( + new String[] { + address, + format, + Integer.toString(wordSize), + value}); + } + + @Override + public MIDataWriteMemoryInfo getResult(MIOutput out) { + return new MIDataWriteMemoryInfo(out); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecContinue.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecContinue.java new file mode 100644 index 00000000000..031cbe38e9a --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecContinue.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; + +/** + * + * -exec-continue + * + * Asynchronous command. Resumes the execution of the inferior program + * until a breakpoint is encountered, or until the inferior exits. + * + */ +public class MIExecContinue extends MICommand +{ + public MIExecContinue(IExecutionDMContext dmc) { + super(dmc, "-exec-continue"); //$NON-NLS-1$ + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecFinish.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecFinish.java new file mode 100644 index 00000000000..59e18ce7d3e --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecFinish.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + * Ericsson - Modified for handling of execution contexts + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; + +/** + * -exec-finish + *

    + * Asynchronous command. Resumes the execution of the inferior program + * until the current function is exited. Displays the results returned by + * the function. + *

    + *

    + * The -exec-finish command operates on the selected stack + * frame. Therefore the constructor requires a stack frame context. + *

    + * + */ +public class MIExecFinish extends MICommand +{ + public MIExecFinish(IFrameDMContext dmc) { + super(dmc, "-exec-finish"); //$NON-NLS-1$ + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecInterrupt.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecInterrupt.java new file mode 100644 index 00000000000..fd38aa16b23 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecInterrupt.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + * Ericsson AB - Modified for Execution Contexts + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; + +/** + * + * -exec-interrupt + * + * Asynchronous command. Interrupts the background execution of the + * target. Note how the token associated with the stop message is the one + * for the execution command that has been interrupted. The token for the + * interrupt itself only appears in the `^done' output. If the user is + * trying to interrupt a non-running program, an error message will be + * printed. + * + */ +public class MIExecInterrupt extends MICommand +{ + public MIExecInterrupt(IExecutionDMContext dmc) { + super(dmc, "-exec-interrupt"); //$NON-NLS-1$ + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecNext.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecNext.java new file mode 100644 index 00000000000..25617b1152c --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecNext.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + * Ericsson - Modified for handling of execution contexts + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; + +/** + * + * -exec-next + * + * Asynchronous command. Resumes execution of the inferior program, + * stopping when the beginning of the next source line is reached. + * + */ +public class MIExecNext extends MICommand +{ + public MIExecNext(IExecutionDMContext dmc) { + super(dmc, "-exec-next"); //$NON-NLS-1$ + } + + public MIExecNext(IExecutionDMContext dmc, int count) { + super(dmc, "-exec-next", new String[] { Integer.toString(count) }); //$NON-NLS-1$ + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecNextInstruction.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecNextInstruction.java new file mode 100644 index 00000000000..0bcf2c83b4e --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecNextInstruction.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; + +/** + * + * -exec-next-instruction + * + * Asynchronous command. Executes one machine instruction. If the + * instruction is a function call continues until the function returns. If + * the program stops at an instruction in the middle of a source line, the + * address will be printed as well. + * + */ +public class MIExecNextInstruction extends MICommand +{ + public MIExecNextInstruction(IExecutionDMContext dmc) { + super(dmc, "-exec-next-instruction"); //$NON-NLS-1$ + } + + public MIExecNextInstruction(IExecutionDMContext dmc, int count) { + super(dmc, "-exec-next-instruction", new String[] { Integer.toString(count) }); //$NON-NLS-1$ + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecReturn.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecReturn.java new file mode 100644 index 00000000000..689c4a2fa02 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecReturn.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; + +/** + * + * -exec-return + * + *

    + * Makes current function return immediately. Doesn't execute the + * inferior. Displays the new current frame. + *

    + *

    + * The -exec-return command operates on the selected stack + * frame. Therefore the constructor requires a stack frame context. + *

    + * + */ +public class MIExecReturn extends MICommand +{ + public MIExecReturn(IFrameDMContext dmc) { + super(dmc, "-exec-return"); //$NON-NLS-1$ + } + + public MIExecReturn(IFrameDMContext dmc, String arg) { + super(dmc, "-exec-return", new String[] { arg }); //$NON-NLS-1$ + } + +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecRun.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecRun.java new file mode 100644 index 00000000000..a5c683a980d --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecRun.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + * Ericsson - Modified for handling of execution contexts + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; + +/** + * + * -exec-run + * + * Asynchronous command. Starts execution of the inferior from the + * beginning. The inferior executes until either a breakpoint is + * encountered or the program exits. + * + */ +public class MIExecRun extends MICommand +{ + public MIExecRun(IExecutionDMContext dmc) { + super(dmc, "-exec-run"); //$NON-NLS-1$ + } + + public MIExecRun(IExecutionDMContext dmc, String[] args) { + super(dmc, "-exec-run", args); //$NON-NLS-1$ + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecStep.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecStep.java new file mode 100644 index 00000000000..9ed7b0f474e --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecStep.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + * Ericsson - Modified for handling of execution contexts + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; + +/** + * + * -exec-step + * + * Asynchronous command. Resumes execution of the inferior program, + * stopping when the beginning of the next source line is reached, if the + * next source line is not a function call. If it is, stop at the first + * instruction of the called function. + * + */ +public class MIExecStep extends MICommand +{ + public MIExecStep(IExecutionDMContext dmc) { + super(dmc, "-exec-step"); //$NON-NLS-1$ + } + + public MIExecStep(IExecutionDMContext dmc, int count) { + super(dmc, "-exec-step", new String[] { Integer.toString(count) }); //$NON-NLS-1$ + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecStepInstruction.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecStepInstruction.java new file mode 100644 index 00000000000..9d4087b95e9 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecStepInstruction.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; + +/** + * + * -exec-step-instruction + + * Asynchronous command. Resumes the inferior which executes one + * machine instruction. The output, once GDB has stopped, will vary + * depending on whether we have stopped in the middle of a source line or + * not. In the former case, the address at which the program stopped will + * be printed as well. + * + */ +public class MIExecStepInstruction extends MICommand +{ + public MIExecStepInstruction(IExecutionDMContext dmc) { + super(dmc, "-exec-step-instruction"); //$NON-NLS-1$ + } + + public MIExecStepInstruction(IExecutionDMContext dmc, int count) { + super(dmc, "-exec-step-instruction", new String[] { Integer.toString(count) }); //$NON-NLS-1$ + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecUntil.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecUntil.java new file mode 100644 index 00000000000..57b57855267 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecUntil.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + * Ericsson - Modified for handling of execution contexts + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; + +/** + * + * -exec-until [ LOCATION ] + * + * Asynchronous command. Executes the inferior until the LOCATION + * specified in the argument is reached. If there is no argument, the + * inferior executes until a source line greater than the current one is + * reached. The reason for stopping in this case will be + * `location-reached'. + * + */ +public class MIExecUntil extends MICommand +{ + public MIExecUntil(IExecutionDMContext dmc) { + super(dmc, "-exec-until"); //$NON-NLS-1$ + } + + public MIExecUntil(IExecutionDMContext dmc, String loc) { + super(dmc, "-exec-until", new String[]{loc}); //$NON-NLS-1$ + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIGDBExit.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIGDBExit.java new file mode 100644 index 00000000000..f3131dfc3d0 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIGDBExit.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; + +/** + * + * -gdb-exit + * + * Exit GDB immediately. + * + */ +public class MIGDBExit extends MICommand +{ + public MIGDBExit(IDMContext ctx) { + super(ctx, "-gdb-exit"); //$NON-NLS-1$ + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIGDBShowExitCode.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIGDBShowExitCode.java new file mode 100644 index 00000000000..f57291136c3 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIGDBShowExitCode.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.mi.service.command.MIControlDMContext; +import org.eclipse.dd.mi.service.command.output.MIGDBShowExitCodeInfo; +import org.eclipse.dd.mi.service.command.output.MIOutput; + +/** + * + *-data-evaluate-expression $_exitcode + * ^done,value="10" + * + * Show the current value of a $_exitcode + * + */ +public class MIGDBShowExitCode extends MIDataEvaluateExpression { + + public MIGDBShowExitCode(MIControlDMContext ctx) { + super(ctx, "$_exitcode"); //$NON-NLS-1$ + } + + @Override + public MIGDBShowExitCodeInfo getResult(MIOutput output) { + return new MIGDBShowExitCodeInfo(output); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIInterpreterExec.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIInterpreterExec.java new file mode 100644 index 00000000000..b355f2443b1 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIInterpreterExec.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + * Ericsson - Modified for additional features in DSF Reference implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; + +/** + * MIInterpreterExec + * + * -interpreter-exec + * + * -interpreter-exec interpreter command + * + * Execute the specified command in the given interpreter. + * + * -interpreter-exec console "break main" + * &"During symbol reading, couldn't parse type; debugger out of date?.\n" + * &"During symbol reading, bad structure-type format.\n" + * ~"Breakpoint 1 at 0x8074fc6: file ../../src/gdb/main.c, line 743.\n" + * ^done + * + */ +public class MIInterpreterExec extends MICommand { + + /** + * @param oper + */ + public MIInterpreterExec(IDMContext ctx, String interpreter, String cmd) { + super(ctx, "-interpreter-exec", new String[]{interpreter}, new String[] {cmd}); //$NON-NLS-1$ + } + +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIInterpreterExecConsole.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIInterpreterExecConsole.java new file mode 100644 index 00000000000..c635a4f4dd3 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIInterpreterExecConsole.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + * Ericsson - Modified for additional features in DSF Reference implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; + +/** + * MIInterpreterExecConsole + */ +public class MIInterpreterExecConsole extends MIInterpreterExec { + + /** + * @param interpreter + * @param cmd + */ + public MIInterpreterExecConsole(IDMContext ctx, String cmd) { + super(ctx, "console", cmd); //$NON-NLS-1$ + } + +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIStackInfoDepth.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIStackInfoDepth.java new file mode 100644 index 00000000000..c0f7a8b63bb --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIStackInfoDepth.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2007 Ericsson 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: + * Ericsson - Initial Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.mi.service.IMIExecutionDMContext; +import org.eclipse.dd.mi.service.command.output.MIOutput; +import org.eclipse.dd.mi.service.command.output.MIStackInfoDepthInfo; + +/** + * + * -stack-info-depth [maxDepth] + * + * + */ +public class MIStackInfoDepth extends MICommand +{ + + public MIStackInfoDepth(IMIExecutionDMContext ctx) { + super(ctx, "-stack-info-depth"); //$NON-NLS-1$ + } + + public MIStackInfoDepth(IMIExecutionDMContext ctx, int maxDepth) { + super(ctx, "-stack-info-depth", new String[]{Integer.toString(maxDepth)}); //$NON-NLS-1$ + } + + @Override + public MIStackInfoDepthInfo getResult(MIOutput out) { + return new MIStackInfoDepthInfo(out); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIStackListArguments.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIStackListArguments.java new file mode 100644 index 00000000000..d9778e91fec --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIStackListArguments.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + * Ericsson - Modified for handling of execution contexts + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; +import org.eclipse.dd.mi.service.IMIExecutionDMContext; +import org.eclipse.dd.mi.service.command.output.MIOutput; +import org.eclipse.dd.mi.service.command.output.MIStackListArgumentsInfo; + +/** + * + * -stack-list-arguments SHOW-VALUES + * [ LOW-FRAME HIGH-FRAME ] + * + * Display a list of the arguments for the frames between LOW-FRAME and + * HIGH-FRAME (inclusive). If LOW-FRAME and HIGH-FRAME are not provided, + * list the arguments for the whole call stack. + * + * The SHOW-VALUES argument must have a value of 0 or 1. A value of 0 + * means that only the names of the arguments are listed, a value of 1 + * means that both names and values of the arguments are printed. + * + */ +public class MIStackListArguments extends MICommand +{ + public MIStackListArguments(IMIExecutionDMContext execDmc, boolean showValues) { + super(execDmc, "-stack-list-arguments"); //$NON-NLS-1$ + if (showValues) { + setParameters(new String[]{"1"}); //$NON-NLS-1$ + } else { + setParameters(new String[]{"0"}); //$NON-NLS-1$ + } + } + + public MIStackListArguments(IFrameDMContext frameDmc, boolean showValues) { + super(frameDmc, "-stack-list-arguments"); //$NON-NLS-1$ + if (showValues) { + setParameters(new String[]{"1"}); //$NON-NLS-1$ + } else { + setParameters(new String[]{"0"}); //$NON-NLS-1$ + } + } + + public MIStackListArguments(IMIExecutionDMContext execDmc, boolean showValues, int low, int high) { + super(execDmc, "-stack-list-arguments"); //$NON-NLS-1$ + String[] params = new String[3]; + if (showValues) { + params[0] = "1"; //$NON-NLS-1$ + } else { + params[0] = "0"; //$NON-NLS-1$ + } + params[1] = Integer.toString(low); + params[2] = Integer.toString(high); + setParameters(params); + } + + @Override + public MIStackListArgumentsInfo getResult(MIOutput out) { + return new MIStackListArgumentsInfo(out); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIStackListFrames.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIStackListFrames.java new file mode 100644 index 00000000000..f074292cfab --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIStackListFrames.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + * Ericsson - Modified for handling of Frame contexts + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + + +import org.eclipse.dd.mi.service.IMIExecutionDMContext; +import org.eclipse.dd.mi.service.command.output.MIOutput; +import org.eclipse.dd.mi.service.command.output.MIStackListFramesInfo; + +/** + * + * -stack-list-frames [ LOW-FRAME HIGH-FRAME ] + * + * List the frames currently on the stack. For each frame it displays + * the following info: + * + * `LEVEL' + * The frame number, 0 being the topmost frame, i.e. the innermost + * function. + * + * `ADDR' + * The `$pc' value for that frame. + * + * `FUNC' + * Function name. + * + * `FILE' + * File name of the source file where the function lives. + * + * `FULLNAME' + * Absolute file name of the source file where the function lives. + * @since gdb 6.4 + * + * `LINE' + * Line number corresponding to the `$pc'. + * + * If invoked without arguments, this command prints a backtrace for the + * whole stack. If given two integer arguments, it shows the frames whose + * levels are between the two arguments (inclusive). If the two arguments + * are equal, it shows the single frame at the corresponding level. + * + */ +public class MIStackListFrames extends MICommand +{ + public MIStackListFrames(IMIExecutionDMContext execDmc) { + super(execDmc, "-stack-list-frames"); //$NON-NLS-1$ + } + + public MIStackListFrames(IMIExecutionDMContext execDmc, int low, int high) { + super(execDmc, "-stack-list-frames", new String[]{Integer.toString(low), //$NON-NLS-1$ + Integer.toString(high)}); + } + + @Override + public MIStackListFramesInfo getResult(MIOutput out) { + return new MIStackListFramesInfo(out); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIStackListLocals.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIStackListLocals.java new file mode 100644 index 00000000000..528212bd7ac --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIStackListLocals.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + * Ericsson - Modified for additional features in DSF Reference implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; +import org.eclipse.dd.mi.service.command.output.MIOutput; +import org.eclipse.dd.mi.service.command.output.MIStackListLocalsInfo; + +/** + * + * -stack-list-locals PRINT-VALUES + * + * Display the local variable names for the current frame. With an + * argument of 0 prints only the names of the variables, with argument of 1 + * prints also their values. + * + */ +public class MIStackListLocals extends MICommand +{ + + public MIStackListLocals(IFrameDMContext frameCtx, boolean printValues) { + super(frameCtx, "-stack-list-locals"); //$NON-NLS-1$ + if (printValues) { + setParameters(new String[]{"1"}); //$NON-NLS-1$ + } else { + setParameters(new String[]{"0"}); //$NON-NLS-1$ + } + } + + @Override + public MIStackListLocalsInfo getResult(MIOutput out) { + return new MIStackListLocalsInfo(out); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIStackSelectFrame.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIStackSelectFrame.java new file mode 100644 index 00000000000..aa12b37b68c --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIStackSelectFrame.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Ericsson - Modified for additional features in DSF Reference implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; + + + +/** + * + * -stack-select-frame FRAMENUM + * + * Change the current frame. Select a different frame FRAMENUM on the + * stack. + * + */ +public class MIStackSelectFrame extends MICommand { + + public MIStackSelectFrame(IDMContext ctx, int frameNum) { + super(ctx, "-stack-select-frame", new String[]{Integer.toString(frameNum)}, new String[0]); //$NON-NLS-1$ + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIThreadListIds.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIThreadListIds.java new file mode 100644 index 00000000000..c01996912e9 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIThreadListIds.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Ericsson - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.dd.mi.service.command.output.MIOutput; +import org.eclipse.dd.mi.service.command.output.MIThreadListIdsInfo; + +/** + * + * -thread-list-ids + * + * Produces a list of the currently known GDB thread ids. At the end + * of the list it also prints the total number of such threads. + * + */ +public class MIThreadListIds extends MICommand { + + public MIThreadListIds(IContainerDMContext contDmc) { + super(contDmc, "-thread-list-ids"); //$NON-NLS-1$ + } + + @Override + public MIThreadListIdsInfo getResult(MIOutput out) { + return new MIThreadListIdsInfo(out); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIThreadSelect.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIThreadSelect.java new file mode 100644 index 00000000000..c25fd671079 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIThreadSelect.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Ericsson AB - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; + + +/** + * + * -thread-select THREADNUM + * + * Make THREADNUM the current thread. It prints the number of the new + * current thread, and the topmost frame for that thread. + * + */ + +public class MIThreadSelect extends MICommand +{ + + public MIThreadSelect(IDMContext ctx, int threadNum) { + super(ctx, "-thread-select", new String[]{Integer.toString(threadNum)}); //$NON-NLS-1$ + } + +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarAssign.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarAssign.java new file mode 100644 index 00000000000..54582ba617a --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarAssign.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.mi.service.command.MIControlDMContext; +import org.eclipse.dd.mi.service.command.output.MIOutput; +import org.eclipse.dd.mi.service.command.output.MIVarAssignInfo; + +/** + * + * -var-assign NAME EXPRESSION + * + * Assigns the value of EXPRESSION to the variable object specified by + * NAME. The object must be `editable'. + * + */ +public class MIVarAssign extends MICommand +{ + public MIVarAssign(MIControlDMContext ctx, String name, String expression) { + super(ctx, "-var-assign", new String[]{name, expression}); //$NON-NLS-1$ + } + + @Override + public MIVarAssignInfo getResult(MIOutput out) { + return new MIVarAssignInfo(out); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarCreate.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarCreate.java new file mode 100644 index 00000000000..6e23766bb0d --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarCreate.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + * Ericsson - Modified for handling of contexts + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.dd.mi.service.command.output.MIOutput; +import org.eclipse.dd.mi.service.command.output.MIVarCreateInfo; + + +/** + * + * -var-create {NAME | "-"} + * {FRAME-ADDR | "*"} EXPRESSION + * + * This operation creates a variable object, which allows the + * monitoring of a variable, the result of an expression, a memory cell or + * a CPU register. + * + * The NAME parameter is the string by which the object can be + * referenced. It must be unique. If `-' is specified, the varobj system + * will generate a string "varNNNNNN" automatically. It will be unique + * provided that one does not specify NAME on that format. The command + * fails if a duplicate name is found. + * + * The frame under which the expression should be evaluated can be + * specified by FRAME-ADDR. A `*' indicates that the current frame should + * be used. + * + * EXPRESSION is any expression valid on the current language set (must + * not begin with a `*'), or one of the following: + * + * * `*ADDR', where ADDR is the address of a memory cell + * + * * `*ADDR-ADDR' -- a memory address range (TBD) + * + * * `$REGNAME' -- a CPU register name + * + */ +public class MIVarCreate extends MICommand +{ + public MIVarCreate(IExpressionDMContext dmc, String expression) { + this(dmc, "-", "*", expression); //$NON-NLS-1$ //$NON-NLS-2$ + } + + public MIVarCreate(IExpressionDMContext dmc,String name, String expression) { + this(dmc, name, "*", expression); //$NON-NLS-1$ + } + + public MIVarCreate(IExpressionDMContext dmc, String name, String frameAddr, String expression) { + super(dmc, "-var-create", new String[]{name, frameAddr, expression}); //$NON-NLS-1$ + } + + @Override + public MIVarCreateInfo getResult(MIOutput out) { + return new MIVarCreateInfo(out); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarDelete.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarDelete.java new file mode 100644 index 00000000000..50a7d536437 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarDelete.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.mi.service.command.MIControlDMContext; +import org.eclipse.dd.mi.service.command.output.MIOutput; +import org.eclipse.dd.mi.service.command.output.MIVarDeleteInfo; + +/** + * + * -var-delete NAME + * + * Deletes a previously created variable object and all of its children. + * + * Returns an error if the object NAME is not found. + * + */ +public class MIVarDelete extends MICommand +{ + public MIVarDelete(MIControlDMContext dmc, String name) { + super(dmc, "-var-delete", new String[]{name}); //$NON-NLS-1$ + } + + @Override + public MIVarDeleteInfo getResult(MIOutput out) { + return new MIVarDeleteInfo(out); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarEvaluateExpression.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarEvaluateExpression.java new file mode 100644 index 00000000000..c675988e5b0 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarEvaluateExpression.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + * Ericsson - Modified for handling of frame contexts + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.mi.service.command.MIControlDMContext; +import org.eclipse.dd.mi.service.command.output.MIOutput; +import org.eclipse.dd.mi.service.command.output.MIVarEvaluateExpressionInfo; + +/** + * + * -var-evaluate-expression NAME + * + * Evaluates the expression that is represented by the specified + * variable object and returns its value as a string in the current format + * specified for the object: + * + * value=VALUE + * + */ +public class MIVarEvaluateExpression extends MICommand { + + public MIVarEvaluateExpression(MIControlDMContext dmc, String name) { + super(dmc, "-var-evaluate-expression", new String[] { name }); //$NON-NLS-1$ + } + + @Override + public MIVarEvaluateExpressionInfo getResult(MIOutput out) { + return new MIVarEvaluateExpressionInfo(out); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarInfoExpression.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarInfoExpression.java new file mode 100644 index 00000000000..501e624426f --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarInfoExpression.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.mi.service.command.MIControlDMContext; +import org.eclipse.dd.mi.service.command.output.MIOutput; +import org.eclipse.dd.mi.service.command.output.MIVarInfoExpressionInfo; + +/** + * + * -var-info-expression NAME + * + * Returns what is represented by the variable object NAME: + * + * lang=LANG-SPEC,exp=EXPRESSION + * + * where LANG-SPEC is `{"C" | "C++" | "Java"}'. + * + */ + +//MIVarInfoExpression.java +public class MIVarInfoExpression extends MICommand +{ + public MIVarInfoExpression(MIControlDMContext ctx, String name) { + super(ctx, "-var-info-expression", new String[]{name}); //$NON-NLS-1$ + } + + @Override + public MIVarInfoExpressionInfo getResult(MIOutput out) { + return new MIVarInfoExpressionInfo(out); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarInfoNumChildren.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarInfoNumChildren.java new file mode 100644 index 00000000000..9d9263e6b12 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarInfoNumChildren.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.dd.mi.service.command.output.MIOutput; +import org.eclipse.dd.mi.service.command.output.MIVarInfoNumChildrenInfo; + +/** + * + * -var-info-num-children NAME + * + * Returns the number of children of a variable object NAME: + * + * numchild=N + * + */ +public class MIVarInfoNumChildren extends MICommand +{ + public MIVarInfoNumChildren(IExpressionDMContext ctx, String name) { + super(ctx, "-var-info-num-children", new String[]{name}); //$NON-NLS-1$ + } + + @Override + public MIVarInfoNumChildrenInfo getResult(MIOutput out) { + return new MIVarInfoNumChildrenInfo(out); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarInfoPathExpression.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarInfoPathExpression.java new file mode 100644 index 00000000000..5338871e7ae --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarInfoPathExpression.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2007 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.mi.service.command.MIControlDMContext; +import org.eclipse.dd.mi.service.command.output.MIOutput; +import org.eclipse.dd.mi.service.command.output.MIVarInfoPathExpressionInfo; + +/** + * + * -var-info-path-expression NAME + * + * as of GDB 6.7 + * + * Print full expression that this variable object represents: + * + * (gdb) -var-info-path-expression C.Base.public.m_size + * ^done,path_expr=((Base)c).m_size) + * + */ + +public class MIVarInfoPathExpression extends MICommand +{ + public MIVarInfoPathExpression(MIControlDMContext dmc, String name) { + super(dmc, "-var-info-path-expression", new String[]{name}); //$NON-NLS-1$ + } + + @Override + public MIVarInfoPathExpressionInfo getResult(MIOutput out) { + return new MIVarInfoPathExpressionInfo(out); + } +} + diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarInfoType.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarInfoType.java new file mode 100644 index 00000000000..027da7880ae --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarInfoType.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.mi.service.command.MIControlDMContext; +import org.eclipse.dd.mi.service.command.output.MIOutput; +import org.eclipse.dd.mi.service.command.output.MIVarInfoTypeInfo; + + +/** + * + * -var-info-type NAME + * + * Returns the type of the specified variable NAME. The type is + * returned as a string in the same format as it is output by the GDB CLI: + * + * type=TYPENAME + * + */ +public class MIVarInfoType extends MICommand +{ + public MIVarInfoType(MIControlDMContext ctx, String name) { + super(ctx, "-var-info-type", new String[]{name}); //$NON-NLS-1$ + } + + @Override + public MIVarInfoTypeInfo getResult(MIOutput out) { + return new MIVarInfoTypeInfo(out); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarListChildren.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarListChildren.java new file mode 100644 index 00000000000..bf240b1b3b4 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarListChildren.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Ericsson - Modified for handling of frame contexts + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + + +import org.eclipse.dd.mi.service.command.MIControlDMContext; +import org.eclipse.dd.mi.service.command.output.MIOutput; +import org.eclipse.dd.mi.service.command.output.MIVarListChildrenInfo; + +/** + * + * -var-list-children NAME + * + * Returns a list of the children of the specified variable object: + * + * numchild=N,children={{name=NAME, + * numchild=N,type=TYPE},(repeats N times)} + * + */ +public class MIVarListChildren extends MICommand +{ + public MIVarListChildren(MIControlDMContext ctx, String name) { + super(ctx, "-var-list-children", new String[]{name}); //$NON-NLS-1$ + } + + @Override + public MIVarListChildrenInfo getResult(MIOutput out) { + return new MIVarListChildrenInfo(out); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarSetFormat.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarSetFormat.java new file mode 100644 index 00000000000..d3829b39262 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarSetFormat.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + * Ericsson - Modified for handling of frame contexts + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.debug.service.IFormattedValues; +import org.eclipse.dd.mi.service.command.MIControlDMContext; +import org.eclipse.dd.mi.service.command.output.MIOutput; +import org.eclipse.dd.mi.service.command.output.MIVarSetFormatInfo; + +/** + * + * -var-set-format NAME FORMAT-SPEC + * + * Sets the output format for the value of the object NAME to be + * FORMAT-SPEC. + * + * The syntax for the FORMAT-SPEC is as follows: + * + * FORMAT-SPEC ==> + * {binary | decimal | hexadecimal | octal | natural} + * + */ +public class MIVarSetFormat extends MICommand +{ + public MIVarSetFormat(MIControlDMContext ctx, String name, String fmt) { + super(ctx, "-var-set-format"); //$NON-NLS-1$ + setParameters(new String[]{name, getFormat(fmt)}); + } + + private String getFormat(String fmt){ + String format = "natural"; //$NON-NLS-1$ + + if (IFormattedValues.HEX_FORMAT.equals(fmt)) { + format = "hexadecimal"; //$NON-NLS-1$ + } else if (IFormattedValues.BINARY_FORMAT.equals(fmt)) { + format = "binary"; //$NON-NLS-1$ + } else if (IFormattedValues.OCTAL_FORMAT.equals(fmt)) { + format = "octal"; //$NON-NLS-1$ + } else if (IFormattedValues.NATURAL_FORMAT.equals(fmt)) { + format = "natural"; //$NON-NLS-1$ + } else if (IFormattedValues.DECIMAL_FORMAT.equals(fmt)) { + format = "decimal"; //$NON-NLS-1$ + } + return format; + } + + @Override + public MIVarSetFormatInfo getResult(MIOutput out) { + return new MIVarSetFormatInfo(out); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarShowAttributes.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarShowAttributes.java new file mode 100644 index 00000000000..fd17c53f116 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarShowAttributes.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.mi.service.command.MIControlDMContext; +import org.eclipse.dd.mi.service.command.output.MIOutput; +import org.eclipse.dd.mi.service.command.output.MIVarShowAttributesInfo; + +/** + * + * -var-show-attributes NAME + * + * List attributes of the specified variable object NAME: + * + * status=ATTR [ ( ,ATTR )* ] + * + * where ATTR is `{ { editable | noneditable } | TBD }'. + * + */ +//DsfMIVarShowAttributesInfo + +public class MIVarShowAttributes extends MICommand +{ + public MIVarShowAttributes(MIControlDMContext ctx, String name) { + super(ctx, "-var-show-attributes", new String[]{name}); //$NON-NLS-1$ + } + + @Override + public MIVarShowAttributesInfo getResult(MIOutput out) { + return new MIVarShowAttributesInfo(out); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarShowFormat.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarShowFormat.java new file mode 100644 index 00000000000..781db498cac --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarShowFormat.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.mi.service.command.MIControlDMContext; +import org.eclipse.dd.mi.service.command.output.MIOutput; +import org.eclipse.dd.mi.service.command.output.MIVarShowFormatInfo; + +/** + * + * -var-show-format NAME + * + * Returns the format used to display the value of the object NAME. + * + * FORMAT ==> + * FORMAT-SPEC + * + */ +public class MIVarShowFormat extends MICommand +{ + public MIVarShowFormat(MIControlDMContext ctx, String name) { + super(ctx, "-var-show-format", new String[]{name}); //$NON-NLS-1$ + } + + @Override + public MIVarShowFormatInfo getResult(MIOutput out) { + return new MIVarShowFormatInfo(out); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarUpdate.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarUpdate.java new file mode 100644 index 00000000000..b011279e507 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarUpdate.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + * Ericsson - Modified for handling of frame contexts + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.mi.service.command.MIControlDMContext; +import org.eclipse.dd.mi.service.command.output.MIOutput; +import org.eclipse.dd.mi.service.command.output.MIVarUpdateInfo; + +/** + * + * -var-update [print-values] {NAME | "*"} + * + * Update the value of the variable object NAME by evaluating its + * expression after fetching all the new values from memory or registers. + * A `*' causes all existing variable objects to be updated. + * If print-values has a value for of 0 or --no-values, print only the names of the variables; + * if print-values is 1 or --all-values, also print their values; + * if it is 2 or --simple-values print the name and value for simple data types and just + * the name for arrays, structures and unions. + */ +public class MIVarUpdate extends MICommand { + + public MIVarUpdate(MIControlDMContext dmc, String name) { + super(dmc, "-var-update", new String[] { "1", name }); //$NON-NLS-1$//$NON-NLS-2$ + } + + @Override + public MIVarUpdateInfo getResult(MIOutput out) { + return new MIVarUpdateInfo(out); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/RawCommand.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/RawCommand.java new file mode 100644 index 00000000000..2e5c86fe787 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/RawCommand.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; +import org.eclipse.dd.mi.service.command.output.MIOutput; + +/** + */ +public class RawCommand extends MICommand { + + String fRaw; + + public RawCommand(IDMContext ctx, String operation) { + super(ctx, operation); + fRaw = operation; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.mi.core.command.Command#getMIOutput() + */ + public MIOutput getMIOutput() { + return new MIOutput(); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIBreakpointChangedEvent.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIBreakpointChangedEvent.java new file mode 100644 index 00000000000..d5d8e1a0b8a --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIBreakpointChangedEvent.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.events; + +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; + + +/** + * + */ +@Immutable +public class MIBreakpointChangedEvent extends MIEvent { + + final private int no; + + public MIBreakpointChangedEvent(IBreakpointsTargetDMContext ctx, int number) { + this(ctx, 0, number); + } + + public MIBreakpointChangedEvent(IBreakpointsTargetDMContext ctx, int id, int number) { + super(ctx, id, null); + no = number; + } + + public int getNumber() { + return no; + } + +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIBreakpointHitEvent.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIBreakpointHitEvent.java new file mode 100644 index 00000000000..452632cd5ff --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIBreakpointHitEvent.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.events; + +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.mi.service.MIRunControl; +import org.eclipse.dd.mi.service.command.output.MIConst; +import org.eclipse.dd.mi.service.command.output.MIFrame; +import org.eclipse.dd.mi.service.command.output.MIResult; +import org.eclipse.dd.mi.service.command.output.MIValue; + +/** + * ^stopped,reason="breakpoint-hit",bkptno="1",thread-id="0",frame={addr="0x08048468",func="main",args=[{name="argc",value="1"},{name="argv",value="0xbffff18c"}],file="hello.c",line="4"} + * + */ +@Immutable +public class MIBreakpointHitEvent extends MIStoppedEvent { + + int bkptno; + + protected MIBreakpointHitEvent(IExecutionDMContext ctx, int token, MIResult[] results, MIFrame frame, int bkptno) { + super(ctx, token, results, frame); + this.bkptno = bkptno; + } + + public int getNumber() { + return bkptno; + } + + public static MIBreakpointHitEvent parse( + MIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) + { + int bkptno = -1; + + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + MIValue value = results[i].getMIValue(); + String str = ""; //$NON-NLS-1$ + if (value != null && value instanceof MIConst) { + str = ((MIConst)value).getString(); + } + + if (var.equals("bkptno")) { //$NON-NLS-1$ + try { + bkptno = Integer.parseInt(str.trim()); + } catch (NumberFormatException e) { + } + } + } + MIStoppedEvent stoppedEvent = MIStoppedEvent.parse(runControl, containerDmc, token, results); + return new MIBreakpointHitEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame(), bkptno); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIDetachedEvent.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIDetachedEvent.java new file mode 100644 index 00000000000..1f1f82aeb16 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIDetachedEvent.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.events; + +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.mi.service.command.MIControlDMContext; + + +/** + * + * ^running + */ +@Immutable +public class MIDetachedEvent extends MIEvent { + + public MIDetachedEvent(MIControlDMContext ctx, int token) { + super(ctx, token, null); + } + + @Override + public String toString() { + return "Detached"; //$NON-NLS-1$ + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIErrorEvent.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIErrorEvent.java new file mode 100644 index 00000000000..8458ad56bce --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIErrorEvent.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.events; + +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.mi.service.command.output.MIConst; +import org.eclipse.dd.mi.service.command.output.MILogStreamOutput; +import org.eclipse.dd.mi.service.command.output.MIOOBRecord; +import org.eclipse.dd.mi.service.command.output.MIResult; +import org.eclipse.dd.mi.service.command.output.MIStreamRecord; +import org.eclipse.dd.mi.service.command.output.MIValue; + +/** + * (gdb) + * &"warning: Cannot insert breakpoint 2:\n" + * &"Cannot access memory at address 0x8020a3\n" + * 30^error,msg=3D"Cannot access memory at address 0x8020a3"=20 + */ +@Immutable +public class MIErrorEvent extends MIStoppedEvent { + + final private String msg; + final private String log; + final private MIOOBRecord[] oobs; + + protected MIErrorEvent( + IExecutionDMContext ctx, int token, MIResult[] results, MIOOBRecord[] oobs, String msg, String log) + { + super(ctx, token, results, null); + this.msg = msg; + this.log = log; + this.oobs = oobs; + } + + public String getMessage() { + return msg; + } + + public String getLogMessage() { + return log; + } + + public static MIErrorEvent parse( + IContainerDMContext containerDmc, int token, MIResult[] results, MIOOBRecord[] oobs) + { + String msg = "", log = ""; //$NON-NLS-1$ //$NON-NLS-2$ + + if (results != null) { + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + MIValue value = results[i].getMIValue(); + String str = ""; //$NON-NLS-1$ + if (value instanceof MIConst) { + str = ((MIConst)value).getString(); + } + + if (var.equals("msg")) { //$NON-NLS-1$ + msg = str; + } + } + } + if (oobs != null) { + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < oobs.length; i++) { + if (oobs[i] instanceof MILogStreamOutput) { + MIStreamRecord o = (MIStreamRecord)oobs[i]; + sb.append(o.getString()); + } + } + log = sb.toString(); + } + return new MIErrorEvent(containerDmc, token, results, oobs, msg, log); + } + + @Override + public String toString() { + if (oobs != null) { + StringBuilder builder = new StringBuilder(); + for (MIOOBRecord oob : oobs) { + builder.append(oob.toString()); + } + builder.append(super.toString()); + return builder.toString(); + } else { + return super.toString(); + } + } +} + diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIEvent.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIEvent.java new file mode 100644 index 00000000000..b0ca3cc601b --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIEvent.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.events; + +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.datamodel.AbstractDMEvent; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.mi.service.command.output.MIResult; + + +/** + */ +@Immutable +public abstract class MIEvent extends AbstractDMEvent { + private final int fToken; + private final MIResult[] fResults; + + public MIEvent(V dmc, int token, MIResult[] results) { + super(dmc); + fToken = token; + fResults = results; + } + + public int getToken() { + return fToken; + } + + public MIResult[] getResults() { + return fResults; + } + + @Override + public String toString() { + if (fResults == null) { + return super.toString(); + } else if (fResults.length == 1) { + return fResults[0].toString(); + } else { + StringBuilder builder = new StringBuilder(); + for (MIResult result : fResults) { + builder.append(result); + builder.append('\n'); + } + return builder.toString(); + } + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIFunctionFinishedEvent.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIFunctionFinishedEvent.java new file mode 100644 index 00000000000..2c8cb838873 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIFunctionFinishedEvent.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.events; + +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.mi.service.MIRunControl; +import org.eclipse.dd.mi.service.command.output.MIConst; +import org.eclipse.dd.mi.service.command.output.MIFrame; +import org.eclipse.dd.mi.service.command.output.MIResult; +import org.eclipse.dd.mi.service.command.output.MIValue; + +/** + * *stopped,reason="function-finished",thread-id="0",frame={addr="0x0804855a",func="main",args=[{name="argc",value="1"},{name="argv",value="0xbffff18c"}],file="hello.c",line="17"},gdb-result-var="$1",return-value="10" + */ +@Immutable +public class MIFunctionFinishedEvent extends MIStoppedEvent { + + final private String gdbResult; + final private String returnValue; + final private String returnType; + + protected MIFunctionFinishedEvent( + IExecutionDMContext ctx, int token, MIResult[] results, MIFrame frame, String gdbResult, + String returnValue, String returnType) + { + super(ctx, token, results, frame); + this.gdbResult = gdbResult; + this.returnValue = returnValue; + this.returnType = returnType; + } + + public String getGDBResultVar() { + return gdbResult; + } + + public String getReturnValue() { + return returnValue; + } + + public String getReturnType() { + return returnType; + } + + public static MIFunctionFinishedEvent parse( + MIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) + { + String gdbResult = ""; //$NON-NLS-1$ + String returnValue = ""; //$NON-NLS-1$ + String returnType = ""; //$NON-NLS-1$ + + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + MIValue value = results[i].getMIValue(); + String str = ""; //$NON-NLS-1$ + if (value instanceof MIConst) { + str = ((MIConst)value).getString(); + } + + if (var.equals("gdb-result-var")) { //$NON-NLS-1$ + gdbResult = str; + } else if (var.equals("return-value")) { //$NON-NLS-1$ + returnValue = str; + } else if (var.equals("return-type")) { //$NON-NLS-1$ + returnType = str; + } + } + + MIStoppedEvent stoppedEvent = MIStoppedEvent.parse(runControl, containerDmc, token, results); + return new MIFunctionFinishedEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame(), gdbResult, returnValue, returnType); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIGDBExitEvent.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIGDBExitEvent.java new file mode 100644 index 00000000000..57bf6595c27 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIGDBExitEvent.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.events; + +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.mi.service.command.MIControlDMContext; + + +/** + * Gdb Session terminated. + */ +@Immutable +public class MIGDBExitEvent extends MIEvent { + + public MIGDBExitEvent(MIControlDMContext ctx, int token) { + super(ctx, token, null); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIInferiorExitEvent.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIInferiorExitEvent.java new file mode 100644 index 00000000000..b129bbb6486 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIInferiorExitEvent.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.events; + +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.mi.service.command.MIControlDMContext; +import org.eclipse.dd.mi.service.command.output.MIConst; +import org.eclipse.dd.mi.service.command.output.MIResult; +import org.eclipse.dd.mi.service.command.output.MIValue; + +/** + * *stopped,reason="exited-normally" + * *stopped,reason="exited",exit-code="04" + * ^done,reason="exited",exit-code="04" + * + */ +@Immutable +public class MIInferiorExitEvent extends MIEvent { + + final private int code; + + public MIInferiorExitEvent(MIControlDMContext ctx, int token, MIResult[] results, int code) { + super(ctx, token, results); + this.code = code; + } + + public int getExitCode() { + return code; + } + + public static MIInferiorExitEvent parse(MIControlDMContext ctx, int token, MIResult[] results) + { + int code = 0; + if (results != null) { + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + MIValue value = results[i].getMIValue(); + String str = ""; //$NON-NLS-1$ + if (value instanceof MIConst) { + str = ((MIConst)value).getString(); + } + + if (var.equals("exit-code")) { //$NON-NLS-1$ + try { + code = Integer.decode(str.trim()).intValue(); + } catch (NumberFormatException e) { + } + } + } + } + return new MIInferiorExitEvent(ctx, token, results, code); + } + +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIInferiorSignalExitEvent.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIInferiorSignalExitEvent.java new file mode 100644 index 00000000000..025b99d88f7 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIInferiorSignalExitEvent.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.events; + +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.mi.service.command.MIControlDMContext; +import org.eclipse.dd.mi.service.command.output.MIConst; +import org.eclipse.dd.mi.service.command.output.MIResult; +import org.eclipse.dd.mi.service.command.output.MIValue; + +/** + * signal 2 + * "signal 2\n" + * ^done,reason="exited-signalled",signal-name="SIGINT",signal-meaning="Interrupt" + * + */ +@Immutable +public class MIInferiorSignalExitEvent extends MIEvent { + + final private String sigName; + final private String sigMeaning; + + public MIInferiorSignalExitEvent(MIControlDMContext ctx, int token, MIResult[] results, String sigName, String sigMeaning) { + super(ctx, token, results); + this.sigName = sigName; + this.sigMeaning = sigMeaning; + } + + public String getName() { + return sigName; + } + + public String getMeaning() { + return sigMeaning; + } + + public static MIInferiorSignalExitEvent parse(MIControlDMContext ctx, int token, MIResult[] results) + { + String sigName = ""; //$NON-NLS-1$ + String sigMeaning = ""; //$NON-NLS-1$ + + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + MIValue value = results[i].getMIValue(); + String str = ""; //$NON-NLS-1$ + if (value instanceof MIConst) { + str = ((MIConst)value).getString(); + } + + if (var.equals("signal-name")) { //$NON-NLS-1$ + sigName = str; + } else if (var.equals("signal-meaning")) { //$NON-NLS-1$ + sigMeaning = str; + } + } + return new MIInferiorSignalExitEvent(ctx, token, results, sigName, sigMeaning); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MILocationReachedEvent.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MILocationReachedEvent.java new file mode 100644 index 00000000000..369d6c870bd --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MILocationReachedEvent.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.events; + +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.mi.service.MIRunControl; +import org.eclipse.dd.mi.service.command.output.MIFrame; +import org.eclipse.dd.mi.service.command.output.MIResult; + +/** + * *stopped,reason="location-reached",thread-id="0",frame={addr="0x0804858e",func="main2",args=[],file="hello.c",line="27"} + */ +@Immutable +public class MILocationReachedEvent extends MIStoppedEvent { + + protected MILocationReachedEvent(IExecutionDMContext ctx, int token, MIResult[] results, MIFrame frame) { + super(ctx, token, results, frame); + } + + public static MILocationReachedEvent parse( + MIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) + { + MIStoppedEvent stoppedEvent = MIStoppedEvent.parse(runControl, containerDmc, token, results); + return new MILocationReachedEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame()); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIRunningEvent.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIRunningEvent.java new file mode 100644 index 00000000000..4413bcc6237 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIRunningEvent.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.events; + +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; + + +/** + * + * ^running + */ +@Immutable +public class MIRunningEvent extends MIEvent { + public static final int CONTINUE = 0; + public static final int NEXT = 1; + public static final int NEXTI = 2; + public static final int STEP = 3; + public static final int STEPI = 4; + public static final int FINISH = 5; + public static final int UNTIL = 6; + public static final int RETURN = 7; + + final private int type; + final private int threadId; + + public MIRunningEvent(IExecutionDMContext ctx, int token, int t) { + this(ctx, token, t, -1); + } + + public MIRunningEvent(IExecutionDMContext ctx, int token, int t, int threadId) { + super(ctx, token, null); + type = t; + this.threadId = threadId; + } + + public int getType() { + return type; + } + + public int getThreadId() { + return threadId; + } + + @Override + public String toString() { + return "Running"; //$NON-NLS-1$ + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MISharedLibEvent.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MISharedLibEvent.java new file mode 100644 index 00000000000..fbb7d01ad67 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MISharedLibEvent.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.events; + +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.mi.service.MIRunControl; +import org.eclipse.dd.mi.service.command.output.MIFrame; +import org.eclipse.dd.mi.service.command.output.MIResult; + +/** + * + */ +@Immutable +public class MISharedLibEvent extends MIStoppedEvent { + + protected MISharedLibEvent(IExecutionDMContext ctx, int token, MIResult[] results, MIFrame frame) { + super(ctx, token, results, frame); + } + + public static MIStoppedEvent parse( + MIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) + { + MIStoppedEvent stoppedEvent = MIStoppedEvent.parse(runControl, containerDmc, token, results); + return new MISharedLibEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame()); + } + +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MISignalChangedEvent.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MISignalChangedEvent.java new file mode 100644 index 00000000000..dafaa304681 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MISignalChangedEvent.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.events; + +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.debug.service.ISignals.ISignalsDMContext; + + +/** + * + */ +@Immutable +public class MISignalChangedEvent extends MIEvent { + + final private String name; + + public MISignalChangedEvent(ISignalsDMContext ctx, String n) { + this(ctx, 0, n); + } + + public MISignalChangedEvent(ISignalsDMContext ctx, int id, String n) { + super(ctx, id, null); + name = n; + } + + public String getName() { + return name; + } + +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MISignalEvent.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MISignalEvent.java new file mode 100644 index 00000000000..1938022d21f --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MISignalEvent.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.events; + +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.mi.service.MIRunControl; +import org.eclipse.dd.mi.service.command.output.MIConst; +import org.eclipse.dd.mi.service.command.output.MIFrame; +import org.eclipse.dd.mi.service.command.output.MIResult; +import org.eclipse.dd.mi.service.command.output.MIValue; + +/** + * *stopped,reason="signal-received",signal-name="SIGINT",signal-meaning="Interrupt",thread-id="0",frame={addr="0x400e18e1",func="__libc_nanosleep",args=[],file="__libc_nanosleep",line="-1"} + * + */ +@Immutable +public class MISignalEvent extends MIStoppedEvent { + + final private String sigName; + final private String sigMeaning; + + protected MISignalEvent( + IExecutionDMContext ctx, int token, MIResult[] results, MIFrame frame, + String sigName, String sigMeaning) + { + super(ctx, token, results, frame); + this.sigName = sigName; + this.sigMeaning = sigMeaning; + } + + public String getName() { + return sigName; + } + + public String getMeaning() { + return sigMeaning; + } + + public static MISignalEvent parse( + MIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) + { + String sigName = ""; //$NON-NLS-1$ + String sigMeaning = ""; //$NON-NLS-1$ + + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + MIValue value = results[i].getMIValue(); + String str = ""; //$NON-NLS-1$ + if (value instanceof MIConst) { + str = ((MIConst)value).getString(); + } + + if (var.equals("signal-name")) { //$NON-NLS-1$ + sigName = str; + } else if (var.equals("signal-meaning")) { //$NON-NLS-1$ + sigMeaning = str; + } + } + MIStoppedEvent stoppedEvent = MIStoppedEvent.parse(runControl, containerDmc, token, results); + return new MISignalEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame(), sigName, sigMeaning); + + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MISteppingRangeEvent.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MISteppingRangeEvent.java new file mode 100644 index 00000000000..6901d9283e0 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MISteppingRangeEvent.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.events; + +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.mi.service.MIRunControl; +import org.eclipse.dd.mi.service.command.output.MIFrame; +import org.eclipse.dd.mi.service.command.output.MIResult; + +/** + * + * *stopped,reason="end-stepping-range",thread-id="0",frame={addr="0x08048538",func="main",args=[{name="argc",value="1"},{name="argv",value="0xbffff18c"}],file="hello.c",line="13"} + */ +@Immutable +public class MISteppingRangeEvent extends MIStoppedEvent { + + protected MISteppingRangeEvent(IExecutionDMContext ctx, int token, MIResult[] results, MIFrame frame) { + super(ctx, token, results, frame); + } + + public static MISteppingRangeEvent parse( + MIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) + { + MIStoppedEvent stoppedEvent = MIStoppedEvent.parse(runControl, containerDmc, token, results); + return new MISteppingRangeEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame()); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIStoppedEvent.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIStoppedEvent.java new file mode 100644 index 00000000000..a1a45b0d47b --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIStoppedEvent.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.events; + +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.mi.service.MIRunControl; +import org.eclipse.dd.mi.service.command.output.MIConst; +import org.eclipse.dd.mi.service.command.output.MIFrame; +import org.eclipse.dd.mi.service.command.output.MIResult; +import org.eclipse.dd.mi.service.command.output.MITuple; +import org.eclipse.dd.mi.service.command.output.MIValue; + +/** + * *stopped + * + */ +@Immutable +public class MIStoppedEvent extends MIEvent { + + final private MIFrame frame; + + protected MIStoppedEvent(IExecutionDMContext ctx, int token, MIResult[] results, MIFrame frame) { + super(ctx, token, results); + this.frame = frame; + } + + public MIFrame getFrame() { + return frame; + } + + public static MIStoppedEvent parse( + MIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) + { + int threadId = -1; + MIFrame frame = null; + + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + MIValue value = results[i].getMIValue(); + + if (var.equals("thread-id")) { //$NON-NLS-1$ + if (value instanceof MIConst) { + String str = ((MIConst)value).getString(); + try { + threadId = Integer.parseInt(str.trim()); + } catch (NumberFormatException e) { + } + } + } else if (var.equals("frame")) { //$NON-NLS-1$ + if (value instanceof MITuple) { + frame = new MIFrame((MITuple)value); + } + } + } + IExecutionDMContext execDmc = containerDmc; + if (runControl != null && threadId != -1) { + execDmc = runControl.createMIExecutionContext(containerDmc, threadId); + } + return new MIStoppedEvent(execDmc, token, results, frame); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIThreadCreatedEvent.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIThreadCreatedEvent.java new file mode 100644 index 00000000000..23583241c39 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIThreadCreatedEvent.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.events; + +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; + + +/** + * This can not be detected yet by gdb/mi. + * + */ +@Immutable +public class MIThreadCreatedEvent extends MIEvent { + + final private int tid; + + public MIThreadCreatedEvent(IContainerDMContext ctx, int id) { + this(ctx, 0, id); + } + + public MIThreadCreatedEvent(IContainerDMContext ctx, int token, int id) { + super(ctx, token, null); + tid = id; + } + + public int getId() { + return tid; + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIThreadExitEvent.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIThreadExitEvent.java new file mode 100644 index 00000000000..e960f8f9b40 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIThreadExitEvent.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.events; + +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; + + +/** + * This can not be detected yet by gdb/mi. + * + */ +@Immutable +public class MIThreadExitEvent extends MIEvent { + + final private int tid; + + public MIThreadExitEvent(IContainerDMContext ctx, int id) { + this(ctx, 0, id); + } + + public MIThreadExitEvent(IContainerDMContext ctx, int token, int id) { + super(ctx, token, null); + tid = id; + } + + public int getId() { + return tid; + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIWatchpointScopeEvent.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIWatchpointScopeEvent.java new file mode 100644 index 00000000000..5de47f2a808 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIWatchpointScopeEvent.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.events; + +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.mi.service.MIRunControl; +import org.eclipse.dd.mi.service.command.output.MIConst; +import org.eclipse.dd.mi.service.command.output.MIFrame; +import org.eclipse.dd.mi.service.command.output.MIResult; +import org.eclipse.dd.mi.service.command.output.MIValue; + +/** + * *stopped,reason="watchpoint-scope",wpnum="5", + * + */ +@Immutable +public class MIWatchpointScopeEvent extends MIStoppedEvent { + + final private int number; + + protected MIWatchpointScopeEvent( + IExecutionDMContext ctx, int token, MIResult[] results, MIFrame frame, int number) + { + super(ctx, token, results, frame); + this.number = number; + } + + public int getNumber() { + return number; + } + + public static MIWatchpointScopeEvent parse( + MIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) + { + int number = 0; + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + MIValue value = results[i].getMIValue(); + + if (var.equals("wpnum")) { //$NON-NLS-1$ + if (value instanceof MIConst) { + String str = ((MIConst) value).getString(); + try { + number = Integer.parseInt(str.trim()); + } catch (NumberFormatException e) { + } + } + } + } + + MIStoppedEvent stoppedEvent = MIStoppedEvent.parse(runControl, containerDmc, token, results); + return new MIWatchpointScopeEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame(), number); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIWatchpointTriggerEvent.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIWatchpointTriggerEvent.java new file mode 100644 index 00000000000..81d4da3ace9 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIWatchpointTriggerEvent.java @@ -0,0 +1,122 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.events; + +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.mi.service.MIRunControl; +import org.eclipse.dd.mi.service.command.output.MIConst; +import org.eclipse.dd.mi.service.command.output.MIFrame; +import org.eclipse.dd.mi.service.command.output.MIResult; +import org.eclipse.dd.mi.service.command.output.MITuple; +import org.eclipse.dd.mi.service.command.output.MIValue; + +/** + * *stopped,reason="watchpoint-trigger",wpt={number="2",exp="i"},value={old="0",new="1"},thread-id="0",frame={addr="0x08048534",func="main",args=[{name="argc",value="1"},{name="argv",value="0xbffff18c"}],file="hello.c",line="10"} + * + */ +@Immutable +public class MIWatchpointTriggerEvent extends MIStoppedEvent { + + final private int number; + final private String exp; + final private String oldValue; + final private String newValue; + + protected MIWatchpointTriggerEvent( + IExecutionDMContext ctx, int token, MIResult[] results, MIFrame frame, + int number, String exp, String oldValue, String newValue) + { + super(ctx, token, results, frame); + this.number = number; + this.exp = exp; + this.oldValue = oldValue; + this.newValue = newValue; + } + + public int getNumber() { + return number; + } + + public String getExpression() { + return exp; + } + + public String getOldValue() { + return oldValue; + } + + public String getNewValue() { + return newValue; + } + + public static MIWatchpointTriggerEvent parse( + MIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) + { + int number = 0; + String exp = ""; //$NON-NLS-1$ + String oldValue = ""; //$NON-NLS-1$ + String newValue = ""; //$NON-NLS-1$ + + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + MIValue value = results[i].getMIValue(); + + if (var.equals("wpt") || var.equals("hw-awpt") || var.equals("hw-rwpt")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + if (value instanceof MITuple) { + for (MIResult wptResult : ((MITuple) value).getMIResults()) { + String wptVar = wptResult.getVariable(); + MIValue wptValue = wptResult.getMIValue(); + + if (wptVar.equals("number")) { //$NON-NLS-1$ + if (wptValue instanceof MIConst) { + String str = ((MIConst) wptValue).getString(); + try { + number = Integer.parseInt(str); + } catch (NumberFormatException e) { + } + } + } else if (wptVar.equals("exp")) { //$NON-NLS-1$ + if (wptValue instanceof MIConst) { + exp = ((MIConst) wptValue).getString(); + } + } + } + } + } else if (var.equals("value")) { //$NON-NLS-1$ + if (value instanceof MITuple) { + for (MIResult valueResult : ((MITuple)value).getMIResults()) { + String valueVar = valueResult.getVariable(); + MIValue valueValue = valueResult.getMIValue(); + String str = ""; //$NON-NLS-1$ + if (valueValue instanceof MIConst) { + str = ((MIConst) valueValue).getString(); + } + + if (valueVar.equals("old")) { //$NON-NLS-1$ + oldValue = str; + } else if (valueVar.equals("new")) { //$NON-NLS-1$ + newValue = str; + } else if (valueVar.equals("value")) { //$NON-NLS-1$ + oldValue = newValue = str; + } + } + + } + } + } + MIStoppedEvent stoppedEvent = MIStoppedEvent.parse(runControl, containerDmc, token, results); + return new MIWatchpointTriggerEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame(), number, exp, oldValue, newValue); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/CLIInfoSharedLibraryInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/CLIInfoSharedLibraryInfo.java new file mode 100644 index 00000000000..f54ef23e05e --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/CLIInfoSharedLibraryInfo.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Ericsson AB - Modified for DSF GDB reference implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.output; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * + */ +public class CLIInfoSharedLibraryInfo extends MIInfo { + + DsfMISharedInfo[] shared; + + public class DsfMISharedInfo { + + String from; + String to; + boolean isread; + String name; + + public DsfMISharedInfo (String start, String end, boolean read, String location) { + from = start; + to = end; + isread = read; + name = location; + } + + public String getFrom() { + return from; + } + + public String getTo() { + return to; + } + + public boolean isRead() { + return isread; + } + + public String getName() { + return name; + } + + public void setSymbolsRead(boolean read) { + isread = read; + } + } + + public CLIInfoSharedLibraryInfo(MIOutput out) { + super(out); + parse(); + } + + public DsfMISharedInfo[] getMIShared() { + return shared; + } + + void parse() { + List aList = new ArrayList(); + if (isDone()) { + MIOutput out = getMIOutput(); + MIOOBRecord[] oobs = out.getMIOOBRecords(); + for (int i = 0; i < oobs.length; i++) { + if (oobs[i] instanceof MIConsoleStreamOutput) { + MIStreamRecord cons = (MIStreamRecord) oobs[i]; + String str = cons.getString(); + // We are interested in the shared info + parseShared(str.trim(), aList); + } + } + } + shared = new DsfMISharedInfo[aList.size()]; + for (int i = 0; i < aList.size(); i++) { + shared[i] = aList.get(i); + } + } + + void parseShared(String str, List aList) { + if (str.length() > 0) { + // Parsing pattern of type ~"0x40000970 0x4001331f Yes /lib/ld-linux.so.2\n" + Pattern pattern = Pattern.compile("(0x.*)(0x.*)(Yes|No)(\\s*)(.*)", Pattern.MULTILINE); //$NON-NLS-1$ + Matcher matcher = pattern.matcher(str); + if (matcher.find()) { + DsfMISharedInfo s = new DsfMISharedInfo(matcher.group(1), matcher.group(2), + (matcher.group(3).equals("Yes"))?true:false, //$NON-NLS-1$ + matcher.group(5)); + aList.add(s); + + } + } + } + +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/CLIInfoThreadsInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/CLIInfoThreadsInfo.java new file mode 100644 index 00000000000..72dee49824f --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/CLIInfoThreadsInfo.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Ericsson - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +/** + * GDB/MI thread list parsing. +~"\n" +~" 2 Thread 2049 (LWP 29354) " +~"* 1 Thread 1024 (LWP 29353) " + + */ +public class CLIInfoThreadsInfo extends MIInfo { + + protected List info; + + public CLIInfoThreadsInfo(MIOutput out) { + super(out); + parse(); + } + + public class ThreadInfo{ + String fName; + String fGdbId; + String fPid; + boolean fIsCurrentThread = false; + + public ThreadInfo(String tid, String pid, String name, boolean isCurrentThread) + { + this.fName = name; + this.fGdbId = tid; + this.fPid = pid; + this.fIsCurrentThread = isCurrentThread; + } + + public String getName(){ return fName ;} + // GDB id given to a thread. Needed to compare with ID stored in DMC fetched via DsfMIThreadListIds command + public String getId(){ return fGdbId; } + public String getOsId(){return fPid; } + public boolean isCurrentThread(){return fIsCurrentThread; } + } + + public List getThreadInfo(){ + return info; + } + + protected void parse() { + info = new ArrayList(); + if (isDone()) { + MIOutput out = getMIOutput(); + MIOOBRecord[] oobs = out.getMIOOBRecords(); + for (int i = 0; i < oobs.length; i++) { + if (oobs[i] instanceof MIConsoleStreamOutput) { + MIStreamRecord cons = (MIStreamRecord) oobs[i]; + String str = cons.getString(); + // We are interested in finding the current thread + parseThreadInfo(str.trim(), info); + } + } + } + } + + protected void parseThreadInfo(String str, List info) { + // Fetch the OS ThreadId & Find the current thread + if(str.length() > 0 ){ + Pattern pattern = Pattern.compile("(^\\d*|^\\*\\s*\\d*)(\\s*Thread\\s*)(\\d*)(\\s*\\(LWP\\s*)(\\d*)", Pattern.MULTILINE); //$NON-NLS-1$ + Matcher matcher = pattern.matcher(str); + boolean isCurrentThread = false; + if (matcher.find()) { + String id = matcher.group(1); + if (id.charAt(0) == '*') { + isCurrentThread = true; + id = id.substring(1).trim(); + } + info.add(new ThreadInfo(id, matcher.group(5), "", isCurrentThread)); //$NON-NLS-1$ + } + } + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/ExprMetaGetAttributesInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/ExprMetaGetAttributesInfo.java new file mode 100644 index 00000000000..ca055aa3912 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/ExprMetaGetAttributesInfo.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2008 Ericsson 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: + * Ericsson - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.output; + +import org.eclipse.dd.dsf.debug.service.command.ICommand; +import org.eclipse.dd.dsf.debug.service.command.ICommandResult; + +public class ExprMetaGetAttributesInfo implements ICommandResult { + + private final boolean editable; + + public ExprMetaGetAttributesInfo(boolean e) { + editable = e; + } + + public boolean getEditable() { return editable; } + + public V getSubsetResult(ICommand command) { + return null; + } +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/ExprMetaGetChildCountInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/ExprMetaGetChildCountInfo.java new file mode 100644 index 00000000000..6bd8f229120 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/ExprMetaGetChildCountInfo.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2007 Ericsson 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: + * Ericsson - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.output; + +import org.eclipse.dd.dsf.debug.service.command.ICommand; +import org.eclipse.dd.dsf.debug.service.command.ICommandResult; + +public class ExprMetaGetChildCountInfo implements ICommandResult { + + private final int childNum; + + public ExprMetaGetChildCountInfo(int n) { + childNum = n; + } + + public int getChildNum() { return childNum; } + + public V getSubsetResult(ICommand command) { + return null; + } +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/ExprMetaGetChildrenInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/ExprMetaGetChildrenInfo.java new file mode 100644 index 00000000000..d5573799f42 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/ExprMetaGetChildrenInfo.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2007 Ericsson 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: + * Ericsson - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.output; + +import org.eclipse.dd.dsf.debug.service.command.ICommand; +import org.eclipse.dd.dsf.debug.service.command.ICommandResult; +import org.eclipse.dd.mi.service.ExpressionService.ExpressionInfo; + +public class ExprMetaGetChildrenInfo implements ICommandResult { + + private final ExpressionInfo[] childrenExpressions; + + public ExprMetaGetChildrenInfo(ExpressionInfo[] c) { + childrenExpressions = c; + } + + public ExpressionInfo[] getChildrenExpressions() { return childrenExpressions; } + + public V getSubsetResult(ICommand command) { + return null; + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/ExprMetaGetValueInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/ExprMetaGetValueInfo.java new file mode 100644 index 00000000000..d55461cf17f --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/ExprMetaGetValueInfo.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2007 Ericsson 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: + * Ericsson - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.output; + +import org.eclipse.dd.dsf.debug.service.command.ICommand; +import org.eclipse.dd.dsf.debug.service.command.ICommandResult; + +public class ExprMetaGetValueInfo implements ICommandResult { + + private final String value; + + public ExprMetaGetValueInfo(String v) { + value = v; + } + + public String getValue() { return value; } + + public V getSubsetResult(ICommand command) { + return null; + } + } \ No newline at end of file diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/ExprMetaGetVarInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/ExprMetaGetVarInfo.java new file mode 100644 index 00000000000..c2cd30560bb --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/ExprMetaGetVarInfo.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2007 Ericsson 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: + * Ericsson - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.output; + +import org.eclipse.dd.dsf.debug.service.command.ICommand; +import org.eclipse.dd.dsf.debug.service.command.ICommandResult; + +public class ExprMetaGetVarInfo implements ICommandResult { + + private final String expression; + private final int numChild; + private final String type; + private final boolean editable; + + public ExprMetaGetVarInfo(String e, int n, String t, boolean edit) { + expression = e; + numChild = n; + type = t; + editable = edit; + } + + public String getExpr() { return expression; } + public int getNumChildren() { return numChild; } + public String getType() { return type; } + public boolean getEditable() { return editable; } + + public V getSubsetResult(ICommand command) { + return null; + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIArg.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIArg.java new file mode 100644 index 00000000000..bbc97b809f6 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIArg.java @@ -0,0 +1,132 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + +import java.util.ArrayList; +import java.util.List; + + +/** + * Represents a set name=value. + */ +public class MIArg { + String name; + String value; + + public MIArg(String name, String value) { + this.name = name; + this.value = value; + } + + public String getName() { + return name; + } + + public String getValue() { + return value; + } + + /** + * Parsing a DsfMIList of the form: + * [{name="xxx",value="yyy"},{name="xxx",value="yyy"},..] + * [name="xxx",name="xxx",..] + * [{name="xxx"},{name="xxx"}] + */ + public static MIArg[] getMIArgs(MIList miList) { + List aList = new ArrayList(); + MIValue[] values = miList.getMIValues(); + for (int i = 0; i < values.length; i++) { + if (values[i] instanceof MITuple) { + MIArg arg = getMIArg((MITuple)values[i]); + if (arg != null) { + aList.add(arg); + } + } + } + MIResult[] results = miList.getMIResults(); + for (int i = 0; i < results.length; i++) { + MIValue value = results[i].getMIValue(); + if (value instanceof MIConst) { + String str = ((MIConst)value).getCString(); + aList.add(new MIArg(str, "")); //$NON-NLS-1$ + } + } + return (aList.toArray(new MIArg[aList.size()])); + } + + /** + * Parsing a DsfMITuple of the form: + * {{name="xxx",value="yyy"},{name="xxx",value="yyy"},..} + * {name="xxx",name="xxx",..} + * {{name="xxx"},{name="xxx"}} + */ + public static MIArg[] getMIArgs(MITuple miTuple) { + List aList = new ArrayList(); + MIValue[] values = miTuple.getMIValues(); + for (int i = 0; i < values.length; i++) { + if (values[i] instanceof MITuple) { + MIArg arg = getMIArg((MITuple)values[i]); + if (arg != null) { + aList.add(arg); + } + } + } + MIResult[] results = miTuple.getMIResults(); + for (int i = 0; i < results.length; i++) { + MIValue value = results[i].getMIValue(); + if (value instanceof MIConst) { + String str = ((MIConst)value).getCString(); + aList.add(new MIArg(str, "")); //$NON-NLS-1$ + } + } + return (aList.toArray(new MIArg[aList.size()])); + } + /** + * Parsing a DsfMITuple of the form: + * {name="xxx",value="yyy"} + * {name="xxx"} + */ + public static MIArg getMIArg(MITuple tuple) { + MIResult[] args = tuple.getMIResults(); + MIArg arg = null; + if (args.length > 0) { + // Name + String aName = ""; //$NON-NLS-1$ + MIValue value = args[0].getMIValue(); + if (value != null && value instanceof MIConst) { + aName = ((MIConst)value).getCString(); + } else { + aName = ""; //$NON-NLS-1$ + } + + // Value + String aValue = ""; //$NON-NLS-1$ + if (args.length == 2) { + value = args[1].getMIValue(); + if (value != null && value instanceof MIConst) { + aValue = ((MIConst)value).getCString(); + } else { + aValue = ""; //$NON-NLS-1$ + } + } + + arg = new MIArg(aName, aValue); + } + return arg; + } + + @Override + public String toString() { + return name + "=" + value; //$NON-NLS-1$ + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIAsyncRecord.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIAsyncRecord.java new file mode 100644 index 00000000000..61d7c235ec6 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIAsyncRecord.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + +/** + * base Abstract class for the OOB stream MI responses. + */ +public abstract class MIAsyncRecord extends MIOOBRecord { + + final static MIResult[] nullResults = new MIResult[0]; + + MIResult[] results = null; + String asynClass = ""; //$NON-NLS-1$ + int token = 0; + + public int getToken() { + return token; + } + + public void setToken(int t) { + token = t; + } + + public String getAsyncClass() { + return asynClass; + } + + public void setAsyncClass(String a) { + asynClass = a; + } + + public MIResult[] getMIResults() { + if (results == null) { + return nullResults; + } + return results; + } + + public void setMIResults(MIResult[] res) { + results = res; + } + + @Override + public String toString() { + StringBuffer buffer = new StringBuffer(); + if (token != 0) { + buffer.append(token); + } + if (this instanceof MIExecAsyncOutput) { + buffer.append('*'); + } else if (this instanceof MIStatusAsyncOutput) { + buffer.append('+'); + } else if (this instanceof MINotifyAsyncOutput) { + buffer.append('='); + } + buffer.append(asynClass); + if (results != null) { + for (int i = 0; i < results.length; i++) { + buffer.append(','); + buffer.append(results[i].toString()); + } + } + buffer.append('\n'); + return buffer.toString(); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIBreakInsertInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIBreakInsertInfo.java new file mode 100644 index 00000000000..79b44cd63d2 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIBreakInsertInfo.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + +import java.util.ArrayList; +import java.util.List; + +/** + * -break-insert main + * ^done,bkpt={number="1",type="breakpoint",disp="keep",enabled="y",addr="0x08048468",func="main",file="hello.c",line="4",times="0"} + * -break-insert -a p + * ^done,hw-awpt={number="2",exp="p"} + * -break-watch -r p + * ^done,hw-rwpt={number="4",exp="p"} + * -break-watch p + * ^done,wpt={number="6",exp="p"} + */ +public class MIBreakInsertInfo extends MIInfo { + + MIBreakpoint[] breakpoints; + + public MIBreakInsertInfo(MIOutput record) { + super(record); + breakpoints = null; + List aList = new ArrayList(1); + if (isDone()) { + MIResultRecord rr = record.getMIResultRecord(); + if (rr != null) { + MIResult[] results = rr.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + MIValue val = results[i].getMIValue(); + MIBreakpoint bpt = null; + if (var.equals("wpt")) { //$NON-NLS-1$ + if (val instanceof MITuple) { + bpt = new MIBreakpoint((MITuple)val); + bpt.setEnabled(true); + bpt.setWriteWatchpoint(true); + } + } else if (var.equals("bkpt")) { //$NON-NLS-1$ + if (val instanceof MITuple) { + bpt = new MIBreakpoint((MITuple)val); + bpt.setEnabled(true); + } + } else if (var.equals("hw-awpt")) { //$NON-NLS-1$ + if (val instanceof MITuple) { + bpt = new MIBreakpoint((MITuple)val); + bpt.setAccessWatchpoint(true); + bpt.setEnabled(true); + } + } else if (var.equals("hw-rwpt")) { //$NON-NLS-1$ + if (val instanceof MITuple) { + bpt = new MIBreakpoint((MITuple)val); + bpt.setReadWatchpoint(true); + bpt.setEnabled(true); + } + } + if (bpt != null) { + aList.add(bpt); + } + } + } + } + breakpoints = aList.toArray(new MIBreakpoint[aList.size()]); + } + + public MIBreakpoint[] getMIBreakpoints() { + return breakpoints; + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIBreakListInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIBreakListInfo.java new file mode 100644 index 00000000000..23de9da1edf --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIBreakListInfo.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.output; + +import java.util.ArrayList; +import java.util.List; + + + +/** + * A -break-list result-record is the form: + *
    + * ^done,BreakpointTable={nr_rows="1",nr_cols="6",hdr=[..],body=[brkpt={},brkpt={}]}
    + *-break-list
    +^done,BreakpointTable={nr_rows="6",nr_cols="6",hdr=[{width="3",alignment="-1",col_name="number",colhdr="Num"},{width="14",alignment="-1",col_name="type",colhdr="Type"},{width="4",alignment="-1",col_name="disp",colhdr="Disp"},{width="3",alignment="-1",col_name="enabled",colhdr="Enb"},{width="10",alignment="-1",col_name="addr",colhdr="Address"},{width="40",alignment="2",col_name="what",colhdr="What"}],body=[bkpt={number="1",type="breakpoint",disp="keep",enabled="y",addr="0x0804846b",func="main",file="hello.c",line="4",times="0"},bkpt={number="2",type="breakpoint",disp="del",enabled="y",addr="0x0804846b",func="main",file="hello.c",line="4",times="0"},bkpt={number="3",type="breakpoint",disp="keep",enabled="y",addr="0x0804846b",func="main",file="hello.c",line="4",cond="1",times="0"},bkpt={number="4",type="hw breakpoint",disp="keep",enabled="y",addr="0x0804846b",func="main",file="hello.c",line="4",times="0"},bkpt={number="5",type="breakpoint",disp="keep",enabled="y",addr="0x0804846b",func="main",file="hello.c",line="4",thread="0",thread="0",times="0"},bkpt={number="6",type="breakpoint",disp="keep",enabled="y",addr="0x0804846b",func="main",file="hello.c",line="4",thread="1",thread="1",times="0"}]}
    + * 
    + */ +public class MIBreakListInfo extends MIInfo { + + MIBreakpoint[] breakpoints; + + public MIBreakListInfo(MIOutput rr) { + super(rr); + } + + public MIBreakpoint[] getMIBreakpoints() { + if (breakpoints == null) { + parse(); + } + return breakpoints; + } + + void parse() { + List aList = new ArrayList(1); + if (isDone()) { + MIOutput out = getMIOutput(); + MIResultRecord rr = out.getMIResultRecord(); + if (rr != null) { + MIResult[] results = rr.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + if (var.equals("BreakpointTable")) { //$NON-NLS-1$ + parseTable(results[i].getMIValue(), aList); + } + } + } + } + breakpoints = aList.toArray(new MIBreakpoint[aList.size()]); + } + + void parseTable(MIValue val, List aList) { + if (val instanceof MITuple) { + MIResult[] table = ((MITuple)val).getMIResults(); + for (int j = 0; j < table.length; j++) { + String variable = table[j].getVariable(); + if (variable.equals("body")) { //$NON-NLS-1$ + parseBody(table[j].getMIValue(), aList); + } + } + } + } + + void parseBody(MIValue body, List aList) { + if (body instanceof MIList) { + MIResult[] bkpts = ((MIList)body).getMIResults(); + for (int i = 0; i < bkpts.length; i++) { + String b = bkpts[i].getVariable(); + if (b.equals("bkpt")) { //$NON-NLS-1$ + MIValue value = bkpts[i].getMIValue(); + if (value instanceof MITuple) { + aList.add(new MIBreakpoint((MITuple)value)); + } + } + } + } + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIBreakpoint.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIBreakpoint.java new file mode 100644 index 00000000000..0047439fc90 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIBreakpoint.java @@ -0,0 +1,294 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + * Ericsson - Modified for the breakpoint service + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + +/** + * Contain info about the GDB/MI breakpoint. + * + * (gdb) + * -break-insert main + * ^done,bkpt={number="1",type="breakpoint",disp="keep",enabled="y",addr="0x0804846b",func="main",file="hello.c",line="4",times="0"} + * (gdb) + * -break-insert -t main + * ^done,bkpt={number="2",type="breakpoint",disp="del",enabled="y",addr="0x0804846b",func="main",file="hello.c",line="4",times="0"} + * (gdb) + * -break-insert -c 1 main + * ^done,bkpt={number="3",type="breakpoint",disp="keep",enabled="y",addr="0x0804846b",func="main",file="hello.c",line="4",cond="1",times="0"} + * (gdb) + * -break-insert -h main + * ^done,bkpt={number="4",type="hw breakpoint",disp="keep",enabled="y",addr="0x0804846b",func="main",file="hello.c",line="4",times="0"} + * (gdb) + * -break-insert -p 0 main + * ^done,bkpt={number="5",type="breakpoint",disp="keep",enabled="y",addr="0x0804846b",func="main",file="hello.c",line="4",thread="0",thread="0",times="0"} + * (gdb) + * -break-watch -a p + * ^done,hw-awpt={number="2",exp="p"} + * (gdb) + * -break-watch -r p + * ^done,hw-rwpt={number="4",exp="p"} + * (gdb) + * -break-watch p + * ^done,wpt={number="6",exp="p"} + * (gdb) + */ +public class MIBreakpoint { + + int number = -1; + String type = ""; //$NON-NLS-1$ + String disp = ""; //$NON-NLS-1$ + boolean enabled = false; + String address = ""; //$NON-NLS-1$ + String func = ""; //$NON-NLS-1$ + String fullName = ""; //$NON-NLS-1$ + String file = ""; //$NON-NLS-1$ + int line = -1; + String cond = ""; //$NON-NLS-1$ + int times = 0; + String exp = ""; //$NON-NLS-1$ + String threadId = "0"; //$NON-NLS-1$ + int ignore = 0; + + boolean isWpt = false; + boolean isAWpt = false; + boolean isRWpt = false; + boolean isWWpt = false; + boolean isHdw = false; + + public MIBreakpoint() { + } + + public MIBreakpoint(MIBreakpoint other) { + number = other.number; + type = new String(other.type); + disp = new String(other.disp); + enabled = other.enabled; + type = new String(other.type); + address = new String(other.address); + func = new String(other.func); + fullName = new String(other.fullName); + file = new String(other.file); + line = other.line; + cond = new String(other.cond); + times = other.times; + exp = new String(other.exp); + threadId = new String(other.threadId); + ignore = other.ignore; + isWpt = other.isWpt; + isAWpt = other.isAWpt; + isRWpt = other.isRWpt; + isWWpt = other.isWWpt; + isHdw = other.isHdw; + } + + public MIBreakpoint(MITuple tuple) { + parse(tuple); + } + + /////////////////////////////////////////////////////////////////////////// + // Properties getters + /////////////////////////////////////////////////////////////////////////// + + public int getNumber() { + return number; + } + + public String getType() { + return type; + } + + public String getDisposition() { + return disp; + } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean e) { + enabled = e; + } + + public String getAddress() { + return address; + } + + public String getFunction() { + return func; + } + + public String getFile() { + return file; + } + + public String getFullName() { + return fullName; + } + + public int getLine() { + return line; + } + + public String getCondition() { + return cond; + } + + public void setCondition(String condition) { + cond = condition; + } + + public int getIgnoreCount() { + return ignore; + } + + public void setIgnoreCount(int ignoreCount) { + ignore = ignoreCount; + } + + public String getThreadId() { + return threadId; + } + + public int getTimes() { + return times; + } + + public String getExpression() { + return exp; + } + + public boolean isTemporary() { + return getDisposition().equals("del"); //$NON-NLS-1$ + } + + public boolean isHardware() { + return isHdw; + } + + public void setHardware(boolean b) { + isWpt = b; + isHdw = b; + } + + public boolean isWatchpoint() { + return isWpt; + } + + public void isWatchpoint(boolean b) { + isWpt = b; + } + + public boolean isAccessWatchpoint() { + return isAWpt; + } + + public void setAccessWatchpoint(boolean b) { + isWpt = b; + isAWpt = b; + } + + public boolean isReadWatchpoint() { + return isRWpt; + } + + public void setReadWatchpoint(boolean b) { + isWpt = b; + isRWpt = b; + } + + public boolean isWriteWatchpoint() { + return isWWpt; + } + + public void setWriteWatchpoint(boolean b) { + isWpt = b; + isWWpt = b; + } + + // Parse the result string + void parse(MITuple tuple) { + MIResult[] results = tuple.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + MIValue value = results[i].getMIValue(); + String str = ""; //$NON-NLS-1$ + if (value != null && value instanceof MIConst) { + str = ((MIConst)value).getCString(); + } + + if (var.equals("number")) { //$NON-NLS-1$ + try { + number = Integer.parseInt(str.trim()); + } catch (NumberFormatException e) { + } + } else if (var.equals("type")) { //$NON-NLS-1$ + type = str; + //type="hw watchpoint" + if (type.startsWith("hw")) { //$NON-NLS-1$ + isHdw = true; + isWWpt = true; + isWpt = true; + } + //type="acc watchpoint" + if (type.startsWith("acc")) { //$NON-NLS-1$ + isAWpt = true; + isWpt = true; + } + //type="read watchpoint" + if (type.startsWith("read")) { //$NON-NLS-1$ + isRWpt = true; + isWpt = true; + } + // type="breakpoint" + // default ok. + } else if (var.equals("disp")) { //$NON-NLS-1$ + disp = str; + } else if (var.equals("enabled")) { //$NON-NLS-1$ + enabled = str.equals("y"); //$NON-NLS-1$ + } else if (var.equals("addr")) { //$NON-NLS-1$ + try { + address = str.trim(); + } catch (NumberFormatException e) { + } + } else if (var.equals("func")) { //$NON-NLS-1$ + func = str; + } else if (var.equals("file")) { //$NON-NLS-1$ + file = str; + } else if (var.equals("fullname")) { //$NON-NLS-1$ + fullName = str; + } else if (var.equals("thread")) { //$NON-NLS-1$ + threadId = str; + } else if (var.equals("line")) { //$NON-NLS-1$ + try { + line = Integer.parseInt(str.trim()); + } catch (NumberFormatException e) { + } + } else if (var.equals("times")) { //$NON-NLS-1$ + try { + times = Integer.parseInt(str.trim()); + } catch (NumberFormatException e) { + } + } else if (var.equals("what") || var.equals("exp")) { //$NON-NLS-1$ //$NON-NLS-2$ + exp = str; + } else if (var.equals("ignore")) { //$NON-NLS-1$ + try { + ignore = Integer.parseInt(str.trim()); + } catch (NumberFormatException e) { + } + } else if (var.equals("cond")) { //$NON-NLS-1$ + cond = str; + } + } + } + +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIConsoleStreamOutput.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIConsoleStreamOutput.java new file mode 100644 index 00000000000..ce01d500c50 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIConsoleStreamOutput.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + +/** + * @see MIStreamRecord + */ +public class MIConsoleStreamOutput extends MIStreamRecord { +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIConst.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIConst.java new file mode 100644 index 00000000000..793d47a6b53 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIConst.java @@ -0,0 +1,124 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + +/** + * GDB/MI const value represents a ios-c string. + */ +public class MIConst extends MIValue { + String cstring = ""; //$NON-NLS-1$ + + public String getCString() { + return cstring; + } + + public void setCString(String str) { + cstring = str; + } + + /** + * Translate gdb c-string. + */ + public String getString() { + return getString(cstring); + } + + public static String getString(String str) { + StringBuffer buffer = new StringBuffer(); + boolean escape = false; + for (int i = 0; i < str.length(); i++) { + char c = str.charAt(i); + if (c == '\\') { + if (escape) { + buffer.append(c); + escape = false; + } else { + escape = true; + } + } else { + if (escape) { + if (isIsoCSpecialChar(c)) { + buffer.append(isoC(c)); + } else { + buffer.append('\\'); + buffer.append(c); + } + } else { + buffer.append(c); + } + escape = false; + } + } + + // If escape is still true it means that the + // last char was an '\'. + if (escape) { + buffer.append('\\'); + } + + return buffer.toString(); + } + + @Override + public String toString() { + return getCString(); + } + + /** + * Assuming that the precedent character was the + * escape sequence '\' + */ + private static String isoC(char c) { + String s = new Character(c).toString(); + if (c == '"') { + s = "\""; //$NON-NLS-1$ + } else if (c == '\'') { + s = "\'"; //$NON-NLS-1$ + } else if (c == '?') { + s = "?"; //$NON-NLS-1$ + } else if (c == 'a') { + s = "\007"; //$NON-NLS-1$ + } else if (c == 'b') { + s = "\b"; //$NON-NLS-1$ + } else if (c == 'f') { + s = "\f"; //$NON-NLS-1$ + } else if (c == 'n') { + s = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ $NON-NLS-2$ + } else if (c == 'r') { + s = "\r"; //$NON-NLS-1$ + } else if (c == 't') { + s = "\t"; //$NON-NLS-1$ + } else if (c == 'v') { + s = "\013"; //$NON-NLS-1$ + } + return s; + } + + private static boolean isIsoCSpecialChar(char c) { + switch (c) { + case '"': + case '\'': + case '?': + case 'a': + case 'b': + case 'f': + case 'n': + case 'r': + case 't': + case 'v': + return true; + } + return false; + + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIDataEvaluateExpressionInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIDataEvaluateExpressionInfo.java new file mode 100644 index 00000000000..9bac5e087c0 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIDataEvaluateExpressionInfo.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + +/** + * GDB/MI Data evaluate expression parsing response. + */ +public class MIDataEvaluateExpressionInfo extends MIInfo { + + String fValue; + + public MIDataEvaluateExpressionInfo(MIOutput rr) { + super(rr); + fValue = ""; //$NON-NLS-1$ + if (isDone()) { + MIOutput out = getMIOutput(); + MIResultRecord outr = out.getMIResultRecord(); + if (outr != null) { + MIResult[] results = outr.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + if (var.equals("value")) { //$NON-NLS-1$ + MIValue value = results[i].getMIValue(); + if (value instanceof MIConst) { + fValue = ((MIConst)value).getCString(); + } + } + } + } + } + } + + public String getValue() { + return fValue; + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIDataListRegisterNamesInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIDataListRegisterNamesInfo.java new file mode 100644 index 00000000000..78acb37e2cd --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIDataListRegisterNamesInfo.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + +import java.util.ArrayList; +import java.util.List; + +/** + * GDB/MI data list regiter names response extraction. + */ +public class MIDataListRegisterNamesInfo extends MIInfo { + + String[] names; + protected int realNameCount = 0; + + public MIDataListRegisterNamesInfo(MIOutput rr) { + super(rr); + names = null; + List aList = new ArrayList(); + if (isDone()) { + MIOutput out = getMIOutput(); + MIResultRecord outr = out.getMIResultRecord(); + if (outr != null) { + MIResult[] results = outr.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + if (var.equals("register-names")) { //$NON-NLS-1$ + MIValue value = results[i].getMIValue(); + if (value instanceof MIList) { + parseRegisters((MIList) value, aList); + } + } + } + } + } + names = aList.toArray(new String[aList.size()]); + } + + /* + * Returns the register names. + */ + public String[] getRegisterNames() { + + /* + * The expectation is that we return an empty list. The + * constructor quarantees this so we are good here. + */ + return names; + } + + private void parseRegisters(MIList list, List aList) { + MIValue[] values = list.getMIValues(); + for (int i = 0; i < values.length; i++) { + if (values[i] instanceof MIConst) { + String str = ((MIConst) values[i]).getCString(); + + /* this cannot filter nulls because index is critical in retreival + * and index is assigned in the layers above. The MI spec allows + * empty returns, for some register names. */ + if (str != null && str.length() > 0) { + realNameCount++; + aList.add(str); + } else { + aList.add(""); //$NON-NLS-1$ + } + } + } + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIDataListRegisterValuesInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIDataListRegisterValuesInfo.java new file mode 100644 index 00000000000..1dd4439431c --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIDataListRegisterValuesInfo.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.dd.dsf.debug.service.command.ICommand; +import org.eclipse.dd.dsf.debug.service.command.ICommandResult; +import org.eclipse.dd.mi.service.command.commands.MIDataListRegisterValues; + +/** + * GDB/MI data list register values extraction. + */ +public class MIDataListRegisterValuesInfo extends MIInfo { + + MIRegisterValue[] registers; + + public MIDataListRegisterValuesInfo(MIOutput rr) { + super(rr); + registers = null; + if (isDone()) { + MIOutput out = getMIOutput(); + MIResultRecord outr = out.getMIResultRecord(); + if (outr != null) { + MIResult[] results = outr.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + if (var.equals("register-values")) { //$NON-NLS-1$ + MIValue value = results[i].getMIValue(); + if (value instanceof MIList) { + registers = MIRegisterValue.getMIRegisterValues((MIList)value); + } + } + } + } + } + if (registers == null) { + registers = new MIRegisterValue[0]; + } + } + + /* + * Returns the array of registers values. + */ + + public MIRegisterValue[] getMIRegisterValues() { + + /* + * The expectation is that we return an empty list. The + * constructor quarantees this so we are good here. + */ + return registers; + } + + /** + * Returns the desired subset of results. When this function is being called + * the data here represents a coalesced request which is a superset of at + * least two original requests. We are extracting the data associated with + * the specified original request which we know is contained in this result. + */ + @Override + public V getSubsetResult(ICommand cmd) { + if (cmd instanceof MIDataListRegisterValues) { + MIDataListRegisterValues command = (MIDataListRegisterValues) cmd; + List aList = new ArrayList(); + int[] wantedRegNos = command.getRegList(); + + /* + * Search through the larger answer set finding the ones we want. + */ + for (MIRegisterValue regVal : registers) { + for ( int curRegNo : wantedRegNos ) { + if ( regVal.getNumber() == curRegNo ) { + aList.add( regVal ); + } + } + } + + /* + * Now construct a new complete answer. + */ + MIRegisterValue[] finalRegSet = aList.toArray(new MIRegisterValue[aList.size()]); + MIDataListRegisterValuesInfo finalSubset = new MIDataListRegisterValuesInfo( getMIOutput()); + finalSubset.registers = finalRegSet; + + @SuppressWarnings("unchecked") + V vFinalSubset = (V)finalSubset; + return vFinalSubset ; + } else { + return super.getSubsetResult(cmd); + } + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIDataReadMemoryInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIDataReadMemoryInfo.java new file mode 100644 index 00000000000..fbe560f05d7 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIDataReadMemoryInfo.java @@ -0,0 +1,248 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Ericsson AB - Modified for new DSF Reference Implementation + * Ericsson AB - Reverted to byte[] and processed multi-line results + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + +import java.math.BigInteger; + +import org.eclipse.debug.core.model.MemoryByte; + +/** + * + * -data-read-memory result + * + * (gdb) + * nn-data-read-memory [command parameters] + * nn^done,addr="ADDRESS",nr-bytes="NR_BYTES",total-bytes="TOTAL_BYTES", + * next-row="NEXT_ROW",prev-row="PREV_ROW",next-page="NEXT_PAGE", + * prev-page="PREV_PAGE",memory=[ + * {addr="addr1",data=["0x00","0x01", ...]}, + * {addr="addr2",data=["0x02","0x03", ...]}, + * {addr="addr3",data=["0x04","0x05", ...]}, + * ...] + * (gdb) + * + * where: + * + * 'ADDRESS' + * Address (in hex) of the first byte fetched. + * + * 'NR_BYTES' + * Number of bytes read. + * + * 'TOTAL_BYTES' + * Number of bytes requested (nr-rows * nr-columns * word-size). + * + * 'NEXT_ROW' + * Address (in hex) of the next row. + * + * 'PREV_ROW' + * Address (in hex) of the previous row. + * + * 'NEXT_PAGE' + * Address (in hex) of the next page. + * + * 'PREV_PAGE' + * Address (in hex) of the previous page. + * + * 'MEMORY' + * Memory bytes retrieved, nr-rows of nr-columns words. + * + */ +public class MIDataReadMemoryInfo extends MIInfo { + + // The parsed values of interest + BigInteger fAddress = new BigInteger("0"); //$NON-NLS-1$ + int fBytesRead; + int fBytesRequested; + MemoryByte[] fMemoryBlock; + + /** + * Constructor + * + * @param output + */ + public MIDataReadMemoryInfo(MIOutput output) { + + super(output); + + fMemoryBlock = new MemoryByte[0]; + if (isDone()) { + parseResult(1); + } + } + + /** + * Constructor + * + * @param output + */ + public MIDataReadMemoryInfo(MIOutput output, int word_size) { + + super(output); + + fMemoryBlock = new MemoryByte[0]; + if (isDone()) { + parseResult(word_size); + } + } + + /** + * Parse the back-end-result. The result is an array of the following form: + * + * [0] addr="address" + * [1] nr-bytes="x" + * [2] total-bytes="y" + * [3] next-row="address2" + * [4] prev-row="address3" + * [5] next-page="address4" + * [6] prev-page="address5" + * [7] memory=[{addr="addr1",data=["0x00","0x01",...]}] + * + * At this point, we only have interest in "memory". + */ + private void parseResult(int word_size) { + + // Get the GDB/MI result record + MIOutput output = getMIOutput(); + MIResultRecord record = output.getMIResultRecord(); + + // Parse the result record + if (record != null) { + + // Parse the output results + // Note: we assume that the result respects the output format + // i.e. nothing missing, nothing out of order. + MIResult[] results = record.getMIResults(); + for (int i = 0; i < results.length; i++) { + + // Get the variable name + String var = results[i].getVariable(); + + // Parse 'addr="address"', the address of the first byte to read + if (var.equals("addr")) { //$NON-NLS-1$ + MIValue value = results[i].getMIValue(); + if (value instanceof MIConst) { + String address = ((MIConst) value).getCString(); + fAddress = new BigInteger(address.substring(2), 16); // Strip the "0x" + } + } + + // Parse 'nr-bytes="x"', the number of bytes read + if (var.equals("total-bytes")) { //$NON-NLS-1$ + MIValue value = results[i].getMIValue(); + if (value instanceof MIConst) { + String size = ((MIConst) value).getCString(); + fBytesRead = Integer.parseInt(size); + } + } + + // Parse '"total-bytes="y"', the number of bytes requested + // Instantiate the corresponding output buffer with invalid bytes + if (var.equals("total-bytes")) { //$NON-NLS-1$ + MIValue value = results[i].getMIValue(); + if (value instanceof MIConst) { + String size = ((MIConst) value).getCString(); + fBytesRequested = Integer.parseInt(size); + fMemoryBlock = new MemoryByte[fBytesRequested]; + for (int j = 0; j < fMemoryBlock.length; j++) + fMemoryBlock[j] = new MemoryByte((byte) 0, (byte) 0); + } + } + + // Parse 'memory=[{addr="addr1",data=["0x00","0x01",...]}]' + if (var.equals("memory")) { //$NON-NLS-1$ + MIValue value = results[i].getMIValue(); + if (value instanceof MIList) { + parseMemoryLines((MIList) value, word_size); + } + } + } + } + } + + /** + * Parse the actual memory lines of the general form: + * + * [{addr="addr1",data=["0x00","0x01",...]}] + * [{addr="addr2",data=["0x00","0x01",...]}] + * + * Since we haven't implemented coalescing yet, we conveniently simplify + * the processing by assuming that the memory block address matches the + * one of the request. Therefore, we only have to fill the memoryBlock[] + * with the incoming bytes. + * + * This will have to be revisited as soon as we start considering + * multiple (and possibly canceled) requests. + */ + private void parseMemoryLines(MIList lines, int word_size) { + + // Parse each line and append the results to the result block + MIValue[] lineValues = lines.getMIValues(); + for (int i = 0; i < lineValues.length; i++) { + + // Each line has 2 tuples: "addr" and "data" + if (lineValues[i] instanceof MITuple) { + MITuple tuple = (MITuple) lineValues[i]; + MIResult[] results = tuple.getMIResults(); + + // The offset of this particular output line in the result buffer + int offset = 0; + + // The 1st tuple ('addr="addr1"') gives us the address of the first byte read + MIValue addrValue = results[0].getMIValue(); + if (addrValue instanceof MIConst) { + String address = ((MIConst) addrValue).getCString(); + BigInteger startAddress = new BigInteger(address.substring(2), 16); // Strip the "0x" + offset = startAddress.subtract(fAddress).intValue(); + } + + // The 2nd tuple ("data=[...]") gives us the actual bytes + MIValue value = results[1].getMIValue(); + if (value instanceof MIList) { + MIList list = (MIList) value; + MIValue[] values = list.getMIValues(); + + MemoryByte[] byteValues = new MemoryByte[values.length * word_size]; + + // Parse the result array + for (int j = 0; j < values.length; j++) { + if (values[j] instanceof MIConst) { + String str = ((MIConst) values[j]).getCString(); + try { + long word = Long.decode(str.trim()).longValue(); + for (int k = 0; k < word_size; k++) { + int bit_shift = (word_size - k - 1) * 8; + byteValues[j * word_size + k] = new MemoryByte((byte) ((word >> bit_shift) % 256)); + } + } catch (NumberFormatException e) { + for (int k = 0; k < word_size; k++) + byteValues[j * word_size + k] = new MemoryByte((byte) -1, (byte) 0); + } + } + } + // Copy the parsed line to the memory block + System.arraycopy(byteValues, 0, fMemoryBlock, offset, byteValues.length); + } + } + } + } + + /** + * Return the memory block + */ + public MemoryByte[] getMIMemoryBlock() { + return fMemoryBlock; + } + +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIDataWriteMemoryInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIDataWriteMemoryInfo.java new file mode 100644 index 00000000000..98f97d7fa48 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIDataWriteMemoryInfo.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Ericsson Communication - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + +/** + * -data-write-memory result + * + * (gdb) + * nn-data-write-memory [command parameters] + * nn^done + * + */ +public class MIDataWriteMemoryInfo extends MIInfo { + + /** + * Constructor + * + * @param output + */ + public MIDataWriteMemoryInfo(MIOutput output) { + + super(output); + } + +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIExecAsyncOutput.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIExecAsyncOutput.java new file mode 100644 index 00000000000..910254e479f --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIExecAsyncOutput.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + +/** + * @see MIAsyncRecord + */ +public class MIExecAsyncOutput extends MIAsyncRecord { +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIFrame.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIFrame.java new file mode 100644 index 00000000000..099b87e0100 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIFrame.java @@ -0,0 +1,136 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.output; + +/** + * GDB/MI Frame tuple parsing. + */ +public class MIFrame { + + int level; + String addr; + String func = ""; //$NON-NLS-1$ + String file = ""; //$NON-NLS-1$ + // since gdb 6.4 + String fullname = ""; //$NON-NLS-1$ + int line; + MIArg[] args = new MIArg[0]; + + public MIFrame(MITuple tuple) { + parse(tuple); + } + + public MIArg[] getArgs() { + return args; + } + + public String getFile() { + String fname = getFullname(); + return ( fname.length() != 0 ) ? fname : file; + } + + public String getFullname() { + return fullname; + } + + public String getFunction() { + return func; + } + + public int getLine() { + return line; + } + + public String getAddress() { + return addr; + } + + public int getLevel() { + return level; + } + + @Override + public String toString() { + StringBuffer buffer = new StringBuffer(); + buffer.append("level=\"" + level + "\""); //$NON-NLS-1$//$NON-NLS-2$ + buffer.append(",addr=\"" + addr + "\""); //$NON-NLS-1$//$NON-NLS-2$ + buffer.append(",func=\"" + func + "\""); //$NON-NLS-1$//$NON-NLS-2$ + buffer.append(",file=\"" + file + "\""); //$NON-NLS-1$//$NON-NLS-2$ + buffer.append(",line=\"").append(line).append('"'); //$NON-NLS-1$ + buffer.append(",args=["); //$NON-NLS-1$ + for (int i = 0; i < args.length; i++) { + if (i != 0) { + buffer.append(','); + } + buffer.append("{name=\"" + args[i].getName() + "\"");//$NON-NLS-1$//$NON-NLS-2$ + buffer.append(",value=\"" + args[i].getValue() + "\"}");//$NON-NLS-1$//$NON-NLS-2$ + } + buffer.append(']'); + return buffer.toString(); + } + + void parse(MITuple tuple) { + MIResult[] results = tuple.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + MIValue value = results[i].getMIValue(); + String str = ""; //$NON-NLS-1$ + if (value != null && value instanceof MIConst) { + str = ((MIConst)value).getCString(); + } + + if (var.equals("level")) { //$NON-NLS-1$ + try { + level = Integer.parseInt(str.trim()); + } catch (NumberFormatException e) { + } + } else if (var.equals("addr")) { //$NON-NLS-1$ + try { + addr = str.trim(); + } catch (NumberFormatException e) { + } + } else if (var.equals("func")) { //$NON-NLS-1$ + func = null; + if ( str != null ) { + str = str.trim(); + if ( str.equals( "??" ) ) //$NON-NLS-1$ + func = ""; //$NON-NLS-1$ + else + { + // In some situations gdb returns the function names that include parameter types. + // To make the presentation consistent truncate the parameters. PR 46592 + int end = str.indexOf( '(' ); + if ( end != -1 ) + func = str.substring( 0, end ); + else + func = str; + } + } + } else if (var.equals("file")) { //$NON-NLS-1$ + file = str; + } else if (var.equals("fullname")) { //$NON-NLS-1$ + fullname = str; + } else if (var.equals("line")) { //$NON-NLS-1$ + try { + line = Integer.parseInt(str.trim()); + } catch (NumberFormatException e) { + } + } else if (var.equals("args")) { //$NON-NLS-1$ + if (value instanceof MIList) { + args = MIArg.getMIArgs((MIList)value); + } else if (value instanceof MITuple) { + args = MIArg.getMIArgs((MITuple)value); + } + } + } + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIGDBShowExitCodeInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIGDBShowExitCodeInfo.java new file mode 100644 index 00000000000..48eb29aff33 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIGDBShowExitCodeInfo.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + +/** + * GDB/MI show parsing. + * (gdb) + * -data-evaluate-expression $_exitcode + * ^done,value="10" + * (gdb) + */ +public class MIGDBShowExitCodeInfo extends MIDataEvaluateExpressionInfo { + + public MIGDBShowExitCodeInfo(MIOutput o) { + super(o); + } + + public int getCode() { + int code = 0; + String exp = getValue(); + try { + code = Integer.parseInt(exp); + } catch (NumberFormatException e) { + } + return code; + } + +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIInfo.java new file mode 100644 index 00000000000..412252b557c --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIInfo.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + +import org.eclipse.dd.dsf.debug.service.command.ICommand; +import org.eclipse.dd.dsf.debug.service.command.ICommandResult; + +/** + * Base class for teh parsing/info GDB/MI classes. + */ +public class MIInfo implements ICommandResult { + + private final MIOutput miOutput; + + public MIInfo(MIOutput record) { + miOutput = record; + } + + public MIOutput getMIOutput () { + return miOutput; + } + + public boolean isDone() { + return isResultClass(MIResultRecord.DONE); + } + + public boolean isRunning() { + return isResultClass(MIResultRecord.RUNNING); + } + + public boolean isConnected() { + return isResultClass(MIResultRecord.CONNECTED); + } + + public boolean isError() { + return isResultClass(MIResultRecord.ERROR); + } + + public boolean isExit() { + return isResultClass(MIResultRecord.EXIT); + } + + @Override + public String toString() { + if (miOutput != null) { + return miOutput.toString(); + } + return ""; //$NON-NLS-1$ + } + + boolean isResultClass(String rc) { + if (miOutput != null) { + MIResultRecord rr = miOutput.getMIResultRecord(); + if (rr != null) { + String clazz = rr.getResultClass(); + return clazz.equals(rc); + } + } + return false; + } + + public String getErrorMsg() { + if (miOutput != null) { + MIResultRecord rr = miOutput.getMIResultRecord(); + if (rr != null) { + MIResult[] results = rr.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + if (var.equals("msg")) { //$NON-NLS-1$ + MIValue value = results[i].getMIValue(); + if (value instanceof MIConst) { + String s = ((MIConst)value).getCString(); + return s; + } + } + } + } + } + return ""; //$NON-NLS-1$ + } + + /** + * Default implementation of this method returns null, which means that a subset + * result canot be calculated for the given command. Deriving classes should + * override this method as needed. + */ + public V getSubsetResult(ICommand command) { + return null; + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIList.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIList.java new file mode 100644 index 00000000000..4ab77f21916 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIList.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + +/** + * GDB/MI list semantic. + */ +public class MIList extends MIValue { + + final static MIResult[] nullResults = new MIResult[0]; + final static MIValue[] nullValues = new MIValue[0]; + + MIResult[] results = nullResults; + MIValue[] values = nullValues; + + public MIResult[] getMIResults() { + return results; + } + + public void setMIResults(MIResult[] res) { + results = res; + } + + public MIValue[] getMIValues() { + return values; + } + + public void setMIValues(MIValue[] vals) { + values = vals; + } + + @Override + public String toString() { + StringBuffer buffer = new StringBuffer(); + buffer.append('['); + for (int i = 0; i < results.length; i++) { + if (i != 0) { + buffer.append(','); + } + buffer.append(results[i].toString()); + } + for (int i = 0; i < values.length; i++) { + if (i != 0) { + buffer.append(','); + } + buffer.append(values[i].toString()); + } + buffer.append(']'); + return buffer.toString(); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MILogStreamOutput.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MILogStreamOutput.java new file mode 100644 index 00000000000..a0e69a554b7 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MILogStreamOutput.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + +/** + * @see MIStreamRecord + */ +public class MILogStreamOutput extends MIStreamRecord { + +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MINotifyAsyncOutput.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MINotifyAsyncOutput.java new file mode 100644 index 00000000000..bdee6afa33d --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MINotifyAsyncOutput.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + + +/** + * @see MIAsyncRecord + */ +public class MINotifyAsyncOutput extends MIAsyncRecord { +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIOOBRecord.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIOOBRecord.java new file mode 100644 index 00000000000..27cddc4651e --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIOOBRecord.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + +/** + * @see MIOOBRecord + */ +public abstract class MIOOBRecord { +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIOutput.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIOutput.java new file mode 100644 index 00000000000..b501d663609 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIOutput.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + * Ericsson - Modified for additional features in DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + +/** + * GDB/MI response. + */ +public class MIOutput { + + private final MIResultRecord rr; + private final MIOOBRecord[] oobs; + + public MIOutput() { + this(null, null); + } + + public MIOutput(MIOOBRecord oob) { + this(null, new MIOOBRecord[] { oob }); + } + + + + public MIOutput(MIResultRecord rr, MIOOBRecord[] oobs) { + this.rr = rr; + this.oobs = oobs; + } + + public MIResultRecord getMIResultRecord() { + return rr; + } + + public MIOOBRecord[] getMIOOBRecords() { + return oobs; + } + + @Override + public String toString() { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < oobs.length; i++) { + buffer.append(oobs[i].toString()); + } + if (rr != null) { + buffer.append(rr.toString()); + } + return buffer.toString(); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIParser.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIParser.java new file mode 100644 index 00000000000..dd18a64d4d2 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIParser.java @@ -0,0 +1,559 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + +import java.util.ArrayList; +import java.util.List; + +/** +
    +`OUTPUT :'
    +     `( OUT-OF-BAND-RECORD )* [ RESULT-RECORD ] "(gdb)" NL'
    +
    +`RESULT-RECORD :'
    +     ` [ TOKEN ] "^" RESULT-CLASS ( "," RESULT )* NL'
    +
    +`OUT-OF-BAND-RECORD :'
    +     `ASYNC-RECORD | STREAM-RECORD'
    +
    +`ASYNC-RECORD :'
    +     `EXEC-ASYNC-OUTPUT | STATUS-ASYNC-OUTPUT | NOTIFY-ASYNC-OUTPUT'
    +
    +`EXEC-ASYNC-OUTPUT :'
    +     `[ TOKEN ] "*" ASYNC-OUTPUT'
    +
    +`STATUS-ASYNC-OUTPUT :'
    +     `[ TOKEN ] "+" ASYNC-OUTPUT'
    +
    +`NOTIFY-ASYNC-OUTPUT :'
    +     `[ TOKEN ] "=" ASYNC-OUTPUT'
    +
    +`ASYNC-OUTPUT :'
    +     `ASYNC-CLASS ( "," RESULT )* NL'
    +
    +`RESULT-CLASS :'
    +     `"done" | "running" | "connected" | "error" | "exit"'
    +
    +`ASYNC-CLASS :'
    +     `"stopped" | OTHERS' (where OTHERS will be added depending on the
    +     needs--this is still in development).
    +
    +`RESULT :'
    +     ` VARIABLE "=" VALUE'
    +
    +`VARIABLE :'
    +     ` STRING '
    +
    +`VALUE :'
    +     ` CONST | TUPLE | LIST '
    +
    +`CONST :'
    +     `C-STRING'
    +
    +`TUPLE :'
    +     ` "{}" | "{" RESULT ( "," RESULT )* "}" '
    +
    +`LIST :'
    +     ` "[]" | "[" VALUE ( "," VALUE )* "]" | "[" RESULT ( "," RESULT )*
    +     "]" '
    +
    +`STREAM-RECORD :'
    +     `CONSOLE-STREAM-OUTPUT | TARGET-STREAM-OUTPUT | LOG-STREAM-OUTPUT'
    +
    +`CONSOLE-STREAM-OUTPUT :'
    +     `"~" C-STRING'
    +
    +`TARGET-STREAM-OUTPUT :'
    +     `"@" C-STRING'
    +
    +`LOG-STREAM-OUTPUT :'
    +     `"&" C-STRING'
    +
    +`NL :'
    +     `CR | CR-LF'
    +
    +`TOKEN :'
    +     _any sequence of digits_.
    +
    +`C-STRING :'
    +     `""" SEVEN-BIT-ISO-C-STRING-CONTENT """'
    +
    + */ +public class MIParser { + public enum RecordType { ResultRecord, OOBRecord, PrimaryPrompt } + + public String primaryPrompt = "(gdb)"; //$NON-NLS-1$ + public String cliPrompt = primaryPrompt; + public String secondaryPrompt = ">"; //$NON-NLS-1$ + + public RecordType getRecordType(String line) { + int i = 0; + if (Character.isDigit(line.charAt(0))) { + i = 1; + while (i < line.length() && Character.isDigit(line.charAt(i))) { + i++; + } + } + + if (i < line.length() && line.charAt(i) == '^') { + return RecordType.ResultRecord; + } else if (line.startsWith(primaryPrompt, i)) { + return RecordType.PrimaryPrompt; + //break; // Do nothing. + } else { + return RecordType.OOBRecord; + } + } + + /** + * + */ + public MIResultRecord parseMIResultRecord(String line) { + StringBuffer buffer = new StringBuffer(line); + // Fetch the Token/Id + int id = parseToken(buffer); + // Consume the '^' + buffer.deleteCharAt(0); + + MIResultRecord rr = new MIResultRecord(); + rr.setToken(id); + if (buffer.toString().startsWith(MIResultRecord.DONE)) { + rr.setResultClass(MIResultRecord.DONE); + buffer.delete(0, MIResultRecord.DONE.length()); + } else if (buffer.toString().startsWith(MIResultRecord.ERROR)) { + rr.setResultClass(MIResultRecord.ERROR); + buffer.delete(0, MIResultRecord.ERROR.length()); + } else if (buffer.toString().startsWith(MIResultRecord.EXIT)) { + rr.setResultClass(MIResultRecord.EXIT); + buffer.delete(0, MIResultRecord.EXIT.length()); + } else if (buffer.toString().startsWith(MIResultRecord.RUNNING)) { + rr.setResultClass(MIResultRecord.RUNNING); + buffer.delete(0, MIResultRecord.RUNNING.length()); + } else if (buffer.toString().startsWith(MIResultRecord.CONNECTED)) { + rr.setResultClass(MIResultRecord.CONNECTED); + buffer.delete(0, MIResultRecord.CONNECTED.length()); + } else { + // Error throw an exception? + } + + // Results are separated by commas. + if (buffer.length() > 0 && buffer.charAt(0) == ',') { + buffer.deleteCharAt(0); + MIResult[] res = processMIResults(new FSB(buffer)); + rr.setMIResults(res); + } + return rr; + } + + /** + * Find OutOfBand Records depending on the starting token. + */ + public MIOOBRecord parseMIOOBRecord(String line) { + StringBuffer buffer = new StringBuffer(line); + int id = parseToken(buffer); + MIOOBRecord oob = null; + char c = buffer.length() != 0 ? buffer.charAt(0) : 0; + if (c == '*' || c == '+' || c == '=') { + // Consume the first char + buffer.deleteCharAt(0); + MIAsyncRecord async = null; + switch (c) { + case '*' : + async = new MIExecAsyncOutput(); + break; + + case '+' : + async = new MIStatusAsyncOutput(); + break; + + case '=' : + async = new MINotifyAsyncOutput(); + break; + } + async.setToken(id); + // Extract the Async-Class + int i = buffer.toString().indexOf(','); + if (i != -1) { + String asyncClass = buffer.substring(0, i); + async.setAsyncClass(asyncClass); + // Consume the async-class and the comma + buffer.delete(0, i + 1); + } else { + async.setAsyncClass(buffer.toString().trim()); + buffer.setLength(0); + } + MIResult[] res = processMIResults(new FSB(buffer)); + async.setMIResults(res); + oob = async; + } else if (c == '~' || c == '@' || c == '&') { + // Consume the first char + buffer.deleteCharAt(0); + MIStreamRecord stream = null; + switch (c) { + case '~' : + stream = new MIConsoleStreamOutput(); + break; + + case '@' : + stream = new MITargetStreamOutput(); + break; + + case '&' : + stream = new MILogStreamOutput(); + break; + } + // translateCString() assumes that the leading " is deleted + if (buffer.length() > 0 && buffer.charAt(0) == '"') { + buffer.deleteCharAt(0); + } + stream.setCString(translateCString(new FSB(buffer))); + oob = stream; + } else { + // Badly format MI line, just pass it to the user as target stream + MIStreamRecord stream = new MITargetStreamOutput(); + stream.setCString(line + "\n"); //$NON-NLS-1$ + oob = stream; + } + return oob; + } + + private int parseToken(StringBuffer buffer) { + int id = -1; + // Fetch the Token/Id + if (Character.isDigit(buffer.charAt(0))) { + int i = 1; + while (i < buffer.length() && Character.isDigit(buffer.charAt(i))) { + i++; + } + String numbers = buffer.substring(0, i); + try { + id = Integer.parseInt(numbers); + } catch (NumberFormatException e) { + } + // Consume the token. + buffer.delete(0, i); + } + return id; + } + + /** + * Assuming that the usual leading comma was consumed. + * Extract the MI Result comma seperated responses. + */ + private MIResult[] processMIResults(FSB buffer) { + List aList = new ArrayList(); + MIResult result = processMIResult(buffer); + if (result != null) { + aList.add(result); + } + while (buffer.length() > 0 && buffer.charAt(0) == ',') { + buffer.deleteCharAt(0); + result = processMIResult(buffer); + if (result != null) { + aList.add(result); + } + } + return aList.toArray(new MIResult[aList.size()]); + } + + /** + * Construct the DsfMIResult. Characters will be consume/delete + * moving forward constructing the AST. + */ + private MIResult processMIResult(FSB buffer) { + MIResult result = new MIResult(); + int equal; + if (buffer.length() > 0 && Character.isLetter(buffer.charAt(0)) && (equal = buffer.indexOf('=')) != -1) { + String variable = buffer.substring(0, equal); + result.setVariable(variable); + buffer.delete(0, equal + 1); + MIValue value = processMIValue(buffer); + result.setMIValue(value); + } else if(buffer.length()>0 && buffer.charAt(0)=='"') { + // This an error but we just swallow it and move on. + MIValue value = processMIValue(buffer); + result.setMIValue(value); + } else { + result.setVariable(buffer.toString()); + result.setMIValue(new MIConst()); // Empty string:??? + buffer.setLength(0); + } + return result; + } + + /** + * Find a DsfMIValue implementation or return null. + */ + private MIValue processMIValue(FSB buffer) { + MIValue value = null; + if (buffer.length() > 0) { + if (buffer.charAt(0) == '{') { + buffer.deleteCharAt(0); + value = processMITuple(buffer); + } else if (buffer.charAt(0) == '[') { + buffer.deleteCharAt(0); + value = processMIList(buffer); + } else if (buffer.charAt(0) == '"') { + buffer.deleteCharAt(0); + MIConst cnst = new MIConst(); + cnst.setCString(translateCString(buffer)); + value = cnst; + } + } + return value; + } + + /** + * Assuming the starting '{' was deleted form the StringBuffer, + * go to the closing '}' consuming/deleting all the characters. + * This is usually call by processMIvalue(); + */ + private MIValue processMITuple(FSB buffer) { + MITuple tuple = new MITuple(); + List valueList = new ArrayList(); + List resultList = new ArrayList(); + // Catch closing '}' + while (buffer.length() > 0 && buffer.charAt(0) != '}') { + // Try for the DsfMIValue first + MIValue value = processMIValue(buffer); + if (value != null) { + valueList.add(value); + } else { + MIResult result = processMIResult(buffer); + if (result != null) { + resultList.add(result); + } + } + if (buffer.length() > 0 && buffer.charAt(0) == ',') { + buffer.deleteCharAt(0); + } + } + if (buffer.length() > 0 && buffer.charAt(0) == '}') { + buffer.deleteCharAt(0); + } + MIValue[] values = valueList.toArray(new MIValue[valueList.size()]); + MIResult[] res = resultList.toArray(new MIResult[resultList.size()]); + tuple.setMIValues(values); + tuple.setMIResults(res); + return tuple; + } + + /** + * Assuming the leading '[' was deleted, find the closing + * ']' consuming/delete chars from the StringBuffer. + */ + private MIValue processMIList(FSB buffer) { + MIList list = new MIList(); + List valueList = new ArrayList(); + List resultList = new ArrayList(); + // catch closing ']' + while (buffer.length() > 0 && buffer.charAt(0) != ']') { + // Try for the DsfMIValue first + MIValue value = processMIValue(buffer); + if (value != null) { + valueList.add(value); + } else { + MIResult result = processMIResult(buffer); + if (result != null) { + resultList.add(result); + } + } + if (buffer.length() > 0 && buffer.charAt(0) == ',') { + buffer.deleteCharAt(0); + } + } + if (buffer.length() > 0 && buffer.charAt(0) == ']') { + buffer.deleteCharAt(0); + } + MIValue[] values = valueList.toArray(new MIValue[valueList.size()]); + MIResult[] res = resultList.toArray(new MIResult[resultList.size()]); + list.setMIValues(values); + list.setMIResults(res); + return list; + } + + /* + * MI C-String rather MICOnst values are enclose in double quotes + * and any double quotes or backslash in the string are escaped. + * Assuming the starting double quote was removed. + * This method will stop at the closing double quote remove the extra + * backslach escaping and return the string __without__ the enclosing double quotes + * The orignal StringBuffer will move forward. + */ + private String translateCString(FSB buffer) { + boolean escape = false; + boolean closingQuotes = false; + + StringBuffer sb = new StringBuffer(); + + int index = 0; + for (; index < buffer.length() && !closingQuotes; index++) { + char c = buffer.charAt(index); + if (c == '\\') { + if (escape) { + sb.append(c); + escape = false; + } else { + escape = true; + } + } else if (c == '"') { + if (escape) { + sb.append(c); + escape = false; + } else { + // Bail out. + closingQuotes = true; + } + } else { + if (escape) { + sb.append('\\'); + } + sb.append(c); + escape = false; + } + } + buffer.delete(0, index); + return sb.toString(); + } + + /** + * Tests if this string starts with the specified prefix beginning + * a specified index. + * + * @param value the string. + * @param prefix the prefix. + * @return true if prefix starts value. + */ + public boolean startsWith(StringBuffer value, String prefix) { + int vlen = value.length(); + int plen = prefix.length(); + + if (vlen < plen) { + return false; + } + for (int i = 0; i < plen; i++) { + if (value.charAt(i) != prefix.charAt(i)) { + return false; + } + } + return true; + } + + /** + * Fast String Buffer class. MIParser does a lot + * of deleting off the front of a string, that's clearly + * an order N operation for StringBuffer which makes + * the MIParser an order N^2 operation. There are "issues" + * with this for large arrays. Use of FSB rather than String + * Buffer makes MIParser N rather than N^2 because FSB can + * delete from the front in constant time. + */ + public class FSB { + StringBuffer buf; + int pos; + boolean shared; + + public FSB(StringBuffer buf) { + this.buf = buf; + pos = 0; + shared = false; + } + + public FSB(FSB fbuf) { + pos = fbuf.pos; + buf = fbuf.buf; + shared = true; + } + + public int length() { + int res = buf.length() - pos; + if (res < 0) + return 0; + + return res; + } + + public char charAt(int index) { + return buf.charAt(index + pos); + } + + private void resolveCopy() { + if (shared) { + buf = new StringBuffer(buf.toString()); + shared = false; + } + } + + public FSB deleteCharAt(int index) { + if (index == 0) { + pos++; + } else { + resolveCopy(); + buf = buf.deleteCharAt(pos + index); + } + + return this; + } + + public FSB delete(int start, int end) { + if (start == 0) { + pos = pos + end - start; + } else { + resolveCopy(); + buf.delete(start + pos, end + pos); + } + + return this; + } + + public void setLength(int a) { + if (a == 0) + pos = buf.length(); + else { + // panic! fortunately we don't do this. + } + } + + public String substring(int start, int end) { + return buf.substring(start + pos, end + pos); + } + + @Override + public String toString() { + return buf.substring(pos, buf.length()); + } + + int indexOf(char c) { + int len = buf.length(); + for (int i = pos; i < len; i++) { + if (buf.charAt(i) == c) + return i - pos; + } + + return -1; + } + + boolean startsWith(String s) { + int len = Math.min(s.length(), length()); + if (len < s.length()) + return false; + + for (int i = 0; i < len; i++) { + if (s.charAt(i) != buf.charAt(pos + i)) + return false; + } + + return true; + } + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIRegisterValue.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIRegisterValue.java new file mode 100644 index 00000000000..5cd896b4ae8 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIRegisterValue.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + +import java.util.ArrayList; +import java.util.List; + +/** + * GDB/MI register response parsing. + */ +public class MIRegisterValue { + int number; + String value; + + public MIRegisterValue(int n, String v) { + number = n; + value = v; + } + + public int getNumber() { + return number; + } + + public String getValue() { + return value; + } + + @Override + public String toString() { + StringBuffer buffer = new StringBuffer(); + buffer.append("number=\"").append(number).append('"'); //$NON-NLS-1$ + buffer.append(',').append("value=\"" + value + "\""); //$NON-NLS-1$ //$NON-NLS-2$ + return buffer.toString(); + } + + /** + * Parsing a MIList of the form: + * [{number="1",value="0xffff"},{number="xxx",value="yyy"},..] + */ + public static MIRegisterValue[] getMIRegisterValues(MIList miList) { + List aList = new ArrayList(); + MIValue[] values = miList.getMIValues(); + for (int i = 0; i < values.length; i++) { + if (values[i] instanceof MITuple) { + MIRegisterValue reg = getMIRegisterValue((MITuple)values[i]); + if (reg != null) { + aList.add(reg); + } + } + } + return (aList.toArray(new MIRegisterValue[aList.size()])); + } + + /** + * Parsing a MITuple of the form: + * {number="xxx",value="yyy"} + */ + public static MIRegisterValue getMIRegisterValue(MITuple tuple) { + MIResult[] args = tuple.getMIResults(); + MIRegisterValue arg = null; + if (args.length == 2) { + // Name + String aName = ""; //$NON-NLS-1$ + MIValue value = args[0].getMIValue(); + if (value != null && value instanceof MIConst) { + aName = ((MIConst)value).getCString(); + } else { + aName = ""; //$NON-NLS-1$ + } + + // Value + String aValue = ""; //$NON-NLS-1$ + value = args[1].getMIValue(); + if (value != null && value instanceof MIConst) { + aValue = ((MIConst)value).getCString(); + } else { + aValue = ""; //$NON-NLS-1$ + } + + try { + int reg = Integer.parseInt(aName.trim()); + arg = new MIRegisterValue(reg, aValue.trim()); + } catch (NumberFormatException e) { + } + } + return arg; + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIResult.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIResult.java new file mode 100644 index 00000000000..f60b843d472 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIResult.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + +/** + * GDB/MI result sematic (Variable=Value) + */ +public class MIResult { + String variable = ""; //$NON-NLS-1$ + MIValue value = null; + + public String getVariable() { + return variable; + } + + public void setVariable(String var) { + variable = var; + } + + public MIValue getMIValue() { + return value; + } + + public void setMIValue(MIValue val) { + value = val; + } + + @Override + public String toString() { + StringBuffer buffer = new StringBuffer(); + buffer.append(variable); + if (value != null) { + String v = value.toString(); + buffer.append('='); + if (v.length() > 0 && (v.charAt(0) == '[' || v.charAt(0) =='{')) { + buffer.append(v); + } else { + buffer.append("\"" + value.toString() + "\""); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + return buffer.toString(); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIResultRecord.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIResultRecord.java new file mode 100644 index 00000000000..c29e1a6ce2d --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIResultRecord.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + +/** + * GDB/MI ResultRecord. + */ +public class MIResultRecord { + + public final static String DONE ="done"; //$NON-NLS-1$ + public final static String RUNNING ="running"; //$NON-NLS-1$ + public final static String CONNECTED ="connected"; //$NON-NLS-1$ + public final static String ERROR ="error"; //$NON-NLS-1$ + public final static String EXIT ="exit"; //$NON-NLS-1$ + + static final MIResult[] nullResults = new MIResult[0]; + MIResult[] results = nullResults; + String resultClass = ""; //$NON-NLS-1$ + int token = -1; + + public int getToken() { + return token; + } + + public void setToken(int t) { + token = t; + } + + /** + */ + public String getResultClass() { + return resultClass; + } + + public void setResultClass(String type) { + resultClass = type; + } + + public MIResult[] getMIResults() { + return results; + } + + public void setMIResults(MIResult[] res) { + results = res; + } + + @Override + public String toString() { + StringBuffer buffer = new StringBuffer(); + buffer.append(token).append('^').append(resultClass); + for (int i = 0; i < results.length; i++) { + buffer.append(',').append(results[i].toString()); + } + return buffer.toString(); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIStackInfoDepthInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIStackInfoDepthInfo.java new file mode 100644 index 00000000000..abf13de8627 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIStackInfoDepthInfo.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2007 Ericsson 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: + * Ericsson - Initial Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + + +/** + * -stack-info-depth [max-depth] + * ^done,depth="12" + * + */ +public class MIStackInfoDepthInfo extends MIInfo { + + int depth = 0; + + public MIStackInfoDepthInfo(MIOutput record) { + super(record); + if (isDone()) { + MIOutput out = getMIOutput(); + MIResultRecord rr = out.getMIResultRecord(); + if (rr != null) { + MIResult[] results = rr.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + + if (var.equals("depth")) { //$NON-NLS-1$ + MIValue value = results[i].getMIValue(); + if (value instanceof MIConst) { + String str = ((MIConst)value).getString(); + try { + depth = Integer.parseInt(str.trim()); + } catch (NumberFormatException e) { + } + } + } + } + } + } + } + + public int getDepth() { + return depth; + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIStackListArgumentsInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIStackListArgumentsInfo.java new file mode 100644 index 00000000000..4d7f84cec84 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIStackListArgumentsInfo.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + +import java.util.ArrayList; +import java.util.List; + + +/** + * GDB/MI stack list arguments parsing. + */ +public class MIStackListArgumentsInfo extends MIInfo { + + MIFrame[] frames; + + public MIStackListArgumentsInfo(MIOutput out) { + super(out); + frames = null; + List aList = new ArrayList(1); + if (isDone()) { + MIResultRecord rr = out.getMIResultRecord(); + if (rr != null) { + MIResult[] results = rr.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + if (var.equals("stack-args")) { //$NON-NLS-1$ + MIValue val = results[i].getMIValue(); + if (val instanceof MIList) { + parseStack((MIList)val, aList); + } else if (val instanceof MIList) { + parseStack((MITuple)val, aList); + } + } + } + } + } + frames = aList.toArray(new MIFrame[aList.size()]); + } + + public MIFrame[] getMIFrames() { + return frames; + } + + private void parseStack(MIList miList, List aList) { + MIResult[] results = miList.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + if (var.equals("frame")) { //$NON-NLS-1$ + MIValue value = results[i].getMIValue(); + if (value instanceof MITuple) { + aList.add (new MIFrame((MITuple)value)); + } + } + } + } + + private void parseStack(MITuple miTuple, List aList) { + MIResult[] results = miTuple.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + if (var.equals("frame")) { //$NON-NLS-1$ + MIValue value = results[i].getMIValue(); + if (value instanceof MITuple) { + aList.add (new MIFrame((MITuple)value)); + } + } + } + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIStackListFramesInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIStackListFramesInfo.java new file mode 100644 index 00000000000..94c0a9ed7c7 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIStackListFramesInfo.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.output; + +import java.util.ArrayList; +import java.util.List; + +/** + * GDB/MI stack list frames info. + */ +public class MIStackListFramesInfo extends MIInfo { + + MIFrame[] frames; + + public MIStackListFramesInfo(MIOutput out) { + super(out); + frames = null; + List aList = new ArrayList(1); + if (isDone()) { + MIResultRecord rr = out.getMIResultRecord(); + if (rr != null) { + MIResult[] results = rr.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + if (var.equals("stack")) { //$NON-NLS-1$ + MIValue val = results[i].getMIValue(); + if (val instanceof MIList) { + parseStack((MIList)val, aList); + } else if (val instanceof MITuple) { + parseStack((MITuple)val, aList); + } + } + } + } + } + frames = aList.toArray(new MIFrame[aList.size()]); + } + + public MIFrame[] getMIFrames() { + return frames; + } + + void parseStack(MIList miList, List aList) { + MIResult[] results = miList.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + if (var.equals("frame")) { //$NON-NLS-1$ + MIValue value = results[i].getMIValue(); + if (value instanceof MITuple) { + aList.add (new MIFrame((MITuple)value)); + } + } + } + } + + // Old gdb use tuple instead of a list. + void parseStack(MITuple tuple, List aList) { + MIResult[] results = tuple.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + if (var.equals("frame")) { //$NON-NLS-1$ + MIValue value = results[i].getMIValue(); + if (value instanceof MITuple) { + aList.add (new MIFrame((MITuple)value)); + } + } + } + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIStackListLocalsInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIStackListLocalsInfo.java new file mode 100644 index 00000000000..7854276dd3d --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIStackListLocalsInfo.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + +/** + * GDB/MI stack list locals parsing. + * -stack-list-locals 1 + * ^done,locals=[{name="p",value="0x8048600 \"ghislaine\""},{name="buf",value="\"'\", 'x' , \"i,xxxxxxxxx\", 'a' "},{name="buf2",value="\"\\\"?'\\\\()~\""},{name="buf3",value="\"alain\""},{name="buf4",value="\"\\t\\t\\n\\f\\r\""},{name="i",value="0"}] + * + * On MacOS X 10.4 this returns a tuple: + * ^done,locals={{name="p",value="0x8048600 \"ghislaine\""},{name="buf",value="\"'\", 'x' , \"i,xxxxxxxxx\", 'a' "},{name="buf2",value="\"\\\"?'\\\\()~\""},{name="buf3",value="\"alain\""},{name="buf4",value="\"\\t\\t\\n\\f\\r\""},{name="i",value="0"}} + */ +public class MIStackListLocalsInfo extends MIInfo { + + MIArg[] locals; + + public MIStackListLocalsInfo(MIOutput out) { + super(out); + locals = null ; + if (isDone()) { + MIResultRecord rr = out.getMIResultRecord(); + if (rr != null) { + MIResult[] results = rr.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + if (var.equals("locals")) { //$NON-NLS-1$ + MIValue value = results[i].getMIValue(); + if (value instanceof MIList) { + locals = MIArg.getMIArgs((MIList)value); + } else if (value instanceof MITuple) { + locals = MIArg.getMIArgs((MITuple)value); + } + } + } + } + } + if (locals == null) { + locals = new MIArg[0]; + } + } + + public MIArg[] getLocals() { + return locals; + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIStatusAsyncOutput.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIStatusAsyncOutput.java new file mode 100644 index 00000000000..60d7891f7b5 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIStatusAsyncOutput.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + + +/** + * @see MIAsyncRecord + */ +public class MIStatusAsyncOutput extends MIAsyncRecord { + +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIStreamRecord.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIStreamRecord.java new file mode 100644 index 00000000000..f245d3263c4 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIStreamRecord.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + +/** + * GDB/MI stream record response. + */ +public abstract class MIStreamRecord extends MIOOBRecord { + + String cstring = ""; //$NON-NLS-1$ + + public String getCString() { + return cstring; + } + + public void setCString(String str) { + cstring = str; + } + + public String getString () { + return MIConst.getString(getCString()); + } + + @Override + public String toString() { + if (this instanceof MIConsoleStreamOutput) { return "~\"" + cstring + "\"\n"; } //$NON-NLS-1$ //$NON-NLS-2$ + else if (this instanceof MITargetStreamOutput) { return "@\"" + cstring + "\"\n"; } //$NON-NLS-1$ //$NON-NLS-2$ + else if (this instanceof MILogStreamOutput) { return "&\"" + cstring + "\"\n"; } //$NON-NLS-1$ //$NON-NLS-2$ + else { return "\"" + cstring + "\"\n"; } //$NON-NLS-1$ //$NON-NLS-2$ + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MITargetStreamOutput.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MITargetStreamOutput.java new file mode 100644 index 00000000000..1d8962b391f --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MITargetStreamOutput.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + +/** + * @see MIStreamRecord + */ +public class MITargetStreamOutput extends MIStreamRecord { + + public static final String startTag = "@"; //$NON-NLS-1$ +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIThreadListIdsInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIThreadListIdsInfo.java new file mode 100644 index 00000000000..956b0a27aa3 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIThreadListIdsInfo.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Ericsson AB - Modified for DSF Reference Implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.output; + +/** + * GDB/MI thread list parsing. + */ +public class MIThreadListIdsInfo extends MIInfo { + + int[] threadIds; + + public MIThreadListIdsInfo(MIOutput out) { + super(out); + } + + public int[] getThreadIds() { + if (threadIds == null) { + parse(); + } + return threadIds; + } + + void parse() { + if (isDone()) { + MIOutput out = getMIOutput(); + MIResultRecord rr = out.getMIResultRecord(); + if (rr != null) { + MIResult[] results = rr.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + if (var.equals("thread-ids")) { //$NON-NLS-1$ + MIValue val = results[i].getMIValue(); + if (val instanceof MITuple) { + parseThreadIds((MITuple)val); + } + } + } + } + } + if (threadIds == null) { + threadIds = new int[0]; + } + } + + void parseThreadIds(MITuple tuple) { + MIResult[] results = tuple.getMIResults(); + threadIds = new int[results.length]; + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + if (var.equals("thread-id")) { //$NON-NLS-1$ + MIValue value = results[i].getMIValue(); + if (value instanceof MIConst) { + String str = ((MIConst)value).getCString(); + try { + threadIds[i] = Integer.parseInt(str.trim()); + } catch (NumberFormatException e) { + } + } + } + } + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MITuple.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MITuple.java new file mode 100644 index 00000000000..da5ac67c6b0 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MITuple.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + +/** + * GDB/MI tuple value. + */ +public class MITuple extends MIValue { + + final static MIResult[] nullResults = new MIResult[0]; + final static MIValue[] nullValues = new MIValue[0]; + MIResult[] results = nullResults; + MIValue[] values = nullValues; + + public MIResult[] getMIResults() { + return results; + } + + public void setMIResults(MIResult[] res) { + results = res; + } + + public MIValue[] getMIValues() { + return values; + } + + public void setMIValues(MIValue[] vals) { + values = vals; + } + + @Override + public String toString() { + StringBuffer buffer = new StringBuffer(); + buffer.append('{'); + for (int i = 0; i < results.length; i++) { + if (i != 0) { + buffer.append(','); + } + buffer.append(results[i].toString()); + } + for (int i = 0; i < values.length; i++) { + if (i != 0) { + buffer.append(','); + } + buffer.append(values[i].toString()); + } + buffer.append('}'); + return buffer.toString(); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIValue.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIValue.java new file mode 100644 index 00000000000..a1346826992 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIValue.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + +/** + * GDB/MI value. + */ +public abstract class MIValue { +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVar.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVar.java new file mode 100644 index 00000000000..834f8cd5f09 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVar.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + +/** + * GDB/MI var-list-children + * -var-list-children var2 + * ^done,numchild="6",children={child={name="var2.0",exp="0",numchild="0",type="char"},child={name="var2.1",exp="1",numchild="0",type="char"},child={name="var2.2",exp="2",numchild="0",type="char"},child={name="var2.3",exp="3",numchild="0",type="char"},child={name="var2.4",exp="4",numchild="0",type="char"},child={name="var2.5",exp="5",numchild="0",type="char"}} + * + */ +public class MIVar { + + String name = ""; //$NON-NLS-1$ + String type = ""; //$NON-NLS-1$ + String exp = ""; //$NON-NLS-1$ + int numchild; + + + public MIVar(String n, int num, String t) { + name = n; + numchild = num; + type = t; + } + + public MIVar(MITuple tuple) { + parse(tuple); + } + + public String getVarName() { + return name; + } + + public String getType() { + return type; + } + + public int getNumChild() { + return numchild; + } + + public String getExp() { + return exp; + } + + void parse(MITuple tuple) { + MIResult[] results = tuple.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + MIValue value = results[i].getMIValue(); + String str = ""; //$NON-NLS-1$ + if (value != null && value instanceof MIConst) { + str = ((MIConst)value).getCString(); + } + + if (var.equals("numchild")) { //$NON-NLS-1$ + try { + numchild = Integer.parseInt(str.trim()); + } catch (NumberFormatException e) { + } + } else if (var.equals("name")) { //$NON-NLS-1$ + name = str; + } else if (var.equals("type")) { //$NON-NLS-1$ + type = str; + } else if (var.equals("exp")) { //$NON-NLS-1$ + exp = str; + } + } + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarAssignInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarAssignInfo.java new file mode 100644 index 00000000000..f6780355b56 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarAssignInfo.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2008 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.output; + +/** + * GDB/MI var-assign + * + * ^done,value="3" + */ +public class MIVarAssignInfo extends MIInfo { + + String value = ""; //$NON-NLS-1$ + + public MIVarAssignInfo(MIOutput record) { + super(record); + if (isDone()) { + MIOutput out = getMIOutput(); + MIResultRecord rr = out.getMIResultRecord(); + if (rr != null) { + MIResult[] results = rr.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + if (var.equals("value")) { //$NON-NLS-1$ + MIValue val = results[i].getMIValue(); + if (val instanceof MIConst) { + value = ((MIConst)val).getCString(); + } + } + } + } + } + } + + public String getValue () { + return value; + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarChange.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarChange.java new file mode 100644 index 00000000000..b6700cb6b57 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarChange.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.output; + +/** + * GDB/MI var-update. + */ + +public class MIVarChange { + String name; + String value; + boolean inScope; + boolean changed; + + public MIVarChange(String n) { + name = n; + } + + public String getVarName() { + return name; + } + + public String getValue() { + return value; + } + + public boolean isInScope() { + return inScope; + } + + public boolean isChanged() { + return changed; + } + + public void setValue(String v) { + value = v; + } + + public void setInScope(boolean b) { + inScope = b; + } + + public void setChanged(boolean c) { + changed = c; + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarCreateInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarCreateInfo.java new file mode 100644 index 00000000000..6f68e286943 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarCreateInfo.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + +/** + * GDB/MI var-create. + * -var-create "-" * a + * ^done,name="var1",numchild="0",value="11",type="int" + * -var-create "-" * buf + * ^done,name="var1",numchild="6",value=[6]",type="char [6]" + * + * Note that the value is returned in the output, as of GDB6.7 + */ +public class MIVarCreateInfo extends MIInfo { + + String name = ""; //$NON-NLS-1$ + int numChild; + String type = ""; //$NON-NLS-1$ + MIVar child; + String value = null; + + public MIVarCreateInfo(MIOutput record) { + super(record); + if (isDone()) { + MIOutput out = getMIOutput(); + MIResultRecord rr = out.getMIResultRecord(); + if (rr != null) { + MIResult[] results = rr.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + MIValue resultVal = results[i].getMIValue(); + String str = ""; //$NON-NLS-1$ + if (resultVal instanceof MIConst) { + str = ((MIConst)resultVal).getString(); + } + + if (var.equals("name")) { //$NON-NLS-1$ + name = str; + } else if (var.equals("numchild")) { //$NON-NLS-1$ + try { + numChild = Integer.parseInt(str.trim()); + } catch (NumberFormatException e) { + } + } else if (var.equals("type")) { //$NON-NLS-1$ + type = str; + } else if (var.equals("value")) { //$NON-NLS-1$ + value = str; + } + } + } + } + } + + public String getType() + { + return type; + } + + public int getNumChildren() + { + return numChild; + } + + public String getName() + { + return name; + } + + public String getValue() + { + return value; + } + + public MIVar getMIVar() { + if (child == null) { + child = new MIVar(name, numChild, type); + } + return child; + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarDeleteInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarDeleteInfo.java new file mode 100644 index 00000000000..9ea42bd3463 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarDeleteInfo.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + +/** + * GDB/MI var-delete. + */ +public class MIVarDeleteInfo extends MIInfo { + + int ndeleted; + + public MIVarDeleteInfo(MIOutput record) { + super(record); + ndeleted=0; + if (isDone()) { + MIOutput out = getMIOutput(); + MIResultRecord rr = out.getMIResultRecord(); + if (rr != null) { + MIResult[] results = rr.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + if (var.equals("ndeleted")) { //$NON-NLS-1$ + MIValue value = results[i].getMIValue(); + if (value instanceof MIConst) { + String str = ((MIConst)value).getString(); + try { + ndeleted = Integer.parseInt(str.trim()); + } catch (NumberFormatException e) { + } + } + } + } + } + } + } + + public int getNumberDeleted () { + return ndeleted; + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarEvaluateExpressionInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarEvaluateExpressionInfo.java new file mode 100644 index 00000000000..1f136b423c2 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarEvaluateExpressionInfo.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Modified for new DSF Reference Implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.output; + +/** + * GDB/MI var-evalute-expression + */ +public class MIVarEvaluateExpressionInfo extends MIInfo { + + String value = ""; //$NON-NLS-1$ + + public MIVarEvaluateExpressionInfo(MIOutput record) { + super(record); + if (isDone()) { + MIOutput out = getMIOutput(); + MIResultRecord rr = out.getMIResultRecord(); + if (rr != null) { + MIResult[] results = rr.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + if (var.equals("value")) { //$NON-NLS-1$ + MIValue val = results[i].getMIValue(); + if (val instanceof MIConst) { + value = ((MIConst)val).getCString(); + } + } + } + } + } + } + + public String getValue () { + return value; + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarInfoExpressionInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarInfoExpressionInfo.java new file mode 100644 index 00000000000..981bbc5dbb6 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarInfoExpressionInfo.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.output; + +/** + * GDB/MI var-info-expression. + */ +public class MIVarInfoExpressionInfo extends MIInfo { + + String lang = ""; //$NON-NLS-1$ + String exp = ""; //$NON-NLS-1$ + + public MIVarInfoExpressionInfo(MIOutput record) { + super(record); + if (isDone()) { + MIOutput out = getMIOutput(); + MIResultRecord rr = out.getMIResultRecord(); + if (rr != null) { + MIResult[] results = rr.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + MIValue value = results[i].getMIValue(); + String str = ""; //$NON-NLS-1$ + if (value instanceof MIConst) { + str = ((MIConst)value).getString(); + } + + if (var.equals("lang")) { //$NON-NLS-1$ + lang = str; + } else if (var.equals("exp")) { //$NON-NLS-1$ + exp = str; + } + } + } + } + } + + public String getLanguage () { + return lang; + } + + public String getExpression() { + return exp; + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarInfoNumChildrenInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarInfoNumChildrenInfo.java new file mode 100644 index 00000000000..d9765f5a311 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarInfoNumChildrenInfo.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + + +/** + * GDB/MI var-info-num-children. + */ +public class MIVarInfoNumChildrenInfo extends MIInfo { + + int children = 0; + + public MIVarInfoNumChildrenInfo(MIOutput record) { + super(record); + if (isDone()) { + MIOutput out = getMIOutput(); + MIResultRecord rr = out.getMIResultRecord(); + if (rr != null) { + MIResult[] results = rr.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + + if (var.equals("numchild")) { //$NON-NLS-1$ + MIValue value = results[i].getMIValue(); + if (value instanceof MIConst) { + String str = ((MIConst)value).getString(); + try { + children = Integer.parseInt(str.trim()); + } catch (NumberFormatException e) { + } + } + } + } + } + } + } + + public int getChildNumber() { + return children; + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarInfoPathExpressionInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarInfoPathExpressionInfo.java new file mode 100644 index 00000000000..b972fba41da --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarInfoPathExpressionInfo.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2007 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.output; + +/** + * GDB/MI var-info-path-expression. + * + * (gdb) -var-info-path-expression C.Base.public.m_size + * ^done,path_expr=((Base)c).m_size) + */ +public class MIVarInfoPathExpressionInfo extends MIInfo { + + String exp = ""; //$NON-NLS-1$ + + public MIVarInfoPathExpressionInfo(MIOutput record) { + super(record); + if (isDone()) { + MIOutput out = getMIOutput(); + MIResultRecord rr = out.getMIResultRecord(); + if (rr != null) { + MIResult[] results = rr.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + if (var.equals("path_expr")) { //$NON-NLS-1$ + MIValue val = results[i].getMIValue(); + if (val instanceof MIConst) { + exp = ((MIConst)val).getString(); + } + } + } + } + } + } + public String getFullExpression () { + return exp; + } + +} + diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarInfoTypeInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarInfoTypeInfo.java new file mode 100644 index 00000000000..e57df7147dc --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarInfoTypeInfo.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.output; + + +/** + * GDB/MI var-info-type + */ +public class MIVarInfoTypeInfo extends MIInfo { + + String type = ""; //$NON-NLS-1$ + + public MIVarInfoTypeInfo(MIOutput record) { + super(record); + if (isDone()) { + MIOutput out = getMIOutput(); + MIResultRecord rr = out.getMIResultRecord(); + if (rr != null) { + MIResult[] results = rr.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + if (var.equals("type")) { //$NON-NLS-1$ + MIValue value = results[i].getMIValue(); + if (value instanceof MIConst) { + type = ((MIConst)value).getString(); + } + } + } + } + } + } + + public String getType() { + return type; + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarListChildrenInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarListChildrenInfo.java new file mode 100644 index 00000000000..8073fb6f032 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarListChildrenInfo.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.output; + +import java.util.ArrayList; +import java.util.List; + +/** + * GDB/MI var-list-children + * -var-list-children var2 + * ^done,numchild="6",children={child={name="var2.0",exp="0",numchild="0",type="char"},child={name="var2.1",exp="1",numchild="0",type="char"},child={name="var2.2",exp="2",numchild="0",type="char"},child={name="var2.3",exp="3",numchild="0",type="char"},child={name="var2.4",exp="4",numchild="0",type="char"},child={name="var2.5",exp="5",numchild="0",type="char"}} + * + */ +public class MIVarListChildrenInfo extends MIInfo { + + MIVar[] children; + int numchild; + + public MIVarListChildrenInfo(MIOutput record) { + super(record); + List aList = new ArrayList(); + if (isDone()) { + MIOutput out = getMIOutput(); + MIResultRecord rr = out.getMIResultRecord(); + if (rr != null) { + MIResult[] results = rr.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + MIValue value = results[i].getMIValue(); + + if (var.equals("numchild")) { //$NON-NLS-1$ + if (value instanceof MIConst) { + String str = ((MIConst)value).getString(); + try { + numchild = Integer.parseInt(str.trim()); + } catch (NumberFormatException e) { + } + } + } else if (var.equals("children")) { //$NON-NLS-1$ + parseChildren(value, aList); + } + } + } + } + children = aList.toArray(new MIVar[aList.size()]); + } + + public MIVar[] getMIVars() { + return children; + } + + /* + * Some gdb MacOSX do not return a MITuple so we have + * to check for different format. + * See PR 81019 + */ + private void parseChildren(MIValue val, List aList) { + MIResult[] results = null; + if (val instanceof MITuple) { + results = ((MITuple)val).getMIResults(); + } else if (val instanceof MIList) { + results = ((MIList)val).getMIResults(); + } + if (results != null) { + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + if (var.equals("child")) { //$NON-NLS-1$ + MIValue value = results[i].getMIValue(); + if (value instanceof MITuple) { + aList.add(new MIVar((MITuple)value)); + } + } + } + } + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarSetFormatInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarSetFormatInfo.java new file mode 100644 index 00000000000..96774d9a3d6 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarSetFormatInfo.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2008 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.output; + +/** + * GDB/MI var-set-format + */ +public class MIVarSetFormatInfo extends MIInfo { + + String value = null; + + public MIVarSetFormatInfo(MIOutput record) { + super(record); + if (isDone()) { + MIOutput out = getMIOutput(); + MIResultRecord rr = out.getMIResultRecord(); + if (rr != null) { + MIResult[] results = rr.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + if (var.equals("value")) { //$NON-NLS-1$ + MIValue val = results[i].getMIValue(); + if (val instanceof MIConst) { + value = ((MIConst)val).getCString(); + } + } + } + } + } + } + + public String getValue () { + return value; + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarShowAttributesInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarShowAttributesInfo.java new file mode 100644 index 00000000000..20ee3e04bca --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarShowAttributesInfo.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.output; + +/** + * GDB/MI var-show-attributes + */ +public class MIVarShowAttributesInfo extends MIInfo { + + String attr = ""; //$NON-NLS-1$ + + public MIVarShowAttributesInfo(MIOutput record) { + super(record); + if (isDone()) { + MIOutput out = getMIOutput(); + MIResultRecord rr = out.getMIResultRecord(); + if (rr != null) { + MIResult[] results = rr.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + if (var.equals("attr")) { //$NON-NLS-1$ + MIValue value = results[i].getMIValue(); + if (value instanceof MIConst) { + attr = ((MIConst)value).getString(); + } + } + } + } + } + } + + public String getAttributes () { + return attr; + } + + public boolean isEditable() { + return attr.equals("editable"); //$NON-NLS-1$ + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarShowFormatInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarShowFormatInfo.java new file mode 100644 index 00000000000..70708edd31a --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarShowFormatInfo.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.output; + +import org.eclipse.dd.mi.service.MIFormat; + + +/** + * GDB/MI var-show-format + */ +public class MIVarShowFormatInfo extends MIInfo { + + int format = MIFormat.NATURAL; + + public MIVarShowFormatInfo(MIOutput record) { + super(record); + if (isDone()) { + MIOutput out = getMIOutput(); + MIResultRecord rr = out.getMIResultRecord(); + if (rr != null) { + MIResult[] results = rr.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + if (var.equals("name")) { //$NON-NLS-1$ + MIValue value = results[i].getMIValue(); + if (value instanceof MIConst) { + String str = ((MIConst)value).getString(); + if ("binary".equals(str)) { //$NON-NLS-1$ + format = MIFormat.BINARY; + } else if ("decimal".equals(str)) { //$NON-NLS-1$ + format = MIFormat.DECIMAL; + } else if ("hexadecimal".equals(str)) { //$NON-NLS-1$ + format = MIFormat.HEXADECIMAL; + } else if ("octal".equals(str)) { //$NON-NLS-1$ + format = MIFormat.OCTAL; + } else if ("natural".equals(str)) { //$NON-NLS-1$ + format = MIFormat.NATURAL; + } + } + } + } + } + } + } + + public int getFormat() { + return format; + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarUpdateInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarUpdateInfo.java new file mode 100644 index 00000000000..a17d43bb4d9 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIVarUpdateInfo.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.output; + +import java.util.ArrayList; +import java.util.List; + +/** + * GDB/MI var-update. + * -var-update * + * ^done,changelist={name="var3",value="3",in_scope="true",type_changed="false",name="var2",value="4",in_scope="true",type_changed="false"} + */ +public class MIVarUpdateInfo extends MIInfo { + + MIVarChange[] changeList; + + public MIVarUpdateInfo(MIOutput record) { + super(record); + List aList = new ArrayList(); + if (isDone()) { + MIOutput out = getMIOutput(); + MIResultRecord rr = out.getMIResultRecord(); + if (rr != null) { + MIResult[] results = rr.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + if (var.equals("changelist")) { //$NON-NLS-1$ + MIValue value = results[i].getMIValue(); + if (value instanceof MITuple) { + parseChangeList((MITuple)value, aList); + } else if (value instanceof MIList) { + parseChangeList((MIList)value, aList); + } + } + } + } + } + changeList = aList.toArray(new MIVarChange[aList.size()]); + } + + public MIVarChange[] getMIVarChanges() { + return changeList; + } + + /** + * For MI2 the format is now a MIList. + * @param tuple + * @param aList + */ + void parseChangeList(MIList miList, List aList) { + MIValue[] values = miList.getMIValues(); + for (int i = 0; i < values.length; ++i) { + if (values[i] instanceof MITuple) { + parseChangeList((MITuple)values[i], aList); + } else if (values[i] instanceof MIList) { + parseChangeList((MIList)values[i], aList); + } + } + } + + void parseChangeList(MITuple tuple, List aList) { + MIResult[] results = tuple.getMIResults(); + MIVarChange change = null; + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + MIValue value = results[i].getMIValue(); + if (value instanceof MITuple) { + parseChangeList((MITuple)value, aList); + } + else + { + String str = ""; //$NON-NLS-1$ + if (value instanceof MIConst) { + str = ((MIConst)value).getString(); + } + if (var.equals("name")) { //$NON-NLS-1$ + change = new MIVarChange(str); + aList.add(change); + } else if (var.equals("value")) { //$NON-NLS-1$ + if (change != null) { + change.setValue(str); + } + } else if (var.equals("in_scope")) { //$NON-NLS-1$ + if (change != null) { + change.setInScope("true".equals(str)); //$NON-NLS-1$ + } + } else if (var.equals("type_changed")) { //$NON-NLS-1$ + if (change != null) { + change.setChanged("true".equals(str)); //$NON-NLS-1$ + } + } + } + } + } +} From aad3ee68f9e5e0f4522c4ff83803a0b9a5afc083 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 13 Feb 2008 20:41:00 +0000 Subject: [PATCH 242/834] [179102] Re-aligned plugin and package names to confirm with Eclipse policy. --- .../.settings/org.eclipse.core.resources.prefs | 4 ++-- plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF | 4 ++-- plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml | 2 +- .../dd/dsf/debug/{ => internal}/ui/DsfDebugUIPlugin.java | 2 +- .../numberformat/detail/MessagesForNumberFormatDetail.java | 2 +- .../numberformat/detail/NumberFormatDetailPane.java | 6 +++--- .../numberformat/detail/NumberFormatDetailPaneFactory.java | 2 +- .../ui/viewmodel/numberformat/detail/TextViewerAction.java | 2 +- .../ui/viewmodel/numberformat/detail/messages.properties | 0 .../eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java | 4 ++-- .../eclipse/dd/dsf/debug/ui/actions/DsfResumeCommand.java | 2 +- .../eclipse/dd/dsf/debug/ui/actions/DsfStepIntoCommand.java | 2 +- .../eclipse/dd/dsf/debug/ui/actions/DsfStepOverCommand.java | 6 +++--- .../dd/dsf/debug/ui/actions/DsfStepReturnCommand.java | 6 +++--- .../eclipse/dd/dsf/debug/ui/actions/DsfSuspendCommand.java | 2 +- .../eclipse/dd/dsf/debug/ui/contexts/DsfSuspendTrigger.java | 2 +- .../dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java | 4 ++-- .../dd/dsf/debug/ui/viewmodel/IDebugVMConstants.java | 2 +- .../ui/viewmodel/expression/AbstractExpressionVMNode.java | 6 +++--- .../viewmodel/expression/ExpressionColumnPresentation.java | 2 +- .../debug/ui/viewmodel/expression/ExpressionVMProvider.java | 4 ++-- .../expression/ExpressionVMProviderContentStragegy.java | 2 +- .../debug/ui/viewmodel/expression/VMExpressionUpdate.java | 2 +- .../dd/dsf/debug/ui/viewmodel/launch/LaunchRootVMNode.java | 2 +- .../dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java | 6 +++--- .../dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPane.java | 6 +++--- .../dd/dsf/debug/ui/viewmodel/modules/ModulesVMNode.java | 6 +++--- .../dsf/debug/ui/viewmodel/modules/ModulesVMProvider.java | 4 ++-- .../ui/viewmodel/numberformat/AbstractSetFormatStyle.java | 2 +- .../numberformat/{ => actions}/SetDefaultFormatBinary.java | 3 ++- .../numberformat/{ => actions}/SetDefaultFormatDecimal.java | 3 ++- .../numberformat/{ => actions}/SetDefaultFormatHex.java | 3 ++- .../numberformat/{ => actions}/SetDefaultFormatNatural.java | 3 ++- .../numberformat/{ => actions}/SetDefaultFormatOctal.java | 3 ++- .../ui/viewmodel/register/RegisterBitFieldCellModifier.java | 2 +- .../debug/ui/viewmodel/register/RegisterBitFieldVMNode.java | 6 +++--- .../debug/ui/viewmodel/register/RegisterCellModifier.java | 2 +- .../ui/viewmodel/register/RegisterColumnPresentation.java | 2 +- .../debug/ui/viewmodel/register/RegisterGroupVMNode.java | 6 +++--- .../dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java | 6 +++--- .../dsf/debug/ui/viewmodel/register/RegisterVMProvider.java | 4 ++-- .../debug/ui/viewmodel/register/SyncRegisterDataAccess.java | 4 ++-- .../debug/ui/viewmodel/variable/SyncVariableDataAccess.java | 2 +- .../ui/viewmodel/variable/VariableColumnPresentation.java | 2 +- .../dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java | 6 +++--- .../dsf/debug/ui/viewmodel/variable/VariableVMProvider.java | 4 ++-- plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF | 4 ++-- .../eclipse/dd/dsf/debug/{ => internal}/DsfDebugPlugin.java | 2 +- .../src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java | 2 +- .../eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java | 2 +- .../eclipse/dd/dsf/debug/service/BreakpointsMediator.java | 2 +- .../org/eclipse/dd/dsf/debug/service/StepQueueManager.java | 2 +- .../eclipse/dd/dsf/debug/service/command/CommandCache.java | 2 +- .../debug/sourcelookup/DsfMISourceLookupParticipant.java | 2 +- plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF | 6 +++--- .../org/eclipse/dd/dsf/{ => internal}/ui/DsfUIPlugin.java | 2 +- .../org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java | 2 +- .../src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMNode.java | 2 +- .../src/org/eclipse/dd/dsf/ui/viewmodel/IRootVMNode.java | 1 - .../src/org/eclipse/dd/dsf/ui/viewmodel/IVMNode.java | 2 +- .../dd/dsf/ui/viewmodel/ModelProxyInstalledEvent.java | 1 + .../org/eclipse/dd/dsf/ui/viewmodel/VMChildrenUpdate.java | 2 +- .../src/org/eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java | 2 +- .../ui/viewmodel/{dm => datamodel}/AbstractDMVMAdapter.java | 2 +- .../ui/viewmodel/{dm => datamodel}/AbstractDMVMNode.java | 4 ++-- .../viewmodel/{dm => datamodel}/AbstractDMVMProvider.java | 2 +- .../viewmodel/{dm => datamodel}/CompositeDMVMContext.java | 2 +- .../dd/dsf/ui/viewmodel/{dm => datamodel}/IDMVMContext.java | 2 +- .../dd/dsf/ui/viewmodel/{dm => datamodel}/RootDMVMNode.java | 2 +- .../eclipse/dd/dsf/ui/viewmodel/properties/LabelText.java | 2 +- .../ui/viewmodel/properties/PropertyBasedLabelProvider.java | 2 +- plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF | 4 ++-- .../eclipse/dd/dsf/concurrent/CountingRequestMonitor.java | 2 +- .../org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java | 2 +- .../src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java | 2 +- .../org/eclipse/dd/dsf/concurrent/ImmediateExecutor.java | 2 +- .../org/eclipse/dd/dsf/concurrent/MultiRequestMonitor.java | 2 +- .../src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java | 2 +- .../src/org/eclipse/dd/dsf/concurrent/Sequence.java | 2 +- .../src/org/eclipse/dd/dsf/{ => internal}/DsfPlugin.java | 2 +- .../src/org/eclipse/dd/dsf/service/DsfSession.java | 2 +- 81 files changed, 120 insertions(+), 115 deletions(-) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal}/ui/DsfDebugUIPlugin.java (97%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal}/ui/viewmodel/numberformat/detail/MessagesForNumberFormatDetail.java (87%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal}/ui/viewmodel/numberformat/detail/NumberFormatDetailPane.java (99%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal}/ui/viewmodel/numberformat/detail/NumberFormatDetailPaneFactory.java (97%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal}/ui/viewmodel/numberformat/detail/TextViewerAction.java (97%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal}/ui/viewmodel/numberformat/detail/messages.properties (100%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/{ => actions}/SetDefaultFormatBinary.java (84%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/{ => actions}/SetDefaultFormatDecimal.java (84%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/{ => actions}/SetDefaultFormatHex.java (84%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/{ => actions}/SetDefaultFormatNatural.java (84%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/{ => actions}/SetDefaultFormatOctal.java (84%) rename plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/{ => internal}/DsfDebugPlugin.java (98%) rename plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/{ => internal}/ui/DsfUIPlugin.java (97%) rename plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/{dm => datamodel}/AbstractDMVMAdapter.java (96%) rename plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/{dm => datamodel}/AbstractDMVMNode.java (99%) rename plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/{dm => datamodel}/AbstractDMVMProvider.java (99%) rename plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/{dm => datamodel}/CompositeDMVMContext.java (98%) rename plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/{dm => datamodel}/IDMVMContext.java (95%) rename plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/{dm => datamodel}/RootDMVMNode.java (98%) rename plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/{ => internal}/DsfPlugin.java (98%) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/.settings/org.eclipse.core.resources.prefs b/plugins/org.eclipse.dd.dsf.debug.ui/.settings/org.eclipse.core.resources.prefs index 9517031575f..6fdff509a41 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/.settings/org.eclipse.core.resources.prefs +++ b/plugins/org.eclipse.dd.dsf.debug.ui/.settings/org.eclipse.core.resources.prefs @@ -1,3 +1,3 @@ -#Tue Nov 20 14:43:47 PST 2007 +#Tue Feb 12 16:03:29 PST 2008 eclipse.preferences.version=1 -encoding//src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/messages.properties=8859_1 +encoding//src/org/eclipse/dd/dsf/debug/internal/ui/viewmodel/numberformat/detail/messages.properties=8859_1 diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF index 09411a94f98..fd7fe663941 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF @@ -4,7 +4,7 @@ Bundle-Name: Debug Services Framework Debug UI Bundle-Vendor: Eclipse.org Bundle-SymbolicName: org.eclipse.dd.dsf.debug.ui; singleton:=true Bundle-Version: 1.0.0.qualifier -Bundle-Activator: org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin +Bundle-Activator: org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin Bundle-Localization: plugin Require-Bundle: org.eclipse.ui, org.eclipse.core.runtime, @@ -19,7 +19,7 @@ Require-Bundle: org.eclipse.ui, org.eclipse.dd.dsf.debug, org.eclipse.cdt.core, org.eclipse.cdt.debug.ui -Eclipse-LazyStart: true +Bundle-ActivationPolicy: lazy Export-Package: org.eclipse.dd.dsf.debug.ui, org.eclipse.dd.dsf.debug.ui.actions, diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml index 242376a0803..1c4c74cc81f 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml +++ b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml @@ -110,7 +110,7 @@ diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/DsfDebugUIPlugin.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/DsfDebugUIPlugin.java similarity index 97% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/DsfDebugUIPlugin.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/DsfDebugUIPlugin.java index 2facb074854..5e20f049521 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/DsfDebugUIPlugin.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/DsfDebugUIPlugin.java @@ -1,4 +1,4 @@ -package org.eclipse.dd.dsf.debug.ui; +package org.eclipse.dd.dsf.debug.internal.ui; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.ui.plugin.AbstractUIPlugin; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/MessagesForNumberFormatDetail.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/viewmodel/numberformat/detail/MessagesForNumberFormatDetail.java similarity index 87% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/MessagesForNumberFormatDetail.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/viewmodel/numberformat/detail/MessagesForNumberFormatDetail.java index ccdba675d7e..17b12ebcd28 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/MessagesForNumberFormatDetail.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/viewmodel/numberformat/detail/MessagesForNumberFormatDetail.java @@ -1,4 +1,4 @@ -package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.detail; +package org.eclipse.dd.dsf.debug.internal.ui.viewmodel.numberformat.detail; import org.eclipse.osgi.util.NLS; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/NumberFormatDetailPane.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/viewmodel/numberformat/detail/NumberFormatDetailPane.java similarity index 99% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/NumberFormatDetailPane.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/viewmodel/numberformat/detail/NumberFormatDetailPane.java index 503b87a9dc2..4ef667d3b88 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/NumberFormatDetailPane.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/viewmodel/numberformat/detail/NumberFormatDetailPane.java @@ -9,7 +9,7 @@ * IBM Corporation - initial API and implementation * Randy Rohrbach (Wind River Systems, Inc.) - extended implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.detail; +package org.eclipse.dd.dsf.debug.internal.ui.viewmodel.numberformat.detail; import java.text.MessageFormat; import java.util.ArrayList; @@ -27,6 +27,7 @@ import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.service.IExpressions; import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.dd.dsf.debug.service.IRegisters; @@ -36,9 +37,8 @@ import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData; import org.eclipse.dd.dsf.debug.service.IFormattedValues.IFormattedDataDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IBitFieldDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext; -import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.service.DsfServicesTracker; -import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.model.IDebugElement; import org.eclipse.debug.core.model.IExpression; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/NumberFormatDetailPaneFactory.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/viewmodel/numberformat/detail/NumberFormatDetailPaneFactory.java similarity index 97% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/NumberFormatDetailPaneFactory.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/viewmodel/numberformat/detail/NumberFormatDetailPaneFactory.java index 637bf2cd92e..9244986f66a 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/NumberFormatDetailPaneFactory.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/viewmodel/numberformat/detail/NumberFormatDetailPaneFactory.java @@ -8,7 +8,7 @@ * Contributors: * Randy Rohrbach (Wind River Systems, Inc.) - initial implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.detail; +package org.eclipse.dd.dsf.debug.internal.ui.viewmodel.numberformat.detail; import java.util.HashSet; import java.util.Set; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/TextViewerAction.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/viewmodel/numberformat/detail/TextViewerAction.java similarity index 97% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/TextViewerAction.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/viewmodel/numberformat/detail/TextViewerAction.java index df9178b6238..a4006004ce8 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/TextViewerAction.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/viewmodel/numberformat/detail/TextViewerAction.java @@ -9,7 +9,7 @@ * IBM Corporation - initial API and implementation * Randy Rohrbach (Wind River Systems, Inc.) - extended implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.detail; +package org.eclipse.dd.dsf.debug.internal.ui.viewmodel.numberformat.detail; import org.eclipse.jface.action.Action; import org.eclipse.jface.text.ITextOperationTarget; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/messages.properties b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/viewmodel/numberformat/detail/messages.properties similarity index 100% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/detail/messages.properties rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/viewmodel/numberformat/detail/messages.properties diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java index cd05575d3bc..3dcb478854d 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java @@ -15,12 +15,12 @@ import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.service.IRunControl; import org.eclipse.dd.dsf.debug.service.StepQueueManager; import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; -import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.service.DsfServicesTracker; -import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext; import org.eclipse.debug.core.commands.IDebugCommandRequest; @Immutable diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfResumeCommand.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfResumeCommand.java index 23adc2644d4..8f30f31bc0a 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfResumeCommand.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfResumeCommand.java @@ -13,7 +13,7 @@ package org.eclipse.dd.dsf.debug.ui.actions; import org.eclipse.dd.dsf.concurrent.DsfExecutor; import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.debug.core.commands.IDebugCommandRequest; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepIntoCommand.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepIntoCommand.java index 16c1b183d48..31a184e29b0 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepIntoCommand.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepIntoCommand.java @@ -12,8 +12,8 @@ package org.eclipse.dd.dsf.debug.ui.actions; import org.eclipse.dd.dsf.concurrent.DsfExecutor; import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.service.IRunControl.StepType; -import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.debug.core.commands.IDebugCommandRequest; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepOverCommand.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepOverCommand.java index 6881453e80d..6967dedd3be 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepOverCommand.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepOverCommand.java @@ -12,16 +12,16 @@ package org.eclipse.dd.dsf.debug.ui.actions; import org.eclipse.dd.dsf.concurrent.DsfExecutor; import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.service.IRunControl.StepType; -import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.debug.core.commands.IDebugCommandRequest; import org.eclipse.debug.core.commands.IEnabledStateRequest; -import org.eclipse.debug.core.commands.IStepIntoHandler; +import org.eclipse.debug.core.commands.IStepOverHandler; @Immutable -public class DsfStepOverCommand implements IStepIntoHandler { +public class DsfStepOverCommand implements IStepOverHandler { private final DsfExecutor fExecutor; private final DsfServicesTracker fTracker; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepReturnCommand.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepReturnCommand.java index 0e179cebc19..295919ac191 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepReturnCommand.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepReturnCommand.java @@ -12,16 +12,16 @@ package org.eclipse.dd.dsf.debug.ui.actions; import org.eclipse.dd.dsf.concurrent.DsfExecutor; import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.service.IRunControl.StepType; -import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.debug.core.commands.IDebugCommandRequest; import org.eclipse.debug.core.commands.IEnabledStateRequest; -import org.eclipse.debug.core.commands.IStepIntoHandler; +import org.eclipse.debug.core.commands.IStepReturnHandler; @Immutable -public class DsfStepReturnCommand implements IStepIntoHandler { +public class DsfStepReturnCommand implements IStepReturnHandler { private final DsfExecutor fExecutor; private final DsfServicesTracker fTracker; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfSuspendCommand.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfSuspendCommand.java index 882d165fe09..6f1a3e963ce 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfSuspendCommand.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfSuspendCommand.java @@ -13,7 +13,7 @@ package org.eclipse.dd.dsf.debug.ui.actions; import org.eclipse.dd.dsf.concurrent.DsfExecutor; import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.debug.core.commands.IDebugCommandRequest; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/contexts/DsfSuspendTrigger.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/contexts/DsfSuspendTrigger.java index e9394594cc4..c5dfe9b0a2c 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/contexts/DsfSuspendTrigger.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/contexts/DsfSuspendTrigger.java @@ -23,8 +23,8 @@ import org.eclipse.core.runtime.jobs.Job; 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.debug.internal.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.service.IRunControl; -import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.debug.core.ILaunch; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java index b4689d6e5b6..c869bd4f8e1 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java @@ -29,6 +29,7 @@ import org.eclipse.dd.dsf.concurrent.Query; import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.service.IRunControl; import org.eclipse.dd.dsf.debug.service.IStack; import org.eclipse.dd.dsf.debug.service.StepQueueManager; @@ -36,11 +37,10 @@ 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.sourcelookup.DsfMISourceLookupParticipant; -import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext; import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector; import org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant; import org.eclipse.debug.ui.IDebugUIConstants; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/IDebugVMConstants.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/IDebugVMConstants.java index e381f8d40b7..213728fcc94 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/IDebugVMConstants.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/IDebugVMConstants.java @@ -1,6 +1,6 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel; -import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; public interface IDebugVMConstants { /** diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionVMNode.java index c5fbf8165d3..86c6a6bf1da 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionVMNode.java @@ -18,13 +18,13 @@ import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.MultiRequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.concurrent.ViewerDataRequestMonitor; import org.eclipse.dd.dsf.ui.viewmodel.VMChildrenUpdate; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMNode; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; import org.eclipse.debug.core.model.IExpression; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionColumnPresentation.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionColumnPresentation.java index 87ea315c615..01d249ccea8 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionColumnPresentation.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionColumnPresentation.java @@ -10,7 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; -import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java index 6cdd02889fd..b9613fe4980 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java @@ -29,8 +29,8 @@ import org.eclipse.dd.dsf.ui.viewmodel.IRootVMNode; import org.eclipse.dd.dsf.ui.viewmodel.IVMModelProxy; import org.eclipse.dd.dsf.ui.viewmodel.IVMNode; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; -import org.eclipse.dd.dsf.ui.viewmodel.dm.RootDMVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.RootDMVMNode; import org.eclipse.dd.dsf.ui.viewmodel.update.AutomaticUpdatePolicy; import org.eclipse.dd.dsf.ui.viewmodel.update.IVMUpdatePolicy; import org.eclipse.dd.dsf.ui.viewmodel.update.ManualUpdatePolicy; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderContentStragegy.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderContentStragegy.java index 68fe43293aa..1488f99f368 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderContentStragegy.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderContentStragegy.java @@ -12,7 +12,7 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.concurrent.ViewerDataRequestMonitor; import org.eclipse.dd.dsf.ui.viewmodel.DefaultVMContentProviderStrategy; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/VMExpressionUpdate.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/VMExpressionUpdate.java index 3c74a22fc17..beb74d991f4 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/VMExpressionUpdate.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/VMExpressionUpdate.java @@ -13,8 +13,8 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.internal.ui.DsfUIPlugin; import org.eclipse.dd.dsf.service.IDsfService; -import org.eclipse.dd.dsf.ui.DsfUIPlugin; import org.eclipse.dd.dsf.ui.viewmodel.VMViewerUpdate; import org.eclipse.debug.core.model.IExpression; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/LaunchRootVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/LaunchRootVMNode.java index c6074e21142..d3e1ea62a3c 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/LaunchRootVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/LaunchRootVMNode.java @@ -16,7 +16,7 @@ import java.util.List; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.IRootVMNode; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java index 317a2c584f1..0ceca2adc27 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java @@ -33,9 +33,9 @@ import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.ModelProxyInstalledEvent; import org.eclipse.dd.dsf.ui.viewmodel.VMChildrenUpdate; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMNode; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; -import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPane.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPane.java index 311de5557bc..f8a099b75a7 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPane.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPane.java @@ -27,15 +27,15 @@ import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.Query; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.debug.internal.ui.viewmodel.numberformat.detail.TextViewerAction; import org.eclipse.dd.dsf.debug.service.IModules; import org.eclipse.dd.dsf.debug.service.IModules.IModuleDMContext; import org.eclipse.dd.dsf.debug.service.IModules.IModuleDMData; -import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; -import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.detail.TextViewerAction; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; -import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext; import org.eclipse.debug.core.model.IDebugElement; import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.internal.ui.IDebugHelpContextIds; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMNode.java index d660b5edc20..40bafae38c3 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMNode.java @@ -15,19 +15,19 @@ import java.util.concurrent.RejectedExecutionException; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.service.IModules; import org.eclipse.dd.dsf.debug.service.IRegisters; import org.eclipse.dd.dsf.debug.service.IRunControl; import org.eclipse.dd.dsf.debug.service.IModules.IModuleDMContext; import org.eclipse.dd.dsf.debug.service.IModules.IModuleDMData; import org.eclipse.dd.dsf.debug.service.IModules.ISymbolDMContext; -import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.ui.IDsfDebugUIConstants; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMNode; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMProvider.java index 436e4d8dd91..231bb84d748 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMProvider.java @@ -14,8 +14,8 @@ import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; import org.eclipse.dd.dsf.ui.viewmodel.IVMNode; import org.eclipse.dd.dsf.ui.viewmodel.IRootVMNode; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; -import org.eclipse.dd.dsf.ui.viewmodel.dm.RootDMVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.RootDMVMNode; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; /** diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/AbstractSetFormatStyle.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/AbstractSetFormatStyle.java index 9347d4f8da9..39bf8fda798 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/AbstractSetFormatStyle.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/AbstractSetFormatStyle.java @@ -12,7 +12,7 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat; import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; -import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext; import org.eclipse.debug.core.model.IDebugElement; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/SetDefaultFormatBinary.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/actions/SetDefaultFormatBinary.java similarity index 84% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/SetDefaultFormatBinary.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/actions/SetDefaultFormatBinary.java index cb4e08a1635..a1c24053d7c 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/SetDefaultFormatBinary.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/actions/SetDefaultFormatBinary.java @@ -8,9 +8,10 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat; +package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.actions; import org.eclipse.dd.dsf.debug.service.IFormattedValues; +import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.AbstractSetFormatStyle; @SuppressWarnings("restriction") public class SetDefaultFormatBinary extends AbstractSetFormatStyle { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/SetDefaultFormatDecimal.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/actions/SetDefaultFormatDecimal.java similarity index 84% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/SetDefaultFormatDecimal.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/actions/SetDefaultFormatDecimal.java index 0cbe7b570bb..ce2aa237b31 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/SetDefaultFormatDecimal.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/actions/SetDefaultFormatDecimal.java @@ -8,9 +8,10 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat; +package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.actions; import org.eclipse.dd.dsf.debug.service.IFormattedValues; +import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.AbstractSetFormatStyle; @SuppressWarnings("restriction") public class SetDefaultFormatDecimal extends AbstractSetFormatStyle { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/SetDefaultFormatHex.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/actions/SetDefaultFormatHex.java similarity index 84% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/SetDefaultFormatHex.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/actions/SetDefaultFormatHex.java index e728974e16b..e193c685959 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/SetDefaultFormatHex.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/actions/SetDefaultFormatHex.java @@ -8,9 +8,10 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat; +package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.actions; import org.eclipse.dd.dsf.debug.service.IFormattedValues; +import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.AbstractSetFormatStyle; @SuppressWarnings("restriction") public class SetDefaultFormatHex extends AbstractSetFormatStyle { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/SetDefaultFormatNatural.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/actions/SetDefaultFormatNatural.java similarity index 84% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/SetDefaultFormatNatural.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/actions/SetDefaultFormatNatural.java index d844b93c3df..60e83c20362 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/SetDefaultFormatNatural.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/actions/SetDefaultFormatNatural.java @@ -8,9 +8,10 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat; +package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.actions; import org.eclipse.dd.dsf.debug.service.IFormattedValues; +import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.AbstractSetFormatStyle; @SuppressWarnings("restriction") public class SetDefaultFormatNatural extends AbstractSetFormatStyle { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/SetDefaultFormatOctal.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/actions/SetDefaultFormatOctal.java similarity index 84% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/SetDefaultFormatOctal.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/actions/SetDefaultFormatOctal.java index 468cf6a9e42..edf05b5fb49 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/SetDefaultFormatOctal.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/actions/SetDefaultFormatOctal.java @@ -8,9 +8,10 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat; +package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.actions; import org.eclipse.dd.dsf.debug.service.IFormattedValues; +import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.AbstractSetFormatStyle; @SuppressWarnings("restriction") public class SetDefaultFormatOctal extends AbstractSetFormatStyle { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldCellModifier.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldCellModifier.java index 50e510ed53f..67bc504f975 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldCellModifier.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldCellModifier.java @@ -16,7 +16,7 @@ import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionCellModifier; import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValuePreferenceStore; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; -import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext; import org.eclipse.dd.dsf.ui.viewmodel.update.AbstractCachingVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.update.UserEditEvent; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java index 83bc2e40d09..3d29b733e04 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java @@ -20,6 +20,7 @@ import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.dd.dsf.debug.service.IRegisters; import org.eclipse.dd.dsf.debug.service.IRunControl; @@ -32,7 +33,6 @@ import org.eclipse.dd.dsf.debug.service.IRegisters.IMnemonic; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext; import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent; -import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.AbstractExpressionVMNode; import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValuePreferenceStore; @@ -42,8 +42,8 @@ import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; -import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext; import org.eclipse.debug.core.model.IExpression; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementEditor; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterCellModifier.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterCellModifier.java index b3cec6066f3..0b28160e064 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterCellModifier.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterCellModifier.java @@ -19,7 +19,7 @@ import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionCellModifier; import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValuePreferenceStore; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; -import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext; import org.eclipse.dd.dsf.ui.viewmodel.update.AbstractCachingVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.update.UserEditEvent; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterColumnPresentation.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterColumnPresentation.java index b7c15157661..360a29a1de8 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterColumnPresentation.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterColumnPresentation.java @@ -10,7 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.viewmodel.register; -import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java index 69380da24dc..ca83235aacb 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java @@ -20,12 +20,12 @@ import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.service.IRegisters; import org.eclipse.dd.dsf.debug.service.IRunControl; import org.eclipse.dd.dsf.debug.service.IRegisters.IGroupChangedDMEvent; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMData; -import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.AbstractExpressionVMNode; import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionCellModifier; @@ -33,8 +33,8 @@ import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; -import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext; import org.eclipse.debug.core.model.IExpression; import org.eclipse.debug.internal.ui.DebugPluginImages; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java index b222bed823e..71ce6399069 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java @@ -20,6 +20,7 @@ import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.dd.dsf.debug.service.IRegisters; import org.eclipse.dd.dsf.debug.service.IRunControl; @@ -29,7 +30,6 @@ import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterChangedDMEvent; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMData; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext; -import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.AbstractExpressionVMNode; import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValuePreferenceStore; @@ -38,8 +38,8 @@ import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; -import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext; import org.eclipse.debug.core.model.IExpression; import org.eclipse.debug.internal.ui.DebugPluginImages; import org.eclipse.debug.internal.ui.DebugUIPlugin; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java index 3927d23c824..e1ec8cefae0 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java @@ -16,8 +16,8 @@ import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; import org.eclipse.dd.dsf.ui.viewmodel.IRootVMNode; import org.eclipse.dd.dsf.ui.viewmodel.IVMNode; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; -import org.eclipse.dd.dsf.ui.viewmodel.dm.RootDMVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.RootDMVMNode; import org.eclipse.dd.dsf.ui.viewmodel.update.AutomaticUpdatePolicy; import org.eclipse.dd.dsf.ui.viewmodel.update.IVMUpdatePolicy; import org.eclipse.dd.dsf.ui.viewmodel.update.ManualUpdatePolicy; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java index f7f3a08eccc..8fecbdb88c5 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java @@ -21,6 +21,7 @@ import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.concurrent.ThreadSafeAndProhibitedFromDsfExecutor; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.service.IRegisters; import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext; import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData; @@ -32,11 +33,10 @@ import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMData; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMData; -import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.service.DsfServices; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; -import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext; import org.osgi.framework.InvalidSyntaxException; import org.osgi.util.tracker.ServiceTracker; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java index 34060bfc2fe..0f715b36969 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java @@ -15,13 +15,13 @@ import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.Query; import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.concurrent.ThreadSafeAndProhibitedFromDsfExecutor; +import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.service.IExpressions; import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMData; import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext; import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData; import org.eclipse.dd.dsf.debug.service.IFormattedValues.IFormattedDataDMContext; -import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.osgi.framework.InvalidSyntaxException; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableColumnPresentation.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableColumnPresentation.java index fd5cfd52ccd..2a35acd6f2f 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableColumnPresentation.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableColumnPresentation.java @@ -10,7 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.viewmodel.variable; -import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java index 9a594f7ab21..8e3883c4e36 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java @@ -23,6 +23,7 @@ import org.eclipse.dd.dsf.concurrent.MultiRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.service.IExpressions; import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.dd.dsf.debug.service.IRunControl; @@ -35,7 +36,6 @@ import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData; import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; import org.eclipse.dd.dsf.debug.service.IStack.IVariableDMContext; import org.eclipse.dd.dsf.debug.service.IStack.IVariableDMData; -import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.AbstractExpressionVMNode; import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.IExpressionUpdate; @@ -45,8 +45,8 @@ import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; -import org.eclipse.dd.dsf.ui.viewmodel.dm.IDMVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext; import org.eclipse.debug.core.model.IExpression; import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java index c518f638978..1e27d8921f0 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java @@ -14,8 +14,8 @@ import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; import org.eclipse.dd.dsf.ui.viewmodel.IRootVMNode; import org.eclipse.dd.dsf.ui.viewmodel.IVMNode; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; -import org.eclipse.dd.dsf.ui.viewmodel.dm.RootDMVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.RootDMVMNode; import org.eclipse.dd.dsf.ui.viewmodel.update.AutomaticUpdatePolicy; import org.eclipse.dd.dsf.ui.viewmodel.update.IVMUpdatePolicy; import org.eclipse.dd.dsf.ui.viewmodel.update.ManualUpdatePolicy; diff --git a/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF index 8edc247599b..2378adc0ed4 100644 --- a/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF @@ -4,14 +4,14 @@ Bundle-Name: Debug Services Framework Debug Bundle-Vendor: Eclipse.org Bundle-SymbolicName: org.eclipse.dd.dsf.debug;singleton:=true Bundle-Version: 1.0.0.qualifier -Bundle-Activator: org.eclipse.dd.dsf.debug.DsfDebugPlugin +Bundle-Activator: org.eclipse.dd.dsf.debug.internal.DsfDebugPlugin Bundle-Localization: plugin Require-Bundle: org.eclipse.core.runtime, org.eclipse.debug.core, org.eclipse.dd.dsf, org.eclipse.cdt.core, org.eclipse.cdt.debug.core -Eclipse-LazyStart: true +Bundle-ActivationPolicy: lazy Export-Package: org.eclipse.dd.dsf.debug.model, org.eclipse.dd.dsf.debug.service, org.eclipse.dd.dsf.debug.service.command, diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/DsfDebugPlugin.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/internal/DsfDebugPlugin.java similarity index 98% rename from plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/DsfDebugPlugin.java rename to plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/internal/DsfDebugPlugin.java index 7a8cbd969f3..bbae6fed35a 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/DsfDebugPlugin.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/internal/DsfDebugPlugin.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug; +package org.eclipse.dd.dsf.debug.internal; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Plugin; diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java index 9e5ad02079d..9fabdab6f67 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java @@ -27,7 +27,7 @@ import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.Query; import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.debug.DsfDebugPlugin; +import org.eclipse.dd.dsf.debug.internal.DsfDebugPlugin; import org.eclipse.dd.dsf.debug.service.IMemory; import org.eclipse.dd.dsf.debug.service.IRunControl; import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryChangedEvent; diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java index 922f5a3adde..5095a8c35ca 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java @@ -25,7 +25,7 @@ import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfExecutor; import org.eclipse.dd.dsf.concurrent.Query; import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.debug.DsfDebugPlugin; +import org.eclipse.dd.dsf.debug.internal.DsfDebugPlugin; import org.eclipse.dd.dsf.debug.service.IExpressions; import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.dd.dsf.debug.service.IMemory; diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/BreakpointsMediator.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/BreakpointsMediator.java index 2adec9cf43a..c7982a28c8c 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/BreakpointsMediator.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/BreakpointsMediator.java @@ -34,7 +34,7 @@ import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.datamodel.DMContexts; -import org.eclipse.dd.dsf.debug.DsfDebugPlugin; +import org.eclipse.dd.dsf.debug.internal.DsfDebugPlugin; import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointDMContext; import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; import org.eclipse.dd.dsf.service.AbstractDsfService; diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/StepQueueManager.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/StepQueueManager.java index c46b28611f7..0d148b08b28 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/StepQueueManager.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/StepQueueManager.java @@ -21,7 +21,7 @@ import java.util.concurrent.TimeUnit; import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMEvent; -import org.eclipse.dd.dsf.debug.DsfDebugPlugin; +import org.eclipse.dd.dsf.debug.internal.DsfDebugPlugin; import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent; import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent; diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java index 72ea07c381e..96093c215dc 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java @@ -24,7 +24,7 @@ import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.debug.DsfDebugPlugin; +import org.eclipse.dd.dsf.debug.internal.DsfDebugPlugin; import org.eclipse.dd.dsf.service.IDsfService; /** diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java index 17f6612dca9..9c4b59b3549 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java @@ -28,7 +28,7 @@ import org.eclipse.dd.dsf.concurrent.DsfExecutor; import org.eclipse.dd.dsf.concurrent.Query; import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.debug.DsfDebugPlugin; +import org.eclipse.dd.dsf.debug.internal.DsfDebugPlugin; import org.eclipse.dd.dsf.debug.service.IStack; import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMData; diff --git a/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF index 7eda21ec60b..b068b2e3ff9 100644 --- a/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF @@ -4,16 +4,16 @@ Bundle-Name: Debug Services Framework UI Bundle-Vendor: Eclipse.org Bundle-SymbolicName: org.eclipse.dd.dsf.ui;singleton:=true Bundle-Version: 1.0.0.qualifier -Bundle-Activator: org.eclipse.dd.dsf.ui.DsfUIPlugin +Bundle-Activator: org.eclipse.dd.dsf.internal.ui.DsfUIPlugin Bundle-Localization: plugin Require-Bundle: org.eclipse.ui, org.eclipse.core.runtime, org.eclipse.dd.dsf, org.eclipse.debug.ui -Eclipse-LazyStart: true +Bundle-ActivationPolicy: lazy Export-Package: org.eclipse.dd.dsf.ui.concurrent, org.eclipse.dd.dsf.ui.viewmodel, - org.eclipse.dd.dsf.ui.viewmodel.dm, + org.eclipse.dd.dsf.ui.viewmodel.datamodel, org.eclipse.dd.dsf.ui.viewmodel.properties, org.eclipse.dd.dsf.ui.viewmodel.update Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/DsfUIPlugin.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/internal/ui/DsfUIPlugin.java similarity index 97% rename from plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/DsfUIPlugin.java rename to plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/internal/ui/DsfUIPlugin.java index bea8083dc93..87d6dafb296 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/DsfUIPlugin.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/internal/ui/DsfUIPlugin.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.ui; +package org.eclipse.dd.dsf.internal.ui; import org.eclipse.ui.plugin.AbstractUIPlugin; import org.osgi.framework.BundleContext; diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java index b04f9a60e50..95de160fabb 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java @@ -18,8 +18,8 @@ import java.util.concurrent.RejectedExecutionException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.dd.dsf.internal.ui.DsfUIPlugin; import org.eclipse.dd.dsf.service.IDsfService; -import org.eclipse.dd.dsf.ui.DsfUIPlugin; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMNode.java index 436aec4aeca..f8f67ed9be9 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMNode.java @@ -14,8 +14,8 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.internal.ui.DsfUIPlugin; import org.eclipse.dd.dsf.service.IDsfService; -import org.eclipse.dd.dsf.ui.DsfUIPlugin; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IRootVMNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IRootVMNode.java index 7af91afcdde..d9a6d9411fe 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IRootVMNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IRootVMNode.java @@ -17,7 +17,6 @@ import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; * for a hierarchy. The root node of a layout hierarchy has to implement this * interface. */ -@SuppressWarnings("restriction") public interface IRootVMNode extends IVMNode{ /** diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMNode.java index f3ea5927271..01ca39635fc 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMNode.java @@ -14,7 +14,7 @@ import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.service.IDsfService; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/ModelProxyInstalledEvent.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/ModelProxyInstalledEvent.java index 68073af3ddb..0e4031bd0d1 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/ModelProxyInstalledEvent.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/ModelProxyInstalledEvent.java @@ -7,6 +7,7 @@ import org.eclipse.jface.viewers.Viewer; * Event generated by an IModelProxy implementation when it is installed * into a viewer. */ +@SuppressWarnings("restriction") public class ModelProxyInstalledEvent { private final IModelProxy fProxy; private final Viewer fViewer; diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMChildrenUpdate.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMChildrenUpdate.java index 5083a0679f9..13943a34ade 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMChildrenUpdate.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMChildrenUpdate.java @@ -16,8 +16,8 @@ import java.util.List; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.internal.ui.DsfUIPlugin; import org.eclipse.dd.dsf.service.IDsfService; -import org.eclipse.dd.dsf.ui.DsfUIPlugin; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java index ab87341ae38..d3b383bfd3a 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java @@ -18,7 +18,7 @@ import java.util.concurrent.atomic.AtomicBoolean; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.ui.DsfUIPlugin; +import org.eclipse.dd.dsf.internal.ui.DsfUIPlugin; import org.eclipse.debug.core.IRequest; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMAdapter.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/datamodel/AbstractDMVMAdapter.java similarity index 96% rename from plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMAdapter.java rename to plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/datamodel/AbstractDMVMAdapter.java index 5035419519a..353727fd996 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMAdapter.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/datamodel/AbstractDMVMAdapter.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.ui.viewmodel.dm; +package org.eclipse.dd.dsf.ui.viewmodel.datamodel; import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.service.DsfSession; diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/datamodel/AbstractDMVMNode.java similarity index 99% rename from plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMNode.java rename to plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/datamodel/AbstractDMVMNode.java index d94b6f06f5b..d297215fb27 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/datamodel/AbstractDMVMNode.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.ui.viewmodel.dm; +package org.eclipse.dd.dsf.ui.viewmodel.datamodel; import java.util.concurrent.RejectedExecutionException; @@ -21,10 +21,10 @@ 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.internal.ui.DsfUIPlugin; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; -import org.eclipse.dd.dsf.ui.DsfUIPlugin; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMContext; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMNode; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/datamodel/AbstractDMVMProvider.java similarity index 99% rename from plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProvider.java rename to plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/datamodel/AbstractDMVMProvider.java index dffba582f48..8b9c7d50749 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/AbstractDMVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/datamodel/AbstractDMVMProvider.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.ui.viewmodel.dm; +package org.eclipse.dd.dsf.ui.viewmodel.datamodel; import java.util.concurrent.RejectedExecutionException; diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/CompositeDMVMContext.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/datamodel/CompositeDMVMContext.java similarity index 98% rename from plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/CompositeDMVMContext.java rename to plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/datamodel/CompositeDMVMContext.java index e763f86ae94..73ffb5f29d2 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/CompositeDMVMContext.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/datamodel/CompositeDMVMContext.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.ui.viewmodel.dm; +package org.eclipse.dd.dsf.ui.viewmodel.datamodel; import java.util.ArrayList; import java.util.List; diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/IDMVMContext.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/datamodel/IDMVMContext.java similarity index 95% rename from plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/IDMVMContext.java rename to plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/datamodel/IDMVMContext.java index 56e9a145111..a59eb070a41 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/IDMVMContext.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/datamodel/IDMVMContext.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.ui.viewmodel.dm; +package org.eclipse.dd.dsf.ui.viewmodel.datamodel; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/RootDMVMNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/datamodel/RootDMVMNode.java similarity index 98% rename from plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/RootDMVMNode.java rename to plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/datamodel/RootDMVMNode.java index 82f7282abc2..c4a762c15fe 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/dm/RootDMVMNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/datamodel/RootDMVMNode.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.ui.viewmodel.dm; +package org.eclipse.dd.dsf.ui.viewmodel.datamodel; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelText.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelText.java index 03ed11d12d6..53b77eda31d 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelText.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelText.java @@ -15,7 +15,7 @@ import java.util.Map; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.ui.DsfUIPlugin; +import org.eclipse.dd.dsf.internal.ui.DsfUIPlugin; import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; /** diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/PropertyBasedLabelProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/PropertyBasedLabelProvider.java index 00a200ddf30..cf2d915942c 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/PropertyBasedLabelProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/PropertyBasedLabelProvider.java @@ -23,8 +23,8 @@ import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.dd.dsf.internal.ui.DsfUIPlugin; import org.eclipse.dd.dsf.service.IDsfService; -import org.eclipse.dd.dsf.ui.DsfUIPlugin; import org.eclipse.dd.dsf.ui.viewmodel.VMViewerUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; diff --git a/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF index 14dea406cf1..407b1de6b64 100644 --- a/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf/META-INF/MANIFEST.MF @@ -4,10 +4,10 @@ Bundle-Name: Debug Services Framework Core Bundle-Vendor: Eclipse.org Bundle-SymbolicName: org.eclipse.dd.dsf;singleton:=true Bundle-Version: 1.0.0.qualifier -Bundle-Activator: org.eclipse.dd.dsf.DsfPlugin +Bundle-Activator: org.eclipse.dd.dsf.internal.DsfPlugin Bundle-Localization: plugin Require-Bundle: org.eclipse.core.runtime -Eclipse-LazyStart: true +Bundle-ActivationPolicy: lazy Export-Package: org.eclipse.dd.dsf.concurrent, org.eclipse.dd.dsf.datamodel, org.eclipse.dd.dsf.service diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/CountingRequestMonitor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/CountingRequestMonitor.java index 736dc3cc957..e00a3f19206 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/CountingRequestMonitor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/CountingRequestMonitor.java @@ -14,7 +14,7 @@ import java.util.concurrent.Executor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; -import org.eclipse.dd.dsf.DsfPlugin; +import org.eclipse.dd.dsf.internal.DsfPlugin; /** * Utility class to collect multiple request monitor results of commands diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java index e8504340207..7c60e3b3611 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DefaultDsfExecutor.java @@ -26,7 +26,7 @@ import org.eclipse.core.runtime.ILog; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.DsfPlugin; +import org.eclipse.dd.dsf.internal.DsfPlugin; /** * Default implementation of a DSF executor interfaces, based on the diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java index 0e3bf249c3d..99acc8c59ea 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/DsfExecutable.java @@ -14,7 +14,7 @@ import java.util.HashSet; import java.util.Set; import org.eclipse.core.runtime.Platform; -import org.eclipse.dd.dsf.DsfPlugin; +import org.eclipse.dd.dsf.internal.DsfPlugin; /** * Base class for DSF-instrumented alternative to the Runnable/Callable interfaces. diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ImmediateExecutor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ImmediateExecutor.java index a2644024477..a7961bbc3af 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ImmediateExecutor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/ImmediateExecutor.java @@ -13,7 +13,7 @@ package org.eclipse.dd.dsf.concurrent; import java.util.concurrent.Executor; import org.eclipse.core.runtime.Platform; -import org.eclipse.dd.dsf.DsfPlugin; +import org.eclipse.dd.dsf.internal.DsfPlugin; /** * Executor that executes a runnable immediately as it is submitted. This diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/MultiRequestMonitor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/MultiRequestMonitor.java index ef8a98acfab..807decdbf25 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/MultiRequestMonitor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/MultiRequestMonitor.java @@ -17,7 +17,7 @@ import java.util.Map; import java.util.concurrent.Executor; import org.eclipse.core.runtime.MultiStatus; -import org.eclipse.dd.dsf.DsfPlugin; +import org.eclipse.dd.dsf.internal.DsfPlugin; /** * Utility class to collect multiple request monitor results of commands diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java index 4a6aa955515..3c281732e41 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java @@ -16,7 +16,7 @@ import java.util.concurrent.RejectedExecutionException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.DsfPlugin; +import org.eclipse.dd.dsf.internal.DsfPlugin; import org.eclipse.dd.dsf.service.IDsfService; /** diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Sequence.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Sequence.java index 4e9e99bfd14..73e88c5a90f 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Sequence.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Sequence.java @@ -23,7 +23,7 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.DsfPlugin; +import org.eclipse.dd.dsf.internal.DsfPlugin; /** * Convenience class for implementing a series of commands that need to be diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/DsfPlugin.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/internal/DsfPlugin.java similarity index 98% rename from plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/DsfPlugin.java rename to plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/internal/DsfPlugin.java index b0823212fc7..c0a3a7ceab2 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/DsfPlugin.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/internal/DsfPlugin.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf; +package org.eclipse.dd.dsf.internal; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Plugin; diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java index 243a012597a..aea4c099341 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfSession.java @@ -26,11 +26,11 @@ import java.util.TreeMap; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.DsfPlugin; import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; import org.eclipse.dd.dsf.concurrent.DsfExecutor; import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.dd.dsf.internal.DsfPlugin; import org.osgi.framework.Filter; /** From faddc5dbcffd4d4122b65c6d4842361848ae4eeb Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 13 Feb 2008 20:50:07 +0000 Subject: [PATCH 243/834] [179102] Re-aligned plugin and package names to confirm with Eclipse policy. --- .../org.eclipse.dd.dsf.examples-feature/feature.xml | 2 +- features/org.eclipse.dd.dsf.gdb-feature/feature.xml | 6 +++--- features/org.eclipse.dd.dsf.sdk-feature/feature.xml | 2 +- .../org.eclipse.dd.dsf.test-feature/feature.xml | 13 ++++++++++--- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/features/org.eclipse.dd.dsf.examples-feature/feature.xml b/features/org.eclipse.dd.dsf.examples-feature/feature.xml index 60bd795e6e9..fb73defb128 100644 --- a/features/org.eclipse.dd.dsf.examples-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.examples-feature/feature.xml @@ -29,7 +29,7 @@ Examples @@ -29,14 +29,14 @@ GDB-MI Implementation - - + + + + Date: Wed, 13 Feb 2008 20:57:46 +0000 Subject: [PATCH 244/834] [179102] Re-aligned plugin and package names to confirm with Eclipse policy. --- plugins/org.eclipse.dd.tests.dsf/.classpath | 7 + plugins/org.eclipse.dd.tests.dsf/.cvsignore | 1 + plugins/org.eclipse.dd.tests.dsf/.project | 28 + .../.settings/org.eclipse.jdt.core.prefs | 65 + .../.settings/org.eclipse.jdt.ui.prefs | 3 + .../META-INF/MANIFEST.MF | 17 + plugins/org.eclipse.dd.tests.dsf/about.html | 24 + .../org.eclipse.dd.tests.dsf/build.properties | 6 + .../plugin.properties | 13 + plugins/org.eclipse.dd.tests.dsf/plugin.xml | 18 + .../service/MultiInstanceTestService.java | 59 + .../dd/dsf/tests/service/ServiceTests.java | 277 ++ .../dsf/tests/service/SimpleTestService.java | 53 + .../eclipse/dd/tests/dsf/DsfTestPlugin.java | 69 + .../eclipse/dd/tests/dsf/TestDsfExecutor.java | 50 + .../org/eclipse/dd/tests/dsf/ValueHolder.java | 28 + .../tests/dsf/concurrent/DsfQueryTests.java | 216 ++ .../dsf/concurrent/DsfSequenceTests.java | 315 ++ .../dd/tests/dsf/events/AbstractService.java | 110 + .../eclipse/dd/tests/dsf/events/Event1.java | 16 + .../eclipse/dd/tests/dsf/events/Event2.java | 15 + .../dd/tests/dsf/events/EventTest.java | 147 + .../eclipse/dd/tests/dsf/events/Service1.java | 42 + .../eclipse/dd/tests/dsf/events/Service2.java | 43 + .../eclipse/dd/tests/dsf/events/Service3.java | 50 + .../dd/tests/dsf/events/ShutdownSequence.java | 75 + .../dd/tests/dsf/events/StartupSequence.java | 39 + plugins/org.eclipse.dd.tests.gdb/.classpath | 7 + .../TestAppBuilder.launch | 21 + plugins/org.eclipse.dd.tests.gdb/.project | 38 + .../.settings/org.eclipse.jdt.core.prefs | 65 + .../META-INF/MANIFEST.MF | 23 + .../TestAppBuilder.xml | 19 + .../org.eclipse.dd.tests.gdb/build.properties | 5 + .../data/launch/bin/BreakpointTestApp.exe | Bin 0 -> 40216 bytes .../data/launch/bin/ExpressionTestApp.exe | Bin 0 -> 16921 bytes .../data/launch/bin/GDBMIGenericTestApp.exe | Bin 0 -> 9594 bytes .../data/launch/bin/MemoryTestApp.exe | Bin 0 -> 39963 bytes .../data/launch/bin/MultiThread.exe | Bin 0 -> 9106 bytes .../data/launch/bin/SpecialTestApp.exe | Bin 0 -> 9581 bytes .../data/launch/src/BreakpointTestApp.cc | 47 + .../data/launch/src/ExpressionTestApp.cc | 298 ++ .../data/launch/src/GDBMIGenericTestApp.cc | 15 + .../data/launch/src/Makefile | 14 + .../data/launch/src/MemoryTestApp.cc | 38 + .../data/launch/src/MultiThread.cc | 29 + .../data/launch/src/SpecialTestApp.cc | 15 + plugins/org.eclipse.dd.tests.gdb/plugin.xml | 16 + .../eclipse/dd/mi/service/ClassAccessor.java | 38 + .../org/eclipse/dd/tests/gdb/AllTests.java | 34 + .../org/eclipse/dd/tests/gdb/ExampleTest.java | 117 + .../dd/tests/gdb/ExpressionServiceTest.java | 2960 +++++++++++++++++ .../dd/tests/gdb/GDBProcessesTest.java | 183 + .../dd/tests/gdb/MIBreakpointsTest.java | 2762 +++++++++++++++ .../eclipse/dd/tests/gdb/MIMemoryTest.java | 1639 +++++++++ .../eclipse/dd/tests/gdb/MIRegistersTest.java | 428 +++ .../dd/tests/gdb/MIRunControlTest.java | 654 ++++ .../gdb/framework/AsyncCompletionWaitor.java | 125 + .../tests/gdb/framework/BackgroundRunner.java | 135 + .../dd/tests/gdb/framework/BaseTestCase.java | 100 + .../gdb/framework/ServiceEventWaitor.java | 104 + .../dd/tests/gdb/framework/SyncUtil.java | 314 ++ .../tests/gdb/launching/LaunchSequence.java | 262 ++ .../tests/gdb/launching/ShutdownSequence.java | 105 + .../gdb/launching/TestLaunchDelegate.java | 302 ++ .../dd/tests/gdb/launching/TestsPlugin.java | 97 + 66 files changed, 12795 insertions(+) create mode 100644 plugins/org.eclipse.dd.tests.dsf/.classpath create mode 100644 plugins/org.eclipse.dd.tests.dsf/.cvsignore create mode 100644 plugins/org.eclipse.dd.tests.dsf/.project create mode 100644 plugins/org.eclipse.dd.tests.dsf/.settings/org.eclipse.jdt.core.prefs create mode 100644 plugins/org.eclipse.dd.tests.dsf/.settings/org.eclipse.jdt.ui.prefs create mode 100644 plugins/org.eclipse.dd.tests.dsf/META-INF/MANIFEST.MF create mode 100644 plugins/org.eclipse.dd.tests.dsf/about.html create mode 100644 plugins/org.eclipse.dd.tests.dsf/build.properties create mode 100644 plugins/org.eclipse.dd.tests.dsf/plugin.properties create mode 100644 plugins/org.eclipse.dd.tests.dsf/plugin.xml create mode 100644 plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/dsf/tests/service/MultiInstanceTestService.java create mode 100644 plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/dsf/tests/service/ServiceTests.java create mode 100644 plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/dsf/tests/service/SimpleTestService.java create mode 100644 plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/DsfTestPlugin.java create mode 100644 plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/TestDsfExecutor.java create mode 100644 plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/ValueHolder.java create mode 100644 plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/concurrent/DsfQueryTests.java create mode 100644 plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/concurrent/DsfSequenceTests.java create mode 100644 plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/AbstractService.java create mode 100644 plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/Event1.java create mode 100644 plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/Event2.java create mode 100644 plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/EventTest.java create mode 100644 plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/Service1.java create mode 100644 plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/Service2.java create mode 100644 plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/Service3.java create mode 100644 plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/ShutdownSequence.java create mode 100644 plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/StartupSequence.java create mode 100644 plugins/org.eclipse.dd.tests.gdb/.classpath create mode 100644 plugins/org.eclipse.dd.tests.gdb/.externalToolBuilders/TestAppBuilder.launch create mode 100644 plugins/org.eclipse.dd.tests.gdb/.project create mode 100644 plugins/org.eclipse.dd.tests.gdb/.settings/org.eclipse.jdt.core.prefs create mode 100644 plugins/org.eclipse.dd.tests.gdb/META-INF/MANIFEST.MF create mode 100644 plugins/org.eclipse.dd.tests.gdb/TestAppBuilder.xml create mode 100644 plugins/org.eclipse.dd.tests.gdb/build.properties create mode 100755 plugins/org.eclipse.dd.tests.gdb/data/launch/bin/BreakpointTestApp.exe create mode 100755 plugins/org.eclipse.dd.tests.gdb/data/launch/bin/ExpressionTestApp.exe create mode 100755 plugins/org.eclipse.dd.tests.gdb/data/launch/bin/GDBMIGenericTestApp.exe create mode 100755 plugins/org.eclipse.dd.tests.gdb/data/launch/bin/MemoryTestApp.exe create mode 100755 plugins/org.eclipse.dd.tests.gdb/data/launch/bin/MultiThread.exe create mode 100755 plugins/org.eclipse.dd.tests.gdb/data/launch/bin/SpecialTestApp.exe create mode 100644 plugins/org.eclipse.dd.tests.gdb/data/launch/src/BreakpointTestApp.cc create mode 100644 plugins/org.eclipse.dd.tests.gdb/data/launch/src/ExpressionTestApp.cc create mode 100644 plugins/org.eclipse.dd.tests.gdb/data/launch/src/GDBMIGenericTestApp.cc create mode 100644 plugins/org.eclipse.dd.tests.gdb/data/launch/src/Makefile create mode 100644 plugins/org.eclipse.dd.tests.gdb/data/launch/src/MemoryTestApp.cc create mode 100644 plugins/org.eclipse.dd.tests.gdb/data/launch/src/MultiThread.cc create mode 100644 plugins/org.eclipse.dd.tests.gdb/data/launch/src/SpecialTestApp.cc create mode 100644 plugins/org.eclipse.dd.tests.gdb/plugin.xml create mode 100644 plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/mi/service/ClassAccessor.java create mode 100644 plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/AllTests.java create mode 100644 plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/ExampleTest.java create mode 100644 plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/ExpressionServiceTest.java create mode 100644 plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/GDBProcessesTest.java create mode 100644 plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIBreakpointsTest.java create mode 100644 plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIMemoryTest.java create mode 100644 plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRegistersTest.java create mode 100644 plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRunControlTest.java create mode 100644 plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/AsyncCompletionWaitor.java create mode 100644 plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BackgroundRunner.java create mode 100644 plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java create mode 100644 plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/ServiceEventWaitor.java create mode 100644 plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/SyncUtil.java create mode 100644 plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/LaunchSequence.java create mode 100644 plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/ShutdownSequence.java create mode 100644 plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java create mode 100644 plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestsPlugin.java diff --git a/plugins/org.eclipse.dd.tests.dsf/.classpath b/plugins/org.eclipse.dd.tests.dsf/.classpath new file mode 100644 index 00000000000..304e86186aa --- /dev/null +++ b/plugins/org.eclipse.dd.tests.dsf/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/plugins/org.eclipse.dd.tests.dsf/.cvsignore b/plugins/org.eclipse.dd.tests.dsf/.cvsignore new file mode 100644 index 00000000000..ba077a4031a --- /dev/null +++ b/plugins/org.eclipse.dd.tests.dsf/.cvsignore @@ -0,0 +1 @@ +bin diff --git a/plugins/org.eclipse.dd.tests.dsf/.project b/plugins/org.eclipse.dd.tests.dsf/.project new file mode 100644 index 00000000000..a662c11dc13 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.dsf/.project @@ -0,0 +1,28 @@ + + + org.eclipse.dd.tests.dsf + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/plugins/org.eclipse.dd.tests.dsf/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.dd.tests.dsf/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000000..8241d8c455d --- /dev/null +++ b/plugins/org.eclipse.dd.tests.dsf/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,65 @@ +#Thu Jun 07 11:08:23 PDT 2007 +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.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=warning +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning +org.eclipse.jdt.core.compiler.problem.nullReference=ignore +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning +org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=error +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/plugins/org.eclipse.dd.tests.dsf/.settings/org.eclipse.jdt.ui.prefs b/plugins/org.eclipse.dd.tests.dsf/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 00000000000..28984618f01 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.dsf/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,3 @@ +#Thu Oct 12 11:27:35 PDT 2006 +eclipse.preferences.version=1 +internal.default.compliance=default diff --git a/plugins/org.eclipse.dd.tests.dsf/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.tests.dsf/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..2e88859313d --- /dev/null +++ b/plugins/org.eclipse.dd.tests.dsf/META-INF/MANIFEST.MF @@ -0,0 +1,17 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Debug Services Framework Unit Tests +Bundle-Vendor: Eclipse.org +Bundle-SymbolicName: org.eclipse.dd.tests.dsf;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: org.eclipse.dd.tests.dsf.DsfTestPlugin +Bundle-Localization: plugin +Bundle-ActivationPolicy: lazy +Require-Bundle: org.eclipse.core.runtime, + org.eclipse.debug.core, + org.eclipse.debug.ui, + org.eclipse.dd.dsf, + org.junit4, + org.eclipse.ui, + org.eclipse.dd.dsf.ui +Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/plugins/org.eclipse.dd.tests.dsf/about.html b/plugins/org.eclipse.dd.tests.dsf/about.html new file mode 100644 index 00000000000..cb740ae8bc8 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.dsf/about.html @@ -0,0 +1,24 @@ + + + + +About +

    About This Content

    + +

    June 5, 2007

    +

    License

    + +

    The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at http://www.eclipse.org/legal/epl-v10.html. +For purposes of the EPL, "Program" will mean the Content.

    + +

    If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at http://www.eclipse.org.

    + + \ No newline at end of file diff --git a/plugins/org.eclipse.dd.tests.dsf/build.properties b/plugins/org.eclipse.dd.tests.dsf/build.properties new file mode 100644 index 00000000000..786b1df9364 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.dsf/build.properties @@ -0,0 +1,6 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml,\ + about.html diff --git a/plugins/org.eclipse.dd.tests.dsf/plugin.properties b/plugins/org.eclipse.dd.tests.dsf/plugin.properties new file mode 100644 index 00000000000..8dc99b1d8eb --- /dev/null +++ b/plugins/org.eclipse.dd.tests.dsf/plugin.properties @@ -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) Test Plugin +providerName=Eclipse.org + diff --git a/plugins/org.eclipse.dd.tests.dsf/plugin.xml b/plugins/org.eclipse.dd.tests.dsf/plugin.xml new file mode 100644 index 00000000000..aa2732002b6 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.dsf/plugin.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + diff --git a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/dsf/tests/service/MultiInstanceTestService.java b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/dsf/tests/service/MultiInstanceTestService.java new file mode 100644 index 00000000000..2b70cf6bed1 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/dsf/tests/service/MultiInstanceTestService.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * 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.tests.service; + +import java.util.Hashtable; + +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.service.AbstractDsfService; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.tests.dsf.DsfTestPlugin; +import org.osgi.framework.BundleContext; + +public class MultiInstanceTestService extends AbstractDsfService { + + public static String PROP_INSTANCE_ID = "org.eclipse.dd.dsf.tests.service.MultiInstanceTestService.id"; //$NON-NLS-1$ + String fInstanceId; + + public MultiInstanceTestService(DsfSession session, String instanceId) { + super(session); + fInstanceId = instanceId; + } + + @Override + protected BundleContext getBundleContext() { + return DsfTestPlugin.getBundleContext(); + } + + @Override + public void initialize(final RequestMonitor requestMonitor) { + super.initialize( + new RequestMonitor(getExecutor(), requestMonitor) { + @Override + public void handleOK() { + doInitialize(requestMonitor); + } + }); + } + + private void doInitialize(RequestMonitor requestMonitor) { + Hashtable properties = new Hashtable(); + properties.put(PROP_INSTANCE_ID, fInstanceId); + register(new String[]{MultiInstanceTestService.class.getName()}, properties); + requestMonitor.done(); + } + + @Override + public void shutdown(RequestMonitor requestMonitor) { + unregister(); + super.shutdown(requestMonitor); + } +} diff --git a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/dsf/tests/service/ServiceTests.java b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/dsf/tests/service/ServiceTests.java new file mode 100644 index 00000000000..102c72e8b09 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/dsf/tests/service/ServiceTests.java @@ -0,0 +1,277 @@ +/******************************************************************************* + * 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.tests.service; + +import java.lang.reflect.Constructor; +import java.util.concurrent.ExecutionException; + +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.Sequence; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.tests.dsf.DsfTestPlugin; +import org.eclipse.dd.tests.dsf.TestDsfExecutor; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; + +public class ServiceTests { + TestDsfExecutor fExecutor; + + @Before public void startExecutor() throws ExecutionException, InterruptedException { + fExecutor = new TestDsfExecutor(); + } + + @After public void shutdownExecutor() throws ExecutionException, InterruptedException { + fExecutor.submit(new DsfRunnable() { public void run() { + fExecutor.shutdown(); + }}).get(); + if (fExecutor.exceptionsCaught()) { + Throwable[] exceptions = fExecutor.getExceptions(); + throw new ExecutionException(exceptions[0]); + } + fExecutor = null; + } + + private class CreateSessionStep extends Sequence.Step { + private DsfSession fSession; + @Override public void execute(RequestMonitor requestMonitor) { + fSession = DsfSession.startSession(fExecutor, "org.eclipse.dd.dsf.tests"); //$NON-NLS-1$ + requestMonitor.done(); + } + + DsfSession getSession() { return fSession; } + } + + private class ShutdownSessionStep extends Sequence.Step { + private CreateSessionStep fCreateSessionStep; + + ShutdownSessionStep(CreateSessionStep createSessionStep) { + fCreateSessionStep = createSessionStep; + } + + @Override + public void execute(RequestMonitor requestMonitor) { + DsfSession.endSession(fCreateSessionStep.getSession()); + requestMonitor.done(); + } + } + + private class InitializeServiceStep extends Sequence.Step { + CreateSessionStep fCreateSessionStep; + Class fServiceClass; + IDsfService fService; + + InitializeServiceStep(CreateSessionStep createSessionStep, Class serviceClass) { + fCreateSessionStep = createSessionStep; + fServiceClass = serviceClass; + } + IDsfService getService() { return fService; } + + @Override + public void execute(RequestMonitor requestMonitor) { + try { + Constructor c = fServiceClass.getConstructor(new Class[] {DsfSession.class}); + fService = c.newInstance(new Object[] {fCreateSessionStep.getSession()}); + } catch (Exception e) { + Assert.fail("Unexpected exception"); //$NON-NLS-1$ + } + fService.initialize(requestMonitor); + } + } + + private class InitializeMultiInstanceServiceStep extends InitializeServiceStep { + String fServiceId; + + InitializeMultiInstanceServiceStep(CreateSessionStep createSessionStep, Class serviceClass, String serviceId) { + super(createSessionStep, serviceClass); + fServiceId = serviceId; + } + @Override + IDsfService getService() { return fService; } + + @Override + public void execute(RequestMonitor requestMonitor) { + try { + Constructor c = + fServiceClass.getConstructor(new Class[] {DsfSession.class, String.class}); + fService = c.newInstance(new Object[] {fCreateSessionStep.getSession(), fServiceId}); + } catch (Exception e) { + Assert.fail("Unexpected exception"); //$NON-NLS-1$ + } + fService.initialize(requestMonitor); + } + } + + private class ShutdownServiceStep extends Sequence.Step { + InitializeServiceStep fInitializeServiceStep; + ShutdownServiceStep(InitializeServiceStep initStep) { + fInitializeServiceStep = initStep; + } + + @Override + public void execute(RequestMonitor requestMonitor) { + fInitializeServiceStep.getService().shutdown(requestMonitor); + } + } + + + abstract private class TestRetrievingReferenceStep extends Sequence.Step { + String fClass; + boolean fShouldSucceed; + + TestRetrievingReferenceStep(Class clazz, boolean shouldSucceed) { + fClass = clazz.getName(); + fShouldSucceed = shouldSucceed; + } + + abstract String getFilter(); + + @Override + public void execute(RequestMonitor requestMonitor) { + ServiceReference[] refs = null; + try { + refs = DsfTestPlugin.getBundleContext().getServiceReferences(fClass, getFilter()); + } catch (InvalidSyntaxException e) { + Assert.fail("Unexpected exception"); //$NON-NLS-1$ + } + if (fShouldSucceed) { + Assert.assertTrue(refs != null); + Assert.assertTrue(refs.length == 1); + IDsfService service = (IDsfService)DsfTestPlugin.getBundleContext().getService(refs[0]); + Assert.assertTrue(service != null); + DsfTestPlugin.getBundleContext().ungetService(refs[0]); + } else { + Assert.assertTrue(refs == null); + } + requestMonitor.done(); + } + } + + private class TestRetrievingSimpleServiceReferenceStep extends TestRetrievingReferenceStep { + CreateSessionStep fCreateSessionStep; + TestRetrievingSimpleServiceReferenceStep(Class clazz, boolean shouldSucceed, CreateSessionStep createSessionStep) { + super(clazz, shouldSucceed); + fCreateSessionStep = createSessionStep; + } + @Override + String getFilter() { + return "(" + IDsfService.PROP_SESSION_ID + "=" + fCreateSessionStep.getSession().getId() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + } + + private class TestRetrievingMultiSessionServiceReferenceStep extends TestRetrievingSimpleServiceReferenceStep { + String fServiceId; + TestRetrievingMultiSessionServiceReferenceStep(Class clazz, boolean shouldSucceed, CreateSessionStep createSessionStep, + String serviceId) { + super(clazz, shouldSucceed, createSessionStep); + fServiceId = serviceId; + } + @Override + String getFilter() { + return "(&" + //$NON-NLS-1$ + "(" + IDsfService.PROP_SESSION_ID + "=" + fCreateSessionStep.getSession().getId() + ")" + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + "(" + MultiInstanceTestService.PROP_INSTANCE_ID + "=" + fServiceId + ")" + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + ")"; //$NON-NLS-1$ + } + } + + @Test + public void singleServiceTest() throws InterruptedException, ExecutionException { + Sequence seq = new Sequence(fExecutor) { + CreateSessionStep fSessionStep; + InitializeServiceStep fServiceStep; + + @Override + public Step[] getSteps() { return fSteps; } + + final private Step[] fSteps = new Step[] + { + fSessionStep = new CreateSessionStep(), + fServiceStep = new InitializeServiceStep(fSessionStep, SimpleTestService.class), + new TestRetrievingSimpleServiceReferenceStep(SimpleTestService.class, true, fSessionStep), + new ShutdownServiceStep(fServiceStep), + new TestRetrievingSimpleServiceReferenceStep(SimpleTestService.class, false, fSessionStep), + new ShutdownSessionStep(fSessionStep) + }; + }; + fExecutor.execute(seq); + seq.get(); + } + + /** + * Creates two sessions and starts a single service within each session. + * Then it tests retrieving the reference to the service. + */ + @Test + public void singleServiceMultiSessionTest() throws InterruptedException, ExecutionException { + Sequence seq = new Sequence(fExecutor) { + CreateSessionStep fSession1Step; + CreateSessionStep fSession2Step; + InitializeServiceStep fSession1ServiceStep; + InitializeServiceStep fSession2ServiceStep; + + @Override + public Step[] getSteps() { return fSteps; } + + final private Step[] fSteps = new Step[] + { + fSession1Step = new CreateSessionStep(), + fSession2Step = new CreateSessionStep(), + fSession1ServiceStep = new InitializeServiceStep(fSession1Step, SimpleTestService.class), + fSession2ServiceStep = new InitializeServiceStep(fSession2Step, SimpleTestService.class), + new TestRetrievingSimpleServiceReferenceStep(SimpleTestService.class, true, fSession1Step), + new TestRetrievingSimpleServiceReferenceStep(SimpleTestService.class, true, fSession2Step), + new ShutdownServiceStep(fSession1ServiceStep), + new ShutdownServiceStep(fSession2ServiceStep), + new TestRetrievingSimpleServiceReferenceStep(SimpleTestService.class, false, fSession1Step), + new TestRetrievingSimpleServiceReferenceStep(SimpleTestService.class, false, fSession2Step), + new ShutdownSessionStep(fSession1Step), + new ShutdownSessionStep(fSession2Step) + }; + }; + fExecutor.execute(seq); + seq.get(); + } + + @Test + public void multiServiceServiceTest() throws InterruptedException, ExecutionException { + Sequence seq = new Sequence(fExecutor) { + CreateSessionStep fSessionStep; + InitializeServiceStep fService1Step; + InitializeServiceStep fService2Step; + + @Override + public Step[] getSteps() { return fSteps; } + + final private Step[] fSteps = new Step[] + { + fSessionStep = new CreateSessionStep(), + fService1Step = new InitializeMultiInstanceServiceStep(fSessionStep, MultiInstanceTestService.class, "1"), //$NON-NLS-1$ + fService2Step = new InitializeMultiInstanceServiceStep(fSessionStep, MultiInstanceTestService.class, "2"), //$NON-NLS-1$ + new TestRetrievingMultiSessionServiceReferenceStep(MultiInstanceTestService.class, true, fSessionStep, "1"), //$NON-NLS-1$ + new TestRetrievingMultiSessionServiceReferenceStep(MultiInstanceTestService.class, true, fSessionStep, "2"), //$NON-NLS-1$ + new ShutdownServiceStep(fService1Step), + new ShutdownServiceStep(fService2Step), + new TestRetrievingMultiSessionServiceReferenceStep(MultiInstanceTestService.class, false, fSessionStep, "1"), //$NON-NLS-1$ + new TestRetrievingMultiSessionServiceReferenceStep(MultiInstanceTestService.class, false, fSessionStep, "2"), //$NON-NLS-1$ + new ShutdownSessionStep(fSessionStep) + }; + }; + fExecutor.execute(seq); + seq.get(); + } + +} diff --git a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/dsf/tests/service/SimpleTestService.java b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/dsf/tests/service/SimpleTestService.java new file mode 100644 index 00000000000..902bf0885cb --- /dev/null +++ b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/dsf/tests/service/SimpleTestService.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * 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.tests.service; + +import java.util.Hashtable; + +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.service.AbstractDsfService; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.tests.dsf.DsfTestPlugin; +import org.osgi.framework.BundleContext; + +public class SimpleTestService extends AbstractDsfService { + + public SimpleTestService(DsfSession session) { + super(session); + } + + @Override + protected BundleContext getBundleContext() { + return DsfTestPlugin.getBundleContext(); + } + + @Override + public void initialize(final RequestMonitor requestMonitor) { + super.initialize( + new RequestMonitor(getExecutor(), requestMonitor) { + @Override + public void handleOK() { + doInitialize(requestMonitor); + } + }); + } + + private void doInitialize(RequestMonitor requestMonitor) { + register(new String[]{SimpleTestService.class.getName()}, new Hashtable()); + requestMonitor.done(); + } + + @Override + public void shutdown(RequestMonitor requestMonitor) { + unregister(); + super.shutdown(requestMonitor); + } +} diff --git a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/DsfTestPlugin.java b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/DsfTestPlugin.java new file mode 100644 index 00000000000..cd4e0288f17 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/DsfTestPlugin.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.tests.dsf; + +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class DsfTestPlugin extends AbstractUIPlugin { + + // The plug-in ID + public static final String PLUGIN_ID = "org.eclipse.dd.tests.dsf"; //$NON-NLS-1$ + + // The shared instance + private static DsfTestPlugin fgPlugin; + private static BundleContext fgBundleContext; + + /** + * The constructor + */ + public DsfTestPlugin() { + fgPlugin = this; + } + + /* + * (non-Javadoc) + * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext) + */ + @Override + public void start(BundleContext context) throws Exception { + fgBundleContext = context; + super.start(context); + } + + /* + * (non-Javadoc) + * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext) + */ + @Override + public void stop(BundleContext context) throws Exception { + super.stop(context); + fgBundleContext = null; + fgPlugin = null; + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static DsfTestPlugin getDefault() { + return fgPlugin; + } + + public static BundleContext getBundleContext() { + return fgBundleContext; + } + +} diff --git a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/TestDsfExecutor.java b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/TestDsfExecutor.java new file mode 100644 index 00000000000..37fe241a8bb --- /dev/null +++ b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/TestDsfExecutor.java @@ -0,0 +1,50 @@ +package org.eclipse.dd.tests.dsf; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor; + +/** + * DsfExecutor for use with unit tests. It records the exceptions that were + * thrown in the executor thread so that they can be re-thrown by the test. + * + */ +public class TestDsfExecutor extends DefaultDsfExecutor { + private List fExceptions = Collections.synchronizedList(new ArrayList()); + + @Override + protected void afterExecute(Runnable r, Throwable t) { + super.afterExecute(r, t); + if (r instanceof Future) { + Future future = (Future)r; + try { + if (future.isDone()) { + future.get(); + } + future.get(); + } catch (InterruptedException e) { // Ignore + } catch (CancellationException e) { // Ignore also + } catch (ExecutionException e) { + if (e.getCause() != null) { + fExceptions.add(e.getCause()); + } + } + } + } + + public boolean exceptionsCaught() { + return fExceptions.size() != 0; + } + + public Throwable[] getExceptions() { + synchronized (fExceptions) { + return fExceptions.toArray(new Throwable[fExceptions.size()]); + } + } + +} diff --git a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/ValueHolder.java b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/ValueHolder.java new file mode 100644 index 00000000000..c3b087dcc12 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/ValueHolder.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * 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.tests.dsf; + +/** + * Utility class to hold a value retrieved in a runnable. + * Usage in a test is as follows: + *
    + *     final ValueHolder value = new ValueHolder();
    + *     fExecutor.execute(new Runnable() {
    + *         public void run() {
    + *             value.fValue = 1;
    + *         }
    + *     }); 
    + *     Assert.assertTrue(value.fValue == 1);
    + * 
    + */ +public class ValueHolder { + public V fValue; +} diff --git a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/concurrent/DsfQueryTests.java b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/concurrent/DsfQueryTests.java new file mode 100644 index 00000000000..e4015eba8ae --- /dev/null +++ b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/concurrent/DsfQueryTests.java @@ -0,0 +1,216 @@ +/******************************************************************************* + * 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.tests.dsf.concurrent; + +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import junit.framework.Assert; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.Query; +import org.eclipse.dd.tests.dsf.DsfTestPlugin; +import org.eclipse.dd.tests.dsf.TestDsfExecutor; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Tests that excercise the Query object. + */ +public class DsfQueryTests { + TestDsfExecutor fExecutor; + + @Before + public void startServices() throws ExecutionException, InterruptedException { + fExecutor = new TestDsfExecutor(); + } + + @After + public void shutdownServices() throws ExecutionException, InterruptedException { + fExecutor.submit(new DsfRunnable() { public void run() { + fExecutor.shutdown(); + }}).get(); + if (fExecutor.exceptionsCaught()) { + Throwable[] exceptions = fExecutor.getExceptions(); + throw new ExecutionException(exceptions[0]); + } + fExecutor = null; + } + + @Test + public void simpleGetTest() throws InterruptedException, ExecutionException { + Query q = new Query() { + @Override + protected void execute(DataRequestMonitor rm) { + rm.setData(1); + rm.done(); + } + }; + // Check initial state + Assert.assertTrue(!q.isDone()); + Assert.assertTrue(!q.isCancelled()); + + fExecutor.execute(q); + Assert.assertEquals(1, (int)q.get()); + + // Check final state + Assert.assertTrue(q.isDone()); + Assert.assertTrue(!q.isCancelled()); + + } + + @Test + public void getWithMultipleDispatchesTest() throws InterruptedException, ExecutionException { + Query q = new Query() { + @Override + protected void execute(final DataRequestMonitor rm) { + fExecutor.execute(new DsfRunnable() { + public void run() { + rm.setData(1); + rm.done(); + } + @Override + public String toString() { return super.toString() + "\n getWithMultipleDispatchesTest() second runnable"; } //$NON-NLS-1$ + }); + } + @Override + public String toString() { return super.toString() + "\n getWithMultipleDispatchesTest() first runnable (query)"; } //$NON-NLS-1$ + }; + fExecutor.execute(q); + Assert.assertEquals(1, (int)q.get()); + } + + @Test (expected = ExecutionException.class) + public void exceptionOnGetTest() throws InterruptedException, ExecutionException { + Query q = new Query() { + @Override + protected void execute(final DataRequestMonitor rm) { + rm.setStatus(new Status(IStatus.ERROR, DsfTestPlugin.PLUGIN_ID, -1, "", null)); //$NON-NLS-1$ + rm.done(); + } + }; + + fExecutor.execute(q); + + try { + q.get(); + } finally { + Assert.assertTrue(q.isDone()); + Assert.assertTrue(!q.isCancelled()); + } + } + + @Test + public void cancelWhileWaitingTest() throws InterruptedException, ExecutionException { + final Query q = new Query() { + @Override + protected void execute(final DataRequestMonitor rm) { + // Call done with a delay of 1 second, to avoid stalling the tests. + fExecutor.schedule( + new DsfRunnable() { + public void run() { rm.done(); } + }, + 1, TimeUnit.SECONDS); + } + }; + + fExecutor.execute(q); + + // Note: no point in checking isDone() and isCancelled() here, because + // the value could change on timing. + + // This does not really guarantee that the cancel will be called after + // the call to Fugure.get(), but the 1ms delay in call to schedule should + // help. + new Job("DsfQueryTests cancel job") { @Override public IStatus run(IProgressMonitor monitor) { //$NON-NLS-1$ + q.cancel(false); + return Status.OK_STATUS; + }}.schedule(1); + + try { + q.get(); + } catch (CancellationException e) { + return; // Success + } finally { + Assert.assertTrue(q.isDone()); + Assert.assertTrue(q.isCancelled()); + } + Assert.assertTrue("CancellationException should have been thrown", false); //$NON-NLS-1$ + } + + @Test + public void cancelBeforeWaitingTest() throws InterruptedException, ExecutionException { + final Query q = new Query() { + @Override protected void execute(final DataRequestMonitor rm) { + Assert.fail("Query was cancelled, it should not be called."); //$NON-NLS-1$ + rm.done(); + } + }; + + // Cancel before invoking the query. + q.cancel(false); + + Assert.assertTrue(q.isDone()); + Assert.assertTrue(q.isCancelled()); + + // Start the query. + fExecutor.execute(q); + + // Block to retrieve data + try { + q.get(); + } catch (CancellationException e) { + return; // Success + } finally { + Assert.assertTrue(q.isDone()); + Assert.assertTrue(q.isCancelled()); + } + Assert.assertTrue("CancellationException should have been thrown", false); //$NON-NLS-1$ + } + + @Test + public void getTimeoutTest() throws InterruptedException, ExecutionException { + final Query q = new Query() { + @Override + protected void execute(final DataRequestMonitor rm) { + // Call done with a delay of 1 second, to avoid stalling the tests. + fExecutor.schedule( + new DsfRunnable() { + public void run() { rm.done(); } + }, + 1, TimeUnit.SECONDS); + } + }; + + fExecutor.execute(q); + + // Note: no point in checking isDone() and isCancelled() here, because + // the value could change on timing. + + try { + q.get(1, TimeUnit.MILLISECONDS); + } catch (TimeoutException e) { + return; // Success + } finally { + Assert.assertFalse("Query should not be done yet, it should have timed out first.", q.isDone()); //$NON-NLS-1$ + } + Assert.assertTrue("TimeoutException should have been thrown", false); //$NON-NLS-1$ + } + +} diff --git a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/concurrent/DsfSequenceTests.java b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/concurrent/DsfSequenceTests.java new file mode 100644 index 00000000000..0f1985acd73 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/concurrent/DsfSequenceTests.java @@ -0,0 +1,315 @@ +/******************************************************************************* + * 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.tests.dsf.concurrent; + +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + +import junit.framework.Assert; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.Sequence; +import org.eclipse.dd.tests.dsf.DsfTestPlugin; +import org.eclipse.dd.tests.dsf.TestDsfExecutor; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Tests that excercise the Sequence object. + */ +public class DsfSequenceTests { + TestDsfExecutor fExecutor; + + @Before + public void startExecutor() throws ExecutionException, InterruptedException { + fExecutor = new TestDsfExecutor(); + } + + @After + public void shutdownExecutor() throws ExecutionException, InterruptedException { + fExecutor.submit(new DsfRunnable() { public void run() { + fExecutor.shutdown(); + }}).get(); + if (fExecutor.exceptionsCaught()) { + Throwable[] exceptions = fExecutor.getExceptions(); + throw new ExecutionException(exceptions[0]); + } + fExecutor = null; + } + + @Test + public void simpleTest() throws InterruptedException, ExecutionException { + // Create a counter for tracking number of steps performed. + class IntegerHolder { int fInteger; } + final IntegerHolder stepCounter = new IntegerHolder(); + + // Create the steps of the sequence + final Sequence.Step[] steps = new Sequence.Step[] { + new Sequence.Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + stepCounter.fInteger++; + requestMonitor.done(); + } + }, + new Sequence.Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + stepCounter.fInteger++; + requestMonitor.done(); + } + } + }; + + // Create, start, and wait for the sequence. + Sequence sequence = new Sequence(fExecutor) { + @Override public Step[] getSteps() { return steps; } + }; + Assert.assertTrue(!sequence.isDone()); + Assert.assertTrue(!sequence.isCancelled()); + + fExecutor.execute(sequence); + sequence.get(); + + // Check the count + Assert.assertTrue(stepCounter.fInteger == 2); + + // Check post conditions + Assert.assertTrue(sequence.isDone()); + Assert.assertTrue(!sequence.isCancelled()); + } + + @Test (expected = ExecutionException.class) + public void rollbackTest() throws InterruptedException, ExecutionException { + // Create a counter for tracking number of steps performed and steps + // rolled back. + class IntegerHolder { int fInteger; } + final IntegerHolder stepCounter = new IntegerHolder(); + final IntegerHolder rollBackCounter = new IntegerHolder(); + + // Create the steps of the sequence + final Sequence.Step[] steps = new Sequence.Step[] { + new Sequence.Step() { + @Override public void execute(RequestMonitor requestMonitor) { + stepCounter.fInteger++; + requestMonitor.done(); + } + @Override public void rollBack(RequestMonitor requestMonitor) { + rollBackCounter.fInteger++; + requestMonitor.done(); + } + }, + new Sequence.Step() { + @Override public void execute(RequestMonitor requestMonitor) { + stepCounter.fInteger++; + requestMonitor.setStatus(new Status(IStatus.ERROR, DsfTestPlugin.PLUGIN_ID, -1, "", null)); //$NON-NLS-1$ + requestMonitor.done(); + } + @Override public void rollBack(RequestMonitor requestMonitor) { + rollBackCounter.fInteger++; + requestMonitor.done(); + } + } + }; + + // Create and start. + Sequence sequence = new Sequence(fExecutor) { + @Override public Step[] getSteps() { return steps; } + }; + fExecutor.execute(sequence); + + // Block and wait for sequence to bomplete. + try { + sequence.get(); + } finally { + // Both steps should be performed + Assert.assertTrue(stepCounter.fInteger == 2); + // Only one step is rolled back, the first one. + Assert.assertTrue(rollBackCounter.fInteger == 1); + + // Check state from Future interface + Assert.assertTrue(sequence.isDone()); + Assert.assertTrue(!sequence.isCancelled()); + } + Assert.assertTrue("Exception should have been thrown", false); //$NON-NLS-1$ + } + + /** + * The goal of this test it to check that if an exception is thrown within + * the Step.execute(), the step will return from the Future.get() method. + */ + @Test (expected = ExecutionException.class) + public void exceptionTest() throws InterruptedException, ExecutionException { + final Sequence.Step[] steps = new Sequence.Step[] { + new Sequence.Step() { + @Override public void execute(RequestMonitor requestMonitor) { + throw new Error("Exception part of unit test."); //$NON-NLS-1$ + } + } + }; + + // Create and start. + Sequence sequence = new Sequence(fExecutor) { + @Override public Step[] getSteps() { return steps; } + }; + fExecutor.execute(sequence); + + // Block and wait for sequence to bomplete. + try { + sequence.get(); + } finally { + // Check state from Future interface + Assert.assertTrue(sequence.isDone()); + Assert.assertTrue(!sequence.isCancelled()); + } + Assert.assertTrue("Exception should have been thrown", false); //$NON-NLS-1$ + } + + + @Test (expected = CancellationException.class) + public void cancelBeforeWaitingTest() throws InterruptedException, ExecutionException { + // Create the sequence + final Sequence.Step[] steps = new Sequence.Step[] { + new Sequence.Step() { + @Override public void execute(RequestMonitor requestMonitor) { + Assert.assertTrue("Sequence was cancelled, it should not be called.", false); //$NON-NLS-1$ + } + } + }; + Sequence sequence = new Sequence(fExecutor) { + @Override public Step[] getSteps() { return steps; } + }; + + // Cancel before invoking the sequence. + sequence.cancel(false); + + Assert.assertTrue(!sequence.isDone()); + Assert.assertTrue(sequence.isCancelled()); + + // Start the sequence + fExecutor.execute(sequence); + + // Block and wait for sequence to bomplete. + try { + sequence.get(); + } finally { + Assert.assertTrue(sequence.isDone()); + Assert.assertTrue(sequence.isCancelled()); + } + Assert.assertTrue("CancellationException should have been thrown", false); //$NON-NLS-1$ + } + + + @Test (expected = CancellationException.class) + public void cancelFromStepTest() throws InterruptedException, ExecutionException { + // Create a counter for tracking number of steps performed and steps + // rolled back. + class IntegerHolder { int fInteger; } + final IntegerHolder stepCounter = new IntegerHolder(); + final IntegerHolder rollBackCounter = new IntegerHolder(); + + // Create the steps of the sequence + final Sequence.Step[] steps = new Sequence.Step[] { + new Sequence.Step() { + @Override public void execute(RequestMonitor requestMonitor) { + stepCounter.fInteger++; + requestMonitor.done(); + } + @Override public void rollBack(RequestMonitor requestMonitor) { + rollBackCounter.fInteger++; + requestMonitor.done(); + } + }, + new Sequence.Step() { + @Override public void execute(RequestMonitor requestMonitor) { + stepCounter.fInteger++; + + // Perform the cancel! + getSequence().cancel(false); + + requestMonitor.done(); + } + @Override public void rollBack(RequestMonitor requestMonitor) { + rollBackCounter.fInteger++; + requestMonitor.done(); + } + } + }; + + // Create and start sequence with a delay. Delay so that we call get() before + // cancel is called. + final Sequence sequence = new Sequence(fExecutor) { + @Override public Step[] getSteps() { return steps; } + }; + fExecutor.schedule(sequence, 1, TimeUnit.MILLISECONDS); + + // Block to retrieve data + try { + sequence.get(); + } finally { + // Both steps should be performed + Assert.assertTrue(stepCounter.fInteger == 2); + // Both roll-backs should be performed since cancel does not take effect until + // after the step is completed. + Assert.assertTrue(rollBackCounter.fInteger == 2); + + Assert.assertTrue(sequence.isDone()); + Assert.assertTrue(sequence.isCancelled()); + } + Assert.assertTrue("CancellationException should have been thrown", false); //$NON-NLS-1$ + } + + @Test (expected = CancellationException.class) + public void cancelBeforeWithProgressManagerTest() throws InterruptedException, ExecutionException { + // Create the sequence + final Sequence.Step[] steps = new Sequence.Step[] { + new Sequence.Step() { + @Override public void execute(RequestMonitor requestMonitor) { + Assert.assertTrue("Sequence was cancelled, it should not be called.", false); //$NON-NLS-1$ + } + } + }; + + // Create the progress monitor that we will cancel. + IProgressMonitor pm = new NullProgressMonitor(); + + // Create the seqeunce with our steps. + Sequence sequence = new Sequence(fExecutor, pm, "", "", null) { //$NON-NLS-1$ //$NON-NLS-2$ + @Override public Step[] getSteps() { return steps; } + }; + + // Cancel the progress monitor before invoking the sequence. Note + // that the state of the sequence doesn't change yet, because the + // sequence does not check the progress monitor until it is executed. + pm.setCanceled(true); + + // Start the sequence + fExecutor.execute(sequence); + + // Block and wait for sequence to bomplete. Exception is thrown, + // which is expected. + try { + sequence.get(); + } finally { + Assert.assertTrue(sequence.isDone()); + Assert.assertTrue(sequence.isCancelled()); + } + } + + +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/AbstractService.java b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/AbstractService.java new file mode 100644 index 00000000000..94a5fdc9de2 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/AbstractService.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * 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.tests.dsf.events; + +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.dd.dsf.service.AbstractDsfService; +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.tests.dsf.DsfTestPlugin; +import org.osgi.framework.BundleContext; + +/** + * Test service class used to test event behavior. It has three types of events + * and three methods to receive the events. + * + */ +abstract public class AbstractService extends AbstractDsfService +{ + AbstractService(DsfSession session) { + super(session); + } + + @Override protected BundleContext getBundleContext() { + return DsfTestPlugin.getBundleContext(); + } + + @Override public void initialize(final RequestMonitor requestMonitor) { + super.initialize( + new RequestMonitor(getExecutor(), requestMonitor) { + @Override + public void handleOK() { + doInitialize(requestMonitor); + } + }); + } + + private void doInitialize(RequestMonitor requestMonitor) { + getSession().addServiceEventListener(this, null); + requestMonitor.done(); + } + + @Override public void shutdown(RequestMonitor requestMonitor) { + getSession().removeServiceEventListener(this); + super.shutdown(requestMonitor); + } + + /////////////////////////////////////////////////////////////////////////// + // Test API + /** Records the number in the event 1 object when this service received the event. */ + int fEvent1RecipientNumber; + + /** Records the number in the event 2 object when this service received the event. */ + int fEvent2RecipientNumber; + + /** Records the number in the event 3 object when this service received the event. */ + int fEvent3RecipientNumber; + + /** Simple event class 1 */ + public class Event1 { + // 1-based counter for the recipient of the event. + int fRecipientNumberCounter = 1; + } + + /** Simple event class 2. Note it doesn't have any relation to event 1 */ + public class Event2 { + int fRecipientNumberCounter = 1; + } + + /** Simple event class 3. Note it does sub-class event 1 */ + public class Event3 extends Event1 {} + + @ThreadSafe + public void dispatchEvent1() { + getSession().dispatchEvent(new Event1(), getProperties()); + } + + @ThreadSafe + public void dispatchEvent2() { + getSession().dispatchEvent(new Event2(), getProperties()); + } + + @ThreadSafe + public void dispatchEvent3() { + getSession().dispatchEvent(new Event3(), getProperties()); + } + + /** Handles event 1 (and event 3 which derives from event 1) */ + @DsfServiceEventHandler public void eventDispatched(Event1 e) { + fEvent1RecipientNumber = e.fRecipientNumberCounter++; + } + + /** Handles event 2 only */ + @DsfServiceEventHandler public void eventDispatched(Event2 e) { + fEvent2RecipientNumber = e.fRecipientNumberCounter++; + } + + /** Handles event 3 only */ + @DsfServiceEventHandler public void eventDispatched(Event3 e) { + fEvent3RecipientNumber = e.fRecipientNumberCounter++; + } +} diff --git a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/Event1.java b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/Event1.java new file mode 100644 index 00000000000..def8159ea60 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/Event1.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * 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.tests.dsf.events; + + +public class Event1 { + +} diff --git a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/Event2.java b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/Event2.java new file mode 100644 index 00000000000..cc7bdbe70df --- /dev/null +++ b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/Event2.java @@ -0,0 +1,15 @@ +/******************************************************************************* + * 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.tests.dsf.events; + +public class Event2 extends Event1 { + +} diff --git a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/EventTest.java b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/EventTest.java new file mode 100644 index 00000000000..102be68b751 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/EventTest.java @@ -0,0 +1,147 @@ +/******************************************************************************* + * 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.tests.dsf.events; + +import java.util.concurrent.ExecutionException; + +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.tests.dsf.DsfTestPlugin; +import org.eclipse.dd.tests.dsf.TestDsfExecutor; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class EventTest { + + DsfSession fSession; + TestDsfExecutor fExecutor; + DsfServicesTracker fTracker; + Service1 fService1; + Service2 fService2; + Service3 fService3; + + @Before public void startServices() throws ExecutionException, InterruptedException { + fExecutor = new TestDsfExecutor(); + + fExecutor.submit(new DsfRunnable() { public void run() { + fSession = DsfSession.startSession(fExecutor, "org.eclipse.dd.dsf.tests"); //$NON-NLS-1$ + }}).get(); + + StartupSequence startupSeq = new StartupSequence(fSession); + fExecutor.execute(startupSeq); + startupSeq.get(); + + fExecutor.submit(new DsfRunnable() { public void run() { + fTracker = new DsfServicesTracker(DsfTestPlugin.getBundleContext(), fSession.getId()); + fService1 = fTracker.getService(Service1.class); + fService2 = fTracker.getService(Service2.class); + fService3 = fTracker.getService(Service3.class); + }}).get(); + Assert.assertNotNull(fService1); + Assert.assertNotNull(fService2); + Assert.assertNotNull(fService3); + } + + @After public void shutdownServices() throws ExecutionException, InterruptedException { + ShutdownSequence shutdownSeq = new ShutdownSequence(fSession); + fExecutor.execute(shutdownSeq); + shutdownSeq.get(); + + fExecutor.submit(new DsfRunnable() { public void run() { + fService1 = null; + fService2 = null; + fService3 = null; + fTracker.dispose(); + fTracker = null; + DsfSession.endSession(fSession); + fSession = null; + fExecutor.shutdown(); + }}).get(); + + if (fExecutor.exceptionsCaught()) { + Throwable[] exceptions = fExecutor.getExceptions(); + throw new ExecutionException(exceptions[0]); + } + fExecutor = null; + } + + /** + * Test only the startup and shutdown sequences. + */ + @Test public void startStopTest() { + } + + /** + * Tests dispatching event 1. The goal of the test is to make sure that + * recipients are called in the correct order. + */ + @Test public void event1Test() throws ExecutionException, InterruptedException { + fService1.dispatchEvent1(); + fExecutor.submit(new DsfRunnable() { public void run() { + Assert.assertTrue(1 == fService1.fEvent1RecipientNumber); + Assert.assertTrue(2 == fService2.fEvent1RecipientNumber); + Assert.assertTrue(3 == fService3.fEvent1RecipientNumber); + Assert.assertTrue(0 == fService1.fEvent2RecipientNumber); + Assert.assertTrue(0 == fService2.fEvent2RecipientNumber); + Assert.assertTrue(0 == fService3.fEvent2RecipientNumber); + Assert.assertTrue(0 == fService1.fEvent3RecipientNumber); + Assert.assertTrue(0 == fService2.fEvent3RecipientNumber); + Assert.assertTrue(0 == fService3.fEvent3RecipientNumber); + }}).get(); + } + + /** + * Tests dispatching event 2. The goal of the test is to make sure that + * recipients are called in the correct order, and that the other events + * are not registered. + */ + @Test public void event2Test() throws ExecutionException, InterruptedException { + fService1.dispatchEvent2(); + fExecutor.submit(new DsfRunnable() { public void run() { + Assert.assertTrue(0 == fService1.fEvent1RecipientNumber); + Assert.assertTrue(0 == fService2.fEvent1RecipientNumber); + Assert.assertTrue(0 == fService3.fEvent1RecipientNumber); + Assert.assertTrue(1 == fService1.fEvent2RecipientNumber); + Assert.assertTrue(2 == fService2.fEvent2RecipientNumber); + Assert.assertTrue(3 == fService3.fEvent2RecipientNumber); + Assert.assertTrue(0 == fService1.fEvent3RecipientNumber); + Assert.assertTrue(0 == fService2.fEvent3RecipientNumber); + Assert.assertTrue(0 == fService3.fEvent3RecipientNumber); + }}).get(); + } + + /** + * Tests dispatching event 2. The goal of the test is to make sure that + * both event 2 and even 3 recipients are called for this event. + *
    + * Note: When a single listener object has more than one method that that + * matches the event, both methods will be called. But there is currently + * no guaranteed order in which they should be called. + */ + @Test public void event3Test() throws ExecutionException, InterruptedException { + fService1.dispatchEvent3(); + fExecutor.submit(new DsfRunnable() { public void run() { + Assert.assertTrue(1 == fService1.fEvent1RecipientNumber || 2 == fService1.fEvent1RecipientNumber); + Assert.assertTrue(3 == fService2.fEvent1RecipientNumber || 4 == fService2.fEvent1RecipientNumber); + Assert.assertTrue(5 == fService3.fEvent1RecipientNumber || 6 == fService3.fEvent1RecipientNumber); + Assert.assertTrue(0 == fService1.fEvent2RecipientNumber); + Assert.assertTrue(0 == fService2.fEvent2RecipientNumber); + Assert.assertTrue(0 == fService3.fEvent2RecipientNumber); + Assert.assertTrue(1 == fService1.fEvent3RecipientNumber || 2 == fService1.fEvent3RecipientNumber); + Assert.assertTrue(3 == fService2.fEvent3RecipientNumber || 4 == fService2.fEvent3RecipientNumber); + Assert.assertTrue(5 == fService3.fEvent3RecipientNumber || 6 == fService3.fEvent3RecipientNumber); + }}).get(); + } + +} diff --git a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/Service1.java b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/Service1.java new file mode 100644 index 00000000000..34e3cd72bb2 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/Service1.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * 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.tests.dsf.events; + +import java.util.Hashtable; + +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.service.DsfSession; + +public class Service1 extends AbstractService { + Service1(DsfSession session) { + super(session); + } + + @Override public void initialize(final RequestMonitor requestMonitor) { + super.initialize( + new RequestMonitor(getExecutor(), requestMonitor) { + @Override + public void handleOK() { + doInitialize(requestMonitor); + } + }); + } + + private void doInitialize(RequestMonitor requestMonitor) { + register(new String[]{Service1.class.getName()}, new Hashtable()); + requestMonitor.done(); + } + + @Override public void shutdown(RequestMonitor requestMonitor) { + unregister(); + super.shutdown(requestMonitor); + } +} diff --git a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/Service2.java b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/Service2.java new file mode 100644 index 00000000000..a466c03e295 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/Service2.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * 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.tests.dsf.events; + +import java.util.Hashtable; + +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.service.DsfSession; + +public class Service2 extends AbstractService { + Service2(DsfSession session) { + super(session); + } + + @Override public void initialize(final RequestMonitor requestMonitor) { + super.initialize( + new RequestMonitor(getExecutor(), requestMonitor) { + @Override + public void handleOK() { + doInitialize(requestMonitor); + } + }); + } + + private void doInitialize(RequestMonitor requestMonitor) { + getServicesTracker().getService(Service1.class); + register(new String[]{Service2.class.getName()}, new Hashtable()); + requestMonitor.done(); + } + + @Override public void shutdown(RequestMonitor requestMonitor) { + unregister(); + super.shutdown(requestMonitor); + } +} diff --git a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/Service3.java b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/Service3.java new file mode 100644 index 00000000000..5069157e8d0 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/Service3.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * 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.tests.dsf.events; + +import java.util.Hashtable; + +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.tests.dsf.DsfTestPlugin; +import org.osgi.framework.BundleContext; + +public class Service3 extends AbstractService { + Service3(DsfSession session) { + super(session); + } + + @Override protected BundleContext getBundleContext() { + return DsfTestPlugin.getBundleContext(); + } + + @Override public void initialize(final RequestMonitor requestMonitor) { + super.initialize( + new RequestMonitor(getExecutor(), requestMonitor) { + @Override + public void handleOK() { + doInitialize(requestMonitor); + } + }); + } + + private void doInitialize(RequestMonitor requestMonitor) { + getServicesTracker().getService(Service1.class); + getServicesTracker().getService(Service2.class); + register(new String[]{Service3.class.getName()}, new Hashtable()); + requestMonitor.done(); + } + + @Override public void shutdown(RequestMonitor requestMonitor) { + unregister(); + super.shutdown(requestMonitor); + } +} diff --git a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/ShutdownSequence.java b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/ShutdownSequence.java new file mode 100644 index 00000000000..84112677e85 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/ShutdownSequence.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.tests.dsf.events; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.concurrent.Sequence; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.tests.dsf.DsfTestPlugin; + +class ShutdownSequence extends Sequence { + + DsfSession fSession; + DsfServicesTracker fTracker; + + ShutdownSequence(DsfSession session) { + super(session.getExecutor()); + fSession = session; + } + + @Override + public Step[] getSteps() { return fSteps; } + + final Step[] fSteps = new Step[] { + new Step() { + @Override public void execute(RequestMonitor requestMonitor) { + fTracker = new DsfServicesTracker(DsfTestPlugin.getBundleContext(), fSession.getId()); + requestMonitor.done(); + } + + @Override public void rollBack(RequestMonitor requestMonitor) { + fTracker.dispose(); + fTracker = null; + requestMonitor.done(); + } + }, + new Step() { @Override public void execute(RequestMonitor requestMonitor) { + shutdownService(Service3.class, requestMonitor); + }}, + new Step() { @Override public void execute(RequestMonitor requestMonitor) { + shutdownService(Service2.class, requestMonitor); + }}, + new Step() { @Override public void execute(RequestMonitor requestMonitor) { + shutdownService(Service1.class, requestMonitor); + }}, + new Step() { @Override public void execute(RequestMonitor requestMonitor) { + fTracker.dispose(); + fTracker = null; + requestMonitor.done(); + }} + }; + + private void shutdownService(Class clazz, RequestMonitor requestMonitor) { + IDsfService service = fTracker.getService(clazz); + if (service != null) { + service.shutdown(requestMonitor); + } + else { + requestMonitor.setStatus(new Status(IStatus.ERROR, DsfTestPlugin.PLUGIN_ID, -1, "Service '" + clazz.getName() + "' not found.", null)); //$NON-NLS-1$//$NON-NLS-2$ + requestMonitor.done(); + } + } + +} diff --git a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/StartupSequence.java b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/StartupSequence.java new file mode 100644 index 00000000000..85d3c5dbef3 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/StartupSequence.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * 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.tests.dsf.events; + +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.concurrent.Sequence; +import org.eclipse.dd.dsf.service.DsfSession; + +class StartupSequence extends Sequence { + DsfSession fSession; + + StartupSequence(DsfSession session) { + super(session.getExecutor()); + fSession = session; + } + + @Override + public Step[] getSteps() { return fSteps; } + + final Step[] fSteps = new Step[] { + new Step() { @Override public void execute(RequestMonitor requestMonitor) { + new Service1(fSession).initialize(requestMonitor); + }}, + new Step() { @Override public void execute(RequestMonitor requestMonitor) { + new Service2(fSession).initialize(requestMonitor); + }}, + new Step() { @Override public void execute(RequestMonitor requestMonitor) { + new Service3(fSession).initialize(requestMonitor); + }} + }; +} diff --git a/plugins/org.eclipse.dd.tests.gdb/.classpath b/plugins/org.eclipse.dd.tests.gdb/.classpath new file mode 100644 index 00000000000..304e86186aa --- /dev/null +++ b/plugins/org.eclipse.dd.tests.gdb/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/plugins/org.eclipse.dd.tests.gdb/.externalToolBuilders/TestAppBuilder.launch b/plugins/org.eclipse.dd.tests.gdb/.externalToolBuilders/TestAppBuilder.launch new file mode 100644 index 00000000000..5c664b7c490 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.gdb/.externalToolBuilders/TestAppBuilder.launch @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/org.eclipse.dd.tests.gdb/.project b/plugins/org.eclipse.dd.tests.gdb/.project new file mode 100644 index 00000000000..7eaa1391123 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.gdb/.project @@ -0,0 +1,38 @@ + + + org.eclipse.dd.tests.gdb + + + + + + org.eclipse.ui.externaltools.ExternalToolBuilder + clean,full,incremental, + + + LaunchConfigHandle + <project>/.externalToolBuilders/TestAppBuilder.launch + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/plugins/org.eclipse.dd.tests.gdb/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.dd.tests.gdb/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000000..e598bffe12f --- /dev/null +++ b/plugins/org.eclipse.dd.tests.gdb/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,65 @@ +#Thu Jun 07 11:08:01 PDT 2007 +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.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=warning +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore +org.eclipse.jdt.core.compiler.problem.nullReference=ignore +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning +org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=error +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/plugins/org.eclipse.dd.tests.gdb/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.tests.gdb/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..326dfb185e7 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.gdb/META-INF/MANIFEST.MF @@ -0,0 +1,23 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: GDB/MI reference application tests +Bundle-SymbolicName: org.eclipse.dd.tests.gdb;singleton:=true +Bundle-Version: 1.0.0 +Bundle-Activator: org.eclipse.dd.tests.gdb.launching.TestsPlugin +Bundle-Vendor: Ericsson +Bundle-Localization: plugin +Require-Bundle: org.eclipse.core.runtime, + org.eclipse.dd.dsf, + org.eclipse.dd.dsf.debug, + org.eclipse.cdt.core, + org.eclipse.cdt.launch, + org.eclipse.cdt.debug.core, + org.eclipse.dd.mi, + org.junit4, + org.eclipse.debug.core, + org.eclipse.cdt.debug.mi.core, + org.eclipse.swt, + org.eclipse.dd.gdb +Bundle-ActivationPolicy: lazy +Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Bundle-ClassPath: . diff --git a/plugins/org.eclipse.dd.tests.gdb/TestAppBuilder.xml b/plugins/org.eclipse.dd.tests.gdb/TestAppBuilder.xml new file mode 100644 index 00000000000..3f8e9f07fed --- /dev/null +++ b/plugins/org.eclipse.dd.tests.gdb/TestAppBuilder.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/plugins/org.eclipse.dd.tests.gdb/build.properties b/plugins/org.eclipse.dd.tests.gdb/build.properties new file mode 100644 index 00000000000..aba8ab478f4 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.gdb/build.properties @@ -0,0 +1,5 @@ +output.tests.jar = bin/ +bin.includes = plugin.xml,\ + META-INF/,\ + . +source.. = src/ diff --git a/plugins/org.eclipse.dd.tests.gdb/data/launch/bin/BreakpointTestApp.exe b/plugins/org.eclipse.dd.tests.gdb/data/launch/bin/BreakpointTestApp.exe new file mode 100755 index 0000000000000000000000000000000000000000..6eb8b78a5b9965ec3247979c002e09ec99a468e6 GIT binary patch literal 40216 zcmd^o33Ob=nQq-y%Whk;EK9a*gt}YCiwwq+Wi4K?!IIs!g^i6j@B(RC-7Tr@R<}^M zybuX2q z?UsZcUe0;%oYzNJb?e{juk}{dt$R&m(>lj-l>PZsnPTkL>-~Xtgu8Chn0D2u0&0P3 zQghV=fQV~90vcSx0H$)l{J6@9L%jW3;BnO=&Wkw8<|RM!;(BVLQoP8osx@9<9{~>6 zN-zvTDfJTXL+}#lUjmNTD~R(Vo;rAK0M7>K=GBNeFN?eI-}8x;;9q$oWaF9(950LC z3Ou5tepY@T@t==T*9+kvnK7wxjYM%;vL1R>*XCjJ{7BoUsi{iAKe>D&zHlL()2X7-{=sY} zn#;$A^U^E!m&S<&(o}(y?4FnN!g{o44nerLwtbZ!DK=@5!X{Yg!`*#)7XE zc(nh}q3BR@IG4@D(y9F6=z+ylJE%3{u0I}+<``=wd?-IKoQx$H7rMBytY-_%N~AK; zkz6tXL*s{H(O5otD3wP9e2^hl55`g%wPx3@uI`>_Yjc}gzp1Ai(P&$9yS|Sufnb5+ zjuiMY@0go@T;<3?2N32X^J6itAANB@vb0=1V_^9+-;Zo9Q!gOSAL;KxX!EZ+m72m5 z@}CBl3#U+|eCodu=kM9u{ecNk`Vzv4Q1l8z#9w2G%z2$5G`_)*1?-~;QJ8k#^zTPs z3LO6wAjjX}zaN9?$w$$iw#G=;s5JOL{9whZU)DyZ}{QJi;tBP?|@0u-+dg-$_?Mh*E~oaxS900e=cDs zzHe!&ACJ&i>cxg*kvASYvYPU7_qhLt)gRODIvRPyx%R3zn5?UR_T(cX+2slz+xZ5_ z-+dh!_5Dr$50TZ&_R~??CWGmw$m?FBm!Ev(mQ8d0aN3E>-+-2_@D0pmNjtt3&N%*6 z{<{kQBsE7L_3ys)me?C6t+Q@|z@4ujz3L5Tr1jdXUS~FpECB!NJK*s%-#l^R@wIaU z0a%HUHCzF=2bpsG<^Of!gtadK9ZEeYIzI(XF5C)I5CkCod+8&$yy_L-v7N6VlNYw0xaqN5?kE4T zNcGXjott3du}CEX|FKBmCjZjJfFl#qT7Tag3%cqx}(};V< zzX4-cBbzByfpTd$EB*d=!&SsJ;(7yRJAzPkRRwPFbx%PR z72HaM-SG6xF>t#8V=kcV7x6I))hEbj?-}yP+_4vJNP9vJayC` z;QjXyvJauL93wD9loCzfjxxW312Qx<<3UqRc znS8Q8X#kYZF)@vUv62KPo)-(W0N#lkAJi)UMBf?$13nm{d=q^aX&|e+Gr`A^oUgnL z3Y5Rx*MV4|+_#m%MBfSo02(Qq5OXH@KhNN_WBgxU#xYm<7Tl|warsm?{`(ziR&m$T zJCaH#^#4RlKL<05mNa*0z@q$cGTD-9Th@tDY;U|Jo*QY259d?O+fRkBAPjs8b)~Uu zdn1NDOPf0uE9XcIY4s_NKK;%k_@6;r#QY}VnuQBbQm_2o7^&?a%EBo-lDT}>&`@(c zu384NgUObm*uiAFM<12o z`WGa4*Z)XxV;w4XVA9Q95**tm!F$pYeCa(BeEG`~{KHQrxc`47c%TU#K%jcX1rnTd ze;s2hpJ7n5=2Z#SI_Mh$HIbPdNfqXZvaBf-a#5`6p` z2|n?D3I6Kq65MfIf;*?4PQJTVN^tjH2|js9g1^2?g1`Be1fP0Ag1@b3Aj4;uNN`V7 zf-k&Ff-inXg1>)Kg8Tkcf-hAC$?)Yx68ysj65OAb;DPr@@Zf_IeC3A{eD#kKJk$^( z-`Bb%_-7`h|KmAT(|2z{NQeejS zC!*C2%=kgK#D3T!xTiKt@UQnt@N~ZfKYot{&-?(v%~4Ku^n&P+3YIyG(VhV?%^^ilIZjRdEOb@1gx7AyEq;@SlLzqJo{Xkox+GXP zzVSncR;-9dnbKIgfQ)A|xqKsyJL~L5F?6*38a_G!8a^rojps5If36*Wc?+h;%ix@f zodFJFF!ix+FyEJs_2-noeraWNd$c#3O~=wh12N?=nnWE0s?N1FIL_`#fV5+8fq)#2uT1JL2DH9h-T2(BuZzPxROC{3@b+0I= z9v%OV7$#+01FjciI1SWid=X7%66(kizp8l1x@pT$GBcP>peEGsr?Ii2A?+Ym0uj)Q z$r?!qLa{$PlGl#O4`Vo>Jwq*7BdVaKev-)yWJsO@{q-N9lKyNq(TiCjvA8!T_mY}q zwvTX~F|kyd5v?2Yp@TvS;(M+5?aAc+L~0n~AEfx+WWN?29~st(VY*#!#IBHQ>wn+H^zKgYb*2&C;Q@AJkCT^2U;wr%$W&b?r7OZm=;!@*7X}dl)eL(b9xl{lA_0an=VIwICd1*@O6lvfU-WEZyd?wQvI1^ zqLHIM-^7NeAuZ_t1qd2mAQc-M49G(q);VZP@)3WiZ+K7z zvOgERG>1aOIOI}fh+{&M=Ck`%;0a;W4JRp8m}5nvlf%Q=VLT^GW9!sXqY8bP$id`b zd;q95605x(FhSRfmPUWje+NLbC%9?Ti3m(cXEXi9DfUmCVA5|AYTP2;C@+TxGx@e9 z=(sA+rU6=lh#^Iw+yij631%XAFCU2|$a>DJFbDChjIt|lU5R0^W+bVfYJlo&C+%%P zAOVQ;A&!6#k{W<~YLLV6%G)Kru4hw3O>TY{aA!g zq|P8_2?9;3ku=l58(g@M&obaf0q0@|tmb-yn5*ey@%s#xGGLZ0~MtcJLe;V7!h$RK2%?Xb@I=B%xb9>~Xf(@B?Mk@Ibo4&R)0)$EOi zrH`p-cFqwK)>lVa4phYwXQKc%K%3EYj9bVj#OT zq)k<_VGVc^{Gi zUrye|#Ljv*uueRkjInK0lmFG{)Di^2e6SAj3EJsH!-3(=jXQn)$$VT*en3iw)zfM*^#0_pc;wX* z1w)y@FdyJW0ElXQo(_Oobdo}Rx_A0GZc&r}C<*uUHeo*WJAG`>)Z~~?cQ!2h(gWy! z;+YVq1xTm`y;&ki>k4zyz(Ms*?pKrF?KPTBt?qcjm6#GBOkov2^VK1qn)?g_`i_CFlS<%TxJMQdwJNDG-_oCLS^EnMJmjx8s|V? zE*{H(>~61hlI(Axrl~Mza-0K(=re}MgXa_v@UFVlnCfb^unRP?k@f|zw1UXFoF_`- zDe!<=Hm#!x4?!tDAL^%*Y0H=nbmUF>f$T^wmPzEIx#W##A?P{klZ;dX1YdxDxdnG;WsQ3MTYu za6=O+ODdm2m(4+zns&a1H#TLG{V@-GqlV8Fllz8a@n|B|kLPnWZ4+BV-<$~DB zTXNWciH0_lya2saLtDi95{oX=xWxuntfW^XTLoESSwiEM7+f)9pGLM>sRdgGHKyIN z6)+i%=};lgM6!Nz9tKr!+Ew(v9$@RXuruS$-H35gw{i)hpG-Ns<2Ziaq8Zt|01oA!&X&@w(OQ3tNy;Xx63F;rr zV<@F+KfngsH)k$kSKygT)qaq*5`|7-Zd|rgM6-BsL_a+Ha`JP~Pz-NuVbae=-^{^U z?Sq`;bwcN1lGfqWI=!T7|54(#ocWc1YC|uCU{e4CxIaN41xyA2tQ6LL*vLm*r_E9ME^u05ygpR2c8j& zkBeEFD8#vDT`n~8B`=aQ(0pbyN&SxQk!gtTjHQ_qi^>PFWrkA)7~MrV7z=Zv+Ud<_ z55`s1e1{Lp=3y^<1u-0G5cPylqX>k_eCP>($|cCDs$csgTFd|XanO+71Hc3fHaYEw zr>!t2!JR&Il@$B55lf<4VF>@h#Y5`Lrl%oLtW+Hv0cnI z&gEhR=!|neX~-li4F%UJ^r(V%yk@kpq?y9N6$}g)TwT|e=8);*xx_&_qwC&r$hZW8 zaf2)FePfz#WOAW|#75@VOYJvgTu5;axFYQcR+6a)AY5Ysg^}}sSB@s&>Wgy_3!~XV zJcTVY`6l&ODu!fPh>J6zf*4fZ_j+m@RjCjcZ3I0yq^ds5meQ$peXT-V%n>wakgDz* zh36`d;D-*Ys&|c&&eb15=Y~+UpZ|G@_%N4+h}TU})v_{8QCuc!r40&k?TEBeOMYJv zr9xazA|@kge1C}*Qhrs4i%pt{Dg9_kN(>Q~qBIfHbMu&z!Wly(jz^8@_j;a4PmKxs z>C6xpwJ2BI@b3lN#nmeOC4j(ga+vR| z`o6YQl0xAsbhkkd^$sI{j(hMVQlW1e{IKx<$b;AX&lxEq2@9dxibr)GQ}^YhDHTpM7KLyEJZPA&hd<{U{AsRL@peZ{1J zMGhTOT!hrLnqhJ#c`#bC(1j(gF_zQNZJec7_ArH6vJUuXucM8v!n0!cms+sHBz^cG z{AubF>hNuj#J#ms=AX^rvC<#ry0W21)%vuf{VTb|3Ti4Kmz_1$2;1K;IAt;~Q9?GC z%hJu!_I4Ghi#J_9lFh5S1RFSx;W2-p>XJInVTE`>XJsfH@dY zaw~J)Ayaz@WLt+|afplRpup@`-TQTW$nlK|ah09$l&brXZo@U4%kG4yRh>+>+Zh(F z!#h}Vj-fWGx=Cf8)dyLEU{%-cHIu8tT(Fn2T{pW-yst;4RHbHd8J`nVNmaKOvnrIO z!d%qnP%nu|fVvNwSsyVf%!Pg@&6-j-r;M58)Y7~1PldVukC7Mqv$}m{g~aF@8s@$L z4$L^z%c;5p-oDWt>!~pJ4S-ArgmoDshK+)rdXuJX7Izgmm*+53t?H`EwBT6a}9t4y26|Eg6M{90u>aROKQmE$XqcELet zkg>Zhp-!Jo5la@7L&9mR+kSwJ7SbimX=}fnQi+|@<y(*ctBJEC*rnkl<)tv1`o#ANHmYFUv8QFK?#skJW@sU&=X&+VR zYZRK$)s9R2b1prJ*w)1b>d1xheK1lBl|n3)a_KVqV9-If#7>sxWrMLpm?*mB{-49X2Hpncwr#^%c*%=J^o-W21f$z>+NS~NTntCdjX5=>K>0k&g~bg_?*>}# zTy1g;llF5{24^=21pVA#)au^>?grjAaHm1TI%o{~pTqyQo7OAEZBqU-maWKe1tM7C z++L;>;f`|-wk2^B=nxibRB)<87MNHz8LuCiB~c8KaIc(|zodnRUIl9$=Hd3-QUgIo zF{{g*n)gz&T3NTyOI}BE4>cTU$UjPQJ^#OQjo}%F!eG78&SUzQ0xTYJN>q!DO`y@)qSN)42$GX{m6YloF$P?3Ei ztyt2F5Txf|SKe;KrBj0#*#yt?7$YF?k6{W0sFgo9yopq9ANB!(eZ4iK6=qm)gvnu1 zbB)j`nYzgMA&Up3;Duz>nH~oKwFYeaz*E??q5JDq>kXegF$H%Q_y~9lzH1F1UXjCm zwF>rXP8I&b}bX>G&S9h%9-{NWrJJr_Np7Y{egbo8sXrk>6gB{}Sc%pE~!QuKcUUlMnj}tkMkgpE~zJ zm-X85SgE_Uz%1Rk&fq_i8QvWnk*!~$Z)p*9xCWtcF^6@<(1l#QF2!rr*)5u#6(|Zf zCsgRm#)u^l;ex%D>pbUq2ibJYrQ04&4i4dcM%^fUN*aaLeUyA`0tkHpTP@qKvB1#7 z)*{(r*?zl=xZfh~fgIKTkc)WKizp;SwZGt!{L9!Ry5Vl0u-I4>`l+Q8M~XYN8FO8d z=Zi=*cD;)|Zn4740<3k+N|WSj?_;V8{v3NsrCBnaMAt`1^mVlP!GG62jBSr>L({GP z9!a*6CHY<7bV*-!NmYXX@w5cLi=UQT&_c+rnNQtRrg8{ z;ZzdBLYI<--u5irF;YqkK2r;9D>UA&xEo!fGmJ1pRV3;@QVkpP7HVmoIu83jjpF1A z{Dqga-N-D^a@(+LVfhk@6%$u!q3w*7id#bF(5QZ>g~BsjD$HnL*r^okXts@ zn#paFer4^~_ zw~+nXe`&&@P2*MezjI07bV`%Lt6U!v~A#{w&-ZcU5XE~Gnc((4*`O=A<$1M2c zG&kKY{hrbE=tsQG4jU*>Gu(C1mCt@^nS!?#D;(QrQ|0G5{-NM%O1?!Os>8-Z#p*!lgUGU$|VqAA_sJ#V((>Y@W8vBq)?N zel`i>z`eL|3csg>Znmt!)BUdv^5U(Y*yV*iVnU3s)8>wH~BCsZ-nBBfQhnC1l_+QC8tnT z@Q;SDozYUdvsZ%-3v`7gXcc_ZFtoN6A;8M1TvtUuS^Kz+I`q#r!HjYet|Y~-zx88C z_g}fJ!TJftSHjA+v)EZ~@1nYYSm0Vv#3fnn^{}f?b(eR!Rz6>3B?dfR7RgCwit0Lt zEHn8uwa%#N7(S_WT?Z^z==VmC;X0{1y6&;8!QNtpZ;`OBUs$G4fWtwS1a0N`2@7^3 zVNW25!6QabYa0`Ww}OUqdAx_C2kS+CDfquDX4ylh8I7gvCr|2~Rz~m>-{>c&n5@)olsXG|y=dlrgxpTHhgq1eH#|%A?v|vU zOnDlui)GWJ-Pt`|L1Yv>ev5? zY!!Ih8@Rm-sLJ36nq<8~FV%gJQn(`tFgtIlf*;aQ|N0mk!w>Uya^IYQYWw6yr6{>F z__3)EKp@wIH>^Na37vP;XIEx7Tui{)E6SDPE7gwEgHe*Z?tzg>b~x6Lf!T$q-WULJ zjaFVhA4L*T)aN+o>t&QL73gK)<pNtAcnoHZD`D>3VwkZZ(pCK}kG*ZsT)=_bso|2aqdIT#a8fqk zlU2dTJiJ^)C9lPLxqt29*0beNY(jELRq#6nK})zCt&L#b7ZJ+rvsk2uU(KQOwKs64 zfF2?~RS?v=7=jD}#_-|DCa1aA@bx1hD)>x+iL31dvJK!EnGYr&P8lJaVe)5121eG{ zJ%t?{p=u76Oi5YJ5x2nggoO;Z3x@03EQ?T`$Biji`Ni%5IQ4~s7)gRbSc_~Tv=wU> zuvoxoyTu~(IWzEPfz|wa^TpWw&6gQ|IhBEH%CD5DH;57sZlq4UQ-gPMLYI0HE(`Jm zTXp+JyYEHRWxPE)CKYU;USRh`!7^z4RbEYj0`4+akNNy|8*|ZcL7gGU|xmO-$jd|Y5f<-OEclY zd(anXP+)Tvn8KOWehaDI{2=bb*)v^8<0kAHQQ^zIcC`Uy%{p)TJhUvb|06Xx1j>-Z zRB`VI&%228&{^6yTe8ch3>oI)B8m*=e2o5dwihR>gk?*G>j)Mzjd6*${EUX4stPxSumHsW1>{BL0S4*KczR{t>qcpH@49S67KxLFiy zfA~wfX~-mSdQ$iidAEdZgB+d{eyliEsl?a^=bSqW;&cIjvXny?^2OX^QbVmy?N#`% zb}r#P>T&qH%vKL();f#%0roctLP;x6;-@ISPyv>t6723%TySR-?$o@S%uMEok>XbW zQA8Vf8ST-f2WO*)>S8vwe{>vREMp%*uRHU=xK(Rh_4GDqMk=vs zl>?F_U+_l3`%_V#bwqp6PqcFMQ$!~fs7AU1wQBx$ElD32;1zaaEMeR=R7&cVw{;!m zv7-u4_Mte4mfC)pt#_wy?Q`)J1-y*zneA%pwJyH0fEU!xyNJ445~adbF4nZoTOV>c zt6iLER_FeXC~3B9Wn^KiruLAxU>EFFE7$DMu95A4(Hu%bRJYxAV+d(=Hx3pk;TVpz ztsB&;PaBDLI@Yv0DHgHWV+cj-Q2!nRa19rqf1nvVVgUK zf>xcMvJmFBfm-~98!z0rd3zKUGvcP8Ruo+VZEDp}i6Y(0hnvRIV)lb_xlLD0t72>g ztomxzGe!XxQ}Y-GX+{i0##2y42L(p9+;oU_o`g_E?Kw<{wB43h8UYnvaxxu4r*#<7 zvV%_N2F2>qj>d|SpuY?M8#>TTFJKL(@{831`jOYgAm}9l;jR8b-o6*NLAee3d7M`{ z-Za3N6feol>b|!^$MFUQ&x@J$#GT;4`!D2s9=H(C7;{oN&7x*~{b?lAsg?I!c_x_( z@$@l=Z+_rp#7s`jdXYFo!Q;wQhzFDL?FNlMPM|$QX!@HeucB#Wg?Aiu1{j;##RZ&eq>nvo`s@_+4cqgr ziwmcs$%FDJ(nuVK= znby^!ah-P~4s#=iqgGGcWq~(aVC`){sqSsW*iqS8YMv~!cwa3TW8bOldPs19r+5E+ zLX>ph;T5&$Ts80GEO)0OYbXy{`YBS&>iQ*R{Q*72ygMnx^Qyym_6%`<_TSPHljyF6 zyRD2*pSp~c`Z67;W#~qzD@#FHWcR##PEpX{V5u<=x-#xNbs1wBhe>b{$zY&lw}=KbTT8aI>{U%c@1CllcG9D0 zu+%c^yo2RFLLr8ee>h(zb3Aw}hw;VA;Wrz) zaIX2|;N8RH5bYxw4#IU>j6NXnZgUpL0v>jOL(sB*)0Xb8P0?tN?8esz%{zw$2z@_i8`D^}ph@mSZkZC$&g+k5szaCWFnqhMDu zH~JgVRriC`ad0fE=OBA$>JJ2};zJ0Pvw#QRbNy20giff$4TzVQ@%tnTcnUt#WKp+k z6uwrHj7Af=EOxtR5}1^f7Z@Fjd0`~ zUhT;B3`RONiJjJI?B9&Or{TBb(Dy}Jmkh*k=xPQ_F>rZA?LLdicKY*Z(i;AAe6}{S zT|Sb+4C?0C<^tdE;qQi5$LCv2K7AH*M7_f(6C0ak*U;!RCEnV`1>>{5rHu>6=NsR~ z%f?|!zO{|9@!8(e#>Du1W7#+``hBizPQH$ivRo`uy*&p}tXlO6H*&Cb&%p?0mJdcE z?WBvC_r&(;<%yHA$fPbOIo#LxEWcjOIAwlwWH+WOd18*^{9l?x9b>j~0cRWCHo#F0 zUq#$I8~IDb@f@$=|1Uh>H#DP3*uM`Iyk0r~hT%rKSL%G4r)AfdIbU``zO+6!yMBUm zKX^2qKg|=g>nAxUFb3D4!2WLB*H<}z1ECsJot6W&>uVf-=0?LBG4YvK^)sAWmvePm zpRrwkn)571?wan%;MusZZ*Z>1h*N{`YC;oLG&oV8GG<{eUr1p z6{!Lla|Cz&Sx&@FpsLQ;!?^1gIp?{Ss>Z>`sIJxdYyq}<|Mv-NcY=4eEm}A zzg>~%52k7S3McC(((g3zB<{311G|2c^CL+3x48DYISsphi}M78Xeb|A9kLAK^j!uz{9%Jcu-OG z?{(e_+XsZy!HIvE3Rd&mbicA#KM!(v)FGINdJw%3Rxg}vI(v|m?V~9L<5K!CDanJ_ z=XZ>z6pTyh&q}AI=68;!6pTw5$R0AJOGlA*YLrV`oz*Ay&0jW(v_mj1Wn)&3Q&IDm zkERriOSw9W#kQdVHGjouO2Jr4f90llCO@23^UoPgDHu!X+cYHaRnA{Inouy7&<}s2 zyI1p9jV2U~B~+Cuw758RVi2dbqXaaa#@#1;;>A0QBZG3Vu`KnvBoXt-T;M}lY6_0Q z#EmE{zUryv z_W`*yg)75JwU9?0AvCVnagnqNLhgVkh((gW)`^p%b`F+%j?W7rA{a) zo>(v^5O5hM$!$4hOs)kZ&k3pUi;{{8EwFL{;0;r7`hKmzNm5noFm0M(Y6DWRZ1NJA zR6Rv2FDC#Wduw*itCZxHldGm2gzdON@@U<3XsjY)2E@TX5QlWv84s1;xH>>5EvX>M zOhB2!V(6@9m;@DqA=zo7(T&y{u8JF1S5X#8PPecgIV7e*`#(5URUl6=pXU(?06D@Q z5K=}^BgvJTJs(4-WM6W)``2zHyf*ZYo6Ry9Ib~silZBXTw=7 zU_Q&{tWpb`l})v_=WG{XY+f`AmNk0}hYR3N+TJq5NM1YxG_BPp;Y(`O`dXW(ZM3@( zZ8w6X6@{#JGwmF2!D2~U>Cvalgf1tm zO5hrLuE!EmYv_66G^WWbVYQc*_H=mxZZf({6lveCDS?uIZ3#bN5f7ct8Ew+KLXB}X ztw-8TlfiWcmXV8RqkQiw zF^);z?O~>Kra3jvYK(CAl9qHR$UvvCh!&OI?#eXnEg3nPq|YN(+cK z8(|i38CyNdjTOYLtZYDHdJ6!ZcX51GxR#g%Z^)A*37fEXX~g;rhjuNQm=XPe7K*cl z4iso@R-!de6`&%Qe%WXEb%D{Q>@Uc)+|ZORaC@MGqiKU{G~GS^hhGvg3oPhtolFXFI9;z z8s$zwrm;g)jumM+ML}U%>&3SwUXb| z%r8o1@EQ@2INgvRiv*p%0}=8QVA;teVBP_Y0V=6eSwo!4Y9KzoX>Yk`nFAEHAiADw zeOfCx-)+h7EDlV6X!q{jcYM|FD+~V0@07)T3!GJbh&2Qn`+QZX z$p=s@{*o;YpHARd8pSW-mQ8ZpMrJXalp4ovcJ#NG`R!-4LRSXNH>RhP89yee6QTXY zw1sowW$74juB*)Tzrp7JT>DLHi?ne2J?m1q{g$&C;4=&8~`f+$l-o?iW9)dYJB5L{<&}xjq$awQ|KCsKY+{6->`CL zqWlI>K`-TdUXj5;n?+?-$+NiGR%>=3aY`bUh)Ow)Xo6+7`n7WsGNL7#w~dr0w;OIb z#ic)jCZb)=rDk3*Qm7$Hw#(>`!Qs2d`aC)n?cz~;(E%LXK5S&m2Hj$DZJ2Vyo>w`= zpv1=I?)U#9%IvEtN+w>~kX^t?n`gs6WaZPUu$ZD*yqg-ZXNVs_l=i{yen4vU!C0QJ z8G2o+&%DyR6|rxq)SXMs+$ucEQ=N_93ZKXmBlNomvIEdMNla%Rnf=UOm3oJZY(SR{ zP^CKCFojhL>ySxf1NEkvNtWrUhKbf(eEVD>vr|Q zG=8e^mC2%2u;OepB}`kHGpi@XrD7Q}Q9eN#QFa}Cl_^6~oJ*|k)Dy@B;=Pv^sq8Ry zK%cQv!n}-m$I@=xW-8G#>_E)n#Sxp=E*M+Z={|7|vd)sxJZbywhAwU|)5U^yw>W*R ziwot+F`E8dPw4~Mc3O4 zt-Cq7C#9u00iAl$pw#vyocy$k7cCOSo?>r{i?-W6L5{AA>rH;RlVVzujS0WHyDW(m}FA>QsmIH4)Yl^xpj&J43Lb>3avYVZ)iwjLcq-a#bWS2BU zMe^I(Tt<|6nN7K^q4HGGA_mj$^LV~On=&e`Sfm2X?5=jdjXRbgwmqdqIwDQ0T^1jU zi*G(ay*9q6LDL&!jd?|_K*3#0%|cG8*&VXr7LjoS2QfaC_cO#Wf%gH19FzFe2p$E-l^{c z3?G;Kf`}&&e^TT948N=I0}Q7iUEX9=AwE@Lc|XHx`W`b4m;{vjg53Ftb6+%*%Ck|)8tV6u_DHwjz8CzqDB2nOmlWEfH zo1t`GHFIRAnsG2W{&S-SP+56@tT{Ol#pkTBcX%KHP8(CrI5`?$q-;*;U|$?ah>YPW z1nO`SJO4F{Y%Ql3#~3%G3J&rs*v*M#??`_XZ_VKwX_O+-p^;v_U){t}IkFZP>+QuS zs%;D_kx6?m*4YTWWp6QNvbRQ!&V*C=e>!N8$H;t)(XT}wA%aO?_eUImb8z7aN9ZbklCU%pq8rK?Jx?W>1>2>}9SF5>LZh!W6BLFCyqIb_xe_#)oY5=o( zX%8>%=X%r7r9qbl-DQALFY(mNUq3Fa0t@VWp!*)^SP85=(lI`S%hEjsx~D+5*wA6- zOXQL6FfQ6kJ*-=P2$+d``?GrU09d*P&@})-9ri~$Uf1BVbhm=;Rsi441ehOv$KMUO zEFJ6eEM#_rVDvxA;_nzP(oqEKb35qVN)MQ&`+$dTCFoXyZZ2T}7T zFX&i??9bu?xUu)db)YiW?6Xt_-1HK<^&{w8;cNS|GR`QWyZ=gA&a-5$uI3WD?_H~X zZwcvR{>~|(yZt)QjiGm430>l5g*T+M4F0#bTTAHfMTOZ=AangU4KU`J{k;yls1*XB zy=CaBu4)Js>pA4_e8AV>Vmerdk)1{IF8rucPk0nqc_170W4ljanbFGjUB|U%w&Oak z1+u-?aqUI6%Q~(L9@}3XXU)N~2HHCv*N$a-s^bzUwwpT6RG@ylaTF^2*bXu*lb!(W zk{j1Gg6*2dV_gA1wqH7qWpMoLxT8$r-3k2I9x*Hv&nd-rN5`2fx_!}c_6+bh>b;KZ zo{{Z^j_X+^whKBwgMniG*YP@uv!3g?Zpm4nb$piKS#NdxG>O}PW!O{Z{go;9)`eeL zQ47uVa7CirdsY zQ4>+cz43a)ZFzQlGt?Z!ZFy~k|C$l!ZwD^cjtz*f#y)H|MAM*uC*ng$FI$2d=uaYU z>nG#f&u4#)xOrzu{C$YCzOrSRhWh$p#BF`9QB{g>Yx2h(h1CB|6TcJbV*D2-&Ic>T z%g|&k^T?|~+@_}*=?NpwE#`2Z*ncMC0aIS4`DUq3#E&37DUmlt@z5PRm(BECgm|@~ zuSWj$B5vodiQkX7o#STwFyd>GUl51Z=XWQrF5$lc@hee2-#|$FKaKD=ru@|SrYOD| zY3INx?^}r5_OXWTW2`r|NFJQFWBWx5zMGRs4&_=>ZOb}alIgw{ykIb#$E3cQ-)6vv zAS_s(!n8A`EW)Bqyd|C+X)z0ualY}_k2xQ{ynwF{0i4T^^z}hxG`eQTmTl2ZJ==Fg zqlm37ik-j4MRC3&jqfWZnmd+uEK@@aI>C_0nj;RP^6(``@aadi#K_>_VXGjrd2KyrpRutmK; zg)cP?ui;4pc-)Ql4MhhIA`rHsNv`%Dn7pPna=<9wwJX}z+z!h{m)MM*?x{?{uEl!l z$ekt=32R47C|(XhDJmqm@KQ?Adn29%(vi?p{Jv2%if4M8YWwO>@f$?i?Maydz?bz7 z9g1QPa4ws{ISKfh!hyxBSFhQ%3zHd9dKcN#xvaC92NMp(qxpf6%>L%yLs$pFR#C}H G^}hj;jg3VB literal 0 HcmV?d00001 diff --git a/plugins/org.eclipse.dd.tests.gdb/data/launch/bin/ExpressionTestApp.exe b/plugins/org.eclipse.dd.tests.gdb/data/launch/bin/ExpressionTestApp.exe new file mode 100755 index 0000000000000000000000000000000000000000..9051861f97e3df5a0af67b67b7fd41de2c10e4df GIT binary patch literal 16921 zcmd^Gdwf*Yoj-TxPPmYSghT-qbRrO-vP&MHyI> zHQx#yM414IJm8s#ZpuJ6-v&8iEoer{Xq!<6rbXO468RxAy{J}l$@>;$h<72uy@<@0 zau>kM(0>^+#zD}Glrs;;CD31jycxZq8MSQ1Z?oYr(ua4L7ULO^F>3ir$U&YIwEg;c zS7&`ZJR{zf$ZhpylD;OD7Ou&%Exvki%?Y%&Y0`u3w3*_qgu4=fTqY70 zsa%$(p^vmO_szksglJp0u603spwTx|EMC^Wpe@h@BX)41M%lB~pX^4mPF{Lq6ROoM z9<=o+PXX6;S>4rD$<}z(mhbJ36zT(jf1Jx8s9+mLMF zFdwVHe14x8n)L!ShNc|ClO~6z&{B-(yKf93OrgaXW$zx6G%d&I&bxah%^YImN$&#P z_`B|22%@-eiexJ0uqTm1W95mn&k5?)lJmCLiGn7TYe=jZd`}ZsHG%4Pt^`1K5 zKhbr-|1os`WE}8+BzpZX@9-b)^&i~ff4$fL$qxS;{r-1WpaA{;0W={D9raHl7;Hwj z@An`3&7Qe61B*~EwkHk!{zFuhrL%d}aFzqM-+$sDWVT4vNA*s>wZng6r~ia5{h#4L z^Vo2jC437tN*@NEgW6v*%~Y_b$k8CWzk?n@ln>Ey`!Wqka8&ma)#!dsnrX0 zbL#rH9ld)DDwp2r{NP_XNB|bMxTHrs4YDsBKjN9K5S{APfg>BhZ7Jr$2u%a98nv#? zb<~nAW(fukqkae8#$$us`%yE}m0tfblo?e@lf8ac9|&bwmECI>OlT8fTp)Z_( z#g!PFXuKtGZJ-jva^Mp_dOpVE9z1lr|GmOxdw*Zyvc2!5;;Vd&{sfOnd|ZhK(!mcg zuvXz=;x_*v@dOpW#m6Ij?B?STA8+ze!%|M`;re*)bh&1sd=Mb8M<_KB{qJI z4X?K$+!7q->+rtE3r-B+wZSPRhV{}PJ{d~h2Z%S8nEoZa?*R9J9tHSgL=Hce=S)Nf zdU6o&26jy^BG*!=Uoj4GHtZ8`0OXp2QwZ0Bgs6(-AncO@~g zUf)3c9^#XTnoszGt#=+XM0n|{&gyk1Zf%JIe+>oss?C3F!us%KN50xpw<{g%OW)oS z4IAP($|&&Kun_tBpy8&~Le#Yh@&1dC)`-PzZF9ZTu>8Bw+w5!fHF>A4>C7dvIYrHA z$VsaCLh=7vlhrP!Bf3N%p6qo(yn}YS0FeEW{fqsP{X_@8z+B=ybZey_zTLDAsUaX$ zIA&bpeJoOyd^7CGro^nOILcC;)FaNkw;=|K*OnA{VOV8$XtWSBU?-jo1>>0}aS(VG z1ACdI#Z@p(vMtsX52qsu(PuM0m+s0l{>>fq)`qc{uWiOQs!MA)WQfl~5kPU4)8 zk;fETN35|KZOKF^mqvzJ@poD$*Vzd#Hwibk8BEj~hDVudfUxQVCYa;A$ zO1Lq3rMsU_nK0R*kPd&?li#rirVga6}F_jF2`pz5% zrh10!quemgX!6Zcj2YQ%C; zku_|c^IE3IT!@bIAsqA&!D>u7TV}2V=~kYWjkpCwC!DS@##v!>1SW7z5+fs6XYtg@ zHOX{~5#Li#MaHeoa<+!Q1D1_|*Mu_~L+g-{_zlXZhI znwdLX7Znde!O-s*{p(#Ah5o%p}^=C^v=88w5B72f`<#0hs!GCg~`wGGe=ini*j_4ayINTaE7y<~yfw;ROf|q-WhyRA z`o;>d8^EMNmfohzOjcl-Y^N$ND`X?&U*EPu>*jC*?5Jq)c_fOa}4wys4DK)EBg=Fka zVnVz};i)rfpl}`{74Egm3U9gcl)31osPS!N(nwcrj>?1fFGqaG&f|XDZe=i#;-LMG z8f)k~T(nAyj&&oK-NwT(Je!7#1*)}ZdlOv7I*vYx{9mYEP z=;JUi2TQSeySv6=`+mgB^Y$Ni*#AM^eoEUfSz8-VY43{#s&>8u%a0+(V4WlSX?sMo zvY(+zci+*^3zG|U=6WXIooh`|#l^X!H1?9+cn*18Qm84#Ryi@3e#Cp36Rhu7r9i!N zQSY#&R{F;CFg2@SN^+H@gRt@zBIh$&`nj6-QODc~lv+Xs|DxC{wQW$gXy-WMQP>)h zLULcAu>r5pf8*Q#kTi@}D2MPb*Fq{=l3NLxOJST0v*9pa39O%~=Ft4eIay74K@Udb zJZ8KbUVNy$XvEs?FuizHR+R05E!~2jm>Zu7HzDWbb215tp-lp!zSh7x$tfVVu~KlMb_|e zCOmwX9{!ip!}q+9(nB>#o^n+PV-U{CK6%P%ly5%xH4pJS@U4nFJ4Yv7p5O8re?UKV zOays}GBO_qqKF4sz^O2T0yd+oe#oWdAMFBiDS2GZXp>CYZU5JRrmHVriFM^iQV9hg z%gv-}8oj+VOar;A{%Z47wlQRxLp+9T#~~+=p{%6FA*(XOo;}Aup&Xip8XsYth3{ns zJj0B^73etRJ<_;GIWi8-G0IRci?BG`kb7FAN-FbAl6x61RukuNpF4N1aES?ew`;g* z(J&@Bw!DU1!;q)!Dyy@oJ406{iQ@NC;GNTTZkT)=t839XkU+e2~c}?JqA@_8b3r8O+z#P zCA;gyUuAb~j4`UqYVe#gy0+Xs`W*P_nk?L-%gg6u;&21C6lykuJGcC@^7h&*DqNWM zJQs*|o+}z-M0MGkGPiY(HN~pMIuaah(}GR#Kh-AgOVrYcrw+F2kzrYtC`S$$^tBK% zZ)S-Tj7m77a-WU7M>@$S$VW|pf!U*omMau{K_5(9QK8a(rNtU!)EF&T_En-Jwk?)p zbfI7*t4dO}*XnfDo_q~Zag41fD+T5YiZxJlWKio94lfF7XOyF&YS07Dl%+?_jdkSh zDKa_E_Sw^3%e==sY6t1gva179*3Q}a48hRepEE~RsH)Bhg(|qB;&P0diOpiMv^-36 zVp7AzG?5K!d^EZePkGCQqg!+(y0X3yM7ZCA=n_}sd6L@cc5m$Q)#(xPK<9ArG|XLY z)YaF`TVEHA*4MAEtE+Pv$OuB7bGs)&IM3x#9G-Z)XWHtnGBDqhzRelVH!4b9*!z?at+L-PbmBb$2vG4|mLu zM(3#*i_V)D#p8=(sc1Lsb6CLxd+C3c|9lLk$#!~}e>pNT{QQU60``2s=PBnH@@N0m3 zq>-6wVsCFEBF>JsjectMx+Pn6swd`{sO;US3^bV>hG$xXtS z6mAi!*|?y46ujRlxk>oG!Y#s&C0@||1T>Gt=&w8)Ljmb8UrALGFX&c-9;4(YVXeX~ z!l@E3=uQKDp^}?~7c1N%yh7py-4@WTN^TOiDcmC5Ch>yq4WMsSa+C08g5W@p*(r3M=e)prPa zlak|taE!zYc56V7RdSPX0-_;S5=^w&gy$*TBIE@DXLcNg2mtbP7;@gVnMi3As`I%4nBC){6 zG_Df_Vqv7zl<2To3pmjhp z8J6OSzA5iZ@vhWc(8KOGpD+Dp+v@Ud!aW?I|mu-j$u2Z*5gaY!hu&7$+X}rURIr2AdlWS7!F|DNiu`?p&WoyA?}xy(-a+Uc{1m;X9eTWI zeF%EmhSMJJ53((oul&6P^agDnfJ{R_`Vn=$yyLzfJMvO{q+f98@y_2t=#|zp_5R(V zHvqi>=!L=4L6`kCFo@GX-YH*(!J=i<)jqrdoc`%Ry$c)+jlK&7jZ=3kI_FlM2vFNT z4&13X2)%YXVFxYaheM51GzT5-X5HyPYuOnkdQW;W=dhF6LF=7gqW9|gxC=Lop07mD znj*wa4n18jmzC(WD_O8DiD;CE%cbJA|ao}%^$Z^}H<@~N_ zl{4pYMJtavUn^Qw0Ow^zs|-2+Dw-ol2z@6NmpvrS`ILy;?oFIG70ptpJFkjHr$^vC zsAzOr1kQJgMyEsIyryXG9@X7PMRR6HpS9N=ZvF-bf%6fe+n)V6?Q5_(d8JWybY4|w*T52UB%DJ8Ejp?M=s z2kNIm@Su-8m#7q9(n3JWdjUD$lWpKvRrdqx_Aszg`A5*YJq)~Io&+s_TO;+)5+>7ZV_`_2n~}ZPT#okt8?^H`dj_UFU4PZ6kI|s@xg7PUg60<>ZIA0eeU3%> z0?_(=jC40>eV$1A4$%4>l=OX|`58&udjzyT*Q5Ly(E9w6^oyX6+WljUYrOb1XnDsT zfbI8N(ELeT7ijAL0W`mlp*p1e6VUpcl=2E>tj`5WpAVX!z_dRzfar5Q%C85l&jm@} z3z{FiwElO2=<`|19|O(tiR>}^elYYDXnt+e`g?)s^J4110J;KlCSZB~1GGK|ru-ey z{G7*kAmtx`UhS~|A!vObOMThVp{swhIUXIK9|=``oF#uG%8z?UChc7Wxjvs|`URl% zc`E78fp(VXI?%f?pYaz>>~FV#*5|d<|0d|Cb^mo$iXVX1=bM!O2(*6R)o|w%?ChE$ zH^Qrg&sU$>mI+5v8F}lrJ`&$pFMqy?gL?Z6lz^LBe4ROkqsd|K?uLT#xZ{VZ{3w&j z<~DAG$v~iO_3~>1%i341=I>Pl3yY{L+wvl8ep9^u9`?<;bk=N_(C${)}aGt+p%s@$ndtA9!9`N3n@??Qpa z%a$)_T^3lrXwfSF>cHyO1s9S-f+qv&x3=oW zx;n$Pe}jt~&;fZA!LRo`1GY6k^|Ay6CAamuME-6={yyWW-Of3cUma@idAE!IE)Cttdgs|JBfg{#^Tuve|>8 literal 0 HcmV?d00001 diff --git a/plugins/org.eclipse.dd.tests.gdb/data/launch/bin/GDBMIGenericTestApp.exe b/plugins/org.eclipse.dd.tests.gdb/data/launch/bin/GDBMIGenericTestApp.exe new file mode 100755 index 0000000000000000000000000000000000000000..6f604184d78dca9158a4d9a3929e29ae829b8b72 GIT binary patch literal 9594 zcmd^FYiwM{b)NfJ>dIPC6e&w|q&iEBl4;1gs|TepmK;+eDUmj~hhrmh7$sE+p%R=|5fqVYqfyaEoCjPN5n8))EjuVs!$#U4{ZaK{fU4D&DI8aT zg|Oc@kL8k=*uQTV)%-t^y4DYZkOPF8_N02)C71!%VI<-_ux?W7H)&NE3Tv=*SCy_Q1crgzT)qwwRDW=97j%O8O5q{aq++MgHrW z{(+`XYZ_gX^6zLm(DL8Y^fxrU5p)hVa{~>hzQ;*pY}uE^Vv!ISvucz{uUW$Z+bn`0 zJ60+N)hJbof6T#7SR5PYDAeT+2 zgDR=@sdB}`>VOI%vlG_)JlWb(zJRt+;^v{Vj@qFjrrVl-VSRYNg)tdfsHR0kc< zCtEa@$`?i7p+noY4+ZP}jbi8U(DuGy11d7Pb?BH3Trm!8(#E`5`X|j)Bp`q5`$sTk zuK2M6LvD*Q@@9S(=kp6W+kdTjEt0my>l*KU+x40-#_dSwAzi@~W1L`$!R=&<8oHRm zVD4rL16#)wMso1<+vC@~$-jiU$rhBKTmx%*{gRm8)B?oxswH@`s_9j%A;;|1E7J(8 zSW}L&t8Yk}HRjmtt1n5KHRsw%KQC#vAeSJ0Ueatyu8Z_pNwY;cj@s3eppnY3{y!f* z{V(JHKDFn-zTEj!Ks=Af-iLCXNG6W~`0m-W=)?Z;Ywjcq9DeH3=iy5xp1uLusW+q8 z z_jG@!J25bI+U=bD$6roQpB}hAF>oEs_~rgi>1vR=mZO zhaWkUx^W3LK62?yv|60GcqiKi`m+!1pL`VAr!MWqN*lknVsaUZof*F_YnxJ;y9TCS zesap5I5>qtTC;xo^s8rHVEKuGmhsCLnuDgsRZ~6GJiT=MRrk|RPSyT-{FN1l9}OP4 zG_j(SLyG$L|AbB$6Yz{ouTMwu@ps(mHzu6%>(jM&$6s*|Kf-o4&e4mDVQOVG=wZwZ zeHrb3U#(co7qf|-VKJ=a(}`{6vPec_U)dIG8Fk6U8CYwdu1TeEk{-o7xl?JH~dcbo!W1%ShvhSH@iri&zX|HtFwjc<21$m(!)^kkVi0zKk`D^fl0Y2fT&2 z0FnK<6_J50iNhx8>w6ISKEfD^Wr!D`pZW7h>07xd`95Wep(yPEA6+Q1>=e?ipppHR z1K*{lP&0h_?T9|&XApNGK8jdGG?*6RclPz&ljy=L@2*6*zuw=F=sGx3D@HX%tzB1> zRQFxt|20zFjX|@;IXr10LOh3YT#b~rLtCKja86BFfs8Fa2@_QKx*cl(?b{Z&!mO11 z7tq7`e@xq;hKUY|BgMK;AO^GFhZNDsRAui$+aDpy_a8-Pq=-4`vt+y3cG@G?hxj6* zeHagSp52GU^6VU0^X!KdbAZeyo0}dx=H!c!aAWo+P+rX5%VeH?4-zo7mSIpVT|`@K$J4c>M?@|;Qp*=I>X}Jq`5s@p!QZ49YokgSCi5G6He;pdKZ(1j;lmCOUvc&<}noD@{6~?I|uy4(p zk604!&i?HW4rzCI03Hw?(NCvEGFKW4ljYR0u#h}fsvN17Q|XXiGFhr*{V-j~m#d+l z$@uh|RX>{1Z zED7fhJ&-+mXg3IFwPtPgf>I&F8LftqaJnp>#_W~7P*X>p}N==xB0j=nFXntfe`^gWQ#1ETjvsbMF+3{u{I5EZ=Wke{RFE~KDYx}*E)@77kIyp4=(;j ze6Y3HYH4c4b5(QO0;hR-GuqlIoaO}!K7%)_gRG~rE@rm*o&{SL47J@Cx3Lq8trkOk z=~|0LOVhz7$6M~L^4hp%o6+e(C-~606pB=7rBzqp&QuUvBo?5`CMHxoug$XBSUZYA zD>jKzLu{z62er>vwcld&VpG_Fhn~2`Ll^N2aZl4mwap!9b`pR^J~;QqO|uqTtyV8~ z1TE;NZYg_tlkTkq*A~A;ne~42LOkUa5T?=+`C>lu(+~;qZA4q_!t(>LUv;{L(C=K@ zkBHgaL%=O}Bs=c?Tt_yWOn$DTqr=Ae*@BRpB4;Ip_u4VV;r7VcsNr@Kn13VN_UujD zR;yN$`C__I!$M6q5Xq4|j{TB@tw1uHPABu-a$kUpoVD3vEh)FK^|Ina-p{C%Hwq;m z>qg#em~3>S99F@_P7HudIEuUjH2TCPx5R6^SgUyt*elz<|FAtDy*LWlZ*qjWqVx!J zN9fGA>VwLiA>L;7VOHl4o_#RtPk0UICN|jYH$Uvyq^(5lANaPHJD!i&@5r}${ncLI z637?$jI7S5+M8@pK8ESd-nG%)a=!Ep&@BDzE1Vl9A#$0@^&<8%!2*+PraayOB9D1I zPTHa-ohPy?a2%PVUH=r3Cj1T}4fimjhSkrSoSpwgG7{l8TX;e{Z&g3v2 zVWlkmVkruJ+)S;FQd!}{Z2erSniGEJL=lBmiY<+l9K{PgUn~<1fq0cE7b4+v zMg?}1coq4hARsDnS1J537mQX?V_}fXproOMpN>k{E%+Ig{B{~bs7#IJ)2OZlHF)?^ zx6(6G1v*_C8w)Y9ekL5LWrI{DRm|eDPm|@^2o%iF`Qm8F$WkLCmGG#caQPaVylkBz zFj^*yx30q-%EYJIc=YZ=3k7XH%VcdeK3{>4KyawEP@OaOFti`RvtIJpHij(X zd_?kiZ*d+tE&`*EIMTdBF*x3HTmX*uAH?x)#o%~yWm{Pf*VYx_cx*Mn)Ej|eaMyvm z4%|rtLP{LtmkF(n_zHH zgJEzNfa7-vjYcM-UYzzrG@QiJ;wjYBsDujlyPr0#4Qa6fFo#es`|2#y!U zte5(D0lEY@Qx{nE{9hrDCP|$94g=hj<{^G`cLlg!3Un|s4;hoED1kT5vm8(zjBLpq+$9+1Mk55)Wbc@Rdk+^h4vkR< zgY)O$ZosM051C-bWy>5~4~+CR143%_?U;k(g=XJPaC_(A27w!Fz?t#my%KHDgtNf$ zo0AD9%e0|;!oz0vF*uFY;NOSHesB%bw>0X@-GT2@4Gg0Xunz?KeKOS-QRUwit!kzp zSF}<{f30XWioEYtwDNkq2UfJ2Xmd~N$Tx`cr%Eni(r+r7y-@eSistr2`9VeVO#s`2 zzf-hY5%g<{=Jo~chaXWijz|b*-{J8490L6jQ%8TDqTf+8X9Z)*`(6Y`e&NHqtJCVu zNPnT^%A=Y4WJlj}bNws1`l!rxu4v`Sxt&P2#>I7l6Fo21Rd5uY$wnL2`R>zUxp z^3W{Llg>iBIWlm zB%s@+|9zvOzJH}a-w@oa{{Mp5)AP;x-v=$f2Owqr^l##8M*m{56m(;I=&usmzNmlh zc<`dn1opQ)hyEI9V?UO?O#A_8GakZj6@Na5ei^i}N6Wrd{1mjYw*>nCGtj&d;Yw{q zd)@|Z)(`1xpiM|1^Zp!q5nKY-6IVXJcP|BP)?2G+7ArtAd>7^T4d>IKa}D@G(55{t zXwN~7H{av4n%;o2EPotykDkB9cDpzQnx9VdQoc}pL*wZ?iT@sGvz}Too<9QJugjBu zQRB_`{MY8-{~mPX_x&l*x9Rz7wHFG0lQw5Yj#nHs_i3ma^}|1)I_7DkiuvpWv2`drC`hY(yue2nAXO)vM;sY0RQPX@eys7AHXQK$@pz5~1W z1;a!85AeSSLH{i3{=T{hhm~?6jKYk+=~J6}M41WyyO1db*+OX~RS4waCrH(f3w1=w z)W*h6m6MyotoNv*$5?|BLEAvYJn&f(qLw+#oockI|d za3DCaZTs*5M}Xsvvsfi{BH*p?EQXvK5%fR2YukfEeS&8>^)Cs)jgR{r+pMJ$ohz ztz5tF-tW8fWoPa6f3N>~?zPrl`+d>%YaPc?_UBU-im{un_6Ir;?)!kobf_j3Q1eu? znyn@PL|n%K(BKjVFjWHP$5lZb;vH84k1L2cFXAYhm;A_!>z;{9@gl#f)p&t@6gXTf zz;H2?QZMm71doCKG2nQ;fjBSXse{*9;5iGrc{L%<%i=cuypXI0fAzKg0I%7=@v`{M zz#}^9XXUqM(!H&j17m)J(?7zrSbqSH7_B-=D;7$?p*p+lH_X7wxjYCfr191R>+?CjK;( zlKyEE|0I+$zRtw&K*)Fk*JUUlZ^KZ={{dG3ex&VF)p1I}Klws3F@HXt)2U*y{=w`} zEMJJ{3bB}qoxLZvCDotK7gD*^nRq^*%B$Fpjav&#)7gBiH=a**^bDm7tJ|V`#)7XA zc&vZlzSwXom(LExGwH(q*q(({JE%3{u0N58OU09n3thrk)^iTbN~VWm zBl%Pkh9>sKWAQ?2U%G$@_#i{99*n1l)avcqySjT~Z7uEU%=JCph{oDmI`n;P5d;eq zccj3NdB@!JwkXm z*MY;IhKR#&^WVK-dhRK8WbuQbI5Ov9{HOdQb0~R$x4-=H5&Y&*!vJx=d_m&WG(dBI z`J}|DabO1H_e-3b2bvhaOX9R(U>@T)A&yYBy?)X4KRNibH#TkCGO+6Xz;437&F>lb z)HVLV;rl@JhnsGKy;~3d+JBhz7hL(&8)#b&-SReY*SuJ$Jluzy?H4@v)J^i!X*;m; z$Izq-)xT;y_@w{uUqj@`i+3|PRC~>fBfomOl6VJ9n*Q#G(X3qaWTEb1>cGvUXZ*7X zJMx01seL9&U#VX;9*VyG^a1rT$j99?{%h37wYv^R-*&FN{B0)dihq0VDUs}Qg$|wj zHps8Lij4aHdjE&X>ScQs+HPDw+Yg5vx#Vp~*nIeXNZw(3Q%pO5=Z*2Vjny-*kG_5V zxo;i3{B38X?aIsFqC-dK!Ekjad>8x6kt5HnnH_i;2}Q`ds(_mf_a2@FoK08YtK@r_ z<@E5Up~i(&THC z5B>p+*GJ#bHz!Bm_}b-f_zs=>1~P4a+mY*^zVR#MKNPJ!_>6Ns3_TRBM&Lgb4P5V^ zeWd>2)Ba_bzcKQogI{mF;G)>hrw%pFW)?%=)<-{!oI!!OTf(=F6siyY%75gALlp<# zIx_NygJ1Vwu#?{RmYK(Vpa&M zWXbym!X1d?_OJf2zqd?_kfv^2TX6N_%Hg^Sm&HFw+A~+LUfwhhUGm9I9cY*rHO)J> zcVwtAqGJmdj!3NIWcB|wr8*T(^QjNvzqAbMLHKblV+dIeSZITHpLxog-$^a<#MiI+9Z8_7-i{)67@?H`^ zoAOWettK$wgMQ_k=zEU_vX(m&d>oMZDl4Es`73>k5eroMHZz#$TaExgBV|2e&IJGG z8Juv4|0^pvbgDcD_v!{*KGlu?en(nU+_mI{7!G2D7>S+fw;L*YI#lBB5FbvV*DC;rQNErgd*Nw>v)^Po!Ft`M%a{ zuD>Of$fSq!sg`82r2w9MOMkMrH5o6&TQl*Ip~OIIK9^9wFTxHCCx=F2$yD!1zp7}d zsAwfn`8{AD`&7mJ%HcvTneOY071V^=UIfhqokNxR^ra~RzxN9OCq7EFmd}YfC^09F%cCZFmdN131XWi=pAA(DY*xYY+zDqC)&%vr2gF! z4BQ|=`W^{(JuboSmnF#jUV_1D6t=*mp>_$f=Sh$sk)Uv=1bd#6VDB#^*cU|W8kltH z0tw!`R)Wj6OK|xm61?v^39kB#1P7m#;OZYq@cutaaBUsxa$wR8DKL+Zr3l@Ub%__;_4`+utj}9Uqk76OTx6=g%bgWYvjexNE5dcb_N0 zrwS7M{T&kA^MnMS{*eUtPDBeBnD)6A3GTZjoX7{2saVEzz=#k=uY;FZRp3{|6^^r=Y`ZC#g0WH!{HaCc;$^Ds> z@;BaBZ2;+^WD3v0gXtkWcB=PTaJ)C4LT{pMd^nd9fTN}~Oi&6B$!R{C=F&s`qU=<( zT+5eJZLE-srwe&)f(Dn_)db6G_Mn6FhmIWgGYouuvy@XC+YlR8p$g|zv}XWJbx09X zj#C#q1>IDT@Zj0F#cy&hwFi&hsaP7OOM-Rdo7lH+`SMtdDUD}}$V7H1UudFnr<~d( zhK{yh!$&7T!$+l{>2#*zueIZEZ^5)g1)Nj08Dq{^4`wgc4i@?{@&3H>H!P`+ZH@J2 zvzd5icp$DEMw2P@VZ7-}@56k9pSJ_4eJa2kj!$x!%}}+BWm0_w)x^7OqM)8syvwEg z2MX$dh{`9@C?V;-bV3~vk@vD%dVY6$crPNNU<9)* zy(4|w-F@`faea08D)KF3# zIN(=R4_P;zGn^V4%qCG28g|pz`0%iH5G#QQ=*4`CqywSYpB*V^#}slH4rtF%OV)@g zYN?-OG6NY>pg@1aEmYE<%_e&>u_G4u#^qj8lgjoHt}`Z{&M=~NLq2p+NKyPnR{Yjf zYIic7gZPIjzBkpcMJGmbIx$SQ>y5mocI8Z&jX?zyAbI9Y=aiRn8iKz1y*{NH8hm3+ ziM6#sPcGG$$l?hms@l+EITgEU@gO0bLx);$3pnXt*<2Os+eEil+K^i!I+YJ(2_!$XO&qy%v zO9|5c^OTzMerUjKU~0cj_;9?yajbG$g>NQuFg2JM0BW_wg0})D=%8q6@`wB%2WaL5H*Go* zfeD%HP=9HP{Szmc^qYhlw}>|?E8)SRLi-|gT-B%204+hpkRnj&0l3-(GZDO(jKq^< zJ?%Fz2l1?ova4@eiea#3B&nZjfa>fZ?T1bP5`YAs+X%Ro)BqIHgB*@m-zM?3J?o=t za?4e~om7ERz~@1M-C9+JZb~<=Rn-oSMhU4Uo^!h~jP_O4RMUa^i*Q!MsyYJ?6yZ|w zs)7blEr`82bZNR|R!uXQS`S8aOgD&W9)u{VH;5U6K$B`D9dF=`E?mfG7;uw-^YJ}a zbAv(5*7Whj?vY_5>O_N@SL6{{jRt;dZEP@}+l}5?RfV1Tc*yY0T38!H5kNy))#S7Z zqyv6TXD}pDRVNuoE;X)Qq^jl`(2CkvHj`uq;`v%t&2vshp7>_1g1C`f4Ao_15He47 zSm%7R*3`!K6ym*^l*_Qd`5H=xZ`Rsc_C`7BW2#!5C1S#vwK0|hRkg@DQvhc{o6&Td zvqm(nuZ_iqtE@Xgw$Auuv(Alo&hT~)0$kP9`WLsgw=AQx-MVpVmP!;0ja zm4utv|5TlA(mGHZ8yVsv07S2MHi$(T7EWCpPiJwQwHJjN1$9Eg`30oRW*gNKYg2)m z4Rf~1{UYVB*)%s6+nX3rHPSNbNUy5dLTc5F;?Krg)oe877mz*i%t%VrY&{hezFB@X z?|R&@Jvo`rq!nuR!y>$0RZlq)}Z%!m9gcvy>2`3y!L;`bu+bD76n+{*W#}(30l>q3U5>eEiK~MAc(D z4FQNfEW+ufdCX4NdTDZjo5v?(7uu{U`;ZLya`JX2cE;7fI*Cjw&bCoa{;tmn5(L3~ zunzMH+UY~Xf#J>M?@+73NBB_f^q~h=lfUotBKVjMgtWAiU-6>CeDrqu`Z6Q=0X6w$ zFB6}}oxc85A)zKeBqhV@Szs~r{^UnI@`6OcP$n?K2Y3+xqB@_a1E3b2q%fcEoj#6R z)Z{-&!acoBgb)2r9~(3^IquV)4a>gt0Q#SJCd_F85^6zzDHEi1ML22Tp!%kEtI5}S zjb>A;JDv#VYe`d(q&?xKlBwK~zXlYIl0Hs5IDLf_ddkT+`Y6OYh%*t6_T0l>&&?Mg zyV}W5Xn2Iv6okS@4IUq<8JxIqF!*HeIQf?-11!iY!ifxLc!ZhqQzQDtqB}Xi;p8yc zvV1b{!z|rZGUR*^u zUqaj-K`!#7Q+M;!p}Xo+oxgMc-kw#rj$`j5xPLoO$$_nQ#H<>zI-A+1hTum*2zfa3Dh(d;Y^OR#}Iwi z5P9&N;sM@OmmX7HPz&Qk5QvSmFLrv5CAn<2QO2|XIz*o?}OE~L?AbC9K`o~_|c%|ogF zxCg#Y!)J@heYtodmQ45K`CLt1&(_d4YhH5+bc2ST+&mmh&XVXKCp3V12Qxf-#6l3+Spa@c>NhPIHr2;HfntzvzdMHg$_ zLW3(+(yNhef-JKvsd0-8u9UG)BipUiqAi0O(_z_)m?4c>tiqg$Wc}nk465GL%jtbR zz}A)iR7azvFit&inDik(OL3(gmIhazi)O9T3`&C=`VgD_1I%U?2Gyy-Ynuz0#ld5I z@H*B|DYt_$Oy8*B^%~$O1&VS`1#i%h03n0P_UoZU>OPDNo+iy&;) z?m^H<8Ih+*WoR532s=T-K=d4mL=-2M9e748J}hQwqA=&0b-B>UUwe_9f#x%tN$S7o z9+`#|+uop9R5^%UFPtjC=q|>=ScDVRPH!Q*H=%0gI($$z4||b4#BiWN)U!T~A`m9? zp(k>;OORJJ|KXEpkpK1Lpdq~%fC(6Ea@r41TMjW7zNV-(bw>2X2WfBke=J42}YEGANyy?zgf!l&a!+FfE2BH_EZS0;z&x-f_l5w0F^yuxIC ze{?2rRY9XUDysQ`heAcT*5Kq_zwS3)6WhgX<6JIAfX+DgQ-(~k(ok@nLXRqF#~+Lq zmNZisxPpP4~)Wdl}GTy`&G^RM@i@EkD&9zDB3?^ zHhaZKxGY4xZh~r-R%nXSGNId`FxQSqE4Ad!q9_&SauP8^lE$0MtdR1n!dz_9L`><& z%2Hy8xD=&{n4TNPloZ)zh{W-zG5uc86X~fjAwQiN=AstmiW`1jv|U`SB40A-LN*Dl zj_z|L7l=W1r6G~;x>S9t=Ibw%F34L6SQGS1zt7X*2xw@J+$`c{P5iX@^8szJ3 zj(*;8Rhp)d3vHTc1XOoApO-O58C96;aHNu1#F~e6>Zny4$GD1cl@3IOEQ;zWrY&NP zRS_=SIeR%h$c(8nI8h@1G(Xq%G!=8^IHx>Snu^PQLM6{kHPgl+o6}^-FrZR3$9t)y z=4fHvLS_4bf~Nwa3%E#-rgDCw1Q)(saHw*a@2q)2TPjJRa25W9K@a!lkUxh#coM1b z;|8A-{_lA3n*TL}N7t=te&s<6d&GxjKJ6*0pI{Q_>enUR$8}D3X-iGIy@jiT4i@Ls z^v`2{ewmAF2Q0czaW>Qm^1o`yk~Ep#qozMlN(xwX-#*1fNKLC5CJ&|d#>y7Du*5aS zavHjgQ}oInrZCIa0srcCw6RrqR_y*(3wD^KkL2M`Q=d?WKjcWh+XA=lxaWcEB7AD7hQCexIp51hTC|urSO;bx>gTtNv!) z9&&u6!dzu1Jgw?KtlMx6=dwHD8C5Tn?RJKR>+lYioa3lXs(w<1XZ1mrAXwFPd(Gsk z2p8<7Y}e1M5bx_zDOIT%>xsm~R7%xffLRsFQV}ldbEucXBtZSGX4XfHig2Od$*`u> z&#GW1IYD|?{;3Gp|1t7ne^$S%qL>(6LnGW5z=0WudU;j9$J;l$V?7n&z5$TQfUthZ zh+(6kr{0)8HG{hfoJ;bUsaEwh720y0YDvE&eZG^!6osn)y>5Xc+dr^fL?T`G z!`$DXY0&x9KcV}cGNK4~KREgQ*l>?h{!>$swDY+mLf0KQQPp2+{73!Xj)~hLKqiBz z`b&)egh*Q32=_@i8J&rzRFpSuVQ!p|at9kfsVlLl4|6MpNg_}$6;a{{lSb~ouxSL< zE4q4@B{IzI7@7*T;fuQ8cWG4kbr+3Q?D_|E%TvV9;PwwE7L~eoBZ{q*-Ii1*&ZLM%vnwItgjMbTij5Z1CCqB? z7^Kwi0XwV9sUyNs9q)Hxs|_sp9bnYr`-r%rq;pWS&N4J+A-3f$62+5AY!k_=S?kc@ ztSfd-ZS5u8J&EWNLmJ(ZP|QWA?uWD@$mFV)we!5fHXggMbqPg}T4}RH+U+7uZ;eT* zSzAjw!_lTKHCs%jMPG< z5dQ+nR!g`E*crsK_N@5P(!6vqz7G>+m!|NJ3L6KLWYu{cWypq?+z9q<%<4aiUCUfr zShWQXEU`;GxD*M+C?>mK&DwnwX-ff%#J&Cq(J$c>%tNSrgsA^bFMHshDrO`X@j#H1VVmpFlzH}0(T>C z8@bb;+D}G1|4ZRB0In2YY`6UK|jAB+-ICVErvRY9$-%DOkat}2eXvjZI zay|dQ;ta!+gThdQ(a;GE06@X*AT27$8R9f{hG2d$)MV(FfnLMFat%g_MV7lQ3)gf* zvpq?`W}jp^`O0q^a;%%}R-t*tBoF{<2o~$rib<#H#3lw(n8pjW8p%sxihx+z5>k?_ zF}k*~I;)l2z1-NDG=xb)6--UfZU_aBE(FQXtILhR(sJTYylvFJ+e#qhhDYS{KI@1#Xpw@tG z7kG-BHgtcza<$=;C#KN(MLq)Ff$ws|hqv4?U#&vDnv+F9gTT8h;c65oaW-3>{u()N zVLchqJZY&igKRqF(rt~U z28Z!VqHYxKK9i+zRWBtUngBvyz*ftS_gY~132TvTvFy0jMSR5~?u8uH@sNx7x))JQ zi0b%}OY-fpNp!>A;ag}d3cqUU#F63-ZAOzz@{|GO@HOSpd zFCZNzOhex>@)pGlV+rg&*Ao7RmZ#}P3G6yRy7}za{!|J~}%bDcIvvrTomrm?FX2Bn)xjEgX-!YmV{fM{OVFTr9hP(1EZ%ZjJ zl2FR&wz{h8Qzt`lMn96R0LwdCPYsSXr-uWc-AL22(+Pwa#XhOzYt8wxoTe2><% z%mu-5wulPHl1_5W@xf_-(pAfhT*mQP&XR`;HVHEL5g#ALXZKp(@I;#)&HGM1`<`VA z-BhY@Y@bb9Vv-ZOtCW0PpRMU7%cs~DJ#JXiL#WP$=ut*sn`DIKX@X<`R?Lj9+g!n~ zl?vW9%DKX&JHc07t~bZvDs!>R=PjGlmzo5HGse#*K^(Z37Ea;!l+d#+Yv@G3E)E{n z(S=TT#s^)dMP*E5Io;!+S6#-{rHseq`Gh=P+0rb|H=X`6q#v)YU^`*x0xfv4MEU43 zs^ZWd)qSytXLkwDG1)T86xIDzkHq)=^%6OshAQ_5?%@VWw2 z*I!)T-;d%Qx6}#0l##CZY1R$?N-5~B^~aRo$emH1mJ%rcbVYv7RZ;&gRg7|DQH7_@ z&R=1ZGXLG{DXABwYE;*UTn($A>lO_|Jmybt4SGj^7_ zD65SaNOkMT7;=l1B)a4b+R7;wysapcx8YAqy>Ekmi%>jKpkBu@iEbtcb-&6sLqGF& zUqV5gs8Qi3nN&O{c9`iUG@Y-YFR?>$DR6GPrB>fg&ivl^unPY{x0oG_MYrHt*tYV_ zX4U--(ZM%BRp@o*CLc!SjZi!hFj4l2p!;=Fatc+2{$vO{7%iupw+eJvpersxtI%Hz zLtA?Z0<4_MbyXzD+Q)6w;cwXlGs;Q0vJ|`i){i0GA9Gnl4HJy7gq3Y)sk7YPMRk9x z$ThEoOS0PQVOO8(cDh_Ee^O#420UIC$w_94>RLjUf8XW)(m34XCw}^BB)-AnXx{QJlEmXI zvZJScyX6kgvuQ8oK6=tWY(<1#8QXw&O8E;e^RLHd9zWs1HAwhEPC@=J%eusq>v+-f zs5yUu6%k%(Q$L1?qr2b}R!->niMq_TjU%U|3>K?%*AJ|OaL+qfGQKk+Q8;651)QnNLjIdzLL+k`hi++>^$NXIcPpiE zM-pIm-cp4=tfBrh<7^B+!q>@tvjVF9&UH#ra&_qA$9)+Bxh8zpa#WS@83%oKW%jJ| z2v~DzrBZyQ+Hra?N^;jdFfz&J;{6zyZ9?_N0Ela}^78p8lBl9S$2nUsqkOqYF9R=^ z9-|H}r8q4worV8MNIEa;F*rvd^i|!4h!${paNyDtq+g^G)iSlmWzJ)Lhs;lm!K`s* z%$@5DGd4uJs{h$zZ#y&>ao~39xFqbT&g(s#l+E{KRp@CCFBehCYq4JLpL)3UY7MlkP72xazJEYicTmWH#nH*lta9wNR}6x6m5f(!!2aI9*R({hpF z>qkOV=;b04SKA3>8^AF#A51))GD0@PWssCOSBS|m_YmrTawqo^c77G|{w^)S#!3?}vU^Tzqd@(kE z%Y}wtPG#Vl@*8F94Wi70>!=g&)Zm?*@J>&{WkH@`t8Uk5_x%EO886hbK(hjymxM$9 z2LWhg1JIt@gsmGBv8N)kX8jO#MAEdX(5YX3>L4ttzC9U9chrVNVgE2lcKs(Rw1znw zhDHWcIUFq#*?pA@^=;q@3CycV=9_3SG_8MwyfhOTybpbW1_d_OfGIMx%5NdH8z07f zBzv+8X&7rZFz@IsZmOPjQx@q1#>L=UY-LvaCee5^xh9Rc{_I zil%Jdfa88J%Z7tI&bb@rM-t9IKu$g`Xf-*V#O9h^AaW9P&}B~Dd#OTo9CTsV7+CO1 zU{uE)F5)JOkZz^ppIpS97C{cZoss>K>iDTka$gCF&AY0QO3yQt+yUdEYV{9Os7u1aGtb_dUaMq4nZm1J$F zDHWpf5ms@nY!lvtGX+m}|F}t7V&F)XxMlNs6fU{E5=BtwbC3m6ZQ&#XUpGqQ;9@M9 zMpl)mmTewIGz3;SWh_$aRAhB2-_jDXx@3}h#SA(aNPR35RALB#lMrz@pNgz4k+F#9 z%Zw(Are#osZ81`6wo2QT#S4~sRtmk6W(x<7s6oSKkdkGXZ%cE-g%ovhqy8tdFrK+$ zJ({gy*ob%i@xPJfJLIR++x*uOz}t}AZp&|0ij~YC`Lb>raC+80y#MEz@lAyso)dYx zG*#*3*azpFJ`Lh@0e`NXLl^Re++$Kltxj-1{;P9ac#nD<`6jc~gPGB7G5;O=8w8=G zl_&8_6kn_Wi_%GU_h~M;({iWoYBDpKHzUPu{`Vo;$lH+IZfkoF&Jc#5rbS+L-ow#a zOY+eJXD=*5&!6{ z^H80~#`aH+1B_+tBj_z>4j4CRjVoW=0?kMzHm!0%lHv>AD0qJ^$+N|=9`qA!9Q~Bg zNd>Btu0X9kX{(l`j|=b$J2I9q?iwm5^~&4aO?m97B9nb64x%NPfZ2L?`sQ92Usc4* z=$_fGHec@ItBZI+oqGpSS4g5%q{hXXwt4eIE@!Qa6V2-M*NKv5J18RyTQ#+Zyal^x zuUc`&HtibO4j9X$B*b*vT|b79Hh1G-krIyKNZYzWt^AacXs2UMtCMCCn>mJ1v_8d| z;vz9-5i#v7O^CL4i2jwjx~SoPJ)my7}|rWP;^(u^30jHjT44hoEH zxmhgMc@jbu!6i(HwB43h8UYnqbTl18r*#<7vV%_N2F2>qj>d|SkbfoqH@2afp2r$Y z<>#q+^dqnHKyVQW2ygSJd3ytHLvkDP^Ej_cylH?jDPEG9(f#=<9mg9KJTGR(v$ul- z@4t}m2f&4S#+Z}NYZf)*ah41xDDS!QOfnVb>0=Jx{J_bGLwPmhSHu|#9#^KqJeZ7c zH)#A}0__M))?!`z?!_q4<$x~utoE8{cAE+eh(rvtSN-3WEzsuBqk_%{D705-A~g#35%Rzvmw zFA?xHA+}?g8{MPGem5>`$yYmuaq~$d;zU=(g^nD??#R1P{D#LjaG~<5ozFtH zKD!JrOu5fHI64Q%^l)-ZCS>pm4dV-y!*427;Q;d6!Fv(UF0{{2IJMT9YxDtu7m>3# z!*9O}9EO%N*PqkfwLTW>k*)LkM0lr}pH!HI>lvDJ+)kQPNc2$|Kg7V(&ff&)V!q4g z`w*_}AX&Z~=Yz+)wruG-Ken}JM-&Hr%AALCdbum#h^~o&)NyczsprIb=eSD+suCw4 zRL(q}P|w9inZP-sk}Zf=R`7cu^KQT`(_~Ry8ilWeq++pTK8vmCLrKga%G-vH(-_6T zYs`Z(lea?wgyIVzedgey#wh2a(cyHMNgkXJhxah@J%iCsO=9O@n))}QqiFoiIP`td zwnYPRoRB(%brZNes?I%y$#(h+Xnz`iJ3d=G*)ADLW4d!=d}ERCO?01)zaO7(A^G&d z$x*e#C=(l-WsA?~G$r5J#(Cqjy`zou$LAa0#*4>cO1-m<@$uQ-(Z=NXd}G--F#6@I z_Z@xGKW({KqYlw(Oat$YMmtCsH7|AT(rXDvW04tH&PcfL+F5?R z^l;4l=6r3;E%JC9$N9fB<2lCE;yg|bx@~}?8WV_nrw$Jxj)!gy|9|0Oyzvw?3A=Zp zf;TAVM;IGS@0B{A;nCI&70!b$$d}QFTsKT`z5*Ui=g;uC>xN0r5e%3$D6qR5_YF19 zJrJrvwHZ16x}nbDXJ|C63A2<1)iB)&x}2*r`atZ46P(vD%+_=V22aI(L!)ywhKCx2 z_XwJ)qRFW(!hD05BGNG1`C1X?AF`)pH#9rjT#+g;WX{WOIK_#&2~@R1_T=n_1ACG=900brb1#8hLDX#vEAP zu-^F&BwUx!UN=WqH=N@<3n3Z`$D2c}8@4%jA$1z;&)5U78_sj?M2={%YUJVN_>`S$ z*yCIXA-@pOfea7aZrJZU3xhPMwvi`mXYf>^8b0WJ5VlWEiWNAX5A(KaZoBSR7V3vL zj%5}LCaNApFNCEAC!5LcC1uBGO2N34KFlEU)bzQFM^g&MrSxZ|(^7LgM^g&Mr3_^E z8PX-ANINykrLE2C#6pTx`DvOn|;Q=*w`DjYPSW18O z`ovHnmr-+18%-$~OX*ubEH6RMT``(aFqY5{f13x*?uatg7m%eo{{^L$(6Ls@DLjlssYT(hNzEZ4C-IS>B^Wv$t%F^0%< zvZSsjvA(wroeRcUXx#Pa;~j|?9y9UYzeX~M$CkYRIBoNiqRlwEk@IRa{oU}4o!ocO z^KNV#Bk}463`c!xC)y3a^FcH!^ALYG-zFORn|zzdnd;O|sKfs`HNmQiniFea+-y}* zQ&n|3hU*o$4d`3E=TuR%yy~>7p5PhPJ~Ts>b5&1}76+j`E-)@i?x52 z$pBDd)!Tyu{hZ@VTszmeOB6R3BlO)oJh%iY;^didRx6lKu{o>M{1#d`RxRbWGPB)SlP6rK6(AEiG6jWyhZJxH%?qamV2$GUZ8H>G=3F!0!po*|1 zUM^StQa6ie66ux|A&f3BX0@AXr+Et&OWF#LK3yhsIayf-*U-~FmXKOQ&k(0EOBST_z8=8=yc9#lhzh%jH~HPq}?sBT1J zdW!&^cL{vOH%Ls9H{?l?giTn7G-7>*L%Wtt%!qzKi^bVO2a2>dE76*#i%^kEzw9#n zy1-~tb{Az@ZfMFBxjoRq(X>dz&}dpfvj$q!#qrW!?RBv!v9f8XdTJto1v{OEycg|P$DyuOts?k)*7q+5BbYg;`2lKV~}a=(3E3ET8~lCJ0|XL zBZME5P@_HwiHzmfm9WomkVOd&#hO=Ny1!)rIi*(c!U7o+r?VP}FJ#(Vt}f;QMGc6Z$wfJ>6`XSDu%?HMc#Z<8$Lx`U z9(|`t^qJEDau1vV>0^rlqY=<)tiYX1ARF#Lq1P-m7)NxG(tZ&NKs1niS~BN}0RX4y zsag`^@!CE5Q4^Oy3Ro+I0Bx+^E+;7lj3<0AfG^`CnSz#T&I0#%MZ2|cZ&HgcIX?^_ zJO#LiK52@4q4>c!4Jpn7AWqZeOm?$XMU${%a~-0h)*1NFCtrGg;lPI;efs&+Uq1i* z^9x_~`zq%C%X%^qbB*CwGd}n zyRJr|v;6jZ(iUmq_FK~Ba4uhv#==btt-p$eXJz@+>*}L?zg14+lz-%KzW~L_U1TLb zHYNXDIElvi?A9?f`=wu@<#%XUd52>B7*A0z<$K;$!HJh8Wm3s=w%OlmwgPdwA)Sm# zIgDz8rM7x?aDp+aC7RcMlqR=3UpalHzeXmaUCt$D&M#W50ZR6*=&!QjdFvSp`isknAbr$y0+@;HGq8<)8s;)^P?!KEabczZ&&<05UIo%fJc$f)8% ziDvQcF2Lp;eu+@(zuks_)aVncJf9Wxx>O%NrMC@Y15dd-mza4|c$CL08^0C5RVPO1 zmjGldo^_I#&O9<3i@hrKRukC?E<2IRb+%)AsvNdhCWH;tn`S0irkVmUKvixtewUL&WB1!c_3T&ZG1ai%Wr(O^!w|x;OHm%|X3q-M}*xTZw z?RJlHqw5lSw;k@Jn3g5E9jhzlx;pjTe>r%WTLwpCY?D@wX~)t^R5FX@z}wE6qHc@h zJ9)BLE;wK8W@p>NVv`Up8MQFkWzA5D{0=skQDxpLQ*LXhJXN%W!L<84C$HG1j7lpO zpa3iXNbOjH*!Gkc>8LcVcFB7zF1~^Q_1gH722Jl!HRhGH0!4Q%F^e?iW-pe-v?zxS zGFI`af}dj+3==RGDg+pE?BP=*n77nF#yRdFEyHE{KEQBL?u)cTi03rk&u||uM{Q=X z-+&puSKkL1VoyYgx|0_#+!txzK>T+a z?`Qa?zL(t@^no|Yieoe26`vPh#l=U%<8bkT@Xxr2Sc(VA+(so(g|jTJy;<>joF)Ibd1io(X+fh0I>Ots)xW_<3kC8>j5 z2_PXdjwc7G!!hUl*CMjDoL-y}+=6N~$WKhSBvZX3{V}|fh7XWYibRJ;di7>-6Gws1 zT3o!h7vF!jF{~V>?7diLBk-2J#W={`8a1w)k9Kn+2w2YX0HHdr^anZ+!6dEwBaT0g zqw!QCbZ3F?EFhW?w?91E$!{_KE%2LQ^Z=-qM9 zAJ_q=I>4-6+QVx*uD=+%4CpeTyBIL)C7ycu>&JyvTY)_fy5~X1LT=@ej`3k!mhL6c zy#%_2h7L1TB9C-z1ZXSuux|Mw;CS5IpVeCcz|u8>t`P|8us_oAdLJ%JcN6Gt0&qJM zV1D!+f7jr$bgavVVL+o`^gqht?+`B1i4Rz(Q7DR)TI(bo8z@Ux4Z3R3%_hS9th~Ds zw{#0Zw-9tpoBdh3`v4#v+@|jNs6TKI=;$~5vvdytVCn7$-TmX(_lSq?VbDDcIxB-R z?fnzDXI@b6W1xEsbZ;0K0yp2D!M)Y{`P=+~&%-HJhNWZtc@N$Fpt~P*vq@lnq~Y~l zTvpyopnC~)W2Ki3I{i=kehj)FQ=Tn+fHmRb@5i_(&;Cd^*8{M(zXXB3Cv5<8wd|zq zkGlAK3zwJf0O&3gjQ(eF0o>SoV%`Sbqv;}{#Z4=tdkBRf3t!uxr8}vNZZ4DtJn6M` zEoF2IuSB0^g(0Mm`8%zQ?q{HTehj^9%joXE9_wg;*`K}LTt@f84Oro@L75JsYFtbQ>oD6Eue^(IgP%PBD-UF&er)#%tT0;H zzU#Qw%ywMIwLrGlI9xL!iCWaqU>Pr#dcyV!Ns1Oa=DyyKxj2 z{MZgMtdO1n?UEbUHG=J$#$z1-Kek^wj%927?6{*s;l%{}*d8&g5YM3#dHTAaVPz0(-!` zzY6(mS`kuF(n8Z-t{@bD6)Iee;I2YN%HmCB@tI}ulgi>asK5j9tKS_dZIga?WL_D* zwJg58ES^K0V@ZO2YKpq541XiyZ0`wnkRP`rwE5v+r1Ck$ZGJeI(fbPG^e63f)CuYv z2wyY)b<_-Le}C-J_fz0&F;9qKO#QzB{PQ0De@6U4Hy%_}beAbVj+(0K5%=1|_UcJf z9+|#!e=Mb;=0|@Hm&LC{+|EOi|09Uo`AWv0COvi^GhljO!i}AuB>pwTZTWM2$E)8X zZvClzb*chY+#9b)oc$b4a(vTO1aVtlo8Z4w5a(|jE{>blFphoGY>1{p|7OHjA-!w~ z>YzW4xUHXz4;X%+RTHkgW${CZv%a!rnTq;)Gvc;B*QpwHo1y0pKuW9Y zYa`-z{+a2!5OF{91LSC3es?5}xSh8q{*p5OeTZL%^7uAF+WRqtkC^gO=bNJLN8HY1 zlm8zPx9wpa+rxNodVxGBZN>J8R(ymenHtWwrrVcxwx%+Dt$5olSHS$cnWJXFhaM~_ z9>dfzr7Xb0N}@H9A89oUh6%nt*N=G{ei$8-ssQH;BYk}k8H=sncFvaA`kt-ZVll+l zl*Gp6kio}_k}ZpuEMBUH8FYdnnKkDH#N=U1&a=~xWXX}i!TnZ2bmN+$d>dK2 zrE5bpW@A)l?~799Nlv7`o78h1W7Hzsm@hxXc678I^UD|MG^RN)ql33DvdkZ(Qoko* zMW3^F?bhhF*tV|j^-;Q&M0lXg#rMZ}#CQon=SghM`5U`7^sH8VAT{}fuVd|tWA=-m zyIQsC%=JCpt7D5=+FIHG zDz}=i?Bmfk);Am**o#2eN+zi~dSLSEw&)(Cc>DHPdrJo_7hPgAcA=+-igqp3Q$OxB zmq=JMT0-e^21-yd!NnIwO5W-4B#@4T5qMs=sVsT_MtisHy`ES~9`f;Jx_$d%*p{2m z4&j^ue2rkw!d0tQZ{LpjiWr@WTzQFEH$wBqM0gz!g A%>V!Z literal 0 HcmV?d00001 diff --git a/plugins/org.eclipse.dd.tests.gdb/data/launch/bin/MultiThread.exe b/plugins/org.eclipse.dd.tests.gdb/data/launch/bin/MultiThread.exe new file mode 100755 index 0000000000000000000000000000000000000000..e89bc956e7f0a40120c112e312df3a52a33ab3b9 GIT binary patch literal 9106 zcmd^Fe{fvYb-wTITj>eOMwY>t;?_^GY($LTO2!6bL$NKdv54?*69)&LSG!NU3#;Aj z?ptFeP@60c5sGK*Nt=YUGl6N6X{X7Qwo{rkO=2pF&4kP_giQY+nYxWLvlO?Z%qSgA z<7WGP_r5FbE@mK^{MV~Fd(L;yx#!+@f1G#keL4{z*=ZPt(8&}LLG;2?mc0S|;&n>1 zK{&z|{o-cPC)$uj-G-B}0m%X=6h)o|ickl<;YsL0OMyw$(KksZmIYmGM?D~x7u`xP z^S%Hb=q?o43Szy~n_#oBpM{Pz15Bcxb&z(!ei!N{Ilv^X+xxR1brj`~K5f~g70{8i zejoIJ?@HQ#ESDXPEu9IsR20g*F*ee zR6_f&hWJi!;$n#3LZ!q{hjkVgG4FtJmKAU%-ip$v*o}q4doK$vR|gj@#9|6FO>`VL@palc*h3lW?XrI zlujnSGSMLOi$SL3CsM=%A_QI%S%E(f{o~nyw#l#+!+X$#R5tHb%6>`|OWAxdhKgws zwrxC-&5NPKhqrAX_6FVC#JwZK+lRdMs6tDFctkly9OVdRQ3RvJu`=YJ>U#(Hhkx}b zhA%3<3z>=f&w_Jo9P(^-5q-Q0naP0Hqu_e%mPoxNei-H{dvo6Y(ibhe4U=USyd4dg zBL}`h&VhIq94)ZOF)?j&Or$PyOv*!(KdWB0Yu|xo?K+gNoj~DNr$v3^Wq7Esp2074 zqQ06nWGKFUv5vHwHD#!K`*n#~V}{Ls`<%qAIkTMj1&P^$j6?jK#B52XpZJW#Y*A)_ z_#`m+d>Z`EhbRB7dTD0w!TlKr^D8repM4Kx4xX~?S{25#XU^a`4pc8&H5NMZsUUpPSs# zXTkU~nqB+puj=)w`{$5*`q0IfE}Ew;b8@7w>->&B`#%R(kdFirV!5*6XLMb0|3( zpHads@tK#Nm@%gg&7jlQ4%R1MIsGEbPsO{d=M7YDPsO{~1~v$7Usip^y7P&d%D+}$ zUUB4M@1g0b6@45c)OX<9d&QdXv}+ji>(H{A zg9d#JBhA>$wKSY}xSBURGALy8X-7p2XLX99S;Y76-?M*0@6~>+B zSkixslP$|4yZl_P;C!@D%B6ap;o#=7Gw$E2eXd%a>V;S1rpOjfe8%uubkipAXV9*r z;LK+-KCxFAkK0ihK)WpKGgx~ZHwVOd%~&dSbQz+ zm$kIhO3Fx_6pfrR+|Lus67LWB(U3DPb&(L$5tPJ*FqUWVKK;e7>V>a>Bb12Drx0_f z2WBV!1k?%Q;=dlm#Qv`#BCrqm{M=G30o?$4vufFtUjyfR!v=A$K#p!Id>r|BgaUoc zfbRr`_-iNb6Lg`?c&7V64}u;6eFF3h=u04NbD8${4h?N~`tdry#o6Evy6c_(L!*^^ zP*G^zKt-Yrw}}7Oma@xk#jh#O;#Y<&@h19m4G`xK=L6>t$5kipw@k4TQ%~7*p1-7( z;GF-axCg_o^u6%I`ExOxhuXAP+7Yqt36R(PPN#|uQI$FH@c=57Z}lHQ*vnVGT*x#O zr==w&3rb8+R7>I%l^LIeU>?Db)ou62AYBwKHnQ>;encU-<(FmLiD{5{8vZLlc zvUYPb7&1dIBS1!*^>wlvr}!I}{KF$NqFQ8B3Ncv1BR8x(7Z;xdmq^CouD!Z3mq7?%*Bn#sOiRT!HR0 z#X;GcY5ZP~c5>usIJ9={`>Yb{{z@*$9#p%uWKzU3g>gStOg!f2VviL{kCuyxq#sL_ z$6|$2+VzvUY_aUSsgxV|<)G}QQ=_p|B1pt?iAp}1iIq!9VSbx!X^&L$U8mAi7umI@*C~mgM$ML8GDb3jj&=X zILMspi&Tx-lrY+;QmK+jh0JuTx-{Pv^RZ!%l+zm?f)EHS#BJiXN(UaGw;TJXYxS9yq4$Th|9QfK^f@gn@n8vqQLA+q^w;3lCG z;)@_t?8fiA%zoWL6(Wp5r~{p1GNwj4jow)A-4FJr)3Mlty}i9A4nzi&d}l;fL3y`{ zgA{Z4_K4gTnwxFNEXlSFU$t$Oaw(S0Cv%mQ9~;dEWg%Ju4@!k=FqkO%WjCW@d(`B@ zi!3(mWoPY}=`Ky%vA_FTB=-+l2xb>*Jtk}Y?ez%fdDtU-!9_ZZ`A*=AF4AM@ZsC54 zdpUH`<95Ry5!v&5#P`@D%KaAY^d3=f5yPQYp^_m>hVl0a;xY=(hr;>jCu7@!Za$xG zuM&$t!2D@`6}7z8oBZ?HxJxiaV3Es7FZPjPnaFH%Zew90x3k<*o1!8kEJS%-@dc%~ z$e&fRP5zRU7i<9+_SKxo{{!Njy#d6T`W8qUHP~@@SAjUJmm2iKEl-RGiBa&Nq zT#mlLtMxd3#{i%z@bxNOKjV#+663y?Nui`h!c7K+QW@1L_DB*+xJ-;^lc=r$H~4X- zZ{=sS4C`cJeB8$*a8v$hCG90jiF_KDJ0UDqM&V!qXY*qPtxJrKmi%KH;j+!wvTU6O z=q)Yg3TTO{C#*&f!~61^V8NBhJ*K?31mGJ$C%H-i7&_(N4qV) z3;N@kDFeH^!aOiJUuioC`fr?TXvZ_vS76r%nPr)1L)rpTlUbd$F2L?N+x0{&=_j0y3Agv0-B0F`WWwJFevmXaLVDI?)%?6o__o!S#FzcAtc- zleYUDGPIq%Z^q=gn!o28>>kIR%;T_2X=mWt-(QAy?0a5^T!h_xuxYUSn+CfY>}u~} z_pJsyUSQ3@PS*w1yv#dGJ?1=1^ZtD%%+q#k$9WK+m+j+y*ZbD3fO5KZMA$6GX3d9yEP3NT6`M@TBhwT zyiJblLg1{6X%5tAcMf*);3l;TIvYlfcGqGt|A38cvE#jKqur0OX}z%_LyI43vHJzC z*#A~5;Zuv;>T8)*{W(suJiqCr`(;au-4)nf&_>|e$IceJmvL!RxQgAr7Q0Odrn?&K zbpN3mIc8dQ5_X=h44GOaZ&o^fS!fl^FM# zslI@z_^z<3nQ>fU<&g1OVbzPg15;QHEe%$1|!tio74NQ|cnOD5x{!h8yKH>NPR zGAa%#jLCzde!Y>SrI|_4DRD4mGH*>hd z!@5^ky%`xV6y}>leUDRE-TZO=E4++M-T^ACB01Ny!pq6zx>fi_iSF4$Sh7#1rS}^Z` zbfTW;8SW*SXJV`RDXj#jo)=S$_sll%h3!wk^>`TAsr&`79uEU=@)v>SHw$ThqxffV ze$N0y`QKI-qeb7A?}us$0h@LBzQ<|45Yn5SnRtXO{^ zF!ybMz=&6g(d;^TkU1b+H&&h~r~G1B-c!c>+*nM02*znRJd={~P=cF?4{%hx>TPE- zk;^rFWab4#IjD?{!KLR79o)0u8yP-ukl&uY9Zl%Ip?MV!FU6c6_$hbe9UC`^A{oD3 zrwU#=R~Sv?Jb4)M5|!gZ9hp*<@$m^=L45a)1^*iC+`sMqxTg^-)AE8>dD4JE{z`Oe* cd;6x_-LxNg#iSQxD)~p<(c|iSgd7d=fASs4uK)l5 literal 0 HcmV?d00001 diff --git a/plugins/org.eclipse.dd.tests.gdb/data/launch/bin/SpecialTestApp.exe b/plugins/org.eclipse.dd.tests.gdb/data/launch/bin/SpecialTestApp.exe new file mode 100755 index 0000000000000000000000000000000000000000..cbe79e76c9bb0e2aa12f6e6609438768c43de0ef GIT binary patch literal 9581 zcmd^FdvH|Oc|Z5DVlhIN5atn7XJrX24{(=r1Rgt?{MWN{?svZL`5;3Gj?Yx9goKa|z%}UvlG&3!!5)`rXij zy(<{|$wGc8S;(v|nZCD$~L(VF^-6;t9J!uU>*kI z=OVHm#GAa7GaqrXjXFdtd16lv9DViApZxdBNX`hXiwOxNK4}>_jn{e9^ClK}HOh%0W?-t5GP1(}hwPh~eXvd=#KK*nmA* zqmfj;D0&VY=-xWuul3f8?Slhbd;E1M$fVZb#bn@&anN@*`pwcmIZQX@J1uLJye;0;_{Nvqcpcg}0Xhe?ofK`{L5jv*MT!#EkYd1e zl45{uBE=xtf99RhcjM!K1#{z#$UnXkqv_2nVsgV0ASRc$;K`yUm$QT%lQ(ZnA}nV~ zIqGg+mpn_%vD!B;OP(d?mXNE*A6m%9KiR_ox?lq9evjwXNE)1UCF?gjD6(}bf@2nV&hwp zIB@9AE9YcT?|bU8ev~Gn`dcldm)$?v24?cDizH)>r{AjHdOb$Hg-i;6u?24A^yO&5 z4_F2gbFaDWlucd-=Img*iz-fj?heqqN8fFSvVgHYz8FPc>zx=y`daV%FM^EqzJF$0 zyF1o9amH;Q|ECWoC(rcW9_zggVg0pj?eWDh59*>P1gw0OR(=E&A;|DmBxMywueKk2 z`fTdX6_oh&m9x}N)i_F?Tr~Q+`K=NU^{nlq%S{++WmM=OdWOD? z<9<)ISj-o*iM{0@olh0^1!2@(E{kL|Qch;V;Rw7Jorpy0Ly+{J)-q=^2O%3Uf_)As z4nhX&nO(wqHXf6XsNQwI%=rR&0+HkCSx~X9-V$?Ns}K6_hWKfF>-<>v3#=jL075Ng zn&p_-uhV-pJ)&tDv>x%ss2j&*7X9c|`n??1o}Ya%S$YMOemnO(<}&CT;Q20ZBhEwQ z`#gZiz?v+?*rdQgGmW6ZVkzy4Z%@*hJvmr1&$r|sR=De*y58If(k!1jx~Ve+ZK%&R!aXf z*kS)4(PL1&?1zJaT@B&m-E0 z@NnnYJs?)x&QUbSeo6^@DXg=(`LSb8z8DENW^Vu&kJ-CP=Gc#dK&Y(@g0t$}KO z#%IjomLj$jY4Q7rw%CfNYe~o;x0#%(B_ zOo!EEx)SBRy&osvv@zu44lmKYH-Y`Yr@ReogmvntXe(RnleM{mCzmpI6@fh~SAN8l zaA$f%FP#?2TxldomQ%-rLh^X2ax^Tb(gD3>vQ)`>LAsDHhk=*Lc=Vc~m(2_%GpQ(* zETpQ%bS@cI(!vh&&jfxXV*mIuYUKQom7C*Mi(x)n3^IvyE>%GX9$sZM$S5&Q)Y;{szX&inVEuktVS@y8hYFJKUYmVkLN=!vUBWRgWiLAOthhg1NM%Fe z)XM{p-6rDHbI<6Pql$2vtP{v+x4F~upqLTP0xgeE%ZF0fI6BQ*Q7;v88|f>}Lak}6 z(a16$(29jM3R%b^tym%zL)BqzX|a~KOvxpDi54fMI7}T2H2xD>(XQ~R^wDZrtCne1 z$8;WPt3}IK#r=^~lgKp7nWIh3#>_P)Z*a&N^#M3i?r+E@`uMSe7&x_x*AzvsO6UtYcELPf1Y8 zUM)GGByb-p6sq8e;%Em*%l$DN&6r>YZ2X{bGQPkMn)i=%U^a z@U@&W_W4|+d_7CfAp3lwaX14%!Tk35GR%L8#VGgNill43fM*9}zl!@U{#x9x)nql+ zEx>bmL-RbRVOay}+Af@idGkJvMb$wvu97Z#w&Brvo97KQKVENR6Bb(`2Dsi@O;|+t z*E#WJ@#XPm?$)Ml#$gk3*jxldDz~z#3vj0kh}|#dp~yNC8lKZ^SLuny4 z(7Xwy&sC-0XY67>Sc8Y1dX0xI;^$+;HPdWEE2^CY;C>I1$LmeCnydv@7d8Wpcu!qZ zzU4h$uMJXL{04Q_FB<0K$x*?z+!Fa>KJwDwgm?+j7CZ2~3--%)w-9={WjP{dbNc|d z+?s5C?6a-eY%=-T*49=VM`#O5?uVQ(KU;JAGs8aL6VogJZw^4`Q==DNcya_wAZS!kG-pz1i=a{#Ua=Gf9&V&o zN2#pvFjl=>D$EHlbFzrcieeulHOH`u=S#&Ij1OHUC=jm_LmRgh4#h7mR zNV*INP9dJ5+oEM4a{Ljy z7V+o$?9TgwSAc7WjCmP|Vcd+U2B*45cmuc#knvstNr~ay?m?vQk>%pvA&11<;7uTw z;YmbuXTbY{Ey%<>2U9NdGaf+X9Rt(6XV?YYE~Hs5Wvm-R7I7{jWxS`j030WQu}2*F zGNQrpUgMj<@xFsN-lZ5EPpYgd%i-L*0UVF1CYW*~2n_BvaJPXwWk8_BF@6!z;P{Q> z6ohO;6WDePrx6W~bGaWC;91-R+F}?(B#!UP`J4gn38YOhxUWE9aPqqYaBOE24DKQX z26q+qt^(I@K%fTqry7UX6ug$>_mU}RQ-k|X4Q?TD3qJ(M3u2Z_d%XB;0nU^K(Ny|x zkw%pyPJVv@ZbHjIB#!mChG^{Z4!aS;+4ji)eGQKHUJHTifXoD982$t*8;0lm0k`I=yo56!~;FD_(0FiL<;(wl|54W~vwWP)jz z&9iWw7^H6)5U8=&Hw$+MxSo69cF)3f;i9v@24~uj_edOjCVUw6?wm_ zc;)qY@2hy#(dJ&(kt>Mur%Eqj(r+rBZ=vpe70<1S@`H-!N`SEkf2VjgBk0!@&#epU zulE^_z_|#)>^mHOmqVaGB6ajvDf%77vsaXVQ9N&*;kS6-i{R*$k^VyQ%A=Y4V@Ka= zbN(y6`k2glu6X6iIiD53gha@1H=vGKDtYs8#3xKrQb%yLo(|3o56%2M-b@EaJUGoD z<;?ghN-oG< zf>O_WSo(X4EqrPH8mQ?H3;ppe@TNa3tT6oOBfoV?{8I5_P<{skLH;Gu|6Z>t@877< z*8=w{|G%MbtSSE&;N|^4D9fjRi~pXn-y{}+udNULRYH$1+MnGXn`#=A?^~Y5KM&rF zAIn}WUIK60L)Z(%w`TFLfj8sPvL6sX25-h&0`GqvJg-4GQx~8|Py9vCRZwoNr7K3N_2J&(Cbb`;-;CsNE`ZS_GyENW>hab}XI^<>k z5PX;Jzb1Q$I0c@cO!HDdU!2o;`cC3s25;t5Bii#Xzz^#DJP!8oad@?8uC*|jM z99#97l7xp4+&+AaquxC)^V6w9q2|v8ymSbo>hLg3`hL&8oqPPjfxY|qp96o}4DN}Z zDHRSYi)Q}VNg(om}4%fpYKs-6()h?J?0jGQzD^zPU;ZQn3` zd%8c<>l==Rne?<(d9spLf0eiA@&E4Y3V-|H&aK^p{?5L>y}kSVecf9Jd-?KgY8=BV zsgpi$foBM0uLytJ!5!V78R!u_#;HF>04Dz>fsY`#1;$} +using namespace std; + +const int ARRAY_SIZE = 256; + +char charBlock[ARRAY_SIZE]; +int integerBlock[ARRAY_SIZE]; + +void zeroBlocks(int abc) +{ + for (int i = 0; i < ARRAY_SIZE; i++) { + charBlock[i] = '\0'; + integerBlock[i] = 0; + } +} + +void setBlocks() +{ + for (int i = 0; i < ARRAY_SIZE; i++) { + charBlock[i] = (char) i; + integerBlock[i] = i; + } +} + +void loop() +{ + int j; + + for (int i = 0; i < ARRAY_SIZE; i++) + j = i; +} + +int main() +{ + zeroBlocks(1); + loop(); + setBlocks(); + return 0; +} diff --git a/plugins/org.eclipse.dd.tests.gdb/data/launch/src/ExpressionTestApp.cc b/plugins/org.eclipse.dd.tests.gdb/data/launch/src/ExpressionTestApp.cc new file mode 100644 index 00000000000..269b5bcf2d7 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.gdb/data/launch/src/ExpressionTestApp.cc @@ -0,0 +1,298 @@ +#include + +int gIntVar = 543; +double gDoubleVar = 543.543; +char gCharVar = 'g'; +bool gBoolVar = false; + +int gIntArray[2] = {987, 654}; +double gDoubleArray[2] = {987.654, 654.321}; +char gCharArray[2] = {'g', 'd'}; +bool gBoolArray[2] = {true, false}; + +int *gIntPtr = &gIntVar; +double *gDoublePtr = &gDoubleVar; +char *gCharPtr = &gCharVar; +bool *gBoolPtr = &gBoolVar; + +int *gIntPtr2 = (int*)0x8; +double *gDoublePtr2 = (double*)0x5432; +char *gCharPtr2 = (char*)0x4321; +bool *gBoolPtr2 = (bool*)0x12ABCDEF; + +class bar { +public: + int d; +private: + int e[2]; +}; + +class bar2 { +public: + int f; +private: + int g[2]; +}; + +class foo: public bar, bar2 { +public: + int a[2]; + bar b; +private: + int c; +}; + +struct Z { +public: + int x; + int y; +}; +struct childStruct { +public: + Z z; +}; +void locals2() { + // Check that we get the content of local variables with + // the same name as the calling method + int lIntVar = 6789; + double lDoubleArray[2] = {123.456, 6789.6789}; + char lCharVar = 'i'; + char *lCharPtr = &lCharVar; + bool *lBoolPtr2 = (bool*)0xABCDE123; + + return; +} + +void testLocals() { + + int lIntVar = 12345; + double lDoubleVar = 12345.12345; + char lCharVar = 'm'; + bool lBoolVar = false; + + int lIntArray[2] = {6789, 12345}; + double lDoubleArray[2] = {456.789, 12345.12345}; + char lCharArray[2] = {'i', 'm'}; + bool lBoolArray[2] = {true, false}; + + int *lIntPtr = &lIntVar; + double *lDoublePtr = &lDoubleVar; + char *lCharPtr = &lCharVar; + bool *lBoolPtr = &gBoolVar; + + int *lIntPtr2 = (int*)0x1; + double *lDoublePtr2 = (double*)0x2345; + char *lCharPtr2 = (char*)0x1234; + bool *lBoolPtr2 = (bool*)0x123ABCDE; + + locals2(); + + return; +} + +int testChildren() { + foo f; + + f.d = 1; + + return 0; +} + +int testWrite() { + int a[2] = {3, 456}; + + return 0; +} + +int testName1(int newVal) { + int a = newVal; + return a; +} + +int testName2(int newVal) { + int a = newVal; + return a; +} + +int testSameName1(int newVal) { + int a = newVal; + Z z; + z.x = newVal; + return a; +} +int testSameName1(int newVal, int ignore) { + int a = newVal; + Z z; + z.x = newVal; + return a; +} + + +int testSameName() { + testSameName1(1); + testSameName1(2, 0); + testSameName1(3); + + return 0; +} + +int testConcurrent() { + int a[2] = {28, 32}; + return a[0]; +} + +int testSubblock() { + int a = 8; + int b = 1; + if (a) { + int a = 12; + b = a; + } + return b; +} + +int testAddress() { + int a = 8; + int* a_ptr = &a; + + return a; +} + + + +int testUpdateChildren(int val) { + childStruct a; + a.z.x = val + 10; + a.z.y = val + 11; + + a.z.x = val + 20; + a.z.y = val + 21; + + return a.z.x; +} +int testUpdateChildren2(int val) { + childStruct a; + a.z.x = val + 10; + a.z.y = val + 11; + + a.z.x = val + 20; + a.z.y = val + 21; + + return a.z.x; +} + +int testDeleteChildren() { + foo f; + int a[1111]; + + return 1; +} + +int testUpdateGDBBug() { + // GDB 6.7 has a bug which will cause var-update not to show + // the new value of 'a' if we switch the format to binary, + // since binary of 3 is 11 which is the same as the old value + // in natural format + int a = 11; + a = 3; + return 0; +} + +int testUpdateIssue() { + double a = 1.99; + a = 1.22; +} + +int testUpdateIssue2() { + struct { + double d; + } z; + + z.d = 1.0; + z.d = 1.22; +} + +int testConcurrentReadAndUpdateChild() { + struct { + int d; + }z; + + z.d = 1; + z.d = 2; +} + +int testConcurrentUpdateOutOfScopeChildThenParent1() { + struct { + int d; + }z; + + z.d = 1; +} + +int testConcurrentUpdateOutOfScopeChildThenParent2() { + struct { + int d; + }z; + + z.d = 2; +} + +int testConcurrentUpdateOutOfScopeChildThenParent() { + testConcurrentUpdateOutOfScopeChildThenParent1(); + testConcurrentUpdateOutOfScopeChildThenParent2(); +} + +int testUpdateOfPointer() { + struct { + int a; + int* b; + }z; + + int c = 3; + + z.b = &(z.a); + z.a = 1; + + z.b = &c; + z.a = 2; +} + +int testCanWrite() { + int a; + int* b; + struct { + int in; + } c; + int d[2]; + + return 1; +} + +int main() { + printf("Running ExpressionTest App\n"); + + testLocals(); + testChildren(); + testWrite(); + testName1(1); + testName2(2); + testName1(3); + testSameName(); + testConcurrent(); + testSubblock(); + testAddress(); + testUpdateChildren(0); + testUpdateChildren(100); + testUpdateChildren2(200); + testDeleteChildren(); + testUpdateGDBBug(); + testUpdateIssue(); + testUpdateIssue2(); + testConcurrentReadAndUpdateChild(); + testConcurrentUpdateOutOfScopeChildThenParent(); + testUpdateOfPointer(); + testCanWrite(); + + return 0; +} + diff --git a/plugins/org.eclipse.dd.tests.gdb/data/launch/src/GDBMIGenericTestApp.cc b/plugins/org.eclipse.dd.tests.gdb/data/launch/src/GDBMIGenericTestApp.cc new file mode 100644 index 00000000000..e4007b95427 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.gdb/data/launch/src/GDBMIGenericTestApp.cc @@ -0,0 +1,15 @@ +#include + +int main() { + printf("Running Generic App\n"); + + const char *path = "/tmp/dsftest.txt"; + const char *mode = "a"; + FILE* fd = fopen(path, mode); + fprintf(fd, "Running Generic App\n"); + fclose(fd); + + + return 0; +} + diff --git a/plugins/org.eclipse.dd.tests.gdb/data/launch/src/Makefile b/plugins/org.eclipse.dd.tests.gdb/data/launch/src/Makefile new file mode 100644 index 00000000000..777b8b828b3 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.gdb/data/launch/src/Makefile @@ -0,0 +1,14 @@ +src = $(wildcard *.cc *.c) +destDir = ../bin +GCCFLAGS = -g -pthread + +all: + @mkdir -p $(destDir) +# Name the target with an .exe extension so that CVS does not +# include it when making a patch + @for file in $(src) ; \ + do \ + target=`basename $$file .c` ; \ + target=`basename $$target .cc` ; \ + g++ $(GCCFLAGS) $$file -o $(destDir)/$$target.exe ; \ + done diff --git a/plugins/org.eclipse.dd.tests.gdb/data/launch/src/MemoryTestApp.cc b/plugins/org.eclipse.dd.tests.gdb/data/launch/src/MemoryTestApp.cc new file mode 100644 index 00000000000..bef0b930e0e --- /dev/null +++ b/plugins/org.eclipse.dd.tests.gdb/data/launch/src/MemoryTestApp.cc @@ -0,0 +1,38 @@ +//============================================================================ +// Name : MemoryTestApp.cpp +// Author : Francois Chouinard +// Version : 1.0 +// Copyright : Ericsson AB +// Description : Memory test application +//============================================================================ + +#include +using namespace std; + +const int ARRAY_SIZE = 256; + +char charBlock[ARRAY_SIZE]; +int integerBlock[ARRAY_SIZE]; + +void zeroBlocks() +{ + for (int i = 0; i < ARRAY_SIZE; i++) { + charBlock[i] = '\0'; + integerBlock[i] = 0; + } +} + +void setBlocks() +{ + for (int i = 0; i < ARRAY_SIZE; i++) { + charBlock[i] = (char) i; + integerBlock[i] = i; + } +} + +int main() +{ + zeroBlocks(); + setBlocks(); + return 0; +} diff --git a/plugins/org.eclipse.dd.tests.gdb/data/launch/src/MultiThread.cc b/plugins/org.eclipse.dd.tests.gdb/data/launch/src/MultiThread.cc new file mode 100644 index 00000000000..80f99fea6aa --- /dev/null +++ b/plugins/org.eclipse.dd.tests.gdb/data/launch/src/MultiThread.cc @@ -0,0 +1,29 @@ +#include +#include +#include +#include +#define NUM_THREADS 5 + +void *PrintHello(void *threadid) +{ + int tid; + tid = (int)threadid; + printf("Hello World! It's me, thread #%d!\n", tid); + pthread_exit(NULL); +} + +int main(int argc, char *argv[]) +{ + pthread_t threads[NUM_THREADS]; + int rc, t; + for(t=0;t + +int main() { + printf("Running SpecialTestApp\n"); + + const char *path = "/tmp/dsftest.txt"; + const char *mode = "a"; + FILE* fd = fopen(path, mode); + fprintf(fd, "Running SpecialTestApp\n"); + fclose(fd); + + + return 0; +} + diff --git a/plugins/org.eclipse.dd.tests.gdb/plugin.xml b/plugins/org.eclipse.dd.tests.gdb/plugin.xml new file mode 100644 index 00000000000..e2b5a7c5bfd --- /dev/null +++ b/plugins/org.eclipse.dd.tests.gdb/plugin.xml @@ -0,0 +1,16 @@ + + + + + + + + + \ No newline at end of file diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/mi/service/ClassAccessor.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/mi/service/ClassAccessor.java new file mode 100644 index 00000000000..3d4bd45fdd3 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/mi/service/ClassAccessor.java @@ -0,0 +1,38 @@ +package org.eclipse.dd.mi.service; + +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.dd.mi.service.ExpressionService.MIExpressionDMC; + +public class ClassAccessor { + + public static class MIExpressionDMCAccessor { + private MIExpressionDMC miExprDmc; + + public MIExpressionDMCAccessor(IExpressionDMContext dmc) { + miExprDmc = (MIExpressionDMC) dmc; + } + + @Override + public boolean equals(Object other) { + return miExprDmc.equals(other); + } + + @Override + public int hashCode() { + return miExprDmc.hashCode(); + } + + @Override + public String toString() { + return miExprDmc.toString(); + } + + public String getExpression() { + return miExprDmc.getExpression(); + } + + public String getRelativeExpression() { + return miExprDmc.getRelativeExpression(); + } + } +} diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/AllTests.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/AllTests.java new file mode 100644 index 00000000000..94f304e8140 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/AllTests.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2007 Ericsson 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: + * Ericsson - Initial Implementation + *******************************************************************************/ +package org.eclipse.dd.tests.gdb; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/* + * This class is meant to be empty. It enables us to define + * the annotations which list all the different JUnit class we + * want to run. When creating a new test class, it should be + * added to the list below. + */ + +@RunWith(Suite.class) +@Suite.SuiteClasses({ + MIRegistersTest.class, + MIRunControlTest.class, + ExpressionServiceTest.class, + MIMemoryTest.class, + MIBreakpointsTest.class, + + /* Add your test class here */ + }) + +public class AllTests {} diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/ExampleTest.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/ExampleTest.java new file mode 100644 index 00000000000..4604d9046ad --- /dev/null +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/ExampleTest.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * Copyright (c) 2007 Ericsson 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: + * Ericsson - Initial Implementation + *******************************************************************************/ +package org.eclipse.dd.tests.gdb; + +import static org.junit.Assert.assertTrue; + +import java.io.FileNotFoundException; + +import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; +import org.eclipse.dd.tests.gdb.framework.BackgroundRunner; +import org.eclipse.dd.tests.gdb.framework.BaseTestCase; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; + +/* + * This is an example of how to write new JUnit test cases + * for services of DSF. + * + * Each test class should extend BaseTestCase + * so as to automatically launch the application before + * each testcase and tear it down after. + * + * Also, each new test class must be added to the list within AllTest. + * + * Finally, each testcase should be @RunWith(BackgroundRunner.class) + * so as to release the UI thread and allow things such as + * timeouts to work in JUnit + */ + +// Each test must run with the BackgroundRunner so as +// to release the UI thread +@RunWith(BackgroundRunner.class) + +public class ExampleTest extends BaseTestCase { + + @BeforeClass + public static void beforeClassMethod() { + // Things to run once specifically for this class, + // before starting this set of tests. + // Any method name can be used + + // To choose your own test application, use the following form + // You must make sure the compiled binary is available in the + // specified location. + // If this method call is not made, the default GDBMIGenericTestApp + // will be used + setLaunchAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, + "data/launch/bin/SpecialTestApp.exe"); + + // Other attributes can be changed here + } + + @AfterClass + public static void afterClassMethod() { + // Things to run once specifically for this class, + // after the launch has been performed + // Any method name can be used + } + + @Before + public void beforeMethod() { + // Things to run specifically for this class, + // before each test but after the launch has been performed + // The Launched used is for the default test application + // Any method name can be used + } + + @After + public void afterMethod() { + // Things to run specifically for this class + // after each test but before the launch has been torn down + // Any method name can be used + } + +// @Override +// public void baseBeforeMethod() { +// // Can be used to override and prevent the baseSetup from being run +// // The name baseBeforeMethod must be used +// } + +// @Override +// public void baseAfterMethod() { +// // Can be used to override and prevent the baseTeardown from being run +// // The name baseAfterMethod must be used +// } + + @Test + public void basicTest() { + // First test to run + assertTrue("", true); + } + + @Test(timeout=5000) + public void timeoutTest() { + // Second test to run, which will timeout if not finished on time + assertTrue("", true); + } + + @Test(expected=FileNotFoundException.class) + public void exceptionTest() throws FileNotFoundException { + // Third test to run which expects an exception + throw new FileNotFoundException("Just testing"); + } + +} diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/ExpressionServiceTest.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/ExpressionServiceTest.java new file mode 100644 index 00000000000..33ccdf3ae6b --- /dev/null +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/ExpressionServiceTest.java @@ -0,0 +1,2960 @@ +/******************************************************************************* + * Copyright (c) 2007 Ericsson 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: + * Ericsson - Initial Implementation + *******************************************************************************/ +package org.eclipse.dd.tests.gdb; + +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; +import org.eclipse.cdt.utils.Addr32; +import org.eclipse.cdt.utils.Addr64; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.IExpressions; +import org.eclipse.dd.dsf.debug.service.IFormattedValues; +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionChangedDMEvent; +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMAddress; +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMData; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData; +import org.eclipse.dd.dsf.debug.service.IRunControl.StepType; +import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.gdb.service.command.GDBControl; +import org.eclipse.dd.mi.service.ClassAccessor.MIExpressionDMCAccessor; +import org.eclipse.dd.mi.service.command.events.MIStoppedEvent; +import org.eclipse.dd.tests.gdb.framework.AsyncCompletionWaitor; +import org.eclipse.dd.tests.gdb.framework.BackgroundRunner; +import org.eclipse.dd.tests.gdb.framework.BaseTestCase; +import org.eclipse.dd.tests.gdb.framework.SyncUtil; +import org.eclipse.dd.tests.gdb.launching.TestsPlugin; +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(BackgroundRunner.class) +public class ExpressionServiceTest extends BaseTestCase { + + private DsfSession fSession; + + private DsfServicesTracker fServicesTracker; + + private GDBControl fGdbControl; + + private IExpressions fExpService; + + private int fExprChangedEventCount = 0; + + private IExpressionDMContext fExprChangedCtx = null; + + private IExpressionDMContext globalExpressionCtx1 = null; + private IExpressionDMContext globalExpressionCtx2 = null; + + + @BeforeClass + public static void beforeClassMethod() { + setLaunchAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, "data/launch/bin/ExpressionTestApp.exe"); + } + + @Before + public void init() { + fSession = getGDBLaunch().getSession(); + fServicesTracker = new DsfServicesTracker(TestsPlugin.getBundleContext(), fSession.getId()); + + fExpService = fServicesTracker.getService(IExpressions.class); + fGdbControl = fServicesTracker.getService(GDBControl.class); + fSession.addServiceEventListener(this, null); + clearExprChangedData(); + } + + @After + public void shutdown() { + fSession.removeServiceEventListener(this); + fExpService = null; + fServicesTracker.dispose(); + } + + // Handles ExpressionChangedEvent + @DsfServiceEventHandler + public void eventDispatched(IExpressionChangedDMEvent e) { + fExprChangedEventCount++; + fExprChangedCtx = e.getDMContext(); + } + + // Clears the counters + private void clearExprChangedData() { + fExprChangedEventCount = 0; + fExprChangedCtx = null; + } + + // Returns the total number of events received + private int getExprChangedCount() { + return fExprChangedEventCount; + } + + private IExpressionDMContext getExprChangedContext() { + return fExprChangedCtx; + } + + // ********************************************************************* + // Below are the tests for the expression service. + // ********************************************************************* + + /** + * Test that we can correctly evaluate integer expressions. + */ + @Test + public void testLiteralIntegerExpressions() throws Throwable { + // Create a map of expressions and their expected values. + Map tests = new HashMap(); + + tests.put("0 + 0 - 0", new String[] { "0x0", "0", "0", "0", "0" }); + tests.put("3 + 4", new String[] { "0x7", "07", "111", "7", "7" }); + tests.put("3 + 4 * 5", new String[] { "0x17", "027", "10111", "23", "23" }); + tests.put("5 * 3 + 4", new String[] { "0x13", "023", "10011", "19", "19" }); + tests.put("5 * (3 + 4)", new String[] { "0x23", "043", "100011", "35", "35" }); + tests.put("10 - 15", new String[] { "0xFFFFFFFB", "037777777773", "11111111111111111111111111111011", "-5", + "-5" }); + tests.put("10 + -15", new String[] { "0xFFFFFFFB", "037777777773", "11111111111111111111111111111011", "-5", + "-5" }); + + executeExpressionSubTests(tests, fGdbControl.getControlDMContext()); + } + + /** + * Test that we can correctly evaluate floating-point expressions. + */ + @Test + public void testLiteralFloatingPointExpressions() throws Throwable { + // Create a map of expressions and their expected values. + Map tests = new HashMap(); + + tests.put("3.1415 + 1.1111", new String[] { "0x4", "04", "100", "4", "4.2526000000000002" }); + tests.put("100.0 / 3.0", new String[] { "0x21", "041", "100001", "33", "33.333333333333336" }); + tests.put("-100.0 / 3.0", new String[] { "0xffffffffffffffdf", "01777777777777777777737", + "1111111111111111111111111111111111111111111111111111111111011111", "-33", "-33.333333333333336" }); + tests.put("-100.0 / -3.0", new String[] { "0x21", "041", "100001", "33", "33.333333333333336" }); + tests.put("100.0 / 0.5", new String[] { "0xc8", "0310", "11001000", "200", "200" }); + + executeExpressionSubTests(tests, fGdbControl.getControlDMContext()); + } + + /** + * Test that we can correctly evaluate C expressions involving local + * variables. + */ + @Test + public void testLocalVariables() throws Throwable { + // Run to the point where all local variables are initialized + SyncUtil.SyncRunToLocation("testLocals"); + MIStoppedEvent stoppedEvent = SyncUtil.SyncStep(StepType.STEP_OVER, 16); + + // Create a map of expressions to expected values. + Map tests1 = new HashMap(); + + tests1.put("lIntVar", new String[] { "0x3039", "030071", "11000000111001", "12345", "12345" }); + tests1.put("lDoubleVar", new String[] { "0x3039", "030071", "11000000111001", "12345", "12345.123449999999" }); + tests1.put("lCharVar", new String[] { "0x6d", "0155", "1101101", "109", "109 'm'" }); + tests1.put("lBoolVar", new String[] { "0x0", "0", "0", "0", "false" }); + + tests1.put("lIntArray[1]", new String[] { "0x3039", "030071", "11000000111001", "12345", "12345" }); + tests1.put("lDoubleArray[1]", new String[] { "0x3039", "030071", "11000000111001", "12345", "12345.123449999999" }); + tests1.put("lCharArray[1]", new String[] { "0x6d", "0155", "1101101", "109", "109 'm'" }); + tests1.put("lBoolArray[1]", new String[] { "0x0", "0", "0", "0", "false" }); + + tests1.put("*lIntPtr", new String[] { "0x3039", "030071", "11000000111001", "12345", "12345" }); + tests1.put("*lDoublePtr", new String[] { "0x3039", "030071", "11000000111001", "12345", "12345.123449999999" }); + tests1.put("*lCharPtr", new String[] { "0x6d", "0155", "1101101", "109", "109 'm'" }); + tests1.put("*lBoolPtr", new String[] { "0x0", "0", "0", "0", "false" }); + + tests1.put("lIntPtr2", new String[] { "0x1", "01", "1", "1", "0x1" }); + tests1.put("lDoublePtr2", new String[] { "0x2345", "021505", "10001101000101", "9029", "0x2345" }); + // GDB says a char* is out of bounds, but not the other pointers??? + // tests1.put("CharPtr2", new String[] { "0x1234", "011064", + // "1001000110100", "4660", "0x1234" }); + tests1.put("lBoolPtr2", new String[] { "0x123ABCDE", "02216536336", "10010001110101011110011011110", "305839326", "0x123ABCDE" }); + + executeExpressionSubTests(tests1, SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0)); + + // Step into the method and stop until all new local variables are + // initialized + SyncUtil.SyncStep(StepType.STEP_INTO); + stoppedEvent = SyncUtil.SyncStep(StepType.STEP_OVER, 5); + + // Create a map of expressions to expected values. + Map tests2 = new HashMap(); + + tests2.put("lIntVar", new String[] { "0x1a85", "015205", "1101010000101", "6789", "6789" }); + tests2.put("lDoubleArray[1]", + new String[] { "0x1a85", "015205", "1101010000101", "6789", "6789.6788999999999" }); + tests2.put("lCharVar", new String[] { "0x69", "0151", "1101001", "105", "105 'i'" }); + tests2.put("*lCharPtr", new String[] { "0x69", "0151", "1101001", "105", "105 'i'" }); + tests2.put("lBoolPtr2", new String[] { "0xABCDE123", "025363360443", "10101011110011011110000100100011", + "2882396451", "0xABCDE123" }); + + // check variables at current stack frame + executeExpressionSubTests(tests2, SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0)); + // check previous stack frame + executeExpressionSubTests(tests1, SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 1)); + + // Now return from the method and check that we see the + // original variables + stoppedEvent = SyncUtil.SyncStep(StepType.STEP_RETURN); + + executeExpressionSubTests(tests1, SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0)); + } + + /** + * This tests verifies that we can deal with variables in a subblock hiding + * variables with the same name in the outer block. + */ + @Ignore("Sublocks do not work with GDB") + @Test + public void testSubBlock() throws Throwable { + SyncUtil.SyncRunToLocation("testSubblock"); + MIStoppedEvent stoppedEvent = SyncUtil.SyncStep(StepType.STEP_OVER, 2); + IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + + Map tests = new HashMap(); + + tests.put("a", new String[] { "0x8", "010", "1000", "8", "8" }); + tests.put("b", new String[] { "0x1", "01", "1", "1", "1" }); + + executeExpressionSubTests(tests, frameDmc); + + // Now enter a subblock with the same variable names + SyncUtil.SyncStep(StepType.STEP_OVER, 2); + + tests = new HashMap(); + + tests.put("a", new String[] { "0xc", "014", "1100", "12", "12" }); + tests.put("b", new String[] { "0x1", "01", "1", "1", "1" }); + + executeExpressionSubTests(tests, frameDmc); + + // Now step to change the b variable + SyncUtil.SyncStep(StepType.STEP_OVER, 1); + + tests = new HashMap(); + + tests.put("a", new String[] { "0xc", "014", "1100", "12", "12" }); + tests.put("b", new String[] { "0xc", "014", "1100", "12", "12" }); + + executeExpressionSubTests(tests, frameDmc); + + // Now exit the sub-block and check that we see the original a but the + // same b + SyncUtil.SyncStep(StepType.STEP_OVER, 1); + + tests = new HashMap(); + + tests.put("a", new String[] { "0x8", "010", "1000", "8", "8" }); + tests.put("b", new String[] { "0xc", "014", "1100", "12", "12" }); + + executeExpressionSubTests(tests, frameDmc); + } + + /** + * This tests verifies that we can obtain children properly. + */ + @Test + public void testChildren() throws Throwable { + + // Get the children of some variables + MIStoppedEvent stoppedEvent = SyncUtil.SyncRunToLocation("testChildren"); + doTestChildren(stoppedEvent); + + // Now do a step and get the children again, to test the internal cache + stoppedEvent = SyncUtil.SyncStep(StepType.STEP_OVER, 1); + doTestChildren(stoppedEvent); + } + + /** + * This test verifies that the ExpressionService can write to a variable. + */ + @Test + public void testWriteVariable() throws Throwable { + SyncUtil.SyncRunToLocation("testWrite"); + MIStoppedEvent stoppedEvent = SyncUtil.SyncStep(StepType.STEP_OVER, 1); + + final IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + final IExpressionDMContext exprDmc = SyncUtil.SyncCreateExpression(frameDmc, "a[1]"); + + writeAndCheck(exprDmc, "987", IFormattedValues.DECIMAL_FORMAT, "987"); + writeAndCheck(exprDmc, "16", IFormattedValues.HEX_FORMAT, "22"); + writeAndCheck(exprDmc, "0x2e", IFormattedValues.HEX_FORMAT, "46"); + writeAndCheck(exprDmc, "16", IFormattedValues.OCTAL_FORMAT, "14"); + writeAndCheck(exprDmc, "022", IFormattedValues.OCTAL_FORMAT, "18"); + writeAndCheck(exprDmc, "1011", IFormattedValues.BINARY_FORMAT, "11"); + writeAndCheck(exprDmc, "0b1001", IFormattedValues.BINARY_FORMAT, "9"); + writeAndCheck(exprDmc, "456", IFormattedValues.NATURAL_FORMAT, "456"); + + } + + /* + * This method does a write and then a read to make sure the new value was + * properly written. + */ + private void writeAndCheck(final IExpressionDMContext exprDmc, final String newValueFormatted, final String format, + final String newValueInDecimal) throws Throwable { + + final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); + + // Write the new value using its formatted value + fExpService.getExecutor().submit(new Runnable() { + public void run() { + fExpService.writeExpression( + exprDmc, + newValueFormatted, + format, + new RequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + wait.waitFinished(getStatus()); + } + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + assertTrue("ExprChangedEvent problem: expected 1, received " + getExprChangedCount(), + getExprChangedCount() == 1); + + clearExprChangedData(); + + wait.waitReset(); + + // Read the new value in decimal and check that it is what we expected + fExpService.getExecutor().submit(new Runnable() { + public void run() { + fExpService.getFormattedExpressionValue(fExpService.getFormattedValueContext(exprDmc, + IFormattedValues.DECIMAL_FORMAT), new DataRequestMonitor(fExpService + .getExecutor(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + wait.setReturnInfo(getData()); + } + + wait.waitFinished(getStatus()); + } + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + + String actualDecimalValue = ((FormattedValueDMData) wait.getReturnInfo()).getFormattedValue(); + + assertTrue("Failed to correctly evaluate '" + exprDmc.getExpression() + "': expected '" + newValueInDecimal + + "', got '" + actualDecimalValue + "'", actualDecimalValue.equalsIgnoreCase(newValueInDecimal)); + + assertTrue("ExprChangedEvent problem: expected 0, received " + getExprChangedCount(), + getExprChangedCount() == 0); + } + + /** + * This tests verifies that we handle invalid formats properly for a write. + */ + @Test + public void testWriteErrorFormat() throws Throwable { + SyncUtil.SyncRunToLocation("testWrite"); + MIStoppedEvent stoppedEvent = SyncUtil.SyncStep(StepType.STEP_OVER, 1); + + IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + IExpressionDMContext exprDmc = SyncUtil.SyncCreateExpression(frameDmc, "a[1]"); + + writeAndCheckError(exprDmc, "goodbye", IFormattedValues.DECIMAL_FORMAT); + writeAndCheckError(exprDmc, "abggg", IFormattedValues.HEX_FORMAT); + writeAndCheckError(exprDmc, "99", IFormattedValues.OCTAL_FORMAT); + writeAndCheckError(exprDmc, "234", IFormattedValues.BINARY_FORMAT); + writeAndCheckError(exprDmc, "hello", IFormattedValues.NATURAL_FORMAT); + writeAndCheckError(exprDmc, "1", "ThisFormatDoesNotExist"); + + IExpressionDMContext notWritableExprDmc = SyncUtil.SyncCreateExpression(frameDmc, "10+5"); + writeAndCheckError(notWritableExprDmc, "1", IFormattedValues.NATURAL_FORMAT); + } + + /* + * This method does a write that should use an invalid value or format, and + * verifies that the operation fails + */ + private void writeAndCheckError(final IExpressionDMContext exprDmc, final String invalidValueFormatted, + final String format) throws Throwable { + + final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); + + // Write the new value using its formatted value + fExpService.getExecutor().submit(new Runnable() { + public void run() { + fExpService.writeExpression(exprDmc, invalidValueFormatted, format, new RequestMonitor(fExpService + .getExecutor(), null) { + @Override + protected void handleCompleted() { + wait.waitFinished(getStatus()); + } + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue("Got an OK status for an error test case. Should not be able to write value " + + invalidValueFormatted + " in " + format, !wait.isOK()); + + assertTrue("ExprChangedEvent problem: expected 0, received " + getExprChangedCount(), + getExprChangedCount() == 0); + } + + /** + * This test tries multiple format reads during the same executor cycle, to + * make sure the internal MI commands are sequenced properly. + */ + @Test + public void testConcurrentReads() throws Throwable { + // Next we test that we can read the value more than once + // of the same variable object at the exact same time + + SyncUtil.SyncRunToLocation("testConcurrent"); + MIStoppedEvent stoppedEvent = SyncUtil.SyncStep(StepType.STEP_OVER, 1); + + final IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + + + final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); + + fExpService.getExecutor().submit(new Runnable() { + public void run() { + IExpressionDMContext exprDmc = fExpService.createExpression(frameDmc, "a[0]"); + + wait.increment(); + fExpService.getFormattedExpressionValue(fExpService.getFormattedValueContext(exprDmc, + IFormattedValues.NATURAL_FORMAT), new DataRequestMonitor(fExpService + .getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else { + if (getData().getFormattedValue().equals("28")) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating natural format", null)); + } + } + } + }); + + wait.increment(); + fExpService.getFormattedExpressionValue(fExpService.getFormattedValueContext(exprDmc, + IFormattedValues.HEX_FORMAT), new DataRequestMonitor(fExpService + .getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else { + if (getData().getFormattedValue().equalsIgnoreCase("0x1c")) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating hex format", null)); + } + } + } + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + + assertTrue("ExprChangedEvent problem: expected 0, received " + getExprChangedCount(), + getExprChangedCount() == 0); + + } + + /** + * This test tries reads and listChildren during the same executor cycle, to + * make sure the internal MI commands are sequenced properly. + */ + @Test + public void testConcurrentReadChildren() throws Throwable { + // Next we test that we can retrieve children while reading the value + // and vice-versa + + SyncUtil.SyncRunToLocation("testConcurrent"); + MIStoppedEvent stoppedEvent = SyncUtil.SyncStep(StepType.STEP_OVER, 1); + + final IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + + final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); + + // First we get the expected value of the array pointer. + final IExpressionDMContext addrDmc = SyncUtil.SyncCreateExpression(frameDmc, "&a"); + + fExpService.getExecutor().submit(new Runnable() { + public void run() { + fExpService.getFormattedExpressionValue( + fExpService.getFormattedValueContext(addrDmc, IFormattedValues.NATURAL_FORMAT), + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + wait.setReturnInfo(getData()); + } + + wait.waitFinished(getStatus()); + } + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + + final String actualAddrStr = ((FormattedValueDMData) wait.getReturnInfo()).getFormattedValue(); + + wait.waitReset(); + + // Now perform the test + fExpService.getExecutor().submit(new Runnable() { + public void run() { + IExpressionDMContext exprDmc = fExpService.createExpression(frameDmc, "a"); + + wait.increment(); + fExpService.getFormattedExpressionValue(fExpService.getFormattedValueContext(exprDmc, + IFormattedValues.NATURAL_FORMAT), new DataRequestMonitor(fExpService + .getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else { + if (getData().getFormattedValue().equals(actualAddrStr)) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating natural format", null)); + } + } + } + }); + + wait.increment(); + fExpService.getSubExpressions(exprDmc, new DataRequestMonitor( + fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else { + IExpressionDMContext[] children = getData(); + int failedIndex = -1; + for (int i = 0; i < 2; i++) { + if (!children[i].getExpression().equals("a[" + i + "]")) { + failedIndex = i; + } + } + + if (failedIndex != -1) { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed getting child number: " + failedIndex, null)); + } else { + wait.waitFinished(); + } + } + } + }); + + // Use different format to avoid triggering the cache + wait.increment(); + fExpService.getFormattedExpressionValue(fExpService.getFormattedValueContext(exprDmc, + IFormattedValues.HEX_FORMAT), new DataRequestMonitor(fExpService + .getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else { + if (getData().getFormattedValue().equals(actualAddrStr)) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating hex format", null)); + } + } + } + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + + assertTrue("ExprChangedEvent problem: expected 0, received " + getExprChangedCount(), + getExprChangedCount() == 0); + } + + /** + * This test tries reads and getChildrenCount during the same executor + * cycle, to make sure the internal MI commands are sequenced properly. + */ + @Test + public void testConcurrentReadChildrenCount() throws Throwable { + // Next we test that we can retrieve children count while reading the + // value and vice-versa + + SyncUtil.SyncRunToLocation("testConcurrent"); + MIStoppedEvent stoppedEvent = SyncUtil.SyncStep(StepType.STEP_OVER, 1); + + final IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + + final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); + + // First we get the expected value of the array pointer. + final IExpressionDMContext addrDmc = SyncUtil.SyncCreateExpression(frameDmc, "&a"); + + fExpService.getExecutor().submit(new Runnable() { + public void run() { + fExpService.getFormattedExpressionValue( + fExpService.getFormattedValueContext(addrDmc, IFormattedValues.NATURAL_FORMAT), + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + wait.setReturnInfo(getData()); + } + + wait.waitFinished(getStatus()); + } + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + + final String actualAddrStr = ((FormattedValueDMData) wait.getReturnInfo()).getFormattedValue(); + + wait.waitReset(); + + fExpService.getExecutor().submit(new Runnable() { + public void run() { + wait.increment(); + IExpressionDMContext exprDmc = fExpService.createExpression(frameDmc, "a"); + + fExpService.getFormattedExpressionValue(fExpService.getFormattedValueContext(exprDmc, + IFormattedValues.NATURAL_FORMAT), new DataRequestMonitor(fExpService + .getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else { + if (getData().getFormattedValue().equals(actualAddrStr)) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating natural format", null)); + } + } + } + }); + + wait.increment(); + fExpService.getSubExpressionCount(exprDmc, new DataRequestMonitor(fExpService.getExecutor(), + null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else { + int count = getData(); + if (count != 2) { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed getting count for children. Got" + count + "instead of 2", null)); + } else { + wait.waitFinished(); + } + } + } + }); + + // Use different format to avoid triggering the cache + wait.increment(); + fExpService.getFormattedExpressionValue(fExpService.getFormattedValueContext(exprDmc, + IFormattedValues.HEX_FORMAT), new DataRequestMonitor(fExpService + .getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else { + if (getData().getFormattedValue().equals(actualAddrStr)) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating hex format", null)); + } + } + } + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + + assertTrue("ExprChangedEvent problem: expected 0, received " + getExprChangedCount(), + getExprChangedCount() == 0); + } + + /** + * This test tries reads and writes during the same executor cycle, to make + * sure the internal MI commands are sequenced properly. + */ + @Test + public void testConcurrentReadWrite() throws Throwable { + // Next we test that we can deal with a write request and read request + // at + // the same time and vice-versa + + SyncUtil.SyncRunToLocation("testConcurrent"); + MIStoppedEvent stoppedEvent = SyncUtil.SyncStep(StepType.STEP_OVER, 1); + + IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + + final IExpressionDMContext exprDmc = SyncUtil.SyncCreateExpression(frameDmc, "a[1]"); + + final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); + + fExpService.getExecutor().submit(new Runnable() { + public void run() { + + wait.increment(); + fExpService.getFormattedExpressionValue(fExpService.getFormattedValueContext(exprDmc, + IFormattedValues.NATURAL_FORMAT), new DataRequestMonitor(fExpService + .getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else { + if (getData().getFormattedValue().equals("32")) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating natural format, got " + getData().getFormattedValue() + + " instead of 32", null)); + } + } + } + }); + + wait.increment(); + fExpService.writeExpression(exprDmc, "56", IFormattedValues.NATURAL_FORMAT, new RequestMonitor( + fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else { + wait.waitFinished(); + } + } + }); + + // Use different format to avoid triggering the cache + wait.increment(); + fExpService.getFormattedExpressionValue(fExpService.getFormattedValueContext(exprDmc, + IFormattedValues.HEX_FORMAT), new DataRequestMonitor(fExpService + .getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else { + if (getData().getFormattedValue().equals("0x38")) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating hex format, got " + getData().getFormattedValue() + + " instead of 0x38", null)); + } + } + } + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + + assertTrue("ExprChangedEvent problem: expected 1, received " + getExprChangedCount(), + getExprChangedCount() == 1); + exprDmc.equals(getExprChangedContext()); + clearExprChangedData(); + } + + /** + * This test tries many different operations during the same executor cycle, + * to make sure the internal MI commands are sequenced properly. + */ + @Test + public void testConcurrentReadWriteChildren() throws Throwable { + // Finally, we go nuts and request two reads, while requesting + // a get children and get children count. + // Note that we don't request a write, because a write is allowed to + // go through at any time and we don't exactly know when it will + // change the value we are reading. + + SyncUtil.SyncRunToLocation("testConcurrent"); + MIStoppedEvent stoppedEvent = SyncUtil.SyncStep(StepType.STEP_OVER, 1); + + IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + + final IExpressionDMContext exprDmc = SyncUtil.SyncCreateExpression(frameDmc, "a[1]"); + + final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); + + fExpService.getExecutor().submit(new Runnable() { + public void run() { + + wait.increment(); + fExpService.getFormattedExpressionValue(fExpService.getFormattedValueContext(exprDmc, + IFormattedValues.NATURAL_FORMAT), new DataRequestMonitor(fExpService + .getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else { + if (getData().getFormattedValue().equals("32")) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating natural format, got " + getData().getFormattedValue() + + " instead of 32", null)); + } + } + } + }); + + wait.increment(); + fExpService.getFormattedExpressionValue(fExpService.getFormattedValueContext(exprDmc, + IFormattedValues.HEX_FORMAT), new DataRequestMonitor(fExpService + .getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else { + if (getData().getFormattedValue().equals("0x20")) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating hex format, got " + getData().getFormattedValue() + + " instead of 0x20", null)); + } + } + } + }); + + wait.increment(); + fExpService.getSubExpressionCount(exprDmc, new DataRequestMonitor(fExpService.getExecutor(), + null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else { + if (getData() != 0) { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed getting child count; expecting 0 got " + getData(), null)); + } else { + wait.waitFinished(); + } + } + } + }); + + wait.increment(); + fExpService.getSubExpressions(exprDmc, new DataRequestMonitor( + fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else { + if (getData().length != 0) { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed getting children; expecting 0 got " + getData().length, null)); + } else { + wait.waitFinished(); + } + } + } + }); + + // Must use a different format or else the cache will be triggered + wait.increment(); + fExpService.getFormattedExpressionValue(fExpService.getFormattedValueContext(exprDmc, + IFormattedValues.OCTAL_FORMAT), new DataRequestMonitor(fExpService + .getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else { + if (getData().getFormattedValue().equals("040")) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating hex format, got " + getData().getFormattedValue() + + " instead of 040", null)); + } + } + } + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + + assertTrue("ExprChangedEvent problem: expected 0, received " + getExprChangedCount(), + getExprChangedCount() == 0); + exprDmc.equals(getExprChangedContext()); + clearExprChangedData(); + } + + /** + * This test verifies that the ExpressionService caches the evaluation of an + * expression in a specific format. It verifies this by: 1- reading a + * variable 2- writing to that variable 3- reading the variable in a new + * format and seeing the new value 4- reading the variable in the same + * format as step 1 and seeing the old value cached Note that all above + * steps must be done within the same Runnable submitted to the executor. + * This allows the cache to be triggered before it is invalidated by a write + * command, since the write command will need an new executor cycle to send + * an MI command to the back-end + */ + @Test + public void testWriteCache() throws Throwable { + // Test the cache by changing a value but triggering a read before the + // write clears the cache + + SyncUtil.SyncRunToLocation("testConcurrent"); + MIStoppedEvent stoppedEvent = SyncUtil.SyncStep(StepType.STEP_OVER, 1); + + IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + + final IExpressionDMContext exprDmc = SyncUtil.SyncCreateExpression(frameDmc, "a[1]"); + + final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); + + fExpService.getExecutor().submit(new Runnable() { + public void run() { + + wait.increment(); + fExpService.getFormattedExpressionValue(fExpService.getFormattedValueContext(exprDmc, + IFormattedValues.NATURAL_FORMAT), new DataRequestMonitor(fExpService + .getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else { + if (getData().getFormattedValue().equals("32")) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating natural format, got " + getData().getFormattedValue() + + " instead of 32", null)); + } + } + } + }); + + wait.increment(); + fExpService.writeExpression(exprDmc, "56", IFormattedValues.NATURAL_FORMAT, new RequestMonitor( + fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else { + wait.waitFinished(); + } + } + }); + + // Must use a different format or else the cache will be + // triggered + // This will prove that the write has changed the backend + wait.increment(); + fExpService.getFormattedExpressionValue(fExpService.getFormattedValueContext(exprDmc, + IFormattedValues.OCTAL_FORMAT), new DataRequestMonitor(fExpService + .getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else { + if (getData().getFormattedValue().equals("070")) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating hex format, got " + getData().getFormattedValue() + + " instead of 070", null)); + } + } + } + }); + + // Test that the cache is triggered, giving us the old value + // This happens because we are calling this operation on the + // same executor run call. + // NOTE that this is not a problem, because the writeExpression + // will eventually + // reset the cache (we'll test this below). + wait.increment(); + fExpService.getFormattedExpressionValue(fExpService.getFormattedValueContext(exprDmc, + IFormattedValues.NATURAL_FORMAT), new DataRequestMonitor(fExpService + .getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else { + if (getData().getFormattedValue().equals("32")) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating natural format, got " + getData().getFormattedValue() + + " instead of 32", null)); + } + } + } + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + + // Now that we know the writeExpressions completed and the cache was + // reset, do a similar + // request as above to see that the cache has indeed been reset + wait.waitReset(); + fExpService.getExecutor().submit(new Runnable() { + public void run() { + + wait.increment(); + fExpService.getFormattedExpressionValue(fExpService.getFormattedValueContext(exprDmc, + IFormattedValues.NATURAL_FORMAT), new DataRequestMonitor(fExpService + .getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else { + if (getData().getFormattedValue().equals("56")) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating natural format, got " + getData().getFormattedValue() + + " instead of 56", null)); + } + } + } + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + + assertTrue("ExprChangedEvent problem: expected 1, received " + getExprChangedCount(), + getExprChangedCount() == 1); + exprDmc.equals(getExprChangedContext()); + clearExprChangedData(); + } + + /** + * Test that we can correctly retrieve the address and type size of an + * expression + */ + @Test + public void testExprAddress() throws Throwable { + + SyncUtil.SyncRunToLocation("testAddress"); + MIStoppedEvent stoppedEvent = SyncUtil.SyncStep(StepType.STEP_OVER, 2); + + IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + + final IExpressionDMContext exprDmc = SyncUtil.SyncCreateExpression(frameDmc, "a"); + + final IExpressionDMContext exprDmc2 = SyncUtil.SyncCreateExpression(frameDmc, "a_ptr"); + + final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); + + // First get the address of 'a' through 'a_ptr' + fExpService.getExecutor().submit(new Runnable() { + public void run() { + fExpService.getFormattedExpressionValue(fExpService.getFormattedValueContext(exprDmc2, + IFormattedValues.NATURAL_FORMAT), new DataRequestMonitor(fExpService + .getExecutor(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + wait.setReturnInfo(getData()); + } + + wait.waitFinished(getStatus()); + } + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + + String actualAddrStr = ((FormattedValueDMData) wait.getReturnInfo()).getFormattedValue(); + wait.waitReset(); + + // Now check the address through our getAddressData + checkAddressData(exprDmc, actualAddrStr, 4); + + assertTrue("ExprChangedEvent problem: expected 0, received " + getExprChangedCount(), + getExprChangedCount() == 0); + } + + + /** + * Test that we can correctly evaluate C expressions involving global + * variables. + * + * @return void + */ + // @Test + public void testGlobalVariables() throws Throwable { + + // Step to a stack level of 2 to be able to test differen stack frames + MIStoppedEvent stoppedEvent = SyncUtil.SyncRunToLocation("locals2"); + + // Create a map of expressions to expected values. + Map tests = new HashMap(); + + // Global variables + tests.put("gIntVar", new String[] { "0x21F", "01037", "1000011111", "543", "543" }); + tests.put("gDoubleVar", new String[] { "0x21F", "01037", "1000011111", "543", "543.54300000000001" }); + tests.put("gCharVar", new String[] { "0x67", "0147", "1100111", "103", "103 'g'" }); + tests.put("gBoolVar", new String[] { "0x0", "0", "0", "0", "false" }); + + tests.put("gIntArray[1]", new String[] { "0x28E", "01216", "1010001110", "654", "654" }); + tests.put("gDoubleArray[1]", new String[] { "0x28E", "01216", "1010001110", "654", "654.32100000000003" }); + tests.put("gCharArray[1]", new String[] { "0x64", "0144", "1100100", "100", "100 'd'" }); + tests.put("gBoolArray[1]", new String[] { "0x0", "0", "0", "0", "false" }); + + tests.put("*gIntPtr", new String[] { "0x21F", "01037", "1000011111", "543", "543" }); + tests.put("*gDoublePtr", new String[] { "0x21F", "01037", "1000011111", "543", "543.54300000000001" }); + tests.put("*gCharPtr", new String[] { "0x67", "0147", "1100111", "103", "103 'g'" }); + tests.put("*gBoolPtr", new String[] { "0x0", "0", "0", "0", "false" }); + + tests.put("gIntPtr2", new String[] { "0x8", "010", "1000", "8", "0x8" }); + tests.put("gDoublePtr2", new String[] { "0x5432", "052062", "101010000110010", "21554", "0x5432" }); + // GDB says a char* is out of bounds, but not the other pointers??? + // tests.put("gCharPtr2", new String[] { "0x4321", "041441", + // "100001100100001", "17185", "0x4321" }); + tests.put("gBoolPtr2", new String[] { "0x12ABCDEF", "02252746757", "10010101010111100110111101111", + "313249263", "0x12ABCDEF" }); + + // Try different stack frames + executeExpressionSubTests(tests, SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0)); + executeExpressionSubTests(tests, SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 1)); + executeExpressionSubTests(tests, SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 2)); + } + + /** + * This test verifies that the ExpressionService can handle having a + * variable with the same name in two different methods but at the same + * stack depth. + */ + @Test + public void testNamingSameDepth() throws Throwable { + SyncUtil.SyncRunToLocation("testName1"); + MIStoppedEvent stoppedEvent = SyncUtil.SyncStep(StepType.STEP_OVER, 1); + IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + + Map tests = new HashMap(); + tests.put("a", new String[] { "0x1", "01", "1", "1", "1" }); + executeExpressionSubTests(tests, frameDmc); + + SyncUtil.SyncRunToLocation("testName2"); + stoppedEvent = SyncUtil.SyncStep(StepType.STEP_INTO, 1); + frameDmc = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + tests = new HashMap(); + tests.put("a", new String[] { "0x2", "02", "10", "2", "2" }); + executeExpressionSubTests(tests, frameDmc); + + SyncUtil.SyncRunToLocation("testName1"); + stoppedEvent = SyncUtil.SyncStep(StepType.STEP_INTO, 1); + frameDmc = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + tests = new HashMap(); + tests.put("a", new String[] { "0x3", "03", "11", "3", "3" }); + executeExpressionSubTests(tests, frameDmc); + } + + /** + * This test verifies that the ExpressionService can handle having a + * variable with the same name in two methods that also have the same name + */ + @Test + public void testNamingSameMethod() throws Throwable { + SyncUtil.SyncRunToLocation("testSameName"); + MIStoppedEvent stoppedEvent = SyncUtil.SyncStep(StepType.STEP_INTO, 2); + IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + + Map tests = new HashMap(); + tests.put("a", new String[] { "0x1", "01", "1", "1", "1" }); + executeExpressionSubTests(tests, frameDmc); + + SyncUtil.SyncStep(StepType.STEP_RETURN); + stoppedEvent = SyncUtil.SyncStep(StepType.STEP_INTO, 2); + frameDmc = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + tests = new HashMap(); + tests.put("a", new String[] { "0x2", "02", "10", "2", "2" }); + executeExpressionSubTests(tests, frameDmc); + + SyncUtil.SyncStep(StepType.STEP_RETURN); + stoppedEvent = SyncUtil.SyncStep(StepType.STEP_INTO, 2); + frameDmc = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + tests = new HashMap(); + tests.put("a", new String[] { "0x3", "03", "11", "3", "3" }); + executeExpressionSubTests(tests, frameDmc); + } + + /** + * This test verifies that the ExpressionService can handle having a + * child variable with the same name in two methods that also have the same name + */ + @Test + public void testChildNamingSameMethod() throws Throwable { + SyncUtil.SyncRunToLocation("testSameName"); + MIStoppedEvent stoppedEvent = SyncUtil.SyncStep(StepType.STEP_INTO, 4); + final IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + + final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); + + fExpService.getExecutor().submit(new Runnable() { + public void run() { + + // First create the var object and all its children + IExpressionDMContext parentDmc = fExpService.createExpression(frameDmc, "z"); + + fExpService.getSubExpressions( + parentDmc, + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else if (getData().length != 2) { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed getting children; expecting 2 got " + getData().length, null)); + } else { + // now get the value of the child + final String valueStr = "1"; + final IExpressionDMContext child = getData()[0]; + fExpService.getFormattedExpressionValue( + fExpService.getFormattedValueContext(child, IFormattedValues.NATURAL_FORMAT), + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else if (getData().getFormattedValue().equals(valueStr)) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating " + child.getExpression() + ", got " + getData().getFormattedValue() + + " instead of " + valueStr, null)); + } + } + + }); + } + + + } + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + wait.waitReset(); + + SyncUtil.SyncStep(StepType.STEP_RETURN); + stoppedEvent = SyncUtil.SyncStep(StepType.STEP_INTO, 4); + final IFrameDMContext frameDmc2 = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + fExpService.getExecutor().submit(new Runnable() { + public void run() { + + // First create the var object and all its children + IExpressionDMContext parentDmc = fExpService.createExpression(frameDmc2, "z"); + + fExpService.getSubExpressions( + parentDmc, + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else if (getData().length != 2) { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed getting children; expecting 2 got " + getData().length, null)); + } else { + // now get the value of the child + final String valueStr = "2"; + final IExpressionDMContext child = getData()[0]; + fExpService.getFormattedExpressionValue( + fExpService.getFormattedValueContext(child, IFormattedValues.NATURAL_FORMAT), + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else if (getData().getFormattedValue().equals(valueStr)) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating " + child.getExpression() + ", got " + getData().getFormattedValue() + + " instead of " + valueStr, null)); + } + } + + }); + } + + + } + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + wait.waitReset(); + + SyncUtil.SyncStep(StepType.STEP_RETURN); + stoppedEvent = SyncUtil.SyncStep(StepType.STEP_INTO, 4); + final IFrameDMContext frameDmc3 = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + fExpService.getExecutor().submit(new Runnable() { + public void run() { + + // First create the var object and all its children + IExpressionDMContext parentDmc = fExpService.createExpression(frameDmc3, "z"); + + fExpService.getSubExpressions( + parentDmc, + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else if (getData().length != 2) { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed getting children; expecting 2 got " + getData().length, null)); + } else { + // now get the value of the child + final String valueStr = "3"; + final IExpressionDMContext child = getData()[0]; + fExpService.getFormattedExpressionValue( + fExpService.getFormattedValueContext(child, IFormattedValues.NATURAL_FORMAT), + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else if (getData().getFormattedValue().equals(valueStr)) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating " + child.getExpression() + ", got " + getData().getFormattedValue() + + " instead of " + valueStr, null)); + } + } + + }); + } + + + } + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + wait.waitReset(); + + } + + /** + * This test verifies that the ExpressionService properly updates + * children variables, when we do not update the parent explicitly + */ + @Test + public void testUpdatingChildren() throws Throwable { + SyncUtil.SyncRunToLocation("testUpdateChildren"); + MIStoppedEvent stoppedEvent = SyncUtil.SyncStep(StepType.STEP_OVER, 2); + final IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + doUpdateTest(frameDmc, 0); + + // Re-run the test to test out-of-scope update again + SyncUtil.SyncStep(StepType.STEP_RETURN); + stoppedEvent = SyncUtil.SyncStep(StepType.STEP_INTO, 3); + final IFrameDMContext frameDmc2 = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + doUpdateTest(frameDmc2, 100); + + // Re-run the test within a different method test out-of-scope updates + SyncUtil.SyncStep(StepType.STEP_RETURN); + stoppedEvent = SyncUtil.SyncStep(StepType.STEP_INTO, 3); + final IFrameDMContext frameDmc3 = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + doUpdateTest(frameDmc3, 200); + + } + + + public void doUpdateTest(final IFrameDMContext frameDmc, final int baseValue) throws Throwable { + final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); + + fExpService.getExecutor().submit(new Runnable() { + public void run() { + + // First create the var object and all its children + IExpressionDMContext parentDmc = fExpService.createExpression(frameDmc, "a"); + + fExpService.getSubExpressions( + parentDmc, + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else if (getData().length != 1) { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed getting children; expecting 1 got " + getData().length, null)); + } else { + // Now list the children of this child + fExpService.getSubExpressions( + getData()[0], + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + final IExpressionDMContext[] childDmcs = getData(); + + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else if (childDmcs.length != 2) { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed getting children; expecting 2 got " + childDmcs.length, null)); + } else { + // now get the value of the two children + for (int i =0; i<2; i++) { + final String valueStr = Integer.toString(baseValue + i + 10); + final int finali = i; + + wait.increment(); + fExpService.getFormattedExpressionValue( + fExpService.getFormattedValueContext(childDmcs[i], IFormattedValues.NATURAL_FORMAT), + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else if (getData().getFormattedValue().equals(valueStr)) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating " + childDmcs[finali].getExpression() + ", got " + getData().getFormattedValue() + + " instead of " + valueStr, null)); + } + } + + }); + } + } + } + }); + } + + + } + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + wait.waitReset(); + + // Now step to change the value of a.z.x and a.z.y and verify the changed values. + // This will confirm that the parent "a" will have been properly updated + // It is a better test to do it for two children because it tests concurrent update requests + MIStoppedEvent stoppedEvent = SyncUtil.SyncStep(StepType.STEP_OVER, 2); + final IFrameDMContext frameDmc2 = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + + fExpService.getExecutor().submit(new Runnable() { + public void run() { + + // First create the var object and all its children + IExpressionDMContext parentDmc = fExpService.createExpression(frameDmc2, "a"); + + fExpService.getSubExpressions( + parentDmc, + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else if (getData().length != 1) { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed getting children; expecting 1 got " + getData().length, null)); + } else { + // Now list the children of this child + fExpService.getSubExpressions( + getData()[0], + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + final IExpressionDMContext[] childDmcs = getData(); + + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else if (childDmcs.length != 2) { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed getting children; expecting 2 got " + childDmcs.length, null)); + } else { + // now get the value of the two children + for (int i =0; i<2; i++) { + final String valueStr = Integer.toString(baseValue + i + 20); + final int finali = i; + + wait.increment(); + fExpService.getFormattedExpressionValue( + fExpService.getFormattedValueContext(childDmcs[i], IFormattedValues.NATURAL_FORMAT), + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else if (getData().getFormattedValue().equals(valueStr)) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating " + childDmcs[finali].getExpression() + ", got " + getData().getFormattedValue() + + " instead of " + valueStr, null)); + } + } + + }); + } + } + } + }); + } + + + } + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + wait.waitReset(); + } + + /** + * This test creates a variable object with children (not an array) and then gets these children + * to be deleted because of a large number of other variable objects being created. + * We then check that the expression service can handle a request for one of those deleted children, + * which has a complex path. + */ + @Test + public void testDeleteChildren() throws Throwable { + SyncUtil.SyncRunToLocation("testDeleteChildren"); + MIStoppedEvent stoppedEvent = SyncUtil.SyncStep(StepType.STEP_OVER, 1); + final IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + + final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); + + fExpService.getExecutor().submit(new Runnable() { + public void run() { + + // First create the var object and all its children + IExpressionDMContext parentDmc = fExpService.createExpression(frameDmc, "f"); + + fExpService.getSubExpressions( + parentDmc, + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else { + if (getData().length != 5) { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed getting children; expecting 5 got " + getData().length, null)); + } else { + String childStr = "((bar) f)"; + if (!getData()[0].getExpression().equals(childStr)) { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Got child " + getData()[0].getExpression() + " instead of " + childStr, null)); + } else { + // Now list the children of the first element + fExpService.getSubExpressions( + getData()[0], + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else { + if (getData().length != 2) { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed getting children; expecting 2 got " + getData().length, null)); + } else { + String childStr = "((((bar) f)).d)"; + if (!getData()[0].getExpression().equals(childStr)) { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Got child " + getData()[0].getExpression() + " instead of " + childStr, null)); + } else { + wait.setReturnInfo(getData()[0]); + wait.waitFinished(); + } + } + } + } + }); + } + } + } + } + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + final IExpressionDMContext deletedChildDmc = (IExpressionDMContext)wait.getReturnInfo(); + + wait.waitReset(); + + fExpService.getExecutor().submit(new Runnable() { + public void run() { + + // Now create more than 1000 expressions to trigger the deletion of the children + // that were created above + for (int i=0; i<1100; i++) { + IExpressionDMContext dmc = fExpService.createExpression(frameDmc, "a[" + i + "]"); + + wait.increment(); + fExpService.getExpressionData( + dmc, + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else { + wait.waitFinished(); + } + } + }); + } + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + wait.waitReset(); + + fExpService.getExecutor().submit(new Runnable() { + public void run() { + + // Evaluate the expression of a child that we know is deleted to make sure + // the expression service can handle that + fExpService.getExpressionData( + deletedChildDmc, + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else { + wait.waitFinished(); + } + } + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + wait.waitReset(); + + } + + /** + * GDB 6.7 has a bug which will cause var-update not to show + * the new value of 'a' if we switch the format to binary, + * since binary of 3 is 11 which is the same as the old value + * in natural format. Our expression service should work around this. + * + * int main() { + * int a = 11; + * a = 3; + * return 0; + * } + */ + @Test + public void testUpdateGDBBug() throws Throwable { + SyncUtil.SyncRunToLocation("testUpdateGDBBug"); + MIStoppedEvent stoppedEvent = SyncUtil.SyncStep(StepType.STEP_OVER, 1); + final IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + + final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); + + fExpService.getExecutor().submit(new Runnable() { + public void run() { + // First create the var object and all its children + IExpressionDMContext exprDmc = fExpService.createExpression(frameDmc, "a"); + + // This call will create the variable object in natural format and then change + // it to binary to fetch the value + fExpService.getFormattedExpressionValue( + fExpService.getFormattedValueContext(exprDmc, IFormattedValues.BINARY_FORMAT), + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else { + if (getData().getFormattedValue().equals("1011")) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating binary format, expected 1011 but got " + + getData().getFormattedValue(), null)); + } + } + } + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + wait.waitReset(); + + // Now step to change the value of "a" and ask for it again + stoppedEvent = SyncUtil.SyncStep(StepType.STEP_OVER, 1); + final IFrameDMContext frameDmc2 = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + + fExpService.getExecutor().submit(new Runnable() { + public void run() { + // First create the var object and all its children + IExpressionDMContext exprDmc = fExpService.createExpression(frameDmc2, "a"); + + // This call will create the variable object in natural format and then change + // it to binary to fetch the value + fExpService.getFormattedExpressionValue( + fExpService.getFormattedValueContext(exprDmc, IFormattedValues.BINARY_FORMAT), + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else { + if (getData().getFormattedValue().equals("11")) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating binary format, expected 11 but got " + + getData().getFormattedValue(), null)); + } + } + } + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + wait.waitReset(); + } + + /** + * var-update will not show a change if eval-expression is the same + * in the current format. This is a problem for us because we don't + * know if another format changed: + * + * int main() { + * double a = 1.99; + * a = 1.11; + * } + * + * If a is displayed in anything but natural, both values of a are the same + * and we won't know it changed in the natural format. + * + * The test below is in case GDB fixes var-update to keep track of the last + * printed value through eval-expression. Until they do that, we do not have + * a problem because of our caching: where, if we change formats since the last + * var-update, it is impossible for us to set the format back + * to the one of the last -var-update, since we already have that value in our cache. + * So, the -var-update will show a change because of the new current format. + * But if GDB has eval-expression reset their stored printed_value, this test + * will fail and we'll know we have to fix something. + */ + @Test + public void testUpdateIssue() throws Throwable { + SyncUtil.SyncRunToLocation("testUpdateIssue"); + MIStoppedEvent stoppedEvent = SyncUtil.SyncStep(StepType.STEP_OVER, 1); + final IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + + final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); + + fExpService.getExecutor().submit(new Runnable() { + public void run() { + // First create the var object and all its children + IExpressionDMContext exprDmc = fExpService.createExpression(frameDmc, "a"); + + // check that we have the proper value + wait.increment(); + fExpService.getFormattedExpressionValue( + fExpService.getFormattedValueContext(exprDmc, IFormattedValues.NATURAL_FORMAT), + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else { + if (getData().getFormattedValue().equals("1.99")) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating a, expected 1.99 but got " + + getData().getFormattedValue(), null)); + } + } + } + }); + + // ask for hex to set the format to hex + wait.increment(); + fExpService.getFormattedExpressionValue( + fExpService.getFormattedValueContext(exprDmc, IFormattedValues.HEX_FORMAT), + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else { + if (getData().getFormattedValue().equals("0x1")) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating a, expected 0x1 but got " + + getData().getFormattedValue(), null)); + } + } + } + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + wait.waitReset(); + + // Now step to change the value of "a" and ask for it again but in the natural format + stoppedEvent = SyncUtil.SyncStep(StepType.STEP_OVER, 1); + final IFrameDMContext frameDmc2 = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + + fExpService.getExecutor().submit(new Runnable() { + public void run() { + // First create the var object and all its children + IExpressionDMContext exprDmc = fExpService.createExpression(frameDmc2, "a"); + + // trigger the var-update in the last format (hex) + // then request the actual value in natural which should not be taken from the cache + wait.increment(); + fExpService.getFormattedExpressionValue( + fExpService.getFormattedValueContext(exprDmc, IFormattedValues.NATURAL_FORMAT), + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else { + if (getData().getFormattedValue().equals("1.22")) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating natural format, expected 1.22 but got " + + getData().getFormattedValue(), null)); + } + } + } + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + wait.waitReset(); + } + + /** + * var-update will not show a change if eval-expression is the same + * in the current format. This is a problem for us because we don't + * know if another format changed: + * + * int main() { + * struct { + * double d; + * } z; + * + * z.d = 1.0; + * z.d = 1.22; + * } + * + * If a is displayed in anything but natural, both values of a are the same + * and we won't know it changed in the natural format. + * This test uses a child to increase the value of the test. + * Also, it avoids the cache saving us since we start with the 1.0 value + * which is the same in natural and decimal + */ + @Test + public void testUpdateIssue2() throws Throwable { + SyncUtil.SyncRunToLocation("testUpdateIssue2"); + MIStoppedEvent stoppedEvent = SyncUtil.SyncStep(StepType.STEP_OVER, 1); + final IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + + final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); + + fExpService.getExecutor().submit(new Runnable() { + public void run() { + + IExpressionDMContext parentDmc = fExpService.createExpression(frameDmc, "z"); + + fExpService.getSubExpressions( + parentDmc, + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else if (getData().length != 1) { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed getting children; expecting 1 got " + getData().length, null)); + } else { + // check that we have the proper value + // This will cache the value 1 in the natural format cache + final String valueStr = "1"; + globalExpressionCtx1 = getData()[0]; + + wait.increment(); + fExpService.getFormattedExpressionValue( + fExpService.getFormattedValueContext(globalExpressionCtx1, IFormattedValues.NATURAL_FORMAT), + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else if (getData().getFormattedValue().equals(valueStr)) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating " + globalExpressionCtx1.getExpression() + ", got " + getData().getFormattedValue() + + " instead of " + valueStr, null)); + } + } + }); + + // ask for decimal to set the format to decimal + wait.increment(); + fExpService.getFormattedExpressionValue( + fExpService.getFormattedValueContext(globalExpressionCtx1, IFormattedValues.DECIMAL_FORMAT), + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else { + if (getData().getFormattedValue().equals(valueStr)) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating " + globalExpressionCtx1.getExpression() + ", got " + getData().getFormattedValue() + + " instead of " + valueStr, null)); + } + } + } + }); + + } + } + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + wait.waitReset(); + + // Now step to change the value of "a" in natural but it remains the same in decimal + SyncUtil.SyncStep(StepType.STEP_OVER, 1); + + fExpService.getExecutor().submit(new Runnable() { + public void run() { + + // trigger the var-update in the last format (decimal) + // then request the actual value in natural which should not be taken from the cache + wait.increment(); + fExpService.getFormattedExpressionValue( + fExpService.getFormattedValueContext(globalExpressionCtx1, IFormattedValues.NATURAL_FORMAT), + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else { + if (getData().getFormattedValue().equals("1.22")) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating natural format, expected 1.22 but got " + + getData().getFormattedValue(), null)); + } + } + } + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + wait.waitReset(); + } + + /** + * This test verifies the state handling of a child variable object + * to make sure that our locking scheme works even though we must deal + * with an update call, internally + */ + @Test + public void testConcurrentReadAndUpdateChild() throws Throwable { + SyncUtil.SyncRunToLocation("testConcurrentReadAndUpdateChild"); + MIStoppedEvent stoppedEvent = SyncUtil.SyncStep(StepType.STEP_OVER, 1); + final IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + + final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); + + // Ask for one value to create the var object + fExpService.getExecutor().submit(new Runnable() { + public void run() { + // First create the var object and all its children + IExpressionDMContext parentDmc = fExpService.createExpression(frameDmc, "z"); + + wait.increment(); + fExpService.getSubExpressions( + parentDmc, + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else if (getData().length != 1) { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed getting children; expecting 1 got " + getData().length, null)); + } else { + // now get the value of the child + final String valueStr = "01"; + globalExpressionCtx1 = getData()[0]; + fExpService.getFormattedExpressionValue( + fExpService.getFormattedValueContext(globalExpressionCtx1, IFormattedValues.OCTAL_FORMAT), + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else if (getData().getFormattedValue().equals(valueStr)) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating " + globalExpressionCtx1.getExpression() + ", got " + getData().getFormattedValue() + + " instead of " + valueStr, null)); + } + } + }); + } + } + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + wait.waitReset(); + + // Now do two reads in two different formats + // We need to make sure that the locking properly works although we are calling + // the internal update method, which does affect the state of the object + fExpService.getExecutor().submit(new Runnable() { + public void run() { + wait.increment(); + fExpService.getFormattedExpressionValue( + fExpService.getFormattedValueContext(globalExpressionCtx1, IFormattedValues.BINARY_FORMAT), + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + final String valueStr = "1"; + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else if (getData().getFormattedValue().equals(valueStr)) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating " + globalExpressionCtx1.getExpression() + ", got " + getData().getFormattedValue() + + " instead of " + valueStr, null)); + } + } + }); + + wait.increment(); + fExpService.getFormattedExpressionValue( + fExpService.getFormattedValueContext(globalExpressionCtx1, IFormattedValues.HEX_FORMAT), + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + final String valueStr = "0x1"; + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else if (getData().getFormattedValue().equals(valueStr)) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating " + globalExpressionCtx1.getExpression() + ", got " + getData().getFormattedValue() + + " instead of " + valueStr, null)); + } + } + + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + wait.waitReset(); + } + + /** + * This test verifies some of the logic of dealing with out-of-scope variables. + * This particular scenario is that we create a parent with a child and then + * have them go out of scope. Then we request the child which will update the parent + * and mark it as out-of-scope and recreate the child. The parent is not re-created. + * We then ask twice for the parent which is already known to be out-of-scope and we need + * to make sure that the parent is re-created once and only once. + * We had a bug where we would enter an infinite loop in this case. + */ + @Test(timeout=5000) + public void testConcurrentUpdateOutOfScopeChildThenParent() throws Throwable { + SyncUtil.SyncRunToLocation("testConcurrentUpdateOutOfScopeChildThenParent"); + MIStoppedEvent stoppedEvent = SyncUtil.SyncStep(StepType.STEP_INTO, 2); + + final IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + + final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); + + fExpService.getExecutor().submit(new Runnable() { + public void run() { + // First create the var object and its child + globalExpressionCtx1 = fExpService.createExpression(frameDmc, "z"); + + wait.increment(); + fExpService.getSubExpressions( + globalExpressionCtx1, + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else if (getData().length != 1) { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed getting children; expecting 1 got " + getData().length, null)); + } else { + // now get the value of the child + final String valueStr = "1"; + globalExpressionCtx2 = getData()[0]; + fExpService.getFormattedExpressionValue( + fExpService.getFormattedValueContext(globalExpressionCtx2, IFormattedValues.NATURAL_FORMAT), + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else if (getData().getFormattedValue().equals(valueStr)) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating " + globalExpressionCtx2.getExpression() + ", got " + getData().getFormattedValue() + + " instead of " + valueStr, null)); + } + } + }); + } + } + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + wait.waitReset(); + + SyncUtil.SyncStep(StepType.STEP_RETURN); + stoppedEvent = SyncUtil.SyncStep(StepType.STEP_INTO, 2); + + // Now step to another method to make the previous variable objects out-of-scope + // then first request the child and then the parent. We want to test this order + fExpService.getExecutor().submit(new Runnable() { + public void run() { + wait.increment(); + fExpService.getFormattedExpressionValue( + fExpService.getFormattedValueContext(globalExpressionCtx2, IFormattedValues.NATURAL_FORMAT), + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + final String valueStr = "2"; + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else if (getData().getFormattedValue().equals(valueStr)) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating " + globalExpressionCtx2.getExpression() + ", got " + getData().getFormattedValue() + + " instead of " + valueStr, null)); + } + } + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + wait.waitReset(); + + fExpService.getExecutor().submit(new Runnable() { + public void run() { + wait.increment(); + fExpService.getFormattedExpressionValue( + fExpService.getFormattedValueContext(globalExpressionCtx1, IFormattedValues.NATURAL_FORMAT), + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + final String valueStr = "{...}"; + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else if (getData().getFormattedValue().equals(valueStr)) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating " + globalExpressionCtx1.getExpression() + ", got " + getData().getFormattedValue() + + " instead of " + valueStr, null)); + } + } + }); + + // Ask a second time but in a different format, to avoid the cache + wait.increment(); + fExpService.getFormattedExpressionValue( + fExpService.getFormattedValueContext(globalExpressionCtx1, IFormattedValues.DECIMAL_FORMAT), + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + final String valueStr = "{...}"; + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else if (getData().getFormattedValue().equals(valueStr)) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating " + globalExpressionCtx1.getExpression() + ", got " + getData().getFormattedValue() + + " instead of " + valueStr, null)); + } + } + }); + + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + wait.waitReset(); + + //TODO although this test passes, the variable z is created twice, without being + // deleted in GDB. We should fix this + } + + /** + * This test verifies that we properly update a pointer and its child since they can both + * change and be reported by var-update + */ + @Test + public void testUpdateOfPointer() throws Throwable { + SyncUtil.SyncRunToLocation("testUpdateOfPointer"); + MIStoppedEvent stoppedEvent = SyncUtil.SyncStep(StepType.STEP_OVER, 3); + final IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + + final String firstValue = "1"; + final String secondValue = "2"; + final String thirdValue = "3"; + + final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); + + fExpService.getExecutor().submit(new Runnable() { + public void run() { + + IExpressionDMContext parentDmc = fExpService.createExpression(frameDmc, "z"); + + fExpService.getSubExpressions( + parentDmc, + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else if (getData().length != 2) { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed getting children; expecting 2 got " + getData().length, null)); + } else { + // check that we have the proper value for both children + globalExpressionCtx1 = getData()[0]; + globalExpressionCtx2 = getData()[1]; + + // Get the value of the first child + wait.increment(); + fExpService.getFormattedExpressionValue( + fExpService.getFormattedValueContext(globalExpressionCtx1, IFormattedValues.NATURAL_FORMAT), + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else if (getData().getFormattedValue().equals(firstValue)) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating " + globalExpressionCtx1.getExpression() + ", got " + getData().getFormattedValue() + + " instead of " + firstValue, null)); + } + } + }); + + // Get the value of the second child + wait.increment(); + fExpService.getFormattedExpressionValue( + fExpService.getFormattedValueContext(globalExpressionCtx2, IFormattedValues.NATURAL_FORMAT), + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else { + wait.setReturnInfo(getData().getFormattedValue()); + wait.waitFinished(); + } + } + }); + } + } + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + final String pointerValue = (String)wait.getReturnInfo(); + wait.waitReset(); + + fExpService.getExecutor().submit(new Runnable() { + public void run() { + + // also get the child of the pointer + fExpService.getSubExpressions( + globalExpressionCtx2, + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else if (getData().length != 1) { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed getting children; expecting 1 got " + getData().length, null)); + } else { + // Get the value of the child of the pointer + globalExpressionCtx2 = getData()[0]; + fExpService.getFormattedExpressionValue( + fExpService.getFormattedValueContext(globalExpressionCtx2, IFormattedValues.NATURAL_FORMAT), + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else if (getData().getFormattedValue().equals(firstValue)) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating " + globalExpressionCtx2.getExpression() + ", got " + getData().getFormattedValue() + + " instead of " + firstValue, null)); + } + } + }); + } + } + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + wait.waitReset(); + + // Now step to change the values of all the children + stoppedEvent = SyncUtil.SyncStep(StepType.STEP_OVER, 2); + final IFrameDMContext frameDmc2 = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + + fExpService.getExecutor().submit(new Runnable() { + public void run() { + + IExpressionDMContext parentDmc = fExpService.createExpression(frameDmc2, "z"); + + fExpService.getSubExpressions( + parentDmc, + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else if (getData().length != 2) { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed getting children; expecting 2 got " + getData().length, null)); + } else { + // check that we have the proper value for both children + globalExpressionCtx1 = getData()[0]; + globalExpressionCtx2 = getData()[1]; + + // Get the value of the first child + wait.increment(); + fExpService.getFormattedExpressionValue( + fExpService.getFormattedValueContext(globalExpressionCtx1, IFormattedValues.NATURAL_FORMAT), + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else if (getData().getFormattedValue().equals(secondValue)) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating " + globalExpressionCtx1.getExpression() + ", got " + getData().getFormattedValue() + + " instead of " + secondValue, null)); + } + } + }); + + // Get the value of the second child + wait.increment(); + fExpService.getFormattedExpressionValue( + fExpService.getFormattedValueContext(globalExpressionCtx2, IFormattedValues.NATURAL_FORMAT), + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else if (!getData().getFormattedValue().equals(pointerValue)) { + // The value should have changed + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating " + globalExpressionCtx2.getExpression() + ", got " + getData().getFormattedValue() + + " instead of some other value", null)); + } + } + }); + } + } + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + wait.waitReset(); + + fExpService.getExecutor().submit(new Runnable() { + public void run() { + + // also get the child of the pointer + fExpService.getSubExpressions( + globalExpressionCtx2, + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else if (getData().length != 1) { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed getting children; expecting 1 got " + getData().length, null)); + } else { + // Get the value of the child of the pointer + globalExpressionCtx2 = getData()[0]; + fExpService.getFormattedExpressionValue( + fExpService.getFormattedValueContext(globalExpressionCtx2, IFormattedValues.NATURAL_FORMAT), + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else if (getData().getFormattedValue().equals(thirdValue)) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed evaluating " + globalExpressionCtx2.getExpression() + ", got " + getData().getFormattedValue() + + " instead of " + thirdValue, null)); + } + } + }); + } + } + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + wait.waitReset(); + } + + /** + * This test verifies that we properly return if we can write to different expressions + */ + @Test + public void testCanWrite() throws Throwable { + MIStoppedEvent stoppedEvent = SyncUtil.SyncRunToLocation("testCanWrite"); + final IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + + final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); + + fExpService.getExecutor().submit(new Runnable() { + public void run() { + + final int exprCount = 5; + final IExpressionDMContext dmcs[] = new IExpressionDMContext[exprCount]; + final boolean expectedValues[] = new boolean[exprCount]; + + int exprIndex = 0; + dmcs[exprIndex] = fExpService.createExpression(frameDmc, "a"); + expectedValues[exprIndex] = true; + exprIndex++; + dmcs[exprIndex] = fExpService.createExpression(frameDmc, "b"); + expectedValues[exprIndex] = true; + exprIndex++; + dmcs[exprIndex] = fExpService.createExpression(frameDmc, "c"); + expectedValues[exprIndex] = false; + exprIndex++; + dmcs[exprIndex] = fExpService.createExpression(frameDmc, "d"); + expectedValues[exprIndex] = false; + exprIndex++; + dmcs[exprIndex] = fExpService.createExpression(frameDmc, "d[1]"); + expectedValues[exprIndex] = true; + exprIndex++; + + for (int index = 0; index < exprCount; index++) { + final int finalIndex = index; + wait.increment(); + fExpService.canWriteExpression( + dmcs[finalIndex], + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else if (getData() == expectedValues[finalIndex]) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed establishing proper canWrite for " + dmcs[finalIndex].getExpression() + + ", got " + getData() + " instead of " + expectedValues[finalIndex], null)); + } + + + } + }); + } + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + wait.waitReset(); + } + + /** + * This test verifies that we properly return if we can write to an expression + * that is an L-Value or a Constant + */ + @Ignore("Only works in versions later than GDB6.7") + @Test + public void testCanWriteLValue() throws Throwable { + MIStoppedEvent stoppedEvent = SyncUtil.SyncRunToLocation("testCanWrite"); // Re-use test + final IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + + final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); + + fExpService.getExecutor().submit(new Runnable() { + public void run() { + + final int exprCount = 2; + final IExpressionDMContext dmcs[] = new IExpressionDMContext[exprCount]; + final boolean expectedValues[] = new boolean[exprCount]; + + int exprIndex = 0; + dmcs[exprIndex] = fExpService.createExpression(frameDmc, "&a"); + expectedValues[exprIndex] = false; + exprIndex++; + dmcs[exprIndex] = fExpService.createExpression(frameDmc, "1"); + expectedValues[exprIndex] = false; + exprIndex++; + + for (int index = 0; index < exprCount; index++) { + final int finalIndex = index; + wait.increment(); + fExpService.canWriteExpression( + dmcs[finalIndex], + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else if (getData() == expectedValues[finalIndex]) { + wait.waitFinished(); + } else { + wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Failed establishing proper canWrite for " + dmcs[finalIndex].getExpression() + + ", got " + getData() + " instead of " + expectedValues[finalIndex], null)); + } + + + } + }); + } + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + wait.waitReset(); + } + + /** + * Executes a group of sub-tests. + * + * @param tests: + * A Map in which the key is an expression to evaluate and the + * value is an array of expected values, one for each of the + * formats supported by the Expressions service (hex, octal, + * binary, decimal, natural). + */ + private void executeExpressionSubTests(final Map tests, IDMContext dmc) + throws Throwable + { + + // Now evaluate each of the above expressions and compare the actual + // value against + // the expected value. + for (final String expressionToEvaluate : tests.keySet()) { + + // Get an IExpressionDMContext object representing the expression to + // be evaluated. + final IExpressionDMContext exprDMC = SyncUtil.SyncCreateExpression(dmc, expressionToEvaluate); + + final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); + + // Get the list of available format IDs for this expression and for + // each one, + // get the value of the expression + fExpService.getExecutor().submit(new Runnable() { + public void run() { + fExpService.getAvailableFormats(exprDMC, new DataRequestMonitor( + fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else { + final String[] formatIds = getData(); + + // Now run the current sub-test using each of + // the formats available for the type of + // the expression in the sub-test. + + for (final String formatId : formatIds) { + // Get a FormattedValueCMContext object for + // the expression-formatID pair. + final FormattedValueDMContext valueDmc = fExpService.getFormattedValueContext( + exprDMC, formatId); + + // Increment the number of completed + // requests to wait for, since we will send + // multiple concurrent requests + wait.increment(); + + // Evaluate the expression represented by + // the FormattedValueDMContext object + // This actually evaluates the expression. + fExpService.getFormattedExpressionValue(valueDmc, + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + wait.waitFinished(getStatus()); + } else { + + // Get the + // FormattedValueDMData + // object from the waiter. + FormattedValueDMData exprValueDMData = getData(); + + final String[] expectedValues = tests.get(expressionToEvaluate); + + // Check the value of the + // expression for + // correctness. + String actualValue = exprValueDMData.getFormattedValue(); + String expectedValue; + + if (formatId.equals(IFormattedValues.HEX_FORMAT)) + expectedValue = expectedValues[0]; + else if (formatId.equals(IFormattedValues.OCTAL_FORMAT)) + expectedValue = expectedValues[1]; + else if (formatId.equals(IFormattedValues.BINARY_FORMAT)) + expectedValue = expectedValues[2]; + else if (formatId.equals(IFormattedValues.DECIMAL_FORMAT)) + expectedValue = expectedValues[3]; + else if (formatId.equals(IFormattedValues.NATURAL_FORMAT)) + expectedValue = expectedValues[4]; + else + expectedValue = "[Unrecognized format ID: " + formatId + "]"; + + if (actualValue.equalsIgnoreCase(expectedValue)) { + wait.waitFinished(); + } else { + String errorMsg = "Failed to correctly evalutate '" + + expressionToEvaluate + "': expected '" + expectedValue + + "', got '" + actualValue + "'"; + wait.waitFinished(new Status(IStatus.ERROR, + TestsPlugin.PLUGIN_ID, errorMsg, null)); + } + } + } + }); + } + } + } + }); + } + }); + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + assertTrue("ExprChangedEvent problem: expected 0, received " + getExprChangedCount(), + getExprChangedCount() == 0); + } + } + + private boolean addressesEqual(IExpressionDMAddress addrToTest, String addrStr, int size) { + IAddress addr; + if (addrStr.length() <= 10) { + addr = new Addr32(addrStr); + } else { + addr = new Addr64(addrStr); + } + return addrToTest.getAddress().equals(addr) && addrToTest.getSize() == size; + } + + private void checkAddressData(final IExpressionDMContext dmc, String actualAddrStr, int actualAddrSize) throws Throwable { + + final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); + + fExpService.getExecutor().submit(new Runnable() { + public void run() { + fExpService.getExpressionAddressData(dmc, new DataRequestMonitor(fExpService + .getExecutor(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + wait.setReturnInfo(getData()); + } + + wait.waitFinished(getStatus()); + } + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + + IExpressionDMAddress addr = (IExpressionDMAddress)wait.getReturnInfo(); + + assertTrue("Unable to get address", addr != null); + assertTrue("Received wrong address of " + addr.toString() + " instead of (" + + actualAddrStr + ", " + actualAddrSize + ")", + addressesEqual(addr, actualAddrStr, actualAddrSize)); + } + + private void doTestChildren(MIStoppedEvent stoppedEvent) throws Throwable { + + final IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 0); + + final IExpressionDMContext exprDMC = SyncUtil.SyncCreateExpression(frameDmc, "f"); + + IExpressionDMContext[] children = + getChildren(exprDMC, new String[] {"bar", "bar2", "a", "b", "c"}); + + // f.bar + IExpressionDMContext[] children1 = + getChildren(children[0], new String[] {"d", "e"}); + // f.bar.d + getChildren(children1[0], new String[0]); + // f.bar.e + IExpressionDMContext[] children2 = + getChildren(children1[1], new String[] {"e[0]", "e[1]"}); + // f.bar.e[0] + getChildren(children2[0], new String[0]); + // f.bar.e[1] + getChildren(children2[1], new String[0]); + + // f.bar2 + children1 = getChildren(children[1], new String[] {"f", "g"}); + // f.bar2.f + getChildren(children1[0], new String[0]); + // f.bar2.g + children2 = getChildren(children1[1], new String[] {"g[0]", "g[1]"}); + // f.bar2.g[0] + getChildren(children2[0], new String[0]); + // f.bar2.g[1] + getChildren(children2[1], new String[0]); + + // f.a + children1 = getChildren(children[2], new String[] {"a[0]", "a[1]"}); + // f.a[0] + getChildren(children1[0], new String[0]); + // f.a[1] + getChildren(children1[1], new String[0]); + + // f.b + children1 = getChildren(children[3], new String[] {"d", "e"}); + // f.b.d + getChildren(children1[0], new String[0]); + // f.b.e + children2 = getChildren(children1[1], new String[] {"e[0]", "e[1]"}); + // f.b.e[0] + getChildren(children2[0], new String[0]); + // f.b.e[1] + getChildren(children2[1], new String[0]); + + // f.c + getChildren(children[4], new String[0]); + + assertTrue("ExprChangedEvent problem: expected 0, received " + getExprChangedCount(), + getExprChangedCount() == 0); + } + + private IExpressionDMContext[] getChildren( + final IExpressionDMContext parentDmc, + String[] expectedValues) throws Throwable { + + final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); + + fExpService.getExecutor().submit(new Runnable() { + public void run() { + + fExpService.getSubExpressions(parentDmc, + new DataRequestMonitor(fExpService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + wait.setReturnInfo(getData()); + } + wait.waitFinished(getStatus()); + } + }); + } + }); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + + IExpressionDMContext[] childDmcs = + (IExpressionDMContext[]) wait.getReturnInfo(); + + String[] childExpressions = new String[childDmcs.length]; + MIExpressionDMCAccessor[] childDmcsAccessor = new MIExpressionDMCAccessor[childDmcs.length]; + + // Convert to a MIExpressionDMCAccessor to be able to call getRelativeExpression + // Also convert to String[] to be able to use Arrays.toString() + for (int i = 0; i < childExpressions.length; i++) { + childDmcsAccessor[i] = new MIExpressionDMCAccessor(childDmcs[i]); + childExpressions[i] = childDmcsAccessor[i].getRelativeExpression(); + } + assertTrue("Expected " + Arrays.toString(expectedValues) + " but got " + Arrays.toString(childExpressions), + expectedValues.length == childExpressions.length); + + for (int i = 0; i < childDmcsAccessor.length; i++) { + assertTrue("Expected: " + expectedValues[i] + " got: " + childDmcsAccessor[i].getRelativeExpression(), + childDmcsAccessor[i].getRelativeExpression().equals(expectedValues[i])); + } + + return childDmcs; + } +} diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/GDBProcessesTest.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/GDBProcessesTest.java new file mode 100644 index 00000000000..1f8fe3aba88 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/GDBProcessesTest.java @@ -0,0 +1,183 @@ +/******************************************************************************* + * Copyright (c) 2007 Ericsson 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: + * Ericsson AB - Initial implementation of Test cases + *******************************************************************************/ +package org.eclipse.dd.tests.gdb; + + + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.gdb.service.GDBRunControl; +import org.eclipse.dd.gdb.service.GDBRunControl.GDBProcessData; +import org.eclipse.dd.gdb.service.GDBRunControl.GDBThreadData; +import org.eclipse.dd.gdb.service.command.GDBControl; +import org.eclipse.dd.mi.service.IMIExecutionDMContext; +import org.eclipse.dd.tests.gdb.framework.AsyncCompletionWaitor; +import org.eclipse.dd.tests.gdb.framework.BaseTestCase; +import org.eclipse.dd.tests.gdb.launching.TestsPlugin; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +public class GDBProcessesTest extends BaseTestCase { + /* + * Path to executable + */ + private static final String EXEC_PATH = "data/launch/bin/"; + /* + * Name of the executable + */ + private static final String EXEC_NAME = "MultiThread.exe"; + + + private DsfSession fSession; + private DsfServicesTracker fServicesTracker; + + private GDBControl fGdbCtrl; + private GDBRunControl fRunCtrl; + + /* + * Create a waiter and a generic completion object. They will be used to + * wait for asynchronous call completion. + */ + private final AsyncCompletionWaitor fWait = new AsyncCompletionWaitor(); + + @Before + public void init() throws Exception { + fSession = getGDBLaunch().getSession(); + fServicesTracker = new DsfServicesTracker(TestsPlugin.getBundleContext(), fSession.getId()); + /* + * Get the GDBProcesses & MIRunControl service. + */ + fRunCtrl = fServicesTracker.getService(GDBRunControl.class); + fGdbCtrl = fServicesTracker.getService(GDBControl.class); + } + + @After + public void tearDown() { + fRunCtrl = null; + fServicesTracker.dispose(); + } + + @BeforeClass + public static void beforeClassMethod() { + setLaunchAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, + EXEC_PATH + EXEC_NAME); + } + + @Test + /* + * Get the process data for the current program. Process is executable name in case of GDB back end + */ + public void getProcessData() throws InterruptedException{ + /* + * Create a request monitor + */ + final DataRequestMonitor rm = + new DataRequestMonitor(fSession.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + fWait.setReturnInfo(getData()); + } + fWait.waitFinished(getStatus()); + } + }; + + /* + * Ask the service to get model data for the process. + * There is only one process in case of GDB back end. + */ + fSession.getExecutor().submit(new Runnable() { + public void run() { + fRunCtrl.getProcessData(fGdbCtrl.getGDBDMContext(), rm); + } + }); + /* + * Wait for the operation to get over + */ + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + /* + * Assert false if status is not OK + */ + Assert.assertTrue(fWait.getMessage(), fWait.isOK()); + + /* + * Get process data + */ + GDBProcessData processData = rm.getData(); + + if(processData == null) + Assert.fail("No process data is returned for Process DMC"); + else{ + /* + * Name of the process is the executable name in case of GDB back-end. + */ + assertEquals("Process data should be executable name " + EXEC_NAME, EXEC_NAME, processData.getName()); + } + } + + /* + * getThreadData() for multiple threads + */ + @Test + public void getThreadData() throws InterruptedException{ + final DataRequestMonitor rm = + new DataRequestMonitor(fSession.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + fWait.setReturnInfo(getData()); + } + fWait.waitFinished(getStatus()); + } + }; + + /* + * Create an execution DMC + */ + final IMIExecutionDMContext dmc = fRunCtrl.createMIExecutionContext(fGdbCtrl.getGDBDMContext(), 1); + + /* + * getModelData for Execution DMC + */ + fRunCtrl.getExecutor().submit(new Runnable() { + public void run() { + fRunCtrl.getThreadData(dmc, rm); + } + }); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + + GDBThreadData threadData = rm.getData(); + if(threadData == null) + fail("Thread data not returned for thread id = " + dmc.getThreadId()); + else{ + // Thread id is only a series of numbers + Pattern pattern = Pattern.compile("\\d*", Pattern.MULTILINE); //$NON-NLS-1$ + Matcher matcher = pattern.matcher(threadData.getId()); + assertTrue("Thread ID is a series of number", matcher.find()); + // Name is blank in case of GDB back end + assertEquals("Thread name is blank for GDB Back end", "", threadData.getName()); + } + fWait.waitReset(); + } +} diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIBreakpointsTest.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIBreakpointsTest.java new file mode 100644 index 00000000000..b54c70b9c04 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIBreakpointsTest.java @@ -0,0 +1,2762 @@ +/******************************************************************************* + * Copyright (c) 2007 Ericsson 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: + * Ericsson - Initial Implementation + *******************************************************************************/ +package org.eclipse.dd.tests.gdb; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.math.BigInteger; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.IBreakpoints; +import org.eclipse.dd.dsf.debug.service.IExpressions; +import org.eclipse.dd.dsf.debug.service.IFormattedValues; +import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointDMContext; +import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointDMData; +import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsAddedEvent; +import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsRemovedEvent; +import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; +import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsUpdatedEvent; +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData; +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.gdb.service.command.GDBControl; +import org.eclipse.dd.gdb.service.command.GDBControlDMContext; +import org.eclipse.dd.mi.service.MIBreakpointDMData; +import org.eclipse.dd.mi.service.MIBreakpoints; +import org.eclipse.dd.mi.service.MIRunControl; +import org.eclipse.dd.mi.service.MIBreakpoints.MIBreakpointDMContext; +import org.eclipse.dd.mi.service.command.events.MIBreakpointHitEvent; +import org.eclipse.dd.mi.service.command.events.MIWatchpointScopeEvent; +import org.eclipse.dd.mi.service.command.events.MIWatchpointTriggerEvent; +import org.eclipse.dd.tests.gdb.framework.AsyncCompletionWaitor; +import org.eclipse.dd.tests.gdb.framework.BackgroundRunner; +import org.eclipse.dd.tests.gdb.framework.BaseTestCase; +import org.eclipse.dd.tests.gdb.framework.SyncUtil; +import org.eclipse.dd.tests.gdb.launching.TestsPlugin; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; + +/* + * This is the Breakpoint Service test suite. + * + * It is meant to be a regression suite to be executed automatically against + * the DSF nightly builds. + * + * It is also meant to be augmented with a proper test case(s) every time a + * feature is added or in the event (unlikely :-) that a bug is found in the + * Breakpoint Service. + * + * Refer to the JUnit4 documentation for an explanation of the annotations. + */ + +@RunWith(BackgroundRunner.class) +public class MIBreakpointsTest extends BaseTestCase { + + // Global constants + public static final String PLUGIN_ID = "org.eclipse.cdt.debug.core" ; //$NON-NLS-1$ + public static final String TEST_APPL = "data/launch/bin/BreakpointTestApp.exe"; //$NON-NLS-1$ + public static final String SOURCE_PATH = "data/launch/src"; //$NON-NLS-1$ + + public static final String SOURCE_PROJECT = "MIBreakpointsTest"; + public static final String SOURCE_FOLDER = "src"; + public static final String SOURCE_FILE = "BreakpointTestApp.cc"; //$NON-NLS-1$ + + // Asynchronous Completion + private final AsyncCompletionWaitor fWait = new AsyncCompletionWaitor(); + + // Services references + private DsfSession fSession; + private GDBControlDMContext fGdbControlDmc; + private DsfServicesTracker fServicesTracker; + private MIRunControl fRunControl; + private IBreakpoints fBreakpointService; + + // Event Management + private static Boolean lock = true; + enum Events { BP_ADDED, BP_UPDATED, BP_REMOVED, BP_HIT, WP_HIT, WP_OOS } + final int BP_ADDED = Events.BP_ADDED.ordinal(); + final int BP_UPDATED = Events.BP_UPDATED.ordinal(); + final int BP_REMOVED = Events.BP_REMOVED.ordinal(); + final int BP_HIT = Events.BP_HIT.ordinal(); + final int WP_HIT = Events.WP_HIT.ordinal(); + final int WP_OOS = Events.WP_OOS.ordinal(); + private int[] fBreakpointEvents = new int[Events.values().length]; + private boolean fBreakpointEvent; + private int fBreakpointEventCount; + private int fBreakpointRef; + + // Some useful constants + final String BREAKPOINT_TYPE_TAG = MIBreakpoints.BREAKPOINT_TYPE; + final String BREAKPOINT_TAG = MIBreakpoints.BREAKPOINT; + final String WATCHPOINT_TAG = MIBreakpoints.WATCHPOINT; + + final String FILE_NAME_TAG = MIBreakpoints.FILE_NAME; + final String LINE_NUMBER_TAG = MIBreakpoints.LINE_NUMBER; + final String FUNCTION_TAG = MIBreakpoints.FUNCTION; + final String ADDRESS_TAG = MIBreakpoints.ADDRESS; + final String CONDITION_TAG = MIBreakpoints.CONDITION; + final String IGNORE_COUNT_TAG = MIBreakpoints.IGNORE_COUNT; + final String IS_ENABLED_TAG = MIBreakpoints.IS_ENABLED; + final String THREAD_ID_TAG = MIBreakpointDMData.THREAD_ID; + final String NUMBER_TAG = MIBreakpointDMData.NUMBER; + + final String EXPRESSION_TAG = MIBreakpoints.EXPRESSION; + final String READ_TAG = MIBreakpoints.READ; + final String WRITE_TAG = MIBreakpoints.WRITE; + + // Target application 'special' locations + private final int LINE_NUMBER_1 = 20; + private final int LINE_NUMBER_2 = 21; + private final int LINE_NUMBER_3 = 27; + private final int LINE_NUMBER_4 = 35; + private final String FUNCTION = "zeroBlocks"; + private final String SIGNED_FUNCTION = "zeroBlocks(int)"; + private final String NO_CONDITION = ""; + + // NOTE: The back-end can reformat the condition. In order for the + // comparison to work, better specify the condition as the back-end + // would have it. + private final String CONDITION_1 = "i == 128"; + private final String CONDITION_2 = "i == 64"; + private final String CONDITION_3 = "j == 20"; + private final int IGNORE_COUNT_1 = 128; + private final int IGNORE_COUNT_2 = 20; + + private final String EXPRESSION_1 = "charBlock[20]"; + private final String EXPRESSION_2 = "j"; + + // Error messages + final String UNKNOWN_EXECUTION_CONTEXT = "Unknown execution context"; + final String INVALID_BREAKPOINT_LOCATION = "Invalid breakpoint location"; + final String BREAKPOINT_INSERTION_FAILURE = "Breakpoint insertion failure"; + final String UNKNOWN_BREAKPOINT = "Unknown breakpoint"; + + // ======================================================================== + // Housekeeping stuff + // ======================================================================== + + @BeforeClass + public static void testSuiteInitialization() { + // Select the binary to run the tests against + setLaunchAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, TEST_APPL); + setLaunchAttribute(ICDTLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY, SOURCE_PATH); + } + + @AfterClass + public static void testSuiteCleanup() { + } + + @Before + public void testCaseInitialization() { + + // Get a reference to the breakpoint service + fSession = getGDBLaunch().getSession(); + fServicesTracker = new DsfServicesTracker(TestsPlugin.getBundleContext(), fSession.getId()); + assert(fServicesTracker != null); + + GDBControl gdbControl = fServicesTracker.getService(GDBControl.class); + fGdbControlDmc = gdbControl.getGDBDMContext(); + assert(fGdbControlDmc != null); + + fRunControl = fServicesTracker.getService(MIRunControl.class); + assert(fRunControl != null); + + fBreakpointService = fServicesTracker.getService(IBreakpoints.class); + assert(fBreakpointService != null); + + // Register to breakpoint events + fRunControl.getSession().addServiceEventListener(MIBreakpointsTest.this, null); + + clearEventCounters(); + } + + @After + public void testCaseCleanup() { + + // Clear the references (not strictly necessary) + fRunControl.getSession().removeServiceEventListener(MIBreakpointsTest.this); + fBreakpointService = null; + fRunControl = null; + fServicesTracker = null; + + clearEventCounters(); + } + + // ======================================================================== + // Event Management Functions + // ======================================================================== + + /* ----------------------------------------------------------------------- + * eventDispatched + * ------------------------------------------------------------------------ + * Processes BreakpointHitEvent. + * ------------------------------------------------------------------------ + * @param e The BreakpointEvent + * ------------------------------------------------------------------------ + */ + @DsfServiceEventHandler + public void eventDispatched(IBreakpointsAddedEvent e) { + synchronized (lock) { + fBreakpointEvents[BP_ADDED]++; + fBreakpointEventCount++; + fBreakpointRef = ((MIBreakpointDMContext) e.getBreakpoints()[0]).getReference(); + fBreakpointEvent = true; + lock.notifyAll(); + } + } + + @DsfServiceEventHandler + public void eventDispatched(IBreakpointsUpdatedEvent e) { + synchronized (lock) { + fBreakpointEvents[BP_UPDATED]++; + fBreakpointEventCount++; + fBreakpointRef = ((MIBreakpointDMContext) e.getBreakpoints()[0]).getReference(); + fBreakpointEvent = true; + lock.notifyAll(); + } + } + + @DsfServiceEventHandler + public void eventDispatched(IBreakpointsRemovedEvent e) { + synchronized (lock) { + fBreakpointEvents[BP_REMOVED]++; + fBreakpointEventCount++; + fBreakpointRef = ((MIBreakpointDMContext) e.getBreakpoints()[0]).getReference(); + fBreakpointEvent = true; + lock.notifyAll(); + } + } + + @DsfServiceEventHandler + public void eventDispatched(MIBreakpointHitEvent e) { + synchronized (lock) { + fBreakpointEvents[BP_HIT]++; + fBreakpointEventCount++; + fBreakpointRef = e.getNumber(); + fBreakpointEvent = true; + lock.notifyAll(); + } + } + + @DsfServiceEventHandler + public void eventDispatched(MIWatchpointTriggerEvent e) { + synchronized (lock) { + fBreakpointEvents[WP_HIT]++; + fBreakpointEventCount++; + fBreakpointRef = e.getNumber(); + fBreakpointEvent = true; + lock.notifyAll(); + } + } + + @DsfServiceEventHandler + public void eventDispatched(MIWatchpointScopeEvent e) { + synchronized (lock) { + fBreakpointEvents[WP_OOS]++; + fBreakpointEventCount++; + fBreakpointRef = e.getNumber(); + fBreakpointEvent = true; + lock.notifyAll(); + } + } + + // Clears the counters + private void clearEventCounters() { + synchronized (lock) { + for (int i = 0; i < fBreakpointEvents.length; i++) { + fBreakpointEvents[i] = 0; + } + fBreakpointEvent = false; + fBreakpointEventCount = 0; + } + } + + // Get the breakpoint hit count + private int getBreakpointEventCount(int event) { + int count = 0; + synchronized (lock) { + count = fBreakpointEvents[event]; + } + return count; + } + + // Suspends the thread until an event is flagged + // NOTE: too simple for real life but good enough for this test suite + private void waitForBreakpointEvent() { + synchronized (lock) { + while (!fBreakpointEvent) { + try { + lock.wait(); + } catch (InterruptedException ex) { + } + } + fBreakpointEvent = false; + } + } + + // ======================================================================== + // Helper Functions + // ======================================================================== + + /* ------------------------------------------------------------------------ + * evaluateExpression + * ------------------------------------------------------------------------ + * Invokes the ExpressionService to evaluate an expression. In theory, + * we shouldn't rely on another service to test this one but we need a + * way to access a variable from the test application in order verify + * that the memory operations (read/write) are working properly. + * ------------------------------------------------------------------------ + * @param expression Expression to resolve @return Resolved expression + * @throws InterruptedException + * ------------------------------------------------------------------------ + */ + private BigInteger evaluateExpression(String expression) throws Throwable { + + final IExpressions fExpressionService = fServicesTracker.getService(IExpressions.class); + assert (fExpressionService != null); + + // Get a stack context (temporary - should be an MIcontainerDMC) + final IExpressionDMContext expressionDMC = SyncUtil.SyncCreateExpression(fGdbControlDmc, expression); + final FormattedValueDMContext formattedValueDMC = SyncUtil.SyncGetFormattedValue(fExpressionService, + expressionDMC, IFormattedValues.DECIMAL_FORMAT); + + // Create the DataRequestMonitor which will store the operation result in the wait object + final DataRequestMonitor drm = + new DataRequestMonitor(fSession.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + fWait.setReturnInfo(getData()); + } + fWait.waitFinished(getStatus()); + } + }; + + // Evaluate the expression (asynchronously) + fWait.waitReset(); + fSession.getExecutor().submit(new Runnable() { + public void run() { + fExpressionService.getFormattedExpressionValue(formattedValueDMC, drm); + } + }); + + // Wait for completion + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Return the string formatted by the back-end + String result = ""; + Object returnInfo = fWait.getReturnInfo(); + if (returnInfo instanceof FormattedValueDMData) + result = ((FormattedValueDMData) returnInfo).getFormattedValue(); + return new BigInteger(result); + } + + /* ------------------------------------------------------------------------ + * getBreakpoints + * ------------------------------------------------------------------------ + * Retrieves the installed breakpoints list + * ------------------------------------------------------------------------ + * Typical usage: + * IBreakpointDMContext[] breakpoints = getBreakpoints(context); + * ------------------------------------------------------------------------ + * @param context the execution context + * ------------------------------------------------------------------------ + */ + private IBreakpointDMContext[] getBreakpoints(final IBreakpointsTargetDMContext context) throws InterruptedException + { + // Clear the completion waiter + fWait.waitReset(); + + // Set the Request Monitor + final DataRequestMonitor drm = + new DataRequestMonitor(fBreakpointService.getExecutor(), null) { + @Override + protected void handleCompleted() { + fWait.waitFinished(getStatus()); + } + }; + + // Issue the breakpoint request + fWait.waitReset(); + fBreakpointService.getExecutor().submit(new Runnable() { + public void run() { + fBreakpointService.getBreakpoints(context, drm); + } + }); + + // Wait for completion + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Return the string formatted by the back-end + return drm.getData(); + } + + /* ------------------------------------------------------------------------ + * getBreakpoint + * ------------------------------------------------------------------------ + * Retrieves the installed breakpoint + * ------------------------------------------------------------------------ + * Typical usage: + * IBreakpointDMContext breakpoint = ...; + * IBreakpointDMData bp = getBreakpoint(breakpoint); + * ------------------------------------------------------------------------ + * @param breakpoint the breakpoint to retrieve + * ------------------------------------------------------------------------ + */ + private IBreakpointDMData getBreakpoint(final IBreakpointDMContext breakpoint) throws InterruptedException + { + // Clear the completion waiter + fWait.waitReset(); + + // Set the Request Monitor + final DataRequestMonitor drm = + new DataRequestMonitor(fBreakpointService.getExecutor(), null) { + @Override + protected void handleCompleted() { + fWait.waitFinished(getStatus()); + } + }; + + // Issue the breakpoint request + fWait.waitReset(); + fBreakpointService.getExecutor().submit(new Runnable() { + public void run() { + fBreakpointService.getBreakpointDMData(breakpoint, drm); + } + }); + + // Wait for completion + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Return the string formatted by the back-end + return drm.getData(); + } + + /* ------------------------------------------------------------------------ + * insertBreakpoint + * ------------------------------------------------------------------------ + * Issues an add breakpoint request. + * ------------------------------------------------------------------------ + * Typical usage: + * bp = insertBreakpoint(context, attributes); + * assertTrue(fWait.getMessage(), fWait.isOK()); + * ------------------------------------------------------------------------ + * @param context the execution context + * @param attributes the breakpoint attributes + * ------------------------------------------------------------------------ + */ + private IBreakpointDMContext insertBreakpoint(final IBreakpointsTargetDMContext context, + final Map attributes) throws InterruptedException + { + // Clear the completion waiter + fWait.waitReset(); + + // Set the Request Monitor + final DataRequestMonitor drm = + new DataRequestMonitor(fBreakpointService.getExecutor(), null) { + @Override + protected void handleCompleted() { + fWait.waitFinished(getStatus()); + } + }; + + // Issue the remove breakpoint request + fBreakpointService.getExecutor().submit(new Runnable() { + public void run() { + fBreakpointService.insertBreakpoint(context, attributes, drm); + } + }); + + // Wait for the result and return the breakpoint id + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + return drm.getData(); + } + + /* ------------------------------------------------------------------------ + * removeBreakpoint + * ------------------------------------------------------------------------ + * Issues a remove breakpoint request. + * ------------------------------------------------------------------------ + * Typical usage: + * IBreakpointDMContext breakpoint = ...; + * removeBreakpoint(context, breakpoint); + * assertTrue(fWait.getMessage(), fWait.isOK()); + * ------------------------------------------------------------------------ + * @param breakpoint the breakpoint to remove + * ------------------------------------------------------------------------ + */ + private void removeBreakpoint(final IBreakpointDMContext breakpoint) throws InterruptedException + { + // Clear the completion waiter + fWait.waitReset(); + + // Set the Request Monitor + final RequestMonitor rm = + new RequestMonitor(fBreakpointService.getExecutor(), null) { + @Override + protected void handleCompleted() { + fWait.waitFinished(getStatus()); + } + }; + + // Issue the add breakpoint request + fBreakpointService.getExecutor().submit(new Runnable() { + public void run() { + fBreakpointService.removeBreakpoint(breakpoint, rm); + } + }); + + // Wait for the result + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + } + + /* ------------------------------------------------------------------------ + * updateBreakpoint + * ------------------------------------------------------------------------ + * Issues an update breakpoint request. + * ------------------------------------------------------------------------ + * Typical usage: + * updateBreakpoint(context, breakpoint, properties); + * assertTrue(fWait.getMessage(), fWait.isOK()); + * ------------------------------------------------------------------------ + * @param breakpoint the breakpoint to update + * @param delta the delta properties + * ------------------------------------------------------------------------ + */ + private void updateBreakpoint(final IBreakpointDMContext breakpoint, + final Map delta) throws InterruptedException + { + // Clear the completion waiter + fWait.waitReset(); + + // Set the Request Monitor + final RequestMonitor rm = + new RequestMonitor(fBreakpointService.getExecutor(), null) { + @Override + protected void handleCompleted() { + fWait.waitFinished(getStatus()); + } + }; + + // Issue the update breakpoint request + fBreakpointService.getExecutor().submit(new Runnable() { + public void run() { + fBreakpointService.updateBreakpoint(breakpoint, delta, rm); + } + }); + + // Wait for the result + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + } + + // ======================================================================== + // Test Cases + // ------------------------------------------------------------------------ + // Templates: + // ------------------------------------------------------------------------ + // @Test + // public void basicTest() { + // // First test to run + // assertTrue("", true); + // } + // ------------------------------------------------------------------------ + // @Test(timeout=5000) + // public void timeoutTest() { + // // Second test to run, which will timeout if not finished on time + // assertTrue("", true); + // } + // ------------------------------------------------------------------------ + // @Test(expected=FileNotFoundException.class) + // public void exceptionTest() throws FileNotFoundException { + // // Third test to run which expects an exception + // throw new FileNotFoundException("Just testing"); + // } + // ======================================================================== + + /////////////////////////////////////////////////////////////////////////// + // Add Breakpoint tests + /////////////////////////////////////////////////////////////////////////// + + // ------------------------------------------------------------------------ + // insertBreakpoint_InvalidContext + // ------------------------------------------------------------------------ + // @Test + public void insertBreakpoint_InvalidContext() throws Throwable { + + // Create a line breakpoint + Map breakpoint = new HashMap(); + breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG); + breakpoint.put(FILE_NAME_TAG, SOURCE_FILE); + breakpoint.put(LINE_NUMBER_TAG, LINE_NUMBER_1); + + // Perform the test + String expected = UNKNOWN_EXECUTION_CONTEXT; + insertBreakpoint(null, breakpoint); + assertFalse(fWait.getMessage(), fWait.isOK()); + assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'", + fWait.getMessage().contains(expected)); + + // Ensure that no BreakpointEvent was received + assertTrue("BreakpointEvent problem: expected " + 0 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 0); + } + + // ------------------------------------------------------------------------ + // insertBreakpoint_InvalidFileName + // ------------------------------------------------------------------------ + // @Test + public void insertBreakpoint_InvalidFileName() throws Throwable { + + // Create a line breakpoint + Map breakpoint = new HashMap(); + breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG); + breakpoint.put(FILE_NAME_TAG, SOURCE_FILE + "_bad"); + breakpoint.put(LINE_NUMBER_TAG, LINE_NUMBER_1); + + // Perform the test + String expected = BREAKPOINT_INSERTION_FAILURE; + insertBreakpoint(fGdbControlDmc, breakpoint); + assertFalse(fWait.getMessage(), fWait.isOK()); + assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'", + fWait.getMessage().contains(expected)); + + // Ensure that no BreakpointEvent was received + assertTrue("BreakpointEvent problem: expected " + 0 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 0); + } + + // ------------------------------------------------------------------------ + // insertBreakpoint_InvalidLineNumber + // ------------------------------------------------------------------------ + // @Test + public void insertBreakpoint_InvalidLineNumber() throws Throwable { + + // Create a line breakpoint + Map breakpoint = new HashMap(); + breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG); + breakpoint.put(FILE_NAME_TAG, SOURCE_FILE); + breakpoint.put(LINE_NUMBER_TAG, 0); + + // Perform the test + String expected = BREAKPOINT_INSERTION_FAILURE; + insertBreakpoint(fGdbControlDmc, breakpoint); + assertFalse(fWait.getMessage(), fWait.isOK()); + assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'", + fWait.getMessage().contains(expected)); + + // Ensure that no BreakpointEvent was received + assertTrue("BreakpointEvent problem: expected " + 0 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 0); + } + + // ------------------------------------------------------------------------ + // insertBreakpoint_InvalidFunctionName + // ------------------------------------------------------------------------ + // @Test + public void insertBreakpoint_InvalidFunctionName() throws Throwable { + + // Create a function breakpoint + Map breakpoint = new HashMap(); + breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG); + breakpoint.put(FILE_NAME_TAG, SOURCE_FILE); + breakpoint.put(FUNCTION_TAG, "invalid-function-name"); + + // Perform the test + String expected = BREAKPOINT_INSERTION_FAILURE; + insertBreakpoint(fGdbControlDmc, breakpoint); + assertFalse(fWait.getMessage(), fWait.isOK()); + assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'", + fWait.getMessage().contains(expected)); + + // Ensure that no BreakpointEvent was received + assertTrue("BreakpointEvent problem: expected " + 0 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 0); + } + + // ------------------------------------------------------------------------ + // insertBreakpoint_InvalidAddress + // ------------------------------------------------------------------------ + // @Test + public void insertBreakpoint_InvalidAddress() throws Throwable { + + // Create an address breakpoint + Map breakpoint = new HashMap(); + breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG); + breakpoint.put(ADDRESS_TAG, "0x0"); + + // Perform the test + String expected = BREAKPOINT_INSERTION_FAILURE; + insertBreakpoint(fGdbControlDmc, breakpoint); + assertFalse(fWait.getMessage(), fWait.isOK()); + assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'", + fWait.getMessage().contains(expected)); + + // Ensure that no BreakpointEvent was received + assertTrue("BreakpointEvent problem: expected " + 0 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 0); + } + + // ------------------------------------------------------------------------ + // insertBreakpoint_LineNumber + // Set a breakpoint on a line number. + // Ensure that it is set correctly at the back-end. + // ------------------------------------------------------------------------ + // @Test + public void insertBreakpoint_LineNumber() throws Throwable { + + // Create a line breakpoint + Map breakpoint = new HashMap(); + breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG); + breakpoint.put(FILE_NAME_TAG, SOURCE_FILE); + breakpoint.put(LINE_NUMBER_TAG, LINE_NUMBER_1); + + // Perform the test + IBreakpointDMContext ref = insertBreakpoint(fGdbControlDmc, breakpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Ensure that the breakpoint was correctly installed + MIBreakpointDMData breakpoint1 = (MIBreakpointDMData) getBreakpoint(ref); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong file name)", + breakpoint1.getFileName().equals(SOURCE_FILE)); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong line number)", + breakpoint1.getLineNumber() == LINE_NUMBER_1); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong condition)", + breakpoint1.getCondition().equals(NO_CONDITION)); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong ignore count)", + breakpoint1.getIgnoreCount() == 0); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong state)", + breakpoint1.isEnabled()); + + // Ensure the BreakpointService holds only the right breakpoints + IBreakpointDMContext[] breakpoints = getBreakpoints(fGdbControlDmc); + assertTrue("BreakpointService problem: expected " + 1 + " breakpoint(s), received " + + breakpoints.length, breakpoints.length == 1); + MIBreakpointDMData breakpoint2 = (MIBreakpointDMData) getBreakpoint(breakpoints[0]); + assertTrue("BreakpointService problem: breakpoint mismatch", + breakpoint1.equals(breakpoint2)); + } + + // ------------------------------------------------------------------------ + // insertBreakpoint_Disabled + // Set a disabled breakpoint on a line number. + // Ensure that it is set correctly at the back-end. + // ------------------------------------------------------------------------ + // @Test + public void insertBreakpoint_Disabled() throws Throwable { + + // Create a line breakpoint + Map breakpoint = new HashMap(); + breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG); + breakpoint.put(FILE_NAME_TAG, SOURCE_FILE); + breakpoint.put(LINE_NUMBER_TAG, LINE_NUMBER_1); + breakpoint.put(IS_ENABLED_TAG, false); + + // Perform the test + IBreakpointDMContext ref = insertBreakpoint(fGdbControlDmc, breakpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Ensure that the breakpoint was correctly installed + MIBreakpointDMData breakpoint1 = (MIBreakpointDMData) getBreakpoint(ref); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong file name)", + breakpoint1.getFileName().equals(SOURCE_FILE)); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong line number)", + breakpoint1.getLineNumber() == LINE_NUMBER_1); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong condition)", + breakpoint1.getCondition().equals(NO_CONDITION)); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong ignore count)", + breakpoint1.getIgnoreCount() == 0); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong state)", + !breakpoint1.isEnabled()); + + // Ensure the BreakpointService holds only the right breakpoints + IBreakpointDMContext[] breakpoints = getBreakpoints(fGdbControlDmc); + assertTrue("BreakpointService problem: expected " + 1 + " breakpoint(s), received " + + breakpoints.length, breakpoints.length == 1); + MIBreakpointDMData breakpoint2 = (MIBreakpointDMData) getBreakpoint(breakpoints[0]); + assertTrue("BreakpointService problem: breakpoint mismatch", + breakpoint1.equals(breakpoint2)); + } + + // ------------------------------------------------------------------------ + // insertBreakpoint_FunctionName + // Set a breakpoint on a function name. + // Ensure that it is set correctly at the back-end. + // ------------------------------------------------------------------------ + // @Test + public void insertBreakpoint_FunctionName() throws Throwable { + + // Create a function breakpoint + Map breakpoint = new HashMap(); + breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG); + breakpoint.put(FILE_NAME_TAG, SOURCE_FILE); + breakpoint.put(FUNCTION_TAG, FUNCTION); + + // Perform the test + IBreakpointDMContext ref = insertBreakpoint(fGdbControlDmc, breakpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Ensure that the breakpoint was correctly installed + MIBreakpointDMData breakpoint1 = (MIBreakpointDMData) getBreakpoint(ref); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong file name)", + breakpoint1.getFileName().equals(SOURCE_FILE)); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong function)", + breakpoint1.getFunctionName().equals(SIGNED_FUNCTION)); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong condition)", + breakpoint1.getCondition().equals(NO_CONDITION)); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong ignore count)", + breakpoint1.getIgnoreCount() == 0); + + // Ensure the BreakpointService holds only the right breakpoints + IBreakpointDMContext[] breakpoints = getBreakpoints(fGdbControlDmc); + assertTrue("BreakpointService problem: expected " + 1 + " breakpoint(s), received " + + breakpoints.length, breakpoints.length == 1); + MIBreakpointDMData breakpoint2 = (MIBreakpointDMData) getBreakpoint(breakpoints[0]); + assertTrue("BreakpointService problem: breakpoint mismatch", + breakpoint1.equals(breakpoint2)); + } + + // ------------------------------------------------------------------------ + // insertBreakpoint_Condition + // Set a conditional breakpoint. + // Ensure that it is set correctly at the back-end. + // ------------------------------------------------------------------------ + // @Test + public void insertBreakpoint_Condition() throws Throwable { + + // Create a conditional line breakpoint + Map breakpoint = new HashMap(); + breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG); + breakpoint.put(FILE_NAME_TAG, SOURCE_FILE); + breakpoint.put(LINE_NUMBER_TAG, LINE_NUMBER_1); + breakpoint.put(CONDITION_TAG, CONDITION_1); + + // Perform the test + IBreakpointDMContext ref = insertBreakpoint(fGdbControlDmc, breakpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Ensure that the breakpoint was correctly installed + MIBreakpointDMData breakpoint1 = (MIBreakpointDMData) getBreakpoint(ref); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong file name)", + breakpoint1.getFileName().equals(SOURCE_FILE)); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong line number)", + breakpoint1.getLineNumber() == LINE_NUMBER_1); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong condition)", + breakpoint1.getCondition().equals(CONDITION_1)); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong ignore count)", + breakpoint1.getIgnoreCount() == 0); + + // Ensure the BreakpointService holds only the right breakpoints + IBreakpointDMContext[] breakpoints = getBreakpoints(fGdbControlDmc); + assertTrue("BreakpointService problem: expected " + 1 + " breakpoint(s), received " + + breakpoints.length, breakpoints.length == 1); + MIBreakpointDMData breakpoint2 = (MIBreakpointDMData) getBreakpoint(breakpoints[0]); + assertTrue("BreakpointService problem: breakpoint mismatch", + breakpoint1.equals(breakpoint2)); + } + + // ------------------------------------------------------------------------ + // insertBreakpoint_IgnoreCnt + // Set a breakpoint with an ignore count. + // Ensure that it is set correctly at the back-end. + // ------------------------------------------------------------------------ + @Test + public void insertBreakpoint_IgnoreCnt() throws Throwable { + + // Create a line breakpoint + Map breakpoint = new HashMap(); + breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG); + breakpoint.put(FILE_NAME_TAG, SOURCE_FILE); + breakpoint.put(LINE_NUMBER_TAG, LINE_NUMBER_1); + breakpoint.put(IGNORE_COUNT_TAG, IGNORE_COUNT_1); + + // Perform the test + IBreakpointDMContext ref = insertBreakpoint(fGdbControlDmc, breakpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Ensure that the breakpoint was correctly installed + MIBreakpointDMData breakpoint1 = (MIBreakpointDMData) getBreakpoint(ref); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong file name)", + breakpoint1.getFileName().equals(SOURCE_FILE)); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong line number)", + breakpoint1.getLineNumber() == LINE_NUMBER_1); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong condition)", + breakpoint1.getCondition().equals(NO_CONDITION)); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong ignore count)", + breakpoint1.getIgnoreCount() == IGNORE_COUNT_1); + + // Ensure the BreakpointService holds only the right breakpoints + IBreakpointDMContext[] breakpoints = getBreakpoints(fGdbControlDmc); + assertTrue("BreakpointService problem: expected " + 1 + " breakpoint(s), received " + + breakpoints.length, breakpoints.length == 1); + MIBreakpointDMData breakpoint2 = (MIBreakpointDMData) getBreakpoint(breakpoints[0]); + assertTrue("BreakpointService problem: breakpoint mismatch", + breakpoint1.equals(breakpoint2)); + } + + // ------------------------------------------------------------------------ + // insertBreakpoint_MultipleBreakpoints + // Set multiple distinct breakpoints. + // Ensure that the state is kosher. + // ------------------------------------------------------------------------ + // @Test + public void insertBreakpoint_MultipleBreakpoints() throws Throwable { + + // Create a line breakpoint + Map breakpoint = new HashMap(); + breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG); + breakpoint.put(FILE_NAME_TAG, SOURCE_FILE); + breakpoint.put(LINE_NUMBER_TAG, LINE_NUMBER_1); + + // Perform the test + IBreakpointDMContext ref = insertBreakpoint(fGdbControlDmc, breakpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Ensure that the breakpoint was correctly installed + MIBreakpointDMData breakpoint1 = (MIBreakpointDMData) getBreakpoint(ref); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong file name)", + breakpoint1.getFileName().equals(SOURCE_FILE)); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong line number)", + breakpoint1.getLineNumber() == LINE_NUMBER_1); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong condition)", + breakpoint1.getCondition().equals(NO_CONDITION)); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong ignore count)", + breakpoint1.getIgnoreCount() == 0); + + // Create a function breakpoint + breakpoint = new HashMap(); + breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG); + breakpoint.put(FILE_NAME_TAG, SOURCE_FILE); + breakpoint.put(FUNCTION_TAG, FUNCTION); + + // Perform the test + ref = insertBreakpoint(fGdbControlDmc, breakpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Ensure that the breakpoint was correctly installed + MIBreakpointDMData breakpoint2 = (MIBreakpointDMData) getBreakpoint(ref); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong file name)", + breakpoint2.getFileName().equals(SOURCE_FILE)); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong function)", + breakpoint2.getFunctionName().equals(SIGNED_FUNCTION)); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong condition)", + breakpoint2.getCondition().equals(NO_CONDITION)); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong ignore count)", + breakpoint2.getIgnoreCount() == 0); + + // Ensure the BreakpointService holds only the right breakpoints + IBreakpointDMContext[] breakpoints = getBreakpoints(fGdbControlDmc); + assertTrue("BreakpointService problem: expected " + 2 + " breakpoint(s), received " + + breakpoints.length, breakpoints.length == 2); + MIBreakpointDMData svc_bp1 = (MIBreakpointDMData) getBreakpoint(breakpoints[0]); + MIBreakpointDMData svc_bp2 = (MIBreakpointDMData) getBreakpoint(breakpoints[1]); + + // The breakpoint references are not necessarily retrieved in the order the + // breakpoints were initially set... + int ref1 = breakpoint1.getNumber(); + int ref2 = svc_bp1.getNumber(); + if (ref1 == ref2) { + assertTrue("BreakpointService problem: breakpoint mismatch", svc_bp1.equals(breakpoint1)); + assertTrue("BreakpointService problem: breakpoint mismatch", svc_bp2.equals(breakpoint2)); + } else { + assertTrue("BreakpointService problem: breakpoint mismatch", svc_bp1.equals(breakpoint2)); + assertTrue("BreakpointService problem: breakpoint mismatch", svc_bp2.equals(breakpoint1)); + } + } + + // ------------------------------------------------------------------------ + // insertBreakpoint_Duplicate + // Set 2 identical breakpoints. + // For GDB, no problem... + // ------------------------------------------------------------------------ + // @Test + public void insertBreakpoint_Duplicate() throws Throwable { + + // Create a line breakpoint + Map breakpoint = new HashMap(); + breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG); + breakpoint.put(FILE_NAME_TAG, SOURCE_FILE); + breakpoint.put(LINE_NUMBER_TAG, LINE_NUMBER_1); + + // Perform the test + IBreakpointDMContext ref = insertBreakpoint(fGdbControlDmc, breakpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Ensure that the breakpoint was correctly installed + MIBreakpointDMData breakpoint1 = (MIBreakpointDMData) getBreakpoint(ref); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong file name)", + breakpoint1.getFileName().equals(SOURCE_FILE)); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong line number)", + breakpoint1.getLineNumber() == LINE_NUMBER_1); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong condition)", + breakpoint1.getCondition().equals(NO_CONDITION)); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong ignore count)", + breakpoint1.getIgnoreCount() == 0); + + // Create a second line breakpoint, same attributes... + ref = insertBreakpoint(fGdbControlDmc, breakpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Ensure that the breakpoint was correctly installed + MIBreakpointDMData breakpoint2 = (MIBreakpointDMData) getBreakpoint(ref); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong file name)", + breakpoint2.getFileName().equals(SOURCE_FILE)); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong line number)", + breakpoint2.getLineNumber() == LINE_NUMBER_1); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong condition)", + breakpoint2.getCondition().equals(NO_CONDITION)); + assertTrue("BreakpointService problem: breakpoint mismatch (wrong ignore count)", + breakpoint2.getIgnoreCount() == 0); + + // Ensure the BreakpointService holds only the right breakpoints + IBreakpointDMContext[] breakpoints = getBreakpoints(fGdbControlDmc); + assertTrue("BreakpointService problem: expected " + 2 + " breakpoint(s), received " + + breakpoints.length, breakpoints.length == 2); + MIBreakpointDMData svc_bp1 = (MIBreakpointDMData) getBreakpoint(breakpoints[0]); + MIBreakpointDMData svc_bp2 = (MIBreakpointDMData) getBreakpoint(breakpoints[1]); + + // The breakpoint references are not necessarily retrieved in the order the + // breakpoints were initially set... + int ref1 = breakpoint1.getNumber(); + int ref2 = svc_bp1.getNumber(); + if (ref1 == ref2) { + assertTrue("BreakpointService problem: breakpoint mismatch", svc_bp1.equals(breakpoint1)); + assertTrue("BreakpointService problem: breakpoint mismatch", svc_bp2.equals(breakpoint2)); + } else { + assertTrue("BreakpointService problem: breakpoint mismatch", svc_bp1.equals(breakpoint2)); + assertTrue("BreakpointService problem: breakpoint mismatch", svc_bp2.equals(breakpoint1)); + } + } + + /////////////////////////////////////////////////////////////////////////// + // Add Watchpoint tests + /////////////////////////////////////////////////////////////////////////// + + // ------------------------------------------------------------------------ + // insertWatchpoint_Write + // Set a write watchpoint. + // Ensure that the state is kosher. + // ------------------------------------------------------------------------ + // @Test + public void insertWatchpoint_Write() throws Throwable { + + // Create a write watchpoint + Map watchpoint = new HashMap(); + watchpoint.put(BREAKPOINT_TYPE_TAG, WATCHPOINT_TAG); + watchpoint.put(EXPRESSION_TAG, EXPRESSION_1); + watchpoint.put(WRITE_TAG, true); + + // Perform the test + IBreakpointDMContext ref = insertBreakpoint(fGdbControlDmc, watchpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Ensure that the watchpoint was correctly installed + MIBreakpointDMData watchpoint1 = (MIBreakpointDMData) getBreakpoint(ref); + assertTrue("BreakpointService problem: watchpoint mismatch (wrong expression)", + watchpoint1.getExpression().equals(EXPRESSION_1)); + assertTrue("BreakpointService problem: watchpoint mismatch (wrong read state)", + !watchpoint1.isReadWatchpoint()); + assertTrue("BreakpointService problem: watchpoint mismatch (wrong write state)", + watchpoint1.isWriteWatchpoint()); + assertTrue("BreakpointService problem: watchpoint mismatch (wrong access state)", + !watchpoint1.isAccessWatchpoint()); + + // Ensure the BreakpointService holds only the right watchpoints + IBreakpointDMContext[] watchpoints = getBreakpoints(fGdbControlDmc); + assertTrue("BreakpointService problem: expected " + 1 + " watchpoints(s), received " + + watchpoints.length, watchpoints.length == 1); + MIBreakpointDMData watchpoint2 = (MIBreakpointDMData) getBreakpoint(watchpoints[0]); + assertTrue("BreakpointService problem: breakpoint mismatch", + watchpoint1.equals(watchpoint2)); + } + + // ------------------------------------------------------------------------ + // insertWatchpoint_Read + // Set a read watchpoint. + // Ensure that the state is kosher. + // ------------------------------------------------------------------------ + // @Test + public void insertWatchpoint_Read() throws Throwable { + + // Create a read watchpoint + Map watchpoint = new HashMap(); + watchpoint.put(BREAKPOINT_TYPE_TAG, WATCHPOINT_TAG); + watchpoint.put(EXPRESSION_TAG, EXPRESSION_1); + watchpoint.put(READ_TAG, true); + + // Perform the test + IBreakpointDMContext ref = insertBreakpoint(fGdbControlDmc, watchpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Ensure that the watchpoint was correctly installed + MIBreakpointDMData watchpoint1 = (MIBreakpointDMData) getBreakpoint(ref); + assertTrue("BreakpointService problem: watchpoint mismatch (wrong expression)", + watchpoint1.getExpression().equals(EXPRESSION_1)); + assertTrue("BreakpointService problem: watchpoint mismatch (wrong read state)", + watchpoint1.isReadWatchpoint()); + assertTrue("BreakpointService problem: watchpoint mismatch (wrong write state)", + !watchpoint1.isWriteWatchpoint()); + assertTrue("BreakpointService problem: watchpoint mismatch (wrong access state)", + !watchpoint1.isAccessWatchpoint()); + + // Ensure the BreakpointService holds only the right watchpoints + IBreakpointDMContext[] watchpoints = getBreakpoints(fGdbControlDmc); + assertTrue("BreakpointService problem: expected " + 1 + " watchpoints(s), received " + + watchpoints.length, watchpoints.length == 1); + MIBreakpointDMData watchpoint2 = (MIBreakpointDMData) getBreakpoint(watchpoints[0]); + assertTrue("BreakpointService problem: breakpoint mismatch", + watchpoint1.equals(watchpoint2)); + } + + // ------------------------------------------------------------------------ + // insertWatchpoint_Access + // Set an access watchpoint. + // Ensure that the state is kosher. + // ------------------------------------------------------------------------ + // @Test + public void insertWatchpoint_Access() throws Throwable { + + // Create an access watchpoint + Map watchpoint = new HashMap(); + watchpoint.put(BREAKPOINT_TYPE_TAG, WATCHPOINT_TAG); + watchpoint.put(EXPRESSION_TAG, EXPRESSION_1); + watchpoint.put(READ_TAG, true); + watchpoint.put(WRITE_TAG, true); + + // Perform the test + IBreakpointDMContext ref = insertBreakpoint(fGdbControlDmc, watchpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Ensure that the watchpoint was correctly installed + MIBreakpointDMData watchpoint1 = (MIBreakpointDMData) getBreakpoint(ref); + assertTrue("BreakpointService problem: watchpoint mismatch (wrong expression)", + watchpoint1.getExpression().equals(EXPRESSION_1)); + assertTrue("BreakpointService problem: watchpoint mismatch (wrong read state)", + !watchpoint1.isReadWatchpoint()); + assertTrue("BreakpointService problem: watchpoint mismatch (wrong write state)", + !watchpoint1.isWriteWatchpoint()); + assertTrue("BreakpointService problem: watchpoint mismatch (wrong access state)", + watchpoint1.isAccessWatchpoint()); + + // Ensure the BreakpointService holds only the right watchpoints + IBreakpointDMContext[] watchpoints = getBreakpoints(fGdbControlDmc); + assertTrue("BreakpointService problem: expected " + 1 + " watchpoints(s), received " + + watchpoints.length, watchpoints.length == 1); + MIBreakpointDMData watchpoint2 = (MIBreakpointDMData) getBreakpoint(watchpoints[0]); + assertTrue("BreakpointService problem: breakpoint mismatch", + watchpoint1.equals(watchpoint2)); + } + + /////////////////////////////////////////////////////////////////////////// + // Remove Breakpoint tests + /////////////////////////////////////////////////////////////////////////// + + // ------------------------------------------------------------------------ + // removeBreakpoint_SimpleCase + // Set a breakpoint and then remove it. + // Ensure that the state is kosher. + // ------------------------------------------------------------------------ + // @Test + public void removeBreakpoint_SimpleCase() throws Throwable { + + // Create a line breakpoint + Map breakpoint = new HashMap(); + breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG); + breakpoint.put(FILE_NAME_TAG, SOURCE_FILE); + breakpoint.put(LINE_NUMBER_TAG, LINE_NUMBER_1); + + // Install the breakpoint + IBreakpointDMContext ref = insertBreakpoint(fGdbControlDmc, breakpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Remove the installed breakpoint + removeBreakpoint(ref); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_REMOVED event(s), received " + + getBreakpointEventCount(BP_REMOVED), getBreakpointEventCount(BP_REMOVED) == 1); + clearEventCounters(); + + // Ensure the breakpoint was effectively removed + IBreakpointDMContext[] breakpoints = getBreakpoints(fGdbControlDmc); + assertTrue("BreakpointService problem: expected " + 0 + " breakpoint(s), received " + + breakpoints.length, breakpoints.length == 0); + } + + // ------------------------------------------------------------------------ + // removeBreakpoint_InvalidBreakpoint + // Try removing a non-existing breakpoint. + // ------------------------------------------------------------------------ + // @Test + public void removeBreakpoint_InvalidBreakpoint() throws Throwable { + + // Create an invalid breakpoint reference + IBreakpointDMContext invalid_ref = + new MIBreakpointDMContext((MIBreakpoints) fBreakpointService, new IDMContext[] { fGdbControlDmc }, 0); + + // Remove the invalid breakpoint + String expected = UNKNOWN_BREAKPOINT; + removeBreakpoint(invalid_ref); + assertFalse(fWait.getMessage(), fWait.isOK()); + assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'", + fWait.getMessage().contains(expected)); + + // Ensure that right BreakpointEvents were received + assertTrue("BreakpointEvent problem: expected " + 0 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 0); + + // Create a line breakpoint + Map breakpoint = new HashMap(); + breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG); + breakpoint.put(FILE_NAME_TAG, SOURCE_FILE); + breakpoint.put(LINE_NUMBER_TAG, LINE_NUMBER_1); + + // Install the breakpoint + IBreakpointDMContext ref = insertBreakpoint(fGdbControlDmc, breakpoint); + IBreakpointDMContext saved_ref = ref; + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Ensure the breakpoint list is OK + IBreakpointDMContext[] breakpoints = getBreakpoints(fGdbControlDmc); + assertTrue("BreakpointService problem: expected " + 1 + " breakpoint(s), received " + + breakpoints.length, breakpoints.length == 1); + + // Remove the installed breakpoint + removeBreakpoint(ref); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_REMOVED event(s), received " + + getBreakpointEventCount(BP_REMOVED), getBreakpointEventCount(BP_REMOVED) == 1); + clearEventCounters(); + + // Ensure the breakpoint list is OK + breakpoints = getBreakpoints(fGdbControlDmc); + assertTrue("BreakpointService problem: expected " + 0 + " breakpoint(s), received " + + breakpoints.length, breakpoints.length == 0); + + // Remove the un-installed breakpoint + removeBreakpoint(saved_ref); + assertFalse(fWait.getMessage(), fWait.isOK()); + assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'", + fWait.getMessage().contains(expected)); + + // Ensure that right BreakpointEvents were received + assertTrue("BreakpointEvent problem: expected " + 0 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 0); + + // Ensure the breakpoint list is OK + breakpoints = getBreakpoints(fGdbControlDmc); + assertTrue("BreakpointService problem: expected " + 0 + " breakpoint(s), received " + + breakpoints.length, breakpoints.length == 0); + + // Re-install the breakpoint + ref = insertBreakpoint(fGdbControlDmc, breakpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + MIBreakpointDMData breakpoint1 = (MIBreakpointDMData) getBreakpoint(ref); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Remove an un-installed breakpoint (again) + removeBreakpoint(saved_ref); + assertFalse(fWait.getMessage(), fWait.isOK()); + assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'", + fWait.getMessage().contains(expected)); + + // Ensure that right BreakpointEvents were received + assertTrue("BreakpointEvent problem: expected " + 0 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 0); + + // Ensure that the existing breakpoint is unaffected + breakpoints = getBreakpoints(fGdbControlDmc); + assertTrue("BreakpointService problem: expected " + 1 + " breakpoint(s), received " + + breakpoints.length, breakpoints.length == 1); + MIBreakpointDMData breakpoint2 = (MIBreakpointDMData) getBreakpoint(breakpoints[0]); + assertTrue("BreakpointService problem: breakpoint mismatch", + breakpoint1.equals(breakpoint2)); + } + + // ------------------------------------------------------------------------ + // removeBreakpoint_MixedCase + // Set a number of breakpoints and then remove them in disorder. + // Ensure that the right breakpoints are left after each iteration. + // ------------------------------------------------------------------------ + // @Test + public void removeBreakpoint_MixedCase() throws Throwable { + + // Create a line breakpoint + for (int i = 0; i < 4; i++) { + Map breakpoint = new HashMap(); + breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG); + breakpoint.put(FILE_NAME_TAG, SOURCE_FILE); + breakpoint.put(LINE_NUMBER_TAG, LINE_NUMBER_1 + i); + insertBreakpoint(fGdbControlDmc, breakpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + int expected = i + 1; + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + expected + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == expected); + assertTrue("BreakpointEvent problem: expected " + expected + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == expected); + } + clearEventCounters(); + + // Get the list of breakpoints + IBreakpointDMContext[] breakpoints = getBreakpoints(fGdbControlDmc); + assertTrue("BreakpointService problem: expected " + 4 + " breakpoint(s), received " + + breakpoints.length, breakpoints.length == 4); + + // Remove the breakpoint one at a time in the following order: 1, 3, 2, 4 + int[] indices = { 0, 2, 1, 3 }; + int breakpoints_left = 4; + for (int i = 0; i < breakpoints_left; i++) { + + // Remove the selected breakpoint + IBreakpointDMContext index = breakpoints[indices[i]]; + removeBreakpoint(index); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + breakpoints_left--; + + // Ensure that right BreakpointEvents were received + int expected = i + 1; + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + expected + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == expected); + assertTrue("BreakpointEvent problem: expected " + expected + " BREAKPOINT_REMOVED event(s), received " + + getBreakpointEventCount(BP_REMOVED), getBreakpointEventCount(BP_REMOVED) == expected); + + // Ensure the breakpoint was effectively removed + IBreakpointDMContext[] remaining_breakpoints = getBreakpoints(fGdbControlDmc); + assertTrue("BreakpointService problem: expected " + breakpoints_left + " breakpoint(s), received " + + remaining_breakpoints.length, remaining_breakpoints.length == breakpoints_left); + for (int j = 0; i < breakpoints_left; i++) { + assertTrue("BreakpointService problem: removed breakpoint still present (" + index + ")", + remaining_breakpoints[j] != index); + } + } + clearEventCounters(); + } + + /////////////////////////////////////////////////////////////////////////// + // Breakpoint Update tests + /////////////////////////////////////////////////////////////////////////// + + // ------------------------------------------------------------------------ + // updateBreakpoint_InvalidBreakpoint + // Updates a non-existing breakpoint. + // For GDB, no problem... + // ------------------------------------------------------------------------ + // @Test + public void updateBreakpoint_InvalidBreakpoint() throws Throwable { + + // Create an invalid breakpoint reference + IBreakpointDMContext invalid_ref = + new MIBreakpointDMContext((MIBreakpoints) fBreakpointService, new IDMContext[] { fGdbControlDmc }, 0); + + // Update the invalid breakpoint + String expected = UNKNOWN_BREAKPOINT; + Map properties = new HashMap(); + properties.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG); + properties.put(FILE_NAME_TAG, SOURCE_FILE); + properties.put(LINE_NUMBER_TAG, LINE_NUMBER_1); + updateBreakpoint(invalid_ref, properties); + assertFalse(fWait.getMessage(), fWait.isOK()); + assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'", + fWait.getMessage().contains(expected)); + + // Ensure that no BreakpointEvent was received + assertTrue("BreakpointEvent problem: expected " + 0 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 0); + } + + // ------------------------------------------------------------------------ + // updateBreakpoint_AddCondition + // Set a breakpoint and then add a condition. + // Ensure that the new breakpoint reflects the changes + // ------------------------------------------------------------------------ + // @Test + public void updateBreakpoint_AddCondition() throws Throwable { + + // Create a line breakpoint + Map breakpoint = new HashMap(); + breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG); + breakpoint.put(FILE_NAME_TAG, SOURCE_FILE); + breakpoint.put(LINE_NUMBER_TAG, LINE_NUMBER_1); + + // Install the breakpoint + IBreakpointDMContext ref = insertBreakpoint(fGdbControlDmc, breakpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Modify the condition + Map delta = new HashMap(); + delta.put(CONDITION_TAG, CONDITION_1); + updateBreakpoint(ref, delta); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_UPDATED event(s), received " + + getBreakpointEventCount(BP_UPDATED), getBreakpointEventCount(BP_UPDATED) == 1); + clearEventCounters(); + + // Verify the state of the breakpoint + MIBreakpointDMData breakpoint2 = (MIBreakpointDMData) getBreakpoint(ref); + assertTrue("BreakpointEvent problem: breakpoint mismatch (wrong condition)", + breakpoint2.getCondition().equals(CONDITION_1)); + } + + // ------------------------------------------------------------------------ + // updateBreakpoint_RemoveCondition + // Set a conditional breakpoint and then remove the condition. + // Ensure that the new breakpoint reflects the changes + // ------------------------------------------------------------------------ + // @Test + public void updateBreakpoint_RemoveCondition() throws Throwable { + + // Create a line breakpoint + Map breakpoint = new HashMap(); + breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG); + breakpoint.put(FILE_NAME_TAG, SOURCE_FILE); + breakpoint.put(LINE_NUMBER_TAG, LINE_NUMBER_1); + breakpoint.put(CONDITION_TAG, CONDITION_1); + + // Install the breakpoint + IBreakpointDMContext ref = insertBreakpoint(fGdbControlDmc, breakpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Remove the condition + Map delta = new HashMap(); + delta.put(CONDITION_TAG, null); + updateBreakpoint(ref, delta); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_UPDATED event(s), received " + + getBreakpointEventCount(BP_UPDATED), getBreakpointEventCount(BP_UPDATED) == 1); + clearEventCounters(); + + // Verify the state of the breakpoint + MIBreakpointDMData breakpoint2 = (MIBreakpointDMData) getBreakpoint(ref); + assertTrue("BreakpointEvent problem: breakpoint mismatch (wrong condition)", + breakpoint2.getCondition().equals("")); + } + + // ------------------------------------------------------------------------ + // updateBreakpoint_ModifyCondition + // Set a conditional breakpoint and then modify the condition. + // Ensure that the new breakpoint reflects the changes + // ------------------------------------------------------------------------ + // @Test + public void updateBreakpoint_ModifyCondition() throws Throwable { + + // Create a line breakpoint + Map breakpoint = new HashMap(); + breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG); + breakpoint.put(FILE_NAME_TAG, SOURCE_FILE); + breakpoint.put(LINE_NUMBER_TAG, LINE_NUMBER_1); + breakpoint.put(CONDITION_TAG, CONDITION_1); + + // Install the breakpoint + IBreakpointDMContext ref = insertBreakpoint(fGdbControlDmc, breakpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Update the condition + Map delta = new HashMap(); + delta.put(CONDITION_TAG, CONDITION_2); + updateBreakpoint(ref, delta); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_UPDATED event(s), received " + + getBreakpointEventCount(BP_UPDATED), getBreakpointEventCount(BP_UPDATED) == 1); + clearEventCounters(); + + // Verify the state of the breakpoint + MIBreakpointDMData breakpoint2 = (MIBreakpointDMData) getBreakpoint(ref); + assertTrue("BreakpointEvent problem: breakpoint mismatch (wrong condition)", + breakpoint2.getCondition().equals(CONDITION_2)); + } + + // ------------------------------------------------------------------------ + // updateWatchpoint_AddCondition + // Set a watchpoint and then add a condition. + // Ensure that the new breakpoint reflects the changes + // ------------------------------------------------------------------------ + // @Test + public void updateWatchpoint_AddCondition() throws Throwable { + + // Run to the point where the variable is initialized + SyncUtil.SyncAddBreakpoint(SOURCE_FILE + ":" + LINE_NUMBER_1, true); + SyncUtil.SyncResumeUntilStopped(); + clearEventCounters(); + + // Create a write watchpoint + Map watchpoint = new HashMap(); + watchpoint.put(BREAKPOINT_TYPE_TAG, WATCHPOINT_TAG); + watchpoint.put(EXPRESSION_TAG, EXPRESSION_1); + watchpoint.put(WRITE_TAG, true); + + // Install the watchpoint + IBreakpointDMContext ref = insertBreakpoint(fGdbControlDmc, watchpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Add the condition + Map delta = new HashMap(); + delta.put(CONDITION_TAG, CONDITION_1); + updateBreakpoint(ref, delta); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_UPDATED event(s), received " + + getBreakpointEventCount(BP_UPDATED), getBreakpointEventCount(BP_UPDATED) == 1); + clearEventCounters(); + + // Verify the state of the watchpoint + MIBreakpointDMData watchpoint2 = (MIBreakpointDMData) getBreakpoint(ref); + assertTrue("BreakpointEvent problem: breakpoint mismatch (wrong condition)", + watchpoint2.getCondition().equals(CONDITION_1)); + } + + // ------------------------------------------------------------------------ + // updateWatchpoint_RemoveCondition + // Set a conditional watchpoint and then remove the condition. + // Ensure that the new breakpoint reflects the changes + // ------------------------------------------------------------------------ + // @Test + public void updateWatchpoint_RemoveCondition() throws Throwable { + + // Run to the point where the variable is initialized + SyncUtil.SyncAddBreakpoint(SOURCE_FILE + ":" + LINE_NUMBER_1, true); + SyncUtil.SyncResumeUntilStopped(); + clearEventCounters(); + + // Create a write watchpoint + Map watchpoint = new HashMap(); + watchpoint.put(BREAKPOINT_TYPE_TAG, WATCHPOINT_TAG); + watchpoint.put(EXPRESSION_TAG, EXPRESSION_1); + watchpoint.put(WRITE_TAG, true); + watchpoint.put(CONDITION_TAG, CONDITION_1); + + // Install the watchpoint + IBreakpointDMContext ref = insertBreakpoint(fGdbControlDmc, watchpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Remove the condition + Map delta = new HashMap(); + delta.put(CONDITION_TAG, null); + updateBreakpoint(ref, delta); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_UPDATED event(s), received " + + getBreakpointEventCount(BP_UPDATED), getBreakpointEventCount(BP_UPDATED) == 1); + clearEventCounters(); + + // Verify the state of the watchpoint + MIBreakpointDMData watchpoint2 = (MIBreakpointDMData) getBreakpoint(ref); + assertTrue("BreakpointEvent problem: breakpoint mismatch (wrong condition)", + watchpoint2.getCondition().equals("")); + } + + // ------------------------------------------------------------------------ + // updateWatchpoint_ModifyCondition + // Set a conditional watchpoint and then modify the condition. + // Ensure that the new breakpoint reflects the changes + // ------------------------------------------------------------------------ + // @Test + public void updateWatchpoint_ModifyCondition() throws Throwable { + + // Run to the point where the variable is initialized + SyncUtil.SyncAddBreakpoint(SOURCE_FILE + ":" + LINE_NUMBER_1, true); + SyncUtil.SyncResumeUntilStopped(); + clearEventCounters(); + + // Create a write watchpoint + Map watchpoint = new HashMap(); + watchpoint.put(BREAKPOINT_TYPE_TAG, WATCHPOINT_TAG); + watchpoint.put(EXPRESSION_TAG, EXPRESSION_1); + watchpoint.put(WRITE_TAG, true); + watchpoint.put(CONDITION_TAG, CONDITION_1); + + // Install the watchpoint + IBreakpointDMContext ref = insertBreakpoint(fGdbControlDmc, watchpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Update the condition + Map delta = new HashMap(); + delta.put(CONDITION_TAG, CONDITION_2); + updateBreakpoint(ref, delta); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_UPDATED event(s), received " + + getBreakpointEventCount(BP_UPDATED), getBreakpointEventCount(BP_UPDATED) == 1); + clearEventCounters(); + + // Verify the state of the breakpoint + MIBreakpointDMData watchpoint2 = (MIBreakpointDMData) getBreakpoint(ref); + assertTrue("BreakpointEvent problem: breakpoint mismatch (wrong condition)", + watchpoint2.getCondition().equals(CONDITION_2)); + } + + // ------------------------------------------------------------------------ + // updateBreakpoint_AddCount + // Set a breakpoint and then add an ignore count. + // Ensure that the new breakpoint reflects the changes + // ------------------------------------------------------------------------ + // @Test + public void updateBreakpoint_AddCount() throws Throwable { + + // Create a line breakpoint + Map breakpoint = new HashMap(); + breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG); + breakpoint.put(FILE_NAME_TAG, SOURCE_FILE); + breakpoint.put(LINE_NUMBER_TAG, LINE_NUMBER_1); + + // Install the breakpoint + IBreakpointDMContext ref = insertBreakpoint(fGdbControlDmc, breakpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Add a count + Map delta = new HashMap(); + delta.put(IGNORE_COUNT_TAG, IGNORE_COUNT_2); + updateBreakpoint(ref, delta); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_UPDATED event(s), received " + + getBreakpointEventCount(BP_UPDATED), getBreakpointEventCount(BP_UPDATED) == 1); + clearEventCounters(); + + // Verify the state of the breakpoint + MIBreakpointDMData breakpoint2 = (MIBreakpointDMData) getBreakpoint(ref); + assertTrue("BreakpointEvent problem: breakpoint mismatch (wrong count)", + breakpoint2.getIgnoreCount() == IGNORE_COUNT_2); + } + + // ------------------------------------------------------------------------ + // updateBreakpoint_RemoveCount + // Set a conditional breakpoint and then remove the count.. + // Ensure that the new breakpoint reflects the changes + // ------------------------------------------------------------------------ + // @Test + public void updateBreakpoint_RemoveCount() throws Throwable { + + // Create a line breakpoint + Map breakpoint = new HashMap(); + breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG); + breakpoint.put(FILE_NAME_TAG, SOURCE_FILE); + breakpoint.put(LINE_NUMBER_TAG, LINE_NUMBER_1); + breakpoint.put(IGNORE_COUNT_TAG, IGNORE_COUNT_2); + + // Install the breakpoint + IBreakpointDMContext ref = insertBreakpoint(fGdbControlDmc, breakpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Remove the count + Map delta = new HashMap(); + delta.put(IGNORE_COUNT_TAG, null); + updateBreakpoint(ref, delta); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_UPDATED event(s), received " + + getBreakpointEventCount(BP_UPDATED), getBreakpointEventCount(BP_UPDATED) == 1); + clearEventCounters(); + + // Verify the state of the breakpoint + MIBreakpointDMData breakpoint2 = (MIBreakpointDMData) getBreakpoint(ref); + assertTrue("BreakpointEvent problem: breakpoint mismatch (wrong count)", + breakpoint2.getIgnoreCount() == 0); + } + + // ------------------------------------------------------------------------ + // updateBreakpoint_ModifyCount + // Set a conditional breakpoint and then modify the count. + // Ensure that the new breakpoint reflects the changes + // ------------------------------------------------------------------------ + // @Test + public void updateBreakpoint_ModifyCount() throws Throwable { + + // Create a line breakpoint + Map breakpoint = new HashMap(); + breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG); + breakpoint.put(FILE_NAME_TAG, SOURCE_FILE); + breakpoint.put(LINE_NUMBER_TAG, LINE_NUMBER_1); + breakpoint.put(IGNORE_COUNT_TAG, IGNORE_COUNT_1); + + // Install the breakpoint + IBreakpointDMContext ref = insertBreakpoint(fGdbControlDmc, breakpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Update the count + Map delta = new HashMap(); + delta.put(IGNORE_COUNT_TAG, IGNORE_COUNT_2); + updateBreakpoint(ref, delta); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_UPDATED event(s), received " + + getBreakpointEventCount(BP_UPDATED), getBreakpointEventCount(BP_UPDATED) == 1); + clearEventCounters(); + + // Verify the state of the breakpoint + MIBreakpointDMData breakpoint2 = (MIBreakpointDMData) getBreakpoint(ref); + assertTrue("BreakpointEvent problem: breakpoint mismatch (wrong count)", + breakpoint2.getIgnoreCount() == IGNORE_COUNT_2); + } + + // ------------------------------------------------------------------------ + // updateBreakpoint_Disable + // Set 2 breakpoints and disable the first one. + // Ensure that we stop on the second one. + // ------------------------------------------------------------------------ + // @Test + public void updateBreakpoint_Disable() throws Throwable { + + // Create a first line breakpoint + Map breakpoint = new HashMap(); + breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG); + breakpoint.put(FILE_NAME_TAG, SOURCE_FILE); + breakpoint.put(LINE_NUMBER_TAG, LINE_NUMBER_1); + + // Install the breakpoint + IBreakpointDMContext ref1 = insertBreakpoint(fGdbControlDmc, breakpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Create a second line breakpoint + breakpoint = new HashMap(); + breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG); + breakpoint.put(FILE_NAME_TAG, SOURCE_FILE); + breakpoint.put(LINE_NUMBER_TAG, LINE_NUMBER_2); + + // Install the breakpoint + IBreakpointDMContext ref2 = insertBreakpoint(fGdbControlDmc, breakpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 2 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 2); + assertTrue("BreakpointEvent problem: expected " + 2 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 2); + clearEventCounters(); + + // Verify the state of the breakpoints + MIBreakpointDMData breakpoint1 = (MIBreakpointDMData) getBreakpoint(ref1); + MIBreakpointDMData breakpoint2 = (MIBreakpointDMData) getBreakpoint(ref2); + assertTrue("BreakpointService problem: breakpoint state error", + breakpoint1.isEnabled() && breakpoint2.isEnabled()); + + // Disable the first breakpoint + Map delta = new HashMap(); + delta.put(IS_ENABLED_TAG, false); + updateBreakpoint(ref1, delta); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_UPDATED event(s), received " + + getBreakpointEventCount(BP_UPDATED), getBreakpointEventCount(BP_UPDATED) == 1); + clearEventCounters(); + + // Verify the state of the breakpoints + breakpoint1 = (MIBreakpointDMData) getBreakpoint(ref1); + breakpoint2 = (MIBreakpointDMData) getBreakpoint(ref2); + assertTrue("BreakpointService problem: breakpoint state error", + !breakpoint1.isEnabled() && breakpoint2.isEnabled()); + + // Run until the breakpoint is hit and the event generated + SyncUtil.SyncResumeUntilStopped(); + + // Ensure the BreakpointEvent was received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_HIT event(s), received " + + getBreakpointEventCount(BP_HIT), getBreakpointEventCount(BP_HIT) == 1); + assertTrue("BreakpointService problem: breakpoint mismatch", + fBreakpointRef == breakpoint2.getNumber()); + clearEventCounters(); + } + + // ------------------------------------------------------------------------ + // updateBreakpoint_Enable + // In a loop, set 2 breakpoints and disable the first one. After hitting + // the second one, enable the first one again. + // Ensure that we stop on the first one on the next iteration. + // ------------------------------------------------------------------------ + // @Test + public void updateBreakpoint_Enable() throws Throwable { + + // Create a first line breakpoint + Map breakpoint = new HashMap(); + breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG); + breakpoint.put(FILE_NAME_TAG, SOURCE_FILE); + breakpoint.put(LINE_NUMBER_TAG, LINE_NUMBER_1); + + // Install the breakpoint + IBreakpointDMContext ref1 = insertBreakpoint(fGdbControlDmc, breakpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Create a second line breakpoint + breakpoint = new HashMap(); + breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG); + breakpoint.put(FILE_NAME_TAG, SOURCE_FILE); + breakpoint.put(LINE_NUMBER_TAG, LINE_NUMBER_2); + + // Install the breakpoint + IBreakpointDMContext ref2 = insertBreakpoint(fGdbControlDmc, breakpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 2 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 2); + assertTrue("BreakpointEvent problem: expected " + 2 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 2); + clearEventCounters(); + + // Verify the state of the breakpoints + MIBreakpointDMData breakpoint1 = (MIBreakpointDMData) getBreakpoint(ref1); + MIBreakpointDMData breakpoint2 = (MIBreakpointDMData) getBreakpoint(ref2); + assertTrue("BreakpointService problem: breakpoint state error", + breakpoint1.isEnabled() && breakpoint2.isEnabled()); + + // Disable the first breakpoint + Map delta = new HashMap(); + delta.put(IS_ENABLED_TAG, false); + updateBreakpoint(ref1, delta); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_UPDATED event(s), received " + + getBreakpointEventCount(BP_UPDATED), getBreakpointEventCount(BP_UPDATED) == 1); + clearEventCounters(); + + // Verify the state of the breakpoints + breakpoint1 = (MIBreakpointDMData) getBreakpoint(ref1); + breakpoint2 = (MIBreakpointDMData) getBreakpoint(ref2); + assertTrue("BreakpointService problem: breakpoint state error", + !breakpoint1.isEnabled() && breakpoint2.isEnabled()); + + // Run until the breakpoint is hit and the event generated + SyncUtil.SyncResumeUntilStopped(); + + // Ensure the BreakpointEvent was received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_HIT event(s), received " + + getBreakpointEventCount(BP_HIT), getBreakpointEventCount(BP_HIT) == 1); + assertTrue("BreakpointService problem: breakpoint mismatch", + fBreakpointRef == breakpoint2.getNumber()); + clearEventCounters(); + + // Enable the first breakpoint + delta = new HashMap(); + delta.put(IS_ENABLED_TAG, true); + updateBreakpoint(ref1, delta); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_UPDATED event(s), received " + + getBreakpointEventCount(BP_UPDATED), getBreakpointEventCount(BP_UPDATED) == 1); + clearEventCounters(); + + // Verify the state of the breakpoints + breakpoint1 = (MIBreakpointDMData) getBreakpoint(ref1); + breakpoint2 = (MIBreakpointDMData) getBreakpoint(ref2); + assertTrue("BreakpointService problem: breakpoint state error", + breakpoint1.isEnabled() && breakpoint2.isEnabled()); + + // Run until the breakpoint is hit and the event generated + SyncUtil.SyncResumeUntilStopped(); + + // Ensure the BreakpointEvent was received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_HIT event(s), received " + + getBreakpointEventCount(BP_HIT), getBreakpointEventCount(BP_HIT) == 1); + assertTrue("BreakpointService problem: breakpoint mismatch", + fBreakpointRef == breakpoint1.getNumber()); + clearEventCounters(); + } + + /////////////////////////////////////////////////////////////////////////// + // Breakpoint Hit tests + /////////////////////////////////////////////////////////////////////////// + + // ------------------------------------------------------------------------ + // breakpointHit_LineNumber + // Set a breakpoint on a line number. + // ------------------------------------------------------------------------ + // @Test + public void breakpointHit_LineNumber() throws Throwable { + + // Create a line breakpoint + Map breakpoint = new HashMap(); + breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG); + breakpoint.put(FILE_NAME_TAG, SOURCE_FILE); + breakpoint.put(LINE_NUMBER_TAG, LINE_NUMBER_1); + + // Install the breakpoint + MIBreakpointDMContext ref = (MIBreakpointDMContext) insertBreakpoint(fGdbControlDmc, breakpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Run until the breakpoint is hit and the event generated + SyncUtil.SyncResumeUntilStopped(); + + // Ensure the correct BreakpointEvent was received + waitForBreakpointEvent(); + MIBreakpointDMData breakpoint1 = (MIBreakpointDMData) getBreakpoint(ref); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_HIT event(s), received " + + getBreakpointEventCount(BP_HIT), getBreakpointEventCount(BP_HIT) == 1); + assertTrue("BreakpointService problem: breakpoint mismatch", + fBreakpointRef == breakpoint1.getNumber()); + clearEventCounters(); + } + + // ------------------------------------------------------------------------ + // breakpointHit_Function + // Set a breakpoint on a function name. + // ------------------------------------------------------------------------ + // @Test + public void breakpointHit_Function() throws Throwable { + + // Create a function breakpoint + Map breakpoint = new HashMap(); + breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG); + breakpoint.put(FILE_NAME_TAG, SOURCE_FILE); + breakpoint.put(FUNCTION_TAG, FUNCTION); + + // Install the breakpoint + MIBreakpointDMContext ref = (MIBreakpointDMContext) insertBreakpoint(fGdbControlDmc, breakpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Run until the breakpoint is hit and the event generated + SyncUtil.SyncResumeUntilStopped(); + + // Ensure the correct BreakpointEvent was received + waitForBreakpointEvent(); + MIBreakpointDMData breakpoint1 = (MIBreakpointDMData) getBreakpoint(ref); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_HIT event(s), received " + + getBreakpointEventCount(BP_HIT), getBreakpointEventCount(BP_HIT) == 1); + assertTrue("BreakpointService problem: breakpoint mismatch", + fBreakpointRef == breakpoint1.getNumber()); + clearEventCounters(); + } + + // ------------------------------------------------------------------------ + // breakpointHit_Condition + // Set a breakpoint on a line where a variable being increased (loop). + // Set a condition so that the break occurs only after variable == count. + // Ensure that the variable was increased 'count' times. + // ------------------------------------------------------------------------ + // @Test + public void breakpointHit_Condition() throws Throwable { + + // Create a conditional line breakpoint + Map breakpoint = new HashMap(); + breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG); + breakpoint.put(FILE_NAME_TAG, SOURCE_FILE); + breakpoint.put(LINE_NUMBER_TAG, LINE_NUMBER_1); + breakpoint.put(CONDITION_TAG, CONDITION_1); + + // Install the breakpoint + MIBreakpointDMContext ref = (MIBreakpointDMContext) insertBreakpoint(fGdbControlDmc, breakpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Run until the breakpoint is hit and the event generated + SyncUtil.SyncResumeUntilStopped(); + + // Ensure the correct BreakpointEvent was received + waitForBreakpointEvent(); + MIBreakpointDMData breakpoint1 = (MIBreakpointDMData) getBreakpoint(ref); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_HIT event(s), received " + + getBreakpointEventCount(BP_HIT), getBreakpointEventCount(BP_HIT) == 1); + assertTrue("BreakpointService problem: breakpoint mismatch", + fBreakpointRef == breakpoint1.getNumber()); + clearEventCounters(); + + // Verify that the condition is met + int i = evaluateExpression("i").intValue(); + assertTrue("BreakpointEvent problem: breakpoint mismatch (wrong condition)", i == 128); + } + + // ------------------------------------------------------------------------ + // breakpointHit_UpdatedCondition + // Set a breakpoint on a line where a variable being increased (loop). + // Set a condition so that the break occurs only after variable == count. + // Ensure that the variable was increased 'count' times. + // ------------------------------------------------------------------------ + // @Test + public void breakpointHit_UpdatedCondition() throws Throwable { + + // Create a conditional line breakpoint + Map breakpoint = new HashMap(); + breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG); + breakpoint.put(FILE_NAME_TAG, SOURCE_FILE); + breakpoint.put(LINE_NUMBER_TAG, LINE_NUMBER_1); + + // Install the breakpoint + MIBreakpointDMContext ref = (MIBreakpointDMContext) insertBreakpoint(fGdbControlDmc, breakpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Add the condition + Map delta = new HashMap(); + delta.put(CONDITION_TAG, CONDITION_1); + updateBreakpoint(ref, delta); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_UPDATED event(s), received " + + getBreakpointEventCount(BP_UPDATED), getBreakpointEventCount(BP_UPDATED) == 1); + clearEventCounters(); + + // Run until the breakpoint is hit and the event generated + SyncUtil.SyncResumeUntilStopped(); + + // Ensure the correct BreakpointEvent was received + waitForBreakpointEvent(); + MIBreakpointDMData breakpoint1 = (MIBreakpointDMData) getBreakpoint(ref); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_HIT event(s), received " + + getBreakpointEventCount(BP_HIT), getBreakpointEventCount(BP_HIT) == 1); + assertTrue("BreakpointService problem: breakpoint mismatch", + fBreakpointRef == breakpoint1.getNumber()); + clearEventCounters(); + + // Verify that the condition is met + int i = evaluateExpression("i").intValue(); + assertTrue("BreakpointEvent problem: breakpoint mismatch (wrong condition)", i == 128); + } + + // ------------------------------------------------------------------------ + // breakpointHit_Count + // Set a breakpoint on a line where a variable being increased (loop). + // Set an ignore count != 0. + // Ensure that the variable was increased 'ignoreCount' times. + // ------------------------------------------------------------------------ + @Test + public void breakpointHit_Count() throws Throwable { + + // Create a conditional line breakpoint + Map breakpoint = new HashMap(); + breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG); + breakpoint.put(FILE_NAME_TAG, SOURCE_FILE); + breakpoint.put(LINE_NUMBER_TAG, LINE_NUMBER_1); + breakpoint.put(IGNORE_COUNT_TAG, IGNORE_COUNT_2); + + // Install the breakpoint + MIBreakpointDMContext ref = (MIBreakpointDMContext) insertBreakpoint(fGdbControlDmc, breakpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Run until the breakpoint is hit and the event generated + SyncUtil.SyncResumeUntilStopped(); + + // Ensure the correct BreakpointEvent was received + waitForBreakpointEvent(); + MIBreakpointDMData breakpoint1 = (MIBreakpointDMData) getBreakpoint(ref); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_HIT event(s), received " + + getBreakpointEventCount(BP_HIT), getBreakpointEventCount(BP_HIT) == 1); + assertTrue("BreakpointService problem: breakpoint mismatch", + fBreakpointRef == breakpoint1.getNumber()); + clearEventCounters(); + + // Verify that the condition is met + int i = evaluateExpression("i").intValue(); + assertTrue("BreakpointEvent problem: breakpoint mismatch (wrong condition)", i == IGNORE_COUNT_2); + } + + // ------------------------------------------------------------------------ + // breakpointHit_UpdatedCount + // Set a breakpoint on a line where a variable being increased (loop). + // Set an ignore count != 0. + // Ensure that the variable was increased 'ignoreCount' times. + // ------------------------------------------------------------------------ + // @Test + public void breakpointHit_UpdatedCount() throws Throwable { + + // Create a conditional line breakpoint + Map breakpoint = new HashMap(); + breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG); + breakpoint.put(FILE_NAME_TAG, SOURCE_FILE); + breakpoint.put(LINE_NUMBER_TAG, LINE_NUMBER_1); + + // Install the breakpoint + MIBreakpointDMContext ref = (MIBreakpointDMContext) insertBreakpoint(fGdbControlDmc, breakpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Add a count + Map delta = new HashMap(); + delta.put(IGNORE_COUNT_TAG, IGNORE_COUNT_2); + updateBreakpoint(ref, delta); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_UPDATED event(s), received " + + getBreakpointEventCount(BP_UPDATED), getBreakpointEventCount(BP_UPDATED) == 1); + clearEventCounters(); + + // Run until the breakpoint is hit and the event generated + SyncUtil.SyncResumeUntilStopped(); + + // Ensure the correct BreakpointEvent was received + waitForBreakpointEvent(); + MIBreakpointDMData breakpoint1 = (MIBreakpointDMData) getBreakpoint(ref); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_HIT event(s), received " + + getBreakpointEventCount(BP_HIT), getBreakpointEventCount(BP_HIT) == 1); + assertTrue("BreakpointService problem: breakpoint mismatch", + fBreakpointRef == breakpoint1.getNumber()); + clearEventCounters(); + + // Verify that the condition is met + int i = evaluateExpression("i").intValue(); + assertTrue("BreakpointEvent problem: breakpoint mismatch (wrong condition)", i == IGNORE_COUNT_2); + } + + // ------------------------------------------------------------------------ + // breakpointHit_WriteWatchpoint + // Set a write watchpoint and go. + // Ensure that the correct event is received. + // ------------------------------------------------------------------------ + // @Test + public void breakpointHit_WriteWatchpoint() throws Throwable { + + // Create a write watchpoint + Map watchpoint = new HashMap(); + watchpoint.put(BREAKPOINT_TYPE_TAG, WATCHPOINT_TAG); + watchpoint.put(EXPRESSION_TAG, EXPRESSION_1); + watchpoint.put(WRITE_TAG, true); + + // Install the watchpoint + IBreakpointDMContext ref = insertBreakpoint(fGdbControlDmc, watchpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Run until the breakpoint is hit and the event generated + SyncUtil.SyncResumeUntilStopped(); + + // Ensure the correct BreakpointEvent was received + waitForBreakpointEvent(); + MIBreakpointDMData watchpoint1 = (MIBreakpointDMData) getBreakpoint(ref); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " WATCHPOINT_HIT event(s), received " + + getBreakpointEventCount(WP_HIT), getBreakpointEventCount(WP_HIT) == 1); + assertTrue("BreakpointService problem: watchpoint mismatch", + fBreakpointRef == watchpoint1.getNumber()); + clearEventCounters(); + + // Verify that the condition is met + int i = evaluateExpression("i").intValue(); + assertTrue("BreakpointEvent problem: breakpoint mismatch (wrong condition)", i == IGNORE_COUNT_2); + } + + // ------------------------------------------------------------------------ + // breakpointHit_ReadWatchpoint + // Set a read watchpoint and go. + // Ensure that the correct event is received. + // ------------------------------------------------------------------------ + // @Test + public void breakpointHit_ReadWatchpoint() throws Throwable { + + // Create a write watchpoint + Map watchpoint = new HashMap(); + watchpoint.put(BREAKPOINT_TYPE_TAG, WATCHPOINT_TAG); + watchpoint.put(EXPRESSION_TAG, EXPRESSION_1); + watchpoint.put(READ_TAG, true); + + // Install the watchpoint + IBreakpointDMContext ref = insertBreakpoint(fGdbControlDmc, watchpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Run until the breakpoint is hit and the event generated + SyncUtil.SyncResumeUntilStopped(); + + // Ensure the correct BreakpointEvent was received + waitForBreakpointEvent(); + MIBreakpointDMData watchpoint1 = (MIBreakpointDMData) getBreakpoint(ref); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " WATCHPOINT_HIT event(s), received " + + getBreakpointEventCount(WP_HIT), getBreakpointEventCount(WP_HIT) == 1); + assertTrue("BreakpointService problem: watchpoint mismatch", + fBreakpointRef == watchpoint1.getNumber()); + clearEventCounters(); + + // Verify that the condition is met + int i = evaluateExpression("i").intValue(); + assertTrue("BreakpointEvent problem: breakpoint mismatch (wrong condition)", i == IGNORE_COUNT_2); + } + + // ------------------------------------------------------------------------ + // breakpointHit_AccessWatchpoint + // Set an access watchpoint and go. + // Ensure that the correct event is received. + // ------------------------------------------------------------------------ + // @Test + public void breakpointHit_AccessWatchpoint() throws Throwable { + + // Create an access watchpoint + Map watchpoint = new HashMap(); + watchpoint.put(BREAKPOINT_TYPE_TAG, WATCHPOINT_TAG); + watchpoint.put(EXPRESSION_TAG, EXPRESSION_1); + watchpoint.put(READ_TAG, true); + watchpoint.put(WRITE_TAG, true); + + // Install the watchpoint + IBreakpointDMContext ref = insertBreakpoint(fGdbControlDmc, watchpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Run until the breakpoint is hit and the event generated + SyncUtil.SyncResumeUntilStopped(); + + // Ensure the correct BreakpointEvent was received + waitForBreakpointEvent(); + MIBreakpointDMData watchpoint1 = (MIBreakpointDMData) getBreakpoint(ref); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " WATCHPOINT_HIT event(s), received " + + getBreakpointEventCount(WP_HIT), getBreakpointEventCount(WP_HIT) == 1); + assertTrue("BreakpointService problem: watchpoint mismatch", + fBreakpointRef == watchpoint1.getNumber()); + clearEventCounters(); + + // Verify that the condition is met + int i = evaluateExpression("i").intValue(); + assertTrue("BreakpointEvent problem: breakpoint mismatch (wrong condition)", i == IGNORE_COUNT_2); + } + + // ------------------------------------------------------------------------ + // breakpointHit_watchpointUpdateCount + // Set a write watchpoint, add an ignoreCount and go. + // Ensure that the correct event is received. + // ------------------------------------------------------------------------ + @Test + public void breakpointHit_watchpointUpdateCount() throws Throwable { + + // Run to the point where the variable is initialized + SyncUtil.SyncAddBreakpoint(SOURCE_FILE + ":" + LINE_NUMBER_3, true); + SyncUtil.SyncAddBreakpoint(SOURCE_FILE + ":" + LINE_NUMBER_4, true); + SyncUtil.SyncResumeUntilStopped(); + clearEventCounters(); + + // Create a write watchpoint + Map watchpoint = new HashMap(); + watchpoint.put(BREAKPOINT_TYPE_TAG, WATCHPOINT_TAG); + watchpoint.put(EXPRESSION_TAG, EXPRESSION_2); + watchpoint.put(WRITE_TAG, true); + + // Install the watchpoint + IBreakpointDMContext ref = insertBreakpoint(fGdbControlDmc, watchpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Add a count + Map delta = new HashMap(); + delta.put(IGNORE_COUNT_TAG, IGNORE_COUNT_2); + updateBreakpoint(ref, delta); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_UPDATED event(s), received " + + getBreakpointEventCount(BP_UPDATED), getBreakpointEventCount(BP_UPDATED) == 1); + clearEventCounters(); + + // Run until the breakpoint is hit and the event generated + SyncUtil.SyncResumeUntilStopped(); + + // Ensure the correct BreakpointEvent was received + waitForBreakpointEvent(); + MIBreakpointDMData watchpoint1 = (MIBreakpointDMData) getBreakpoint(ref); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " WATCHPOINT_HIT event(s), received " + + getBreakpointEventCount(WP_HIT), getBreakpointEventCount(WP_HIT) == 1); + assertTrue("BreakpointService problem: watchpoint mismatch", + fBreakpointRef == watchpoint1.getNumber()); + clearEventCounters(); + + // Verify that the condition is met + int j = evaluateExpression("j").intValue(); + assertTrue("BreakpointEvent problem: breakpoint mismatch (wrong condition)", j == IGNORE_COUNT_2); + } + + // ------------------------------------------------------------------------ + // breakpointHit_watchpointUpdateCondition + // Set a write watchpoint, add a condition and go. + // Ensure that the correct event is received. + // ------------------------------------------------------------------------ + // @Test + public void breakpointHit_watchpointUpdateCondition() throws Throwable { + + // Run to the point where the variable is initialized + SyncUtil.SyncAddBreakpoint(SOURCE_FILE + ":" + LINE_NUMBER_3, true); + SyncUtil.SyncAddBreakpoint(SOURCE_FILE + ":" + LINE_NUMBER_4, true); + SyncUtil.SyncResumeUntilStopped(); + clearEventCounters(); + + // Create a write watchpoint + Map watchpoint = new HashMap(); + watchpoint.put(BREAKPOINT_TYPE_TAG, WATCHPOINT_TAG); + watchpoint.put(EXPRESSION_TAG, EXPRESSION_2); + watchpoint.put(WRITE_TAG, true); + + // Install the watchpoint + IBreakpointDMContext ref = insertBreakpoint(fGdbControlDmc, watchpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Add a condition + Map delta = new HashMap(); + delta.put(CONDITION_TAG, CONDITION_3); + updateBreakpoint(ref, delta); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_UPDATED event(s), received " + + getBreakpointEventCount(BP_UPDATED), getBreakpointEventCount(BP_UPDATED) == 1); + clearEventCounters(); + + // Run until the breakpoint is hit and the event generated + SyncUtil.SyncResumeUntilStopped(); + + // Ensure the correct BreakpointEvent was received + waitForBreakpointEvent(); + MIBreakpointDMData watchpoint1 = (MIBreakpointDMData) getBreakpoint(ref); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " WATCHPOINT_HIT event(s), received " + + getBreakpointEventCount(WP_HIT), getBreakpointEventCount(WP_HIT) == 1); + assertTrue("BreakpointService problem: watchpoint mismatch", + fBreakpointRef == watchpoint1.getNumber()); + clearEventCounters(); + + // Verify that the condition is met + int j = evaluateExpression("j").intValue(); + assertTrue("BreakpointEvent problem: breakpoint mismatch (wrong condition)", j == IGNORE_COUNT_2); + } + + // ------------------------------------------------------------------------ + // breakpointHit_WatchpointOutOfScope + // Set an access watchpoint and watch it go out of scope. + // Ensure that the correct event is received. + // ------------------------------------------------------------------------ + // @ T e s t removed due to lack of cooperation from GDB :-) + public void breakpointHit_WatchpointOutOfScope() throws Throwable { + + // Run to the point where the variable is initialized + SyncUtil.SyncAddBreakpoint(SOURCE_FILE + ":" + LINE_NUMBER_1, true); + SyncUtil.SyncAddBreakpoint(SOURCE_FILE + ":" + LINE_NUMBER_3, true); + SyncUtil.SyncResumeUntilStopped(); + clearEventCounters(); + + // Create a write watchpoint + Map watchpoint = new HashMap(); + watchpoint.put(BREAKPOINT_TYPE_TAG, WATCHPOINT_TAG); + watchpoint.put(EXPRESSION_TAG, EXPRESSION_2); + watchpoint.put(READ_TAG, true); + watchpoint.put(WRITE_TAG, true); + + // Install the watchpoint + IBreakpointDMContext ref = insertBreakpoint(fGdbControlDmc, watchpoint); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure that right BreakpointEvents were received + waitForBreakpointEvent(); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received " + + getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1); + clearEventCounters(); + + // Run until the breakpoint is hit and the event generated + SyncUtil.SyncResumeUntilStopped(); + + // Ensure the correct BreakpointEvent was received + waitForBreakpointEvent(); + MIBreakpointDMData watchpoint1 = (MIBreakpointDMData) getBreakpoint(ref); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 1); + assertTrue("BreakpointEvent problem: expected " + 1 + " WATCHPOINT_HIT event(s), received " + + getBreakpointEventCount(WP_OOS), getBreakpointEventCount(WP_OOS) == 1); + assertTrue("BreakpointService problem: watchpoint mismatch", + fBreakpointRef == watchpoint1.getNumber()); + clearEventCounters(); + + // Ensure the watchpoint is gone + getBreakpoints(fGdbControlDmc); + watchpoint1 = (MIBreakpointDMData) getBreakpoint(ref); + assertTrue("BreakpointEvent problem: expected watchpoint to be deleted after going out of scope", + watchpoint1 == null); + } + +} diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIMemoryTest.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIMemoryTest.java new file mode 100644 index 00000000000..31632a7e2c2 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIMemoryTest.java @@ -0,0 +1,1639 @@ +/******************************************************************************* + * Copyright (c) 2007 Ericsson 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: + * Ericsson AB - Initial Implementation + *******************************************************************************/ +package org.eclipse.dd.tests.gdb; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; +import org.eclipse.cdt.utils.Addr64; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.debug.service.IExpressions; +import org.eclipse.dd.dsf.debug.service.IFormattedValues; +import org.eclipse.dd.dsf.debug.service.IMemory; +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData; +import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryChangedEvent; +import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.StepType; +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.gdb.service.command.GDBControl; +import org.eclipse.dd.gdb.service.command.GDBControlDMContext; +import org.eclipse.dd.mi.service.MIRunControl; +import org.eclipse.dd.tests.gdb.framework.AsyncCompletionWaitor; +import org.eclipse.dd.tests.gdb.framework.BackgroundRunner; +import org.eclipse.dd.tests.gdb.framework.BaseTestCase; +import org.eclipse.dd.tests.gdb.framework.SyncUtil; +import org.eclipse.dd.tests.gdb.launching.TestsPlugin; +import org.eclipse.debug.core.model.MemoryByte; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; + +/* + * This is the Memory Service test suite. + * + * It is meant to be a regression suite to be executed automatically against + * the DSF nightly builds. + * + * It is also meant to be augmented with a proper test case(s) every time a + * feature is added or in the event (unlikely :-) that a bug is found in the + * Memory Service. + * + * Refer to the JUnit4 documentation for an explanation of the annotations. + */ + +@RunWith(BackgroundRunner.class) +public class MIMemoryTest extends BaseTestCase { + + private final AsyncCompletionWaitor fWait = new AsyncCompletionWaitor(); + private DsfSession fSession; + private DsfServicesTracker fServicesTracker; + private GDBControlDMContext fGdbControlDmc; + private MIRunControl fRunControl; + private IMemory fMemoryService; + private IExpressions fExpressionService; + + // Keeps track of the MemoryChangedEvents + private final int BLOCK_SIZE = 256; + private IAddress fBaseAddress; + private Integer fMemoryChangedEventCount = new Integer(0); + private boolean[] fMemoryAddressesChanged = new boolean[BLOCK_SIZE]; + + // ======================================================================== + // Housekeeping stuff + // ======================================================================== + + @BeforeClass + public static void testSuiteInitialization() { + // Select the binary to run the tests against + setLaunchAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, "data/launch/bin/MemoryTestApp.exe"); + } + + @AfterClass + public static void testSuiteCleanup() { + } + + @Before + public void testCaseInitialization() { + fSession = getGDBLaunch().getSession(); + + // Get a reference to the memory service + fServicesTracker = new DsfServicesTracker(TestsPlugin.getBundleContext(), fSession.getId()); + assert(fServicesTracker != null); + + GDBControl gdbControl = fServicesTracker.getService(GDBControl.class); + fGdbControlDmc = gdbControl.getGDBDMContext(); + assert(fGdbControlDmc != null); + + fRunControl = fServicesTracker.getService(MIRunControl.class); + assert(fRunControl != null); + + fMemoryService = fServicesTracker.getService(IMemory.class); + assert(fMemoryService != null); + + fExpressionService = fServicesTracker.getService(IExpressions.class); + assert(fExpressionService != null); + + fSession.addServiceEventListener(MIMemoryTest.this, null); + fBaseAddress = null; + clearEventCounters(); + } + + @After + public void testCaseCleanup() { + // Clear the references (not strictly necessary) + fBaseAddress = null; + fSession.removeServiceEventListener(MIMemoryTest.this); + fExpressionService = null; + fMemoryService = null; + fRunControl = null; + fServicesTracker.dispose(); + fServicesTracker = null; + clearEventCounters(); + } + + // ======================================================================== + // Helper Functions + // ======================================================================== + + /* ------------------------------------------------------------------------ + * eventDispatched + * ------------------------------------------------------------------------ + * Processes MemoryChangedEvents. + * First checks if the memory block base address was set so the individual + * test can control if it wants to verify the event(s). + * ------------------------------------------------------------------------ + * @param e The MemoryChangedEvent + * ------------------------------------------------------------------------ + */ + @DsfServiceEventHandler + public void eventDispatched(IMemoryChangedEvent e) { + synchronized(fMemoryChangedEventCount) { + fMemoryChangedEventCount++; + } + IAddress[] addresses = e.getAddresses(); + for (int i = 0; i < addresses.length; i++) { + int offset = Math.abs(addresses[i].distanceTo(fBaseAddress).intValue()); + if (offset < BLOCK_SIZE) + synchronized(fMemoryAddressesChanged) { + fMemoryAddressesChanged[offset] = true; + } + } + } + + // Clears the counters + private void clearEventCounters() { + synchronized(fMemoryChangedEventCount) { + fMemoryChangedEventCount = 0; + } + synchronized(fMemoryAddressesChanged) { + for (int i = 0; i < BLOCK_SIZE; i++) + fMemoryAddressesChanged[i] = false; + } + } + + // Returns the total number of events received + private int getEventCount() { + int count; + synchronized(fMemoryChangedEventCount) { + count = fMemoryChangedEventCount; + } + return count; + } + + // Returns the number of distinct addresses reported + private int getAddressCount() { + int count = 0; + synchronized(fMemoryAddressesChanged) { + for (int i = 0; i < BLOCK_SIZE; i++) + if (fMemoryAddressesChanged[i]) + count++; + } + return count; + } + + /* ------------------------------------------------------------------------ + * evaluateExpression + * ------------------------------------------------------------------------ + * Invokes the ExpressionService to evaluate an expression. In theory, we + * shouldn't rely on another service to test this one but we need a way to + * access a variable from the test application in order verify that the + * memory operations (read/write) are working properly. + * ------------------------------------------------------------------------ + * @param expression Expression to resolve + * @return Resolved expression + * @throws InterruptedException + * ------------------------------------------------------------------------ + */ + private IAddress evaluateExpression(String expression) throws Throwable + { + // Create the expression and format contexts + final IExpressionDMContext expressionDMC = SyncUtil.SyncCreateExpression(fGdbControlDmc, expression); + final FormattedValueDMContext formattedValueDMC = SyncUtil.SyncGetFormattedValue(fExpressionService, expressionDMC, IFormattedValues.HEX_FORMAT); + + // Create the DataRequestMonitor which will store the operation result in the wait object + final DataRequestMonitor drm = + new DataRequestMonitor(fSession.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + fWait.setReturnInfo(getData()); + } + fWait.waitFinished(getStatus()); + } + }; + + // Evaluate the expression (asynchronously) + fSession.getExecutor().submit(new Runnable() { + public void run() { + fExpressionService.getFormattedExpressionValue(formattedValueDMC, drm); + } + }); + + // Wait for completion + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Return the string formatted by the back-end + String result = ""; + Object returnInfo = fWait.getReturnInfo(); + if (returnInfo instanceof FormattedValueDMData) + result = ((FormattedValueDMData) returnInfo).getFormattedValue(); + return new Addr64(result); + } + + /* ------------------------------------------------------------------------ + * readMemory + * ------------------------------------------------------------------------ + * Issues a memory read request. The result is stored in fWait. + * ------------------------------------------------------------------------ + * Typical usage: + * getMemory(dmc, address, offset, count); + * fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + * assertTrue(fWait.getMessage(), fWait.isOK()); + * ------------------------------------------------------------------------ + * @param dmc the data model context + * @param address the memory block address + * @param offset the offset in the buffer + * @param count the number of bytes to read + * @throws InterruptedException + * ------------------------------------------------------------------------ + */ + private void readMemory(final IMemoryDMContext dmc, final IAddress address, + final long offset, final int word_size, final int count) + throws InterruptedException + { + // Set the Data Request Monitor + final DataRequestMonitor drm = + new DataRequestMonitor(fSession.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + fWait.setReturnInfo(getData()); + } + fWait.waitFinished(getStatus()); + } + }; + + // Issue the get memory request + fSession.getExecutor().submit(new Runnable() { + public void run() { + fMemoryService.getMemory(dmc, address, offset, word_size, count, drm); + } + }); + } + + /* ------------------------------------------------------------------------ + * readMemoryByteAtOffset + * ------------------------------------------------------------------------ + * Issues a memory read request. The result is stored in fWait. + * ------------------------------------------------------------------------ + * Typical usage: + * getMemory(dmc, address, offset, count); + * fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + * assertTrue(fWait.getMessage(), fWait.isOK()); + * ------------------------------------------------------------------------ + * @param dmc the data model context + * @param address the memory block address + * @param offset the offset in the buffer + * @param count the number of bytes to read + * @param result the expected byte + * @throws InterruptedException + * ------------------------------------------------------------------------ + */ + private void readMemoryByteAtOffset(final IMemoryDMContext dmc, final IAddress address, + final long offset, final int word_size, final int count, final MemoryByte[] result) + throws InterruptedException + { + // Set the Data Request Monitor + final DataRequestMonitor drm = + new DataRequestMonitor(fSession.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + result[(int) offset] = getData()[0]; + } + fWait.waitFinished(getStatus()); + } + }; + + // Issue the get memory request + fSession.getExecutor().submit(new Runnable() { + public void run() { + fMemoryService.getMemory(dmc, address, offset, word_size, count, drm); + } + }); + } + + /* ------------------------------------------------------------------------ + * writeMemory + * ------------------------------------------------------------------------ + * Issues a memory write request. + * ------------------------------------------------------------------------ + * Typical usage: + * writeMemory(dmc, address, offset, count, buffer); + * fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + * assertTrue(fWait.getMessage(), fWait.isOK()); + * ------------------------------------------------------------------------ + * @param dmc the data model context + * @param address the memory block address (could be an expression) + * @param offset the offset from address + * @param count the number of bytes to write + * @param buffer the byte buffer to write from + * @throws InterruptedException + * ------------------------------------------------------------------------ + */ + private void writeMemory(final IMemoryDMContext dmc, final IAddress address, + final long offset, final int word_size, final int count, final byte[] buffer) + throws InterruptedException + { + // Set the Data Request Monitor + final RequestMonitor rm = + new RequestMonitor(fSession.getExecutor(), null) { + @Override + protected void handleCompleted() { + fWait.waitFinished(getStatus()); + } + }; + + // Issue the get memory request + fSession.getExecutor().submit(new Runnable() { + public void run() { + fMemoryService.setMemory(dmc, address, offset, word_size, count, buffer, rm); + } + }); + } + + /* ------------------------------------------------------------------------ + * fillMemory + * ------------------------------------------------------------------------ + * Issues a memory write request. + * ------------------------------------------------------------------------ + * Typical usage: + * writeMemory(dmc, address, offset, count, buffer); + * fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + * assertTrue(fWait.getMessage(), fWait.isOK()); + * ------------------------------------------------------------------------ + * @param dmc the data model context + * @param address the memory block address (could be an expression) + * @param offset the offset from address + * @param count the number of bytes to write + * @param pattern the byte pattern to write + * @throws InterruptedException + * ------------------------------------------------------------------------ + */ + private void fillMemory(final IMemoryDMContext dmc, final IAddress address, + final long offset, final int word_size, final int count, final byte[] pattern) + throws InterruptedException + { + // Set the Data Request Monitor + final RequestMonitor rm = + new RequestMonitor(fSession.getExecutor(), null) { + @Override + protected void handleCompleted() { + fWait.waitFinished(getStatus()); + } + }; + + // Issue the fill memory request + fSession.getExecutor().submit(new Runnable() { + public void run() { + fMemoryService.fillMemory(dmc, address, offset, word_size, count, pattern, rm); + } + }); + } + + // ======================================================================== + // Test Cases + // ------------------------------------------------------------------------ + // Templates: + // ------------------------------------------------------------------------ + // @ Test + // public void basicTest() { + // // First test to run + // assertTrue("", true); + // } + // ------------------------------------------------------------------------ + // @ Test(timeout=5000) + // public void timeoutTest() { + // // Second test to run, which will timeout if not finished on time + // assertTrue("", true); + // } + // ------------------------------------------------------------------------ + // @ Test(expected=FileNotFoundException.class) + // public void exceptionTest() throws FileNotFoundException { + // // Third test to run which expects an exception + // throw new FileNotFoundException("Just testing"); + // } + // ======================================================================== + + /////////////////////////////////////////////////////////////////////////// + // getMemory tests + /////////////////////////////////////////////////////////////////////////// + + // ------------------------------------------------------------------------ + // readWithNullContext + // Test that a null context is caught and generates an error + // ------------------------------------------------------------------------ + @Test + public void readWithNullContext() throws Throwable { + + // Run to the point where the variable is initialized + SyncUtil.SyncAddBreakpoint("MemoryTestApp.cc:zeroBlocks", true); + SyncUtil.SyncResumeUntilStopped(); + SyncUtil.SyncStep(StepType.STEP_RETURN); + + // Setup call parameters + IMemoryDMContext dmc = null; + long offset = 0; + int word_size = 1; + int count = 1; + fBaseAddress = evaluateExpression("&charBlock"); + + // Perform the test + String expected = "Unknown context type"; + fWait.waitReset(); + readMemory(dmc, fBaseAddress, offset, word_size, count); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertFalse(fWait.getMessage(), fWait.isOK()); + assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'", + fWait.getMessage().contains(expected)); + + // Ensure no MemoryChangedEvent event was received + assertTrue("MemoryChangedEvent problem: expected " + 0 + ", received " + getEventCount(), getEventCount() == 0); + } + + // ------------------------------------------------------------------------ + // readWithInvalidAddress + // Test that an invalid address is caught and generates an error + // ------------------------------------------------------------------------ + @Test + public void readWithInvalidAddress() throws Throwable { + + // Run to the point where the variable is initialized + SyncUtil.SyncAddBreakpoint("MemoryTestApp.cc:zeroBlocks", true); + SyncUtil.SyncResumeUntilStopped(); + SyncUtil.SyncStep(StepType.STEP_RETURN); + + // Setup call parameters + long offset = 0; + int word_size = 1; + int count = 1; + fBaseAddress = new Addr64("0"); + + // Perform the test + fWait.waitReset(); + readMemory(fGdbControlDmc, fBaseAddress, offset, word_size, count); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + +// // Un-comment this part if GDB returns a bunch of 'N/A's +// // when the address is invalid +// assertTrue(fWait.getMessage(), fWait.isOK()); +// MemoryByte[] buffer = (MemoryByte[]) fWait.getReturnInfo(); +// assertTrue("Wrong value: expected '-1, 0', received '" + buffer[0].getValue() + ", " + buffer[0].getFlags() + "'", +// (buffer[0].getValue() == (byte) -1) && (buffer[0].getFlags() == (byte) 0)); + + // Un-comment this part if GDB returns an error message + // when the address is invalid + String expected = "Unable to read memory"; // Error msg returned by gdb + assertFalse(fWait.getMessage(), fWait.isOK()); + assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'", + fWait.getMessage().contains(expected)); + + // Ensure no MemoryChangedEvent event was received + assertTrue("MemoryChangedEvent problem: expected " + 0 + ", received " + getEventCount(), getEventCount() == 0); + } + + // ------------------------------------------------------------------------ + // readWithInvalidWordSize + // Test that an invalid word size is caught and generates an error + // ------------------------------------------------------------------------ + @Test + public void readWithInvalidWordSize() throws Throwable { + + // Run to the point where the variable is initialized + SyncUtil.SyncAddBreakpoint("MemoryTestApp.cc:zeroBlocks", true); + SyncUtil.SyncResumeUntilStopped(); + SyncUtil.SyncStep(StepType.STEP_RETURN); + + // Setup call parameters + long offset = 0; + int count = -1; + fBaseAddress = evaluateExpression("&charBlock"); + + // Perform the test + String expected = "Word size not supported (!= 1)"; + fWait.waitReset(); + readMemory(fGdbControlDmc, fBaseAddress, offset, 0, count); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertFalse(fWait.getMessage(), fWait.isOK()); + assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'", + fWait.getMessage().contains(expected)); + + fWait.waitReset(); + readMemory(fGdbControlDmc, fBaseAddress, offset, 2, count); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertFalse(fWait.getMessage(), fWait.isOK()); + assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'", + fWait.getMessage().contains(expected)); + + // Ensure no MemoryChangedEvent event was received + assertTrue("MemoryChangedEvent problem: expected " + 0 + ", received " + getEventCount(), getEventCount() == 0); + } + + // ------------------------------------------------------------------------ + // readWithInvalidCount + // Test that an invalid count is caught and generates an error + // ------------------------------------------------------------------------ + @Test + public void readWithInvalidCount() throws Throwable { + + // Run to the point where the variable is initialized + SyncUtil.SyncAddBreakpoint("MemoryTestApp.cc:zeroBlocks", true); + SyncUtil.SyncResumeUntilStopped(); + SyncUtil.SyncStep(StepType.STEP_RETURN); + + // Setup call parameters + long offset = 0; + int word_size = 1; + int count = -1; + fBaseAddress = evaluateExpression("&charBlock"); + + // Perform the test + String expected = "Invalid word count (< 0)"; + fWait.waitReset(); + readMemory(fGdbControlDmc, fBaseAddress, offset, word_size, count); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertFalse(fWait.getMessage(), fWait.isOK()); + assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'", + fWait.getMessage().contains(expected)); + + // Ensure no MemoryChangedEvent event was received + assertTrue("MemoryChangedEvent problem: expected " + 0 + ", received " + getEventCount(), getEventCount() == 0); + } + + // ------------------------------------------------------------------------ + // readCharVaryingBaseAddress + // Test the reading of individual bytes by varying the base address + // ------------------------------------------------------------------------ + @Test + public void readCharVaryingBaseAddress() throws Throwable { + + // Run to the point where the variable is zeroed + SyncUtil.SyncAddBreakpoint("MemoryTestApp.cc:zeroBlocks", true); + SyncUtil.SyncResumeUntilStopped(); + SyncUtil.SyncStep(StepType.STEP_RETURN); + + // Setup call parameters + long offset = 0; + int word_size = 1; + int count = 1; + fBaseAddress = evaluateExpression("&charBlock"); + + // Verify that all bytes are '0' + for (int i = 0; i < BLOCK_SIZE; i++) { + IAddress address = fBaseAddress.add(i); + fWait.waitReset(); + readMemory(fGdbControlDmc, address, offset, word_size, count); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + MemoryByte[] buffer = (MemoryByte[]) fWait.getReturnInfo(); + assertTrue("Wrong value read at offset " + i + ": expected '" + 0 + "', received '" + buffer[0].getValue() + "'", + (buffer[0].getValue() == (byte) 0)); + } + + // Run to the point where the variable is initialized + SyncUtil.SyncAddBreakpoint("MemoryTestApp.cc:setBlocks", true); + SyncUtil.SyncResumeUntilStopped(); + SyncUtil.SyncStep(StepType.STEP_RETURN); + + // Verify that all bytes are set + for (int i = 0; i < BLOCK_SIZE; i++) { + IAddress address = fBaseAddress.add(i); + fWait.waitReset(); + readMemory(fGdbControlDmc, address, offset, word_size, count); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + MemoryByte[] buffer = (MemoryByte[]) fWait.getReturnInfo(); + assertTrue(fWait.getMessage(), fWait.isOK()); + assertTrue("Wrong value read at offset " + i + ": expected '" + i + "', received '" + buffer[0].getValue() + "'", + (buffer[0].getValue() == (byte) i)); + } + + // Ensure no MemoryChangedEvent event was received + assertTrue("MemoryChangedEvent problem: expected " + 0 + ", received " + getEventCount(), getEventCount() == 0); + } + + // ------------------------------------------------------------------------ + // readCharVaryingOffset + // Test the reading of individual bytes by varying the offset + // ------------------------------------------------------------------------ + @Test + public void readCharVaryingOffset() throws Throwable { + + // Run to the point where the array is zeroed + SyncUtil.SyncAddBreakpoint("MemoryTestApp.cc:zeroBlocks", true); + SyncUtil.SyncResumeUntilStopped(); + SyncUtil.SyncStep(StepType.STEP_RETURN); + + // Setup call parameters + int word_size = 1; + int count = 1; + fBaseAddress = evaluateExpression("&charBlock"); + + // Verify that all bytes are '0' + for (int offset = 0; offset < BLOCK_SIZE; offset++) { + fWait.waitReset(); + readMemory(fGdbControlDmc, fBaseAddress, offset, word_size, count); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + MemoryByte[] buffer = (MemoryByte[]) fWait.getReturnInfo(); + assertTrue("Wrong value read at offset " + offset + ": expected '" + 0 + "', received '" + buffer[0].getValue() + "'", + (buffer[0].getValue() == (byte) 0)); + } + + // Run to the point where the array is set + SyncUtil.SyncAddBreakpoint("MemoryTestApp.cc:setBlocks", true); + SyncUtil.SyncResumeUntilStopped(); + SyncUtil.SyncStep(StepType.STEP_RETURN); + + // Verify that all bytes are set + for (int offset = 0; offset < BLOCK_SIZE; offset++) { + fWait.waitReset(); + readMemory(fGdbControlDmc, fBaseAddress, offset, word_size, count); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + MemoryByte[] buffer = (MemoryByte[]) fWait.getReturnInfo(); + assertTrue("Wrong value read at offset " + offset + ": expected '" + offset + "', received '" + buffer[0].getValue() + "'", + (buffer[0].getValue() == (byte) offset)); + } + + // Ensure no MemoryChangedEvent event was received + assertTrue("MemoryChangedEvent problem: expected " + 0 + ", received " + getEventCount(), getEventCount() == 0); + } + + // ------------------------------------------------------------------------ + // readCharArray + // Test the reading of a byte array + // ------------------------------------------------------------------------ + @Test + public void readCharArray() throws Throwable { + + // Run to the point where the variable is zeroed + SyncUtil.SyncAddBreakpoint("MemoryTestApp.cc:zeroBlocks", true); + SyncUtil.SyncResumeUntilStopped(); + SyncUtil.SyncStep(StepType.STEP_RETURN); + + // Setup call parameters + long offset = 0; + int word_size = 1; + int count = BLOCK_SIZE; + fBaseAddress = evaluateExpression("&charBlock"); + + // Get the memory block + fWait.waitReset(); + readMemory(fGdbControlDmc, fBaseAddress, offset, word_size, count); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + MemoryByte[] buffer = (MemoryByte[]) fWait.getReturnInfo(); + + // Verify that all bytes are '0' + for (int i = 0; i < count; i++) { + assertTrue("Wrong value read at offset " + i + ": expected '" + 0 + "', received '" + buffer[i].getValue() + "'", + (buffer[i].getValue() == (byte) 0)); + } + + // Run to the point where the variable is initialized + SyncUtil.SyncAddBreakpoint("MemoryTestApp.cc:setBlocks", true); + SyncUtil.SyncResumeUntilStopped(); + SyncUtil.SyncStep(StepType.STEP_RETURN); + + // Get the memory block + fWait.waitReset(); + readMemory(fGdbControlDmc, fBaseAddress, offset, word_size, count); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + buffer = (MemoryByte[]) fWait.getReturnInfo(); + + // Verify that all bytes are '0' + for (int i = 0; i < count; i++) { + assertTrue("Wrong value read at offset " + i + ": expected '" + i + "', received '" + buffer[i].getValue() + "'", + (buffer[i].getValue() == (byte) i)); + } + + // Ensure no MemoryChangedEvent event was received + assertTrue("MemoryChangedEvent problem: expected " + 0 + ", received " + getEventCount(), getEventCount() == 0); + } + + /////////////////////////////////////////////////////////////////////////// + // setMemory tests + /////////////////////////////////////////////////////////////////////////// + + // ------------------------------------------------------------------------ + // writeWithNullContext + // Test that a null context is caught and generates an error + // ------------------------------------------------------------------------ + @Test + public void writeWithNullContext() throws Throwable { + + // Run to the point where the variable is initialized + SyncUtil.SyncAddBreakpoint("MemoryTestApp.cc:zeroBlocks", true); + SyncUtil.SyncResumeUntilStopped(); + SyncUtil.SyncStep(StepType.STEP_RETURN); + + // Setup call parameters + long offset = 0; + int word_size = 1; + int count = 1; + byte[] buffer = new byte[count]; + fBaseAddress = evaluateExpression("&charBlock"); + + // Perform the test + String expected = "Unknown context type"; + fWait.waitReset(); + writeMemory(null, fBaseAddress, offset, word_size, count, buffer); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertFalse(fWait.getMessage(), fWait.isOK()); + assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'", + fWait.getMessage().contains(expected)); + + // Ensure no MemoryChangedEvent event was received + assertTrue("MemoryChangedEvent problem: expected " + 0 + ", received " + getEventCount(), getEventCount() == 0); + } + + // ------------------------------------------------------------------------ + // writeWithInvalidAddress + // Test that an invalid address is caught and generates an error + // ------------------------------------------------------------------------ + @Test + public void writeWithInvalidAddress() throws Throwable { + + // Run to the point where the variable is initialized + SyncUtil.SyncAddBreakpoint("MemoryTestApp.cc:zeroBlocks", true); + SyncUtil.SyncResumeUntilStopped(); + SyncUtil.SyncStep(StepType.STEP_RETURN); + + // Setup call parameters + long offset = 0; + int word_size = 1; + int count = 1; + byte[] buffer = new byte[count]; + fBaseAddress = new Addr64("0"); + + // Perform the test + fWait.waitReset(); + writeMemory(fGdbControlDmc, fBaseAddress, offset, word_size, count, buffer); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertFalse(fWait.getMessage(), fWait.isOK()); + String expected = "Cannot access memory at address"; // Error msg returned by gdb + assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'", + fWait.getMessage().contains(expected)); + + // Ensure no MemoryChangedEvent event was received + assertTrue("MemoryChangedEvent problem: expected " + 0 + ", received " + getEventCount(), getEventCount() == 0); + } + + // ------------------------------------------------------------------------ + // writeWithInvalidWordSize + // Test that an invalid word size is caught and generates an error + // ------------------------------------------------------------------------ + @Test + public void writeWithInvalidWordSize() throws Throwable { + + // Run to the point where the variable is initialized + SyncUtil.SyncAddBreakpoint("MemoryTestApp.cc:zeroBlocks", true); + SyncUtil.SyncResumeUntilStopped(); + SyncUtil.SyncStep(StepType.STEP_RETURN); + + // Setup call parameters + long offset = 0; + int count = -1; + byte[] buffer = new byte[1]; + fBaseAddress = evaluateExpression("&charBlock"); + + // Perform the test + String expected = "Word size not supported (!= 1)"; + fWait.waitReset(); + writeMemory(fGdbControlDmc, fBaseAddress, offset, 0, count, buffer); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertFalse(fWait.getMessage(), fWait.isOK()); + assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'", + fWait.getMessage().contains(expected)); + + fWait.waitReset(); + writeMemory(fGdbControlDmc, fBaseAddress, offset, 2, count, buffer); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertFalse(fWait.getMessage(), fWait.isOK()); + assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'", + fWait.getMessage().contains(expected)); + + // Ensure no MemoryChangedEvent event was received + assertTrue("MemoryChangedEvent problem: expected " + 0 + ", received " + getEventCount(), getEventCount() == 0); + } + + // ------------------------------------------------------------------------ + // writeWithInvalidCount + // Test that an invalid count is caught and generates an error + // ------------------------------------------------------------------------ + @Test + public void writeWithInvalidCount() throws Throwable { + + // Run to the point where the variable is initialized + SyncUtil.SyncAddBreakpoint("MemoryTestApp.cc:zeroBlocks", true); + SyncUtil.SyncResumeUntilStopped(); + SyncUtil.SyncStep(StepType.STEP_RETURN); + + // Setup call parameters + long offset = 0; + int word_size = 1; + int count = -1; + byte[] buffer = new byte[1]; + fBaseAddress = evaluateExpression("&charBlock"); + + // Perform the test + String expected = "Invalid word count (< 0)"; + fWait.waitReset(); + writeMemory(fGdbControlDmc, fBaseAddress, offset, word_size, count, buffer); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertFalse(fWait.getMessage(), fWait.isOK()); + assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'", + fWait.getMessage().contains(expected)); + + // Ensure no MemoryChangedEvent event was received + assertTrue("MemoryChangedEvent problem: expected " + 0 + ", received " + getEventCount(), getEventCount() == 0); + } + + // ------------------------------------------------------------------------ + // writeWithInvalidBuffer + // Test that the buffer contains at least count bytes + // ------------------------------------------------------------------------ + @Test + public void writeWithInvalidBuffer() throws Throwable { + + // Run to the point where the variable is initialized + SyncUtil.SyncAddBreakpoint("MemoryTestApp.cc:zeroBlocks", true); + SyncUtil.SyncResumeUntilStopped(); + SyncUtil.SyncStep(StepType.STEP_RETURN); + + // Setup call parameters + long offset = 0; + int word_size = 1; + int count = 10; + byte[] buffer = new byte[count - 1]; + fBaseAddress = evaluateExpression("&charBlock"); + + // Perform the test + String expected = "Buffer too short"; + fWait.waitReset(); + writeMemory(fGdbControlDmc, fBaseAddress, offset, word_size, count, buffer); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertFalse(fWait.getMessage(), fWait.isOK()); + assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'", + fWait.getMessage().contains(expected)); + + // Ensure no MemoryChangedEvent event was received + assertTrue("MemoryChangedEvent problem: expected " + 0 + ", received " + getEventCount(), getEventCount() == 0); + } + + // ------------------------------------------------------------------------ + // writeCharVaryingAddress + // Test the writing of individual bytes by varying the base address + // ------------------------------------------------------------------------ + @Test + public void writeCharVaryingAddress() throws Throwable { + + // Run to the point where the variable is zeroed + SyncUtil.SyncAddBreakpoint("MemoryTestApp.cc:zeroBlocks", true); + SyncUtil.SyncResumeUntilStopped(); + SyncUtil.SyncStep(StepType.STEP_RETURN); + + // Setup call parameters + long offset = 0; + int word_size = 1; + int count = BLOCK_SIZE; + byte[] buffer = new byte[count]; + fBaseAddress = evaluateExpression("&charBlock"); + + // Perform the test + for (int i = 0; i < count; i++) { + + // [1] Ensure that the memory byte = 0 + fWait.waitReset(); + readMemory(fGdbControlDmc, fBaseAddress, i, word_size, 1); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + MemoryByte[] block = (MemoryByte[]) fWait.getReturnInfo(); + assertTrue("Wrong value read at offset " + i + ": expected '" + 0 + "', received '" + block[0].getValue() + "'", + (block[0].getValue() == (byte) 0)); + + // [2] Write a byte value (count - i - 1) + IAddress address = fBaseAddress.add(i); + fWait.waitReset(); + byte expected = (byte) (count - i - 1); + buffer[0] = expected; + writeMemory(fGdbControlDmc, address, offset, word_size, 1, buffer); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // [3] Verify that the correct MemoryChangedEvent was sent + // (I hardly believe there are no synchronization problems here...) + assertTrue("MemoryChangedEvent problem at offset " + i + ": expected " + (i + 1) + " events, received " + getEventCount(), + getEventCount() == (i + 1)); + assertTrue("MemoryChangedEvent problem at offset " + i, fMemoryAddressesChanged[i]); + + // [4] Verify that the memory byte was written correctly + fWait.waitReset(); + readMemory(fGdbControlDmc, fBaseAddress, i, word_size, 1); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + block = (MemoryByte[]) fWait.getReturnInfo(); + assertTrue("Wrong value read at offset " + i + ": expected '" + expected + "', received '" + block[0].getValue() + "'", + (block[0].getValue() == expected)); + } + + // Ensure the MemoryChangedEvent events were received + assertTrue("MemoryChangedEvent problem: expected " + BLOCK_SIZE + " events, received " + getEventCount(), + getEventCount() == BLOCK_SIZE); + assertTrue("MemoryChangedEvent problem: expected " + BLOCK_SIZE + " distinct addresses, received " + getAddressCount(), + getEventCount() == BLOCK_SIZE); + } + + // ------------------------------------------------------------------------ + // writeCharVaryingOffset + // Test the writing of individual bytes by varying the base address + // ------------------------------------------------------------------------ + @Test + public void writeCharVaryingOffset() throws Throwable { + + // Run to the point where the variable is zeroed + SyncUtil.SyncAddBreakpoint("MemoryTestApp.cc:zeroBlocks", true); + SyncUtil.SyncResumeUntilStopped(); + SyncUtil.SyncStep(StepType.STEP_RETURN); + + int word_size = 1; + int count = BLOCK_SIZE; + byte[] buffer = new byte[count]; + fBaseAddress = evaluateExpression("&charBlock"); + + // Perform the test + for (int offset = 0; offset < count; offset++) { + + // [1] Ensure that the memory byte = 0 + fWait.waitReset(); + readMemory(fGdbControlDmc, fBaseAddress, offset, word_size, 1); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + MemoryByte[] block = (MemoryByte[]) fWait.getReturnInfo(); + assertTrue("Wrong value read at offset " + offset + ": expected '" + 0 + "', received '" + block[0].getValue() + "'", + (block[0].getValue() == (byte) 0)); + + // [2] Write a byte value (count - offset - 1) + fWait.waitReset(); + byte expected = (byte) (count - offset - 1); + buffer[0] = expected; + writeMemory(fGdbControlDmc, fBaseAddress, offset, word_size, 1, buffer); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // [3] Verify that the correct MemoryChangedEvent was sent + assertTrue("MemoryChangedEvent problem at offset " + offset + ": expected " + (offset + 1) + " events, received " + getEventCount(), + getEventCount() == (offset + 1)); + assertTrue("MemoryChangedEvent problem at offset " + offset, fMemoryAddressesChanged[offset]); + + // [4] Verify that the memory byte was written correctly + fWait.waitReset(); + readMemory(fGdbControlDmc, fBaseAddress, offset, word_size, 1); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + block = (MemoryByte[]) fWait.getReturnInfo(); + assertTrue("Wrong value read at offset " + offset + ": expected '" + expected + "', received '" + block[0].getValue() + "'", + (block[0].getValue() == expected)); + } + + // Ensure the MemoryChangedEvent events were received + assertTrue("MemoryChangedEvent problem: expected " + BLOCK_SIZE + " events, received " + getEventCount(), + getEventCount() == BLOCK_SIZE); + assertTrue("MemoryChangedEvent problem: expected " + BLOCK_SIZE + " distinct addresses, received " + getAddressCount(), + getAddressCount() == BLOCK_SIZE); + } + + // ------------------------------------------------------------------------ + // writeCharArray + // Test the writing of a byte array + // ------------------------------------------------------------------------ + @Test + public void writeCharArray() throws Throwable { + + // Run to the point where the variable is zeroed + SyncUtil.SyncAddBreakpoint("MemoryTestApp.cc:zeroBlocks", true); + SyncUtil.SyncResumeUntilStopped(); + SyncUtil.SyncStep(StepType.STEP_RETURN); + + // Setup call parameters + long offset = 0; + int word_size = 1; + int count = BLOCK_SIZE; + fBaseAddress = evaluateExpression("&charBlock"); + + // Make sure that the memory block is zeroed + fWait.waitReset(); + readMemory(fGdbControlDmc, fBaseAddress, offset, word_size, count); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + MemoryByte[] block = (MemoryByte[]) fWait.getReturnInfo(); + for (int i = 0; i < count; i++) { + assertTrue("Wrong value read at offset " + i + ": expected '" + 0 + "', received '" + block[i].getValue() + "'", + (block[i].getValue() == (byte) 0)); + } + + // Write an initialized memory block + byte[] buffer = new byte[count]; + for (int i = 0; i < count; i++) { + buffer[i] = (byte) i; + } + fWait.waitReset(); + writeMemory(fGdbControlDmc, fBaseAddress, offset, word_size, count, buffer); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Make sure that the memory block is initialized + fWait.waitReset(); + readMemory(fGdbControlDmc, fBaseAddress, offset, word_size, count); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + block = (MemoryByte[]) fWait.getReturnInfo(); + for (int i = 0; i < count; i++) { + assertTrue("Wrong value read at offset " + i + ": expected '" + 0 + "', received '" + block[i].getValue() + "'", + (block[i].getValue() == (byte) i)); + } + + // Ensure the MemoryChangedEvent events were received + assertTrue("MemoryChangedEvent problem: expected " + 1 + " event, received " + getEventCount(), + getEventCount() == 1); + assertTrue("MemoryChangedEvent problem: expected " + BLOCK_SIZE + " distinct addresses, received " + getAddressCount(), + getAddressCount() == BLOCK_SIZE); + } + + /////////////////////////////////////////////////////////////////////////// + // fillMemory tests + /////////////////////////////////////////////////////////////////////////// + + // ------------------------------------------------------------------------ + // fillWithNullContext + // Test that a null context is caught and generates an error + // ------------------------------------------------------------------------ + @Test + public void fillWithNullContext() throws Throwable { + + // Run to the point where the variable is initialized + SyncUtil.SyncAddBreakpoint("MemoryTestApp.cc:zeroBlocks", true); + SyncUtil.SyncResumeUntilStopped(); + SyncUtil.SyncStep(StepType.STEP_RETURN); + + // Setup call parameters + long offset = 0; + int word_size = 1; + int count = 1; + byte[] pattern = new byte[count]; + fBaseAddress = evaluateExpression("&charBlock"); + + // Perform the test + String expected = "Unknown context type"; + fWait.waitReset(); + fillMemory(null, fBaseAddress, offset, word_size, count, pattern); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertFalse(fWait.getMessage(), fWait.isOK()); + assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'", + fWait.getMessage().contains(expected)); + + // Ensure no MemoryChangedEvent event was received + assertTrue("MemoryChangedEvent problem: expected " + 0 + ", received " + getEventCount(), getEventCount() == 0); + } + + // ------------------------------------------------------------------------ + // fillWithInvalidAddress + // Test that an invalid address is caught and generates an error + // ------------------------------------------------------------------------ + @Test + public void fillWithInvalidAddress() throws Throwable { + + // Run to the point where the variable is initialized + SyncUtil.SyncAddBreakpoint("MemoryTestApp.cc:zeroBlocks", true); + SyncUtil.SyncResumeUntilStopped(); + SyncUtil.SyncStep(StepType.STEP_RETURN); + + // Setup call parameters + long offset = 0; + int word_size = 1; + int count = 1; + byte[] pattern = new byte[count]; + fBaseAddress = new Addr64("0"); + + // Perform the test + fWait.waitReset(); + fillMemory(fGdbControlDmc, fBaseAddress, offset, word_size, count, pattern); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertFalse(fWait.getMessage(), fWait.isOK()); + String expected = "Cannot access memory at address"; // Error msg returned by gdb + assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'", + fWait.getMessage().contains(expected)); + + // Ensure no MemoryChangedEvent event was received + assertTrue("MemoryChangedEvent problem: expected " + 0 + ", received " + getEventCount(), getEventCount() == 0); + } + + // ------------------------------------------------------------------------ + // fillWithInvalidWordSize + // Test that an invalid word size is caught and generates an error + // ------------------------------------------------------------------------ + @Test + public void fillWithInvalidWordSize() throws Throwable { + + // Run to the point where the variable is initialized + SyncUtil.SyncAddBreakpoint("MemoryTestApp.cc:zeroBlocks", true); + SyncUtil.SyncResumeUntilStopped(); + SyncUtil.SyncStep(StepType.STEP_RETURN); + + // Setup call parameters + long offset = 0; + int count = 1; + byte[] pattern = new byte[1]; + fBaseAddress = evaluateExpression("&charBlock"); + + // Perform the test + String expected = "Word size not supported (!= 1)"; + fWait.waitReset(); + fillMemory(fGdbControlDmc, fBaseAddress, offset, 0, count, pattern); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertFalse(fWait.getMessage(), fWait.isOK()); + assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'", + fWait.getMessage().contains(expected)); + + fWait.waitReset(); + fillMemory(fGdbControlDmc, fBaseAddress, offset, 2, count, pattern); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertFalse(fWait.getMessage(), fWait.isOK()); + assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'", + fWait.getMessage().contains(expected)); + + // Ensure no MemoryChangedEvent event was received + assertTrue("MemoryChangedEvent problem: expected " + 0 + ", received " + getEventCount(), getEventCount() == 0); + } + + // ------------------------------------------------------------------------ + // fillWithInvalidCount + // Test that an invalid count is caught and generates an error + // ------------------------------------------------------------------------ + @Test + public void fillWithInvalidCount() throws Throwable { + + // Run to the point where the variable is initialized + SyncUtil.SyncAddBreakpoint("MemoryTestApp.cc:zeroBlocks", true); + SyncUtil.SyncResumeUntilStopped(); + SyncUtil.SyncStep(StepType.STEP_RETURN); + + // Setup call parameters + long offset = 0; + int word_size = 1; + int count = -1; + byte[] pattern = new byte[1]; + fBaseAddress = evaluateExpression("&charBlock"); + + // Perform the test + String expected = "Invalid repeat count (< 0)"; + fWait.waitReset(); + fillMemory(fGdbControlDmc, fBaseAddress, offset, word_size, count, pattern); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertFalse(fWait.getMessage(), fWait.isOK()); + assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'", + fWait.getMessage().contains(expected)); + + // Ensure no MemoryChangedEvent event was received + assertTrue("MemoryChangedEvent problem: expected " + 0 + ", received " + getEventCount(), getEventCount() == 0); + } + + // ------------------------------------------------------------------------ + // fillWithInvalidPattern + // Test that an empty pattern is caught and generates an error + // ------------------------------------------------------------------------ + @Test + public void fillWithInvalidPattern() throws Throwable { + + // Run to the point where the variable is initialized + SyncUtil.SyncAddBreakpoint("MemoryTestApp.cc:zeroBlocks", true); + SyncUtil.SyncResumeUntilStopped(); + SyncUtil.SyncStep(StepType.STEP_RETURN); + + // Setup call parameters + long offset = 0; + int word_size = 1; + int count = 1; + byte[] pattern = new byte[0]; + fBaseAddress = evaluateExpression("&charBlock"); + + // Perform the test + String expected = "Empty pattern"; + fWait.waitReset(); + fillMemory(fGdbControlDmc, fBaseAddress, offset, word_size, count, pattern); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertFalse(fWait.getMessage(), fWait.isOK()); + assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'", + fWait.getMessage().contains(expected)); + + // Ensure no MemoryChangedEvent event was received + assertTrue("MemoryChangedEvent problem: expected " + 0 + ", received " + getEventCount(), getEventCount() == 0); + } + + // ------------------------------------------------------------------------ + // writePatternVaryingAddress + // Test the writing of the pattern by varying the base address + // ------------------------------------------------------------------------ + @Test + public void writePatternVaryingAddress() throws Throwable { + + // Run to the point where the variable is zeroed + SyncUtil.SyncAddBreakpoint("MemoryTestApp.cc:zeroBlocks", true); + SyncUtil.SyncResumeUntilStopped(); + SyncUtil.SyncStep(StepType.STEP_RETURN); + + // Setup call parameters + long offset = 0; + int word_size = 1; + int count = 1; + int length = 4; + byte[] pattern = new byte[length]; + for (int i = 0; i < length; i++) pattern[i] = (byte) i; + fBaseAddress = evaluateExpression("&charBlock"); + + // Ensure that the memory is zeroed + fWait.waitReset(); + readMemory(fGdbControlDmc, fBaseAddress, offset, word_size, count * length); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + MemoryByte[] block = (MemoryByte[]) fWait.getReturnInfo(); + for (int i = 0; i < (count * length); i++) + assertTrue("Wrong value read at offset " + i + ": expected '" + 0 + "', received '" + block[i].getValue() + "'", + (block[i].getValue() == (byte) 0)); + + for (int i = 0; i < BLOCK_SIZE; i += length) { + IAddress address = fBaseAddress.add(i); + fWait.waitReset(); + fillMemory(fGdbControlDmc, address, offset, word_size, count, pattern); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + + } + + // Verify that the memory is correctly set + fWait.waitReset(); + readMemory(fGdbControlDmc, fBaseAddress, 0, word_size, count * length); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + block = (MemoryByte[]) fWait.getReturnInfo(); + for (int i = 0; i < count; i++) + for (int j = 0; j < length; j++) { + int index = i * length + j; + assertTrue("Wrong value read at offset " + index + ": expected '" + j + "', received '" + block[index].getValue() + "'", + (block[index].getValue() == (byte) j)); + } + + // Ensure the MemoryChangedEvent events were received + assertTrue("MemoryChangedEvent problem: expected " + (BLOCK_SIZE / length) + " events, received " + getEventCount(), + getEventCount() == (BLOCK_SIZE / length)); + assertTrue("MemoryChangedEvent problem: expected " + BLOCK_SIZE + " distinct addresses, received " + getAddressCount(), + getAddressCount() == BLOCK_SIZE); + } + + // ------------------------------------------------------------------------ + // writePatternVaryingOffset + // Test the writing of the pattern by varying the base address + // ------------------------------------------------------------------------ + @Test + public void writePatternVaryingOffset() throws Throwable { + + // Run to the point where the variable is zeroed + SyncUtil.SyncAddBreakpoint("MemoryTestApp.cc:zeroBlocks", true); + SyncUtil.SyncResumeUntilStopped(); + SyncUtil.SyncStep(StepType.STEP_RETURN); + + // Setup call parameters + long offset = 0; + int word_size = 1; + int count = 64; + int length = 4; + byte[] pattern = new byte[length]; + for (int i = 0; i < length; i++) pattern[i] = (byte) i; + fBaseAddress = evaluateExpression("&charBlock"); + + // Ensure that the memory is zeroed + fWait.waitReset(); + readMemory(fGdbControlDmc, fBaseAddress, offset, word_size, count * length); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + MemoryByte[] block = (MemoryByte[]) fWait.getReturnInfo(); + for (int i = 0; i < (count * length); i++) + assertTrue("Wrong value read at offset " + i + ": expected '" + 0 + "', received '" + block[i].getValue() + "'", + (block[i].getValue() == (byte) 0)); + + for (int i = 0; i < (BLOCK_SIZE / length); i++) { + offset = i * length; + fWait.waitReset(); + fillMemory(fGdbControlDmc, fBaseAddress, offset, word_size, 1, pattern); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + + } + + // Verify that the memory is correctly set + fWait.waitReset(); + readMemory(fGdbControlDmc, fBaseAddress, 0, word_size, count * length); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + block = (MemoryByte[]) fWait.getReturnInfo(); + for (int i = 0; i < count; i++) + for (int j = 0; j < length; j++) { + int index = i * length + j; + assertTrue("Wrong value read at offset " + index + ": expected '" + j + "', received '" + block[index].getValue() + "'", + (block[index].getValue() == (byte) j)); + } + + // Ensure the MemoryChangedEvent events were received + assertTrue("MemoryChangedEvent problem: expected " + (BLOCK_SIZE / length) + " events, received " + getEventCount(), + getEventCount() == (BLOCK_SIZE / length)); + assertTrue("MemoryChangedEvent problem: expected " + BLOCK_SIZE + " distinct addresses, received " + getAddressCount(), + getAddressCount() == BLOCK_SIZE); + } + + // ------------------------------------------------------------------------ + // writePatternCountTimes + // Test the writing of the pattern [count] times + // ------------------------------------------------------------------------ + @Test + public void writePatternCountTimes() throws Throwable { + + // Run to the point where the variable is zeroed + SyncUtil.SyncAddBreakpoint("MemoryTestApp.cc:zeroBlocks", true); + SyncUtil.SyncResumeUntilStopped(); + SyncUtil.SyncStep(StepType.STEP_RETURN); + + // Setup call parameters + long offset = 0; + int word_size = 1; + int count = 64; + int length = 4; + byte[] pattern = new byte[length]; + for (int i = 0; i < length; i++) pattern[i] = (byte) i; + fBaseAddress = evaluateExpression("&charBlock"); + + // Ensure that the memory is zeroed + fWait.waitReset(); + readMemory(fGdbControlDmc, fBaseAddress, offset, word_size, count * length); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + MemoryByte[] block = (MemoryByte[]) fWait.getReturnInfo(); + for (int i = 0; i < (count * length); i++) + assertTrue("Wrong value read at offset " + i + ": expected '" + 0 + "', received '" + block[i].getValue() + "'", + (block[i].getValue() == (byte) 0)); + + // Write the pattern [count] times + fWait.waitReset(); + fillMemory(fGdbControlDmc, fBaseAddress, offset, word_size, count, pattern); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Verify that the memory is correctly set + fWait.waitReset(); + readMemory(fGdbControlDmc, fBaseAddress, offset, word_size, count * length); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + block = (MemoryByte[]) fWait.getReturnInfo(); + for (int i = 0; i < count; i++) + for (int j = 0; j < length; j++) { + int index = i * length + j; + assertTrue("Wrong value read at offset " + index + ": expected '" + j + "', received '" + block[index].getValue() + "'", + (block[index].getValue() == (byte) j)); + } + + // Ensure the MemoryChangedEvent events were received + assertTrue("MemoryChangedEvent problem: expected " + 1 + " events, received " + getEventCount(), + getEventCount() == 1); + assertTrue("MemoryChangedEvent problem: expected " + BLOCK_SIZE + " distinct addresses, received " + getAddressCount(), + getAddressCount() == BLOCK_SIZE); + } + + // ------------------------------------------------------------------------ + // asynchronousReadWrite + // Test the asynchronous reading/writing of individual bytes (varying offset) + // ------------------------------------------------------------------------ + @Test + public void asynchronousReadWrite() throws Throwable { + + // Run to the point where the array is zeroed + SyncUtil.SyncAddBreakpoint("MemoryTestApp.cc:zeroBlocks", true); + SyncUtil.SyncResumeUntilStopped(); + SyncUtil.SyncStep(StepType.STEP_RETURN); + + // Setup call parameters + int word_size = 1; + int count = 1; + fBaseAddress = evaluateExpression("&charBlock"); + + // Verify asynchronously that all bytes are '0' + fWait.waitReset(); + MemoryByte[] buffer = new MemoryByte[BLOCK_SIZE]; + for (int offset = 0; offset < BLOCK_SIZE; offset++) { + fWait.increment(); + readMemoryByteAtOffset(fGdbControlDmc, fBaseAddress, offset, word_size, count, buffer); + } + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + for (int offset = 0; offset < BLOCK_SIZE; offset++) { + assertTrue("Wrong value read at offset " + offset + ": expected '" + 0 + "', received '" + buffer[offset].getValue() + "'", + (buffer[offset].getValue() == (byte) 0)); + } + + // Write asynchronously + fWait.waitReset(); + for (int offset = 0; offset < BLOCK_SIZE; offset++) { + fWait.increment(); + byte[] block = new byte[count]; + block[0] = (byte) offset; + writeMemory(fGdbControlDmc, fBaseAddress, offset, word_size, count, block); + } + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Ensure the MemoryChangedEvent events were received + assertTrue("MemoryChangedEvent problem: expected " + BLOCK_SIZE + " events, received " + getEventCount(), + getEventCount() == BLOCK_SIZE); + assertTrue("MemoryChangedEvent problem: expected " + BLOCK_SIZE + " distinct addresses, received " + getAddressCount(), + getAddressCount() == BLOCK_SIZE); + + // Verify asynchronously that all bytes are set + fWait.waitReset(); + for (int offset = 0; offset < BLOCK_SIZE; offset++) { + fWait.increment(); + readMemoryByteAtOffset(fGdbControlDmc, fBaseAddress, offset, word_size, count, buffer); + } + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + for (int offset = 0; offset < BLOCK_SIZE; offset++) { + assertTrue("Wrong value read at offset " + offset + ": expected '" + offset + "', received '" + buffer[offset].getValue() + "'", + (buffer[offset].getValue() == (byte) offset)); + } + } + + // ------------------------------------------------------------------------ + // memoryCacheRead + // Get a bunch of blocks to exercise the memory cache + // ------------------------------------------------------------------------ + @Test + public void memoryCacheRead() throws Throwable { + + // Run to the point where the variable is initialized + SyncUtil.SyncAddBreakpoint("MemoryTestApp.cc:setBlocks", true); + SyncUtil.SyncResumeUntilStopped(); + SyncUtil.SyncStep(StepType.STEP_RETURN); + + // Setup call parameters + long offset = 0; + int word_size = 1; + int count = BLOCK_SIZE; + fBaseAddress = evaluateExpression("&charBlock"); + + // Get the 'reference' memory block + fWait.waitReset(); + readMemory(fGdbControlDmc, fBaseAddress, offset, word_size, count); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + MemoryByte[] buffer = (MemoryByte[]) fWait.getReturnInfo(); + + // Verify that all bytes are set to 'i' + for (int i = 0; i < count; i++) { + assertTrue("Wrong value read at offset " + i + ": expected '" + i + "', received '" + buffer[i].getValue() + "'", + (buffer[i].getValue() == (byte) i)); + } + + // Clear the cache + SyncUtil.SyncStep(StepType.STEP_OVER); + + // Get a first block + fWait.waitReset(); + offset = 0; + count = 64; + readMemory(fGdbControlDmc, fBaseAddress, offset, word_size, count); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + buffer = (MemoryByte[]) fWait.getReturnInfo(); + + // Verify that all bytes are correctly set + for (int i = 0; i < count; i++) { + assertTrue("Wrong value read at offset " + i + ": expected '" + offset + i + "', received '" + buffer[i].getValue() + "'", + (buffer[i].getValue() == (byte) (offset + i))); + } + + // Get a second block + fWait.waitReset(); + offset = 128; + count = 64; + readMemory(fGdbControlDmc, fBaseAddress, offset, word_size, count); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + buffer = (MemoryByte[]) fWait.getReturnInfo(); + + // Verify that all bytes are correctly set + for (int i = 0; i < count; i++) { + assertTrue("Wrong value read at offset " + i + ": expected '" + offset + i + "', received '" + buffer[i].getValue() + "'", + (buffer[i].getValue() == (byte) (offset + i))); + } + + // Get a third block between the first 2 + fWait.waitReset(); + offset = 80; + count = 32; + readMemory(fGdbControlDmc, fBaseAddress, offset, word_size, count); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + buffer = (MemoryByte[]) fWait.getReturnInfo(); + + // Verify that all bytes are correctly set + for (int i = 0; i < count; i++) { + assertTrue("Wrong value read at offset " + i + ": expected '" + offset + i + "', received '" + buffer[i].getValue() + "'", + (buffer[i].getValue() == (byte) (offset + i))); + } + + // Get a block that is contiguous to the end of an existing block + fWait.waitReset(); + offset = 192; + count = 32; + readMemory(fGdbControlDmc, fBaseAddress, offset, word_size, count); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + buffer = (MemoryByte[]) fWait.getReturnInfo(); + + // Verify that all bytes are correctly set + for (int i = 0; i < count; i++) { + assertTrue("Wrong value read at offset " + i + ": expected '" + offset + i + "', received '" + buffer[i].getValue() + "'", + (buffer[i].getValue() == (byte) (offset + i))); + } + + // Get a block that ends beyond an existing block + fWait.waitReset(); + offset = 192; + count = 64; + readMemory(fGdbControlDmc, fBaseAddress, offset, word_size, count); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + buffer = (MemoryByte[]) fWait.getReturnInfo(); + + // Verify that all bytes are correctly set + for (int i = 0; i < count; i++) { + assertTrue("Wrong value read at offset " + i + ": expected '" + offset + i + "', received '" + buffer[i].getValue() + "'", + (buffer[i].getValue() == (byte) (offset + i))); + } + + // Get a block that will require 2 reads (for the gaps between blocks 1-2 and 2-3) + fWait.waitReset(); + offset = 32; + count = 128; + readMemory(fGdbControlDmc, fBaseAddress, offset, word_size, count); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + buffer = (MemoryByte[]) fWait.getReturnInfo(); + + // Verify that all bytes are correctly set + for (int i = 0; i < count; i++) { + assertTrue("Wrong value read at offset " + i + ": expected '" + offset + i + "', received '" + buffer[i].getValue() + "'", + (buffer[i].getValue() == (byte) (offset + i))); + } + + // Get a block that involves multiple cached blocks + fWait.waitReset(); + offset = 48; + count = 192; + readMemory(fGdbControlDmc, fBaseAddress, offset, word_size, count); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + buffer = (MemoryByte[]) fWait.getReturnInfo(); + + // Verify that all bytes are set to 'i' + for (int i = 0; i < count; i++) { + assertTrue("Wrong value read at offset " + i + ": expected '" + offset + i + "', received '" + buffer[i].getValue() + "'", + (buffer[i].getValue() == (byte) (offset + i))); + } + + // Get the whole block + fWait.waitReset(); + offset = 0; + count = BLOCK_SIZE; + readMemory(fGdbControlDmc, fBaseAddress, offset, word_size, count); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + buffer = (MemoryByte[]) fWait.getReturnInfo(); + + // Verify that all bytes are correctly set + for (int i = 0; i < count; i++) { + assertTrue("Wrong value read at offset " + i + ": expected '" + offset + i + "', received '" + buffer[i].getValue() + "'", + (buffer[i].getValue() == (byte) (offset + i))); + } + // Ensure no MemoryChangedEvent event was received + assertTrue("MemoryChangedEvent problem: expected " + 0 + ", received " + getEventCount(), getEventCount() == 0); + } + +} diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRegistersTest.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRegistersTest.java new file mode 100644 index 00000000000..d2006049a4a --- /dev/null +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRegistersTest.java @@ -0,0 +1,428 @@ +package org.eclipse.dd.tests.gdb; + + +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.List; + +import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.debug.service.IFormattedValues; +import org.eclipse.dd.dsf.debug.service.IRegisters; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData; +import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext; +import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext; +import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.gdb.service.command.GDBControl; +import org.eclipse.dd.gdb.service.command.GDBControlDMContext; +import org.eclipse.dd.mi.service.IMIExecutionDMContext; +import org.eclipse.dd.mi.service.MIRunControl; +import org.eclipse.dd.mi.service.MIStack; +import org.eclipse.dd.mi.service.command.events.MIStoppedEvent; +import org.eclipse.dd.tests.gdb.framework.AsyncCompletionWaitor; +import org.eclipse.dd.tests.gdb.framework.BackgroundRunner; +import org.eclipse.dd.tests.gdb.framework.BaseTestCase; +import org.eclipse.dd.tests.gdb.framework.SyncUtil; +import org.eclipse.dd.tests.gdb.launching.TestsPlugin; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(BackgroundRunner.class) + +public class MIRegistersTest extends BaseTestCase { + + final int NUMBER_OF_REGISTERS = 50; + /* + * Path to executable + */ + private static final String EXEC_PATH = "data/launch/bin/"; + /* + * Name of the executable + */ + private static final String EXEC_NAME = "MultiThread.exe"; + + // Will be used to wait for asynchronous call to complete + //private final AsyncCompletionWaitor fWait = new AsyncCompletionWaitor(); + private DsfSession fSession; + private DsfServicesTracker fServicesTracker; + private GDBControlDMContext fGdbControlDmc; + private IRegisters fRegService; + private MIRunControl fRunControl; + private MIStack fStack; + + @Before + public void init() throws Exception { + fSession = getGDBLaunch().getSession(); + // We obtain the services we need after the new + // launch has been performed + fServicesTracker = new DsfServicesTracker(TestsPlugin.getBundleContext(), fSession.getId()); + + GDBControl gdbControl = fServicesTracker.getService(GDBControl.class); + fGdbControlDmc = gdbControl.getGDBDMContext(); + + fRegService = fServicesTracker.getService(IRegisters.class); + fRunControl = fServicesTracker.getService(MIRunControl.class); + fStack = fServicesTracker.getService(MIStack.class); + +// This is the way to have the entire application run +// final IDMContext execDMContext = ((MIRunControl)fRunControl).getExecutionDMC(); +// fRunControl.getExecutor().submit(new Runnable() { +// public void run() { +// fRunControl.resume(execDMContext, null); +// } +// }); + + } + + @BeforeClass + public static void beforeClassMethod() { + setLaunchAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, + EXEC_PATH + EXEC_NAME); + } + + + @After + public void tearDown() { + fRegService = null; + fRunControl = null; + fStack = null; + } + + /* + * This is a common support method which gets the Register Group Information + * and verifies it. + */ + private IRegisterGroupDMContext getRegisterGroup() throws Throwable { + final AsyncCompletionWaitor fWait = new AsyncCompletionWaitor(); + + final DataRequestMonitor regGroupDone = + new DataRequestMonitor(fRegService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + fWait.setReturnInfo(getData()); + } + + fWait.waitFinished(getStatus()); + } + }; + + fRegService.getExecutor().submit(new Runnable() { + public void run() { + fRegService.getRegisterGroups(fGdbControlDmc, regGroupDone); + } + }); + + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + + IRegisterGroupDMContext[] regGroupsDMCs = (IRegisterGroupDMContext[])fWait.getReturnInfo(); + assertTrue("There was more than one register group (" + regGroupsDMCs.length + ")", //$NON-NLS-1$ + regGroupsDMCs.length == 1 ); + fWait.waitReset(); + + return(regGroupsDMCs[0]); + } + + /* + * This is a common support method which gets the Registers names. + */ + + private IRegisterDMContext[] getRegisters(final IFrameDMContext frameDmc) throws Throwable { + final AsyncCompletionWaitor fWait = new AsyncCompletionWaitor(); + final IRegisterGroupDMContext regGroupsDMC = getRegisterGroup(); + + final DataRequestMonitor regDone = + new DataRequestMonitor(fRegService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + fWait.setReturnInfo(getData()); + } + + fWait.waitFinished(getStatus()); + } + }; + + fRegService.getExecutor().submit(new Runnable() { + public void run() { +// fRegService.getRegisters(regGroupsDMC, frameDmc, regDone); + fWait.waitFinished( + new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Commented out some code until it can compile", null)); + } + }); + + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + + IRegisterDMContext[] regContexts = (IRegisterDMContext[]) fWait.getReturnInfo(); + + fWait.waitReset(); + + assertTrue("The number of registers should have been " + NUMBER_OF_REGISTERS + + " instead of " + regContexts.length, + regContexts.length == NUMBER_OF_REGISTERS); + + return(regContexts); + } + + /************************************************************************* + * + * The tests for the register service. + * + *************************************************************************/ + + @Test + public void getRegisterGroups() throws Throwable { + final IRegisterGroupDMContext regGroupsDMC = getRegisterGroup(); + + assertTrue("The name of the main group should be: General Registers instead of: " + + regGroupsDMC.getName(), + regGroupsDMC.getName().equals("General Registers")); + } + + @Test + public void getRegistersLength() throws Throwable { + IMIExecutionDMContext execDmc = fRunControl.createMIExecutionContext(fGdbControlDmc, 1); + IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(execDmc, 0); + final IRegisterDMContext[] regDMCs = getRegisters(frameDmc); + assertTrue("The number of registers should have been " + NUMBER_OF_REGISTERS + + " instead of " + regDMCs.length, + regDMCs.length == NUMBER_OF_REGISTERS); + + } + + @Test + public void getRegisters() throws Throwable { + IMIExecutionDMContext execDmc = fRunControl.createMIExecutionContext(fGdbControlDmc, 1); + IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(execDmc, 0); + final IRegisterDMContext[] regDMCs = getRegisters(frameDmc); + List regNames = Arrays.asList("eax","ecx","edx","ebx","esp","ebp","esi","edi","eip","eflags","cs","ss","ds","es","fs","gs","st0","st1","st2","st3","st4","st5","st6","st7","fctrl","fstat","ftag","fiseg","fioff","foseg","fooff","fop","xmm0","xmm1","xmm2","xmm3","xmm4","xmm5","xmm6","xmm7","mxcsr","orig_eax","mm0","mm1","mm2","mm3","mm4","mm5","mm6","mm7"); + for(IRegisterDMContext reg: regDMCs){ + String regName = reg.getName(); + Assert.assertFalse("GDB does not support register name: " + regName, !regNames.contains(regName)); + } + } + + //private static String REGISTER_VALUE = "16"; + private String getModelDataForRegisterDataValue(IFrameDMContext frameDmc, String format, int regNo) throws Throwable { + final AsyncCompletionWaitor fWait = new AsyncCompletionWaitor(); + + final IRegisterDMContext[] regDMCs = getRegisters(frameDmc); + final FormattedValueDMContext valueDmc = fRegService.getFormattedValueContext(regDMCs[regNo], format); + + final DataRequestMonitor regRm = + new DataRequestMonitor(fRegService.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + fWait.setReturnInfo(getData()); + } + + fWait.waitFinished(getStatus()); + } + }; + + fRegService.getExecutor().submit(new Runnable() { + public void run() { + fRegService.getFormattedExpressionValue(valueDmc, regRm); + } + }); + + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + + + FormattedValueDMData data = (FormattedValueDMData)fWait.getReturnInfo(); + String val = data.getFormattedValue(); + fWait.waitReset(); + return val; + } + + + private static String REGISTER_VALUE = ""; + @Test + public void getModelDataForRegisterDataValueNatural() throws Throwable { + IMIExecutionDMContext execDmc = fRunControl.createMIExecutionContext(fGdbControlDmc, 1); + IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(execDmc, 0); + String val = getModelDataForRegisterDataValue(frameDmc, IFormattedValues.NATURAL_FORMAT, 0); + REGISTER_VALUE = val; + assertTrue("Register Value is not in NATURAL format " , Integer.parseInt(val)== Integer.parseInt(REGISTER_VALUE)); + } + + @Test + public void getModelDataForRegisterDataValueHex() throws Throwable { + IMIExecutionDMContext execDmc = fRunControl.createMIExecutionContext(fGdbControlDmc, 1); + IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(execDmc, 0); + String val = getModelDataForRegisterDataValue(frameDmc, IFormattedValues.HEX_FORMAT, 0); + assertTrue("Register Value is not in HEX_FORMAT " ,val.startsWith("0x")); + } + + @Test + public void getModelDataForRegisterDataValueBinary() throws Throwable { + IMIExecutionDMContext execDmc = fRunControl.createMIExecutionContext(fGdbControlDmc, 1); + IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(execDmc, 0); + + String val = getModelDataForRegisterDataValue(frameDmc, IFormattedValues.BINARY_FORMAT, 0); + assertTrue("Register Value is not in BINARY_FORMAT " , val.equals(Integer.toBinaryString(Integer.parseInt(REGISTER_VALUE)))); + } + + @Test + public void getModelDataForRegisterDataValueDecimal() throws Throwable { + IMIExecutionDMContext execDmc = fRunControl.createMIExecutionContext(fGdbControlDmc, 1); + IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(execDmc, 0); + + String val = getModelDataForRegisterDataValue(frameDmc, IFormattedValues.DECIMAL_FORMAT , 0); + assertTrue("Register Value is not in DECIMAL_FORMAT" ,Integer.parseInt(val) == Integer.parseInt(REGISTER_VALUE)); + } + + @Test + public void getModelDataForRegisterDataValueOctal() throws Throwable { + IMIExecutionDMContext execDmc = fRunControl.createMIExecutionContext(fGdbControlDmc, 1); + IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(execDmc, 0); + String val = getModelDataForRegisterDataValue(frameDmc, IFormattedValues.OCTAL_FORMAT, 0); + assertTrue("Register Value is not in OCTAL_FORMAT " ,val.startsWith("0")); + } + + + @Test + public void compareRegisterForMultipleExecutionContexts() throws Throwable { + final AsyncCompletionWaitor fWait = new AsyncCompletionWaitor(); + + IMIExecutionDMContext execDmc = fRunControl.createMIExecutionContext(fGdbControlDmc, 1); + IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(execDmc, 0); + + String regVal0 = getModelDataForRegisterDataValue(frameDmc, IFormattedValues.NATURAL_FORMAT, 0); + String regVal1 = getModelDataForRegisterDataValue(frameDmc, IFormattedValues.NATURAL_FORMAT, 1); + String regVal2 = getModelDataForRegisterDataValue(frameDmc, IFormattedValues.NATURAL_FORMAT, 2); + String regVal3 = getModelDataForRegisterDataValue(frameDmc, IFormattedValues.NATURAL_FORMAT, 3); + String regVal4 = getModelDataForRegisterDataValue(frameDmc, IFormattedValues.NATURAL_FORMAT, 4); + String regVal5 = getModelDataForRegisterDataValue(frameDmc, IFormattedValues.NATURAL_FORMAT, 5); + + MIStoppedEvent stoppedEvent = SyncUtil.SyncRunToLine(EXEC_NAME + ".cc", "22"); + execDmc = fRunControl.createMIExecutionContext(fGdbControlDmc, 2); + frameDmc = SyncUtil.SyncGetStackFrame(execDmc, 0); + String thread2RegVal0 = getModelDataForRegisterDataValue(frameDmc, IFormattedValues.NATURAL_FORMAT, 0); + String thread2RegVal1 = getModelDataForRegisterDataValue(frameDmc, IFormattedValues.NATURAL_FORMAT, 1); + String thread2RegVal2 = getModelDataForRegisterDataValue(frameDmc, IFormattedValues.NATURAL_FORMAT, 2); + String thread2RegVal3 = getModelDataForRegisterDataValue(frameDmc, IFormattedValues.NATURAL_FORMAT, 3); + String thread2RegVal4 = getModelDataForRegisterDataValue(frameDmc, IFormattedValues.NATURAL_FORMAT, 4); + String thread2RegVal5 = getModelDataForRegisterDataValue(frameDmc, IFormattedValues.NATURAL_FORMAT, 5); + + // Set execution context to 1 + execDmc = fRunControl.createMIExecutionContext(fGdbControlDmc, 1); + frameDmc = SyncUtil.SyncGetStackFrame(execDmc, 0); + getModelDataForRegisterDataValue(frameDmc, IFormattedValues.NATURAL_FORMAT, 0); + + // Re-set the execution context to 2 and Fetch from the Cache + execDmc = fRunControl.createMIExecutionContext(fGdbControlDmc, 2); + frameDmc = SyncUtil.SyncGetStackFrame(execDmc, 0); + String dupliThread2RegVal0 = getModelDataForRegisterDataValue(frameDmc, IFormattedValues.NATURAL_FORMAT, 0); + String dupliThread2RegVal1 = getModelDataForRegisterDataValue(frameDmc, IFormattedValues.NATURAL_FORMAT, 1); + String dupliThread2RegVal2 = getModelDataForRegisterDataValue(frameDmc, IFormattedValues.NATURAL_FORMAT, 2); + String dupliThread2RegVal3 = getModelDataForRegisterDataValue(frameDmc, IFormattedValues.NATURAL_FORMAT, 3); + String dupliThread2RegVal4 = getModelDataForRegisterDataValue(frameDmc, IFormattedValues.NATURAL_FORMAT, 4); + String dupliThread2RegVal5= getModelDataForRegisterDataValue(frameDmc, IFormattedValues.NATURAL_FORMAT, 5); + + // If Values not equal , then context haven't been re-set properly + assertTrue("Multiple context not working. Execution Context is not reset to 2", thread2RegVal0.equals(dupliThread2RegVal0)); + assertTrue("Multiple context not working. Execution Context is not reset to 2", thread2RegVal1.equals(dupliThread2RegVal1)); + assertTrue("Multiple context not working. Execution Context is not reset to 2", thread2RegVal2.equals(dupliThread2RegVal2)); + assertTrue("Multiple context not working. Execution Context is not reset to 2", thread2RegVal3.equals(dupliThread2RegVal3)); + assertTrue("Multiple context not working. Execution Context is not reset to 2", thread2RegVal4.equals(dupliThread2RegVal4)); + assertTrue("Multiple context not working. Execution Context is not reset to 2", thread2RegVal5.equals(dupliThread2RegVal5)); + + } + + private void writeRegister(IFrameDMContext frameDmc, final int regIndex, final String regValue, final String formatId) throws Throwable { + final AsyncCompletionWaitor fWait = new AsyncCompletionWaitor(); + +// final MIRegisterGroupDMC grpDmc = new MIRegisterGroupDMC( (MIRegisters)fRegService , 0 , "General Registers" ) ; + final IRegisterDMContext[] regDMCs = getRegisters(frameDmc); + + + final RequestMonitor writeDone = + new RequestMonitor(fRegService.getExecutor(), null) { + @Override + protected void handleCompleted() { + fWait.waitFinished(getStatus()); + } + }; + + fRegService.getExecutor().submit(new Runnable() { + public void run() { +// fRegService.writeRegister(grpDmc, regDMCs[regIndex], regValue, +// formatId, writeDone); + fWait.waitFinished( + new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "Commented out some code until it can compile", null)); + + } + }); + + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + fWait.waitReset(); + } + + + @Test + public void writeRegisterNaturalFormat() throws Throwable{ + IMIExecutionDMContext execDmc = fRunControl.createMIExecutionContext(fGdbControlDmc, 1); + IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(execDmc, 0); + String regValue = "10"; + int regIndex = 3; + writeRegister(frameDmc, 3, regValue, IFormattedValues.NATURAL_FORMAT); + String val = getModelDataForRegisterDataValue(frameDmc, IFormattedValues.NATURAL_FORMAT, regIndex); + assertTrue("Failed writing register. New value should have been " + regValue, regValue.equals(val)); + } + + @Test + public void writeRegisterHEXFormat() throws Throwable{ + IMIExecutionDMContext execDmc = fRunControl.createMIExecutionContext(fGdbControlDmc, 1); + IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(execDmc, 0); + String regValue = "0x10"; + int regIndex = 3; + writeRegister(frameDmc, 3, regValue, IFormattedValues.HEX_FORMAT); + String val = getModelDataForRegisterDataValue(frameDmc, IFormattedValues.HEX_FORMAT, regIndex); + assertTrue("Failed writing register. New value should have been " + regValue, regValue.equals(val)); + } + + @Test + @Ignore + public void writeRegisterBinaryFormat() throws Throwable{ + IMIExecutionDMContext execDmc = fRunControl.createMIExecutionContext(fGdbControlDmc, 1); + IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(execDmc, 0); + //String regValue = "0100101001"; + String regValue = "10"; + int regIndex = 3; + writeRegister(frameDmc, 3, regValue, IFormattedValues.BINARY_FORMAT); + String val = getModelDataForRegisterDataValue(frameDmc, IFormattedValues.BINARY_FORMAT, regIndex); + assertTrue("Failed writing register. New value should have been " + regValue + " instead of " + val, regValue.equals(val)); + } + + @Test + public void writeRegisterOctalFormat() throws Throwable{ + IMIExecutionDMContext execDmc = fRunControl.createMIExecutionContext(fGdbControlDmc, 1); + IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(execDmc, 0); + //String regValue = "10"; + String regValue = "012"; + int regIndex = 3; + writeRegister(frameDmc, 3, regValue, IFormattedValues.OCTAL_FORMAT); + String val = getModelDataForRegisterDataValue(frameDmc, IFormattedValues.OCTAL_FORMAT, regIndex); + assertTrue("Failed writing register. New value should have been " + regValue + "instead of " + val, regValue.equals(val)); + } + +} diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRunControlTest.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRunControlTest.java new file mode 100644 index 00000000000..46405971cd8 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRunControlTest.java @@ -0,0 +1,654 @@ +/******************************************************************************* + * Copyright (c) 2007 Ericsson 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: + * Ericsson AB - Initial implementation of Test cases + *******************************************************************************/ +package org.eclipse.dd.tests.gdb; + + +import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMData; +import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl.IStartedDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason; +import org.eclipse.dd.dsf.debug.service.IRunControl.StepType; +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.gdb.service.command.GDBControl; +import org.eclipse.dd.gdb.service.command.GDBControlDMContext; +import org.eclipse.dd.mi.service.IMIExecutionDMContext; +import org.eclipse.dd.mi.service.MIRunControl; +import org.eclipse.dd.mi.service.MIStack; +import org.eclipse.dd.mi.service.command.events.MIStoppedEvent; +import org.eclipse.dd.mi.service.command.output.MIInfo; +import org.eclipse.dd.tests.gdb.framework.AsyncCompletionWaitor; +import org.eclipse.dd.tests.gdb.framework.BaseTestCase; +import org.eclipse.dd.tests.gdb.framework.ServiceEventWaitor; +import org.eclipse.dd.tests.gdb.framework.SyncUtil; +import org.eclipse.dd.tests.gdb.launching.TestsPlugin; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; + + +/* + * Tests MIRunControl class for Multi-threaded application. + */ +public class MIRunControlTest extends BaseTestCase { + + private DsfServicesTracker fServicesTracker; + + private GDBControl fGDBCtrl; + private MIRunControl fRunCtrl; + private MIStack fStack; + + /* + * Boolean variables for testing events. Test thread create event only when this is set to true + */ + private boolean fIsTestingThreadCreateEvent = false; + /* + * Boolean variables for error from events. Set to true only if there is an error in the event being tested. + */ + private boolean fIsEventError = false; + + + /* + * Path to executable + */ + private static final String EXEC_PATH = "data/launch/bin/"; + /* + * Name of the executable + */ + private static final String EXEC_NAME = "MultiThread.exe"; + private static final String SOURCE_NAME = "MultiThread.cc"; + + + /* + * Variable to wait for asynchronous call to complete + */ + private final AsyncCompletionWaitor fWait = new AsyncCompletionWaitor(); + + @Before + public void init() throws Exception { + fServicesTracker = + new DsfServicesTracker(TestsPlugin.getBundleContext(), + getGDBLaunch().getSession().getId()); + /* + * Get the MIRunControl & MIStack service. + */ + fGDBCtrl = fServicesTracker.getService(GDBControl.class); + fRunCtrl = fServicesTracker.getService(MIRunControl.class); + fStack = fServicesTracker.getService(MIStack.class); + /* + * Add to the Listeners list + */ + getGDBLaunch().getSession().addServiceEventListener(this, null); + } + + @After + public void tearDown() { + fRunCtrl = null; + fStack = null; + fServicesTracker.dispose(); + } + + @BeforeClass + public static void beforeClassMethod() { + setLaunchAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, + EXEC_PATH + EXEC_NAME); + } + + + /* + * For Multi-threaded application - In case of one thread, Thread id should start with 1. + */ + @Test + public void getExecutionContext() throws InterruptedException{ + //TestsPlugin.debugMethod("getExecutionContext()"); + /* + * Create a request monitor + */ + final DataRequestMonitor rm = + new DataRequestMonitor(fRunCtrl.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + fWait.setReturnInfo(getData()); + } + fWait.waitFinished(getStatus()); + } + }; + + /* + * Test getExecutionContexts() when only one thread exist. + */ + fRunCtrl.getExecutor().submit(new Runnable() { + public void run() { + fRunCtrl.getExecutionContexts(fGDBCtrl.getGDBDMContext(), rm); + } + }); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + Assert.assertTrue(fWait.getMessage(), fWait.isOK()); + + /* + * Get data from the Request Monitor + */ + IRunControl.IExecutionDMContext[] ctxts = rm.getData(); + + // Context can not be null + if(ctxts == null) + Assert.fail("Context returned is null. Atleast one context should have been returned"); + else{ + // Only one Context in this case + if(ctxts.length > 1) + Assert.fail("Context returned canot be more than 1. This test case is for single context application."); + IMIExecutionDMContext dmc = (IMIExecutionDMContext)ctxts[0]; + // Thread id for the main thread should be one + Assert.assertEquals(1, dmc.getThreadId()); + } + fWait.waitReset(); + } + + + /* + * Get Execution DMCs for a valid container DMC + * Testing for two execution DMC with id 1 & 2 + */ + @Test + public void getExecutionContexts() throws InterruptedException{ + //TestsPlugin.debugMethod("getExecutionContexts()"); + /* + * Create a request monitor + */ + final DataRequestMonitor rmExecutionCtxts = + new DataRequestMonitor(fRunCtrl.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + fWait.setReturnInfo(getData()); + } + fWait.waitFinished(getStatus()); + } + }; + /* + * Also Testing Thread create event. Set boolean variable to true + */ + fIsTestingThreadCreateEvent = true; + try{ + /* + * Run till line for 2 threads to be created + */ + SyncUtil.SyncRunToLine(fGDBCtrl.getGDBDMContext(), SOURCE_NAME, "22", true); + } + catch(Throwable t){ + Assert.fail("Exception in SyncUtil.SyncRunToLine: " + t.getMessage()); + } + /* + * Re-set the boolean variable for testing thread create event. + */ + fIsTestingThreadCreateEvent = false; + /* + * Check if error in thread create event + */ + if(fIsEventError){ + Assert.fail("Thread create event has failed."); + } + /* + * Test getExecutionContexts for a valid container DMC + */ + fRunCtrl.getExecutor().submit(new Runnable() { + public void run() { + fRunCtrl.getExecutionContexts(fGDBCtrl.getGDBDMContext(), rmExecutionCtxts); + } + }); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + Assert.assertTrue(fWait.getMessage(), fWait.isOK()); + fWait.waitReset(); + /* + * Get data + */ + IRunControl.IExecutionDMContext[] data = rmExecutionCtxts.getData(); + /* + * Contexts returned can not be null + */ + if(data == null) + Assert.fail("No context returned. 2 Contexts with id 1 & 2 should have been returned"); + else{ + // 2 Contexts shd be returned + Assert.assertTrue(data.length==2); + IMIExecutionDMContext dmc1 = (IMIExecutionDMContext)data[0]; + IMIExecutionDMContext dmc2 = (IMIExecutionDMContext)data[1]; + // Context ids should be 1 & 2 + Assert.assertTrue(dmc1.getThreadId()==2 && dmc2.getThreadId() == 1); + } + } + + /* + * Testing getModelData() for ExecutionDMC + */ + @Test + public void getModelDataForThread() throws InterruptedException{ + //TestsPlugin.debugMethod("getModelDataForThread("); + /* + * Create a request monitor + */ + final DataRequestMonitor rm = + new DataRequestMonitor(fRunCtrl.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + fWait.setReturnInfo(getData()); + } + fWait.waitFinished(getStatus()); + } + }; + /* + * Call getModelData for Execution DMC + */ + fRunCtrl.getExecutor().submit(new Runnable() { + public void run() { + fRunCtrl.getExecutionData(fRunCtrl.createMIExecutionContext(fGDBCtrl.getGDBDMContext(), 1), rm); + } + }); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + Assert.assertTrue(fWait.getMessage(), fWait.isOK()); + + IRunControl.IExecutionDMData data = rm.getData(); + if(data == null) + Assert.fail("No data returned."); + else{ + /* + * getModelData should return StateChangeReason. + */ + Assert.assertTrue(" State change reason for a normal execution should be CONTAINER." , + StateChangeReason.CONTAINER == data.getStateChangeReason()); + } + } + + @Test + public void getModelDataForThreadWhenStep() throws Throwable { + //TestsPlugin.debugMethod("getModelDataForThread()"); + /* + * Run till step returns + */ + final MIStoppedEvent stoppedEvent = SyncUtil.SyncStep(StepType.STEP_OVER); + + final DataRequestMonitor rm = + new DataRequestMonitor(fRunCtrl.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + fWait.setReturnInfo(getData()); + } + fWait.waitFinished(getStatus()); + } + }; + /* + * getModelData for Execution DMC + */ + fRunCtrl.getExecutor().submit(new Runnable() { + public void run() { + fRunCtrl.getExecutionData(stoppedEvent.getDMContext(), rm); + } + }); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + Assert.assertTrue(fWait.getMessage(), fWait.isOK()); + + IRunControl.IExecutionDMData data = rm.getData(); + if(data == null) + Assert.fail("No data Returned."); + else{ + /* + * getModelData for Execution DMC in case Step has been performed. + */ + Assert.assertTrue("getModelData for ExecutionDMC in case of step should be STEP." , + StateChangeReason.STEP == data.getStateChangeReason()); + } + } + + /* + * getModelData() for ExecutionDMC when a breakpoint is hit + */ + @Test + public void getModelDataForThreadWhenBreakpoint() throws Throwable { + //TestsPlugin.debugMethod("getModelDataForThreadWhenBreakpoint()"); + /* + * Add a breakpoint + */ + SyncUtil.SyncAddBreakpoint(SOURCE_NAME + ":21", false); + + /* + * Resume till the breakpoint is hit + */ + final MIStoppedEvent stoppedEvent = SyncUtil.SyncResumeUntilStopped(); + + final DataRequestMonitor rm = + new DataRequestMonitor(fRunCtrl.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + fWait.setReturnInfo(getData()); + } + fWait.waitFinished(getStatus()); + } + }; + fRunCtrl.getExecutor().submit(new Runnable() { + public void run() { + fRunCtrl.getExecutionData(stoppedEvent.getDMContext(), rm); + } + }); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + Assert.assertTrue(fWait.getMessage(), fWait.isOK()); + + IRunControl.IExecutionDMData data = rm.getData(); + if(data == null) + Assert.fail("No data Returned."); + else{ + /* + * getModelData for ExecutionDMC in case a breakpoint is hit + */ + Assert.assertTrue("getModelData for an Execution DMC when a breakpoint is hit is not BREAKPOINT and is " + data.getStateChangeReason(), + StateChangeReason.BREAKPOINT == data.getStateChangeReason()); + } + } + + /* + * getModelData() for Container DMC + */ + @Test + public void getModelDataForContainer() throws InterruptedException{ + //TestsPlugin.debugMethod("getModelDataForContainer()"); + final DataRequestMonitor rm = + new DataRequestMonitor(fRunCtrl.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + fWait.setReturnInfo(getData()); + } + fWait.waitFinished(getStatus()); + } + }; + + fRunCtrl.getExecutor().submit(new Runnable() { + public void run() { + fRunCtrl.getExecutionData(fGDBCtrl.getGDBDMContext(), rm); + } + }); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + Assert.assertTrue(fWait.getMessage(), fWait.isOK()); + + IRunControl.IExecutionDMData data = rm.getData(); + if(data == null) + Assert.fail("No data returned."); + else{ + /* + * StateChangeReason in getModelData for Container DMC is null. + */ + Assert.assertNull(data.getStateChangeReason()); + } + } + + /* + * getExecutionContexts for an invalid container DMC + */ + @Ignore + @Test + public void getExecutionContextsForInvalidContainerDMC() throws InterruptedException{ + //TestsPlugin.debug("getExecutionContextsForInvalidContainerDMC()"); + final DataRequestMonitor rm = + new DataRequestMonitor(fRunCtrl.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + fWait.setReturnInfo(getData()); + } + fWait.waitFinished(getStatus()); + } + }; + final IContainerDMContext ctxt = new GDBControlDMContext("-1", getClass().getName() + ":" + 1); + fRunCtrl.getExecutor().submit(new Runnable() { + public void run() { + // Pass an invalid dmc + fRunCtrl.getExecutionContexts(fGDBCtrl.getGDBDMContext(), rm); + } + }); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + Assert.assertTrue(fWait.getMessage(), !fWait.isOK()); + + IStatus status = rm.getStatus(); + Assert.assertEquals("Error message for invalid container", IStatus.ERROR, status.getSeverity()); + } + + /* + * Test Thread Create event for thread ID. Thread IDs should be GDB generated thread ids. + */ + @DsfServiceEventHandler + public void eventDispatched(IStartedDMEvent e) { + if(fIsTestingThreadCreateEvent){ + if(((IMIExecutionDMContext)e.getExecutionContext()).getThreadId() != 2) + /* + * Set variable if thread create event is unsuccesful + */ + fIsEventError = true; + } + } + + /* + * Cache after ContainerSuspendEvent should be re-set + */ + @Test + public void cacheAfterContainerSuspendEvent() throws InterruptedException{ + //TestsPlugin.debugMethod("cacheAfterContainerSuspendEvent()"); + final IExecutionDMContext dmc = fRunCtrl.createMIExecutionContext(fGDBCtrl.getGDBDMContext(), 1); + /* + * Step to fire ContainerSuspendEvent + */ + try { + SyncUtil.SyncStep(dmc, StepType.STEP_OVER); + } catch (Throwable e) { + Assert.fail("Exception in SyncUtil.SyncStep: " + e.getMessage()); + } + /* + * Cache should be re-set + */ + //TODO TRy going to back end and fetching values instead + //Assert.assertEquals(fRunCtrl.getCache().getCachedContext().size(), 0); + } + + + //Also test Cache after ContainerResumeEvent + @Test + public void resume() throws InterruptedException{ + //TestsPlugin.debugMethod("resume()"); + + final DataRequestMonitor rm = + new DataRequestMonitor(fRunCtrl.getExecutor(), null) { + @Override + protected void handleCompleted() { + fWait.waitFinished(getStatus()); + //TestsPlugin.debug("handleCompleted over"); + } + }; + final ServiceEventWaitor eventWaitor = + new ServiceEventWaitor( + getGDBLaunch().getSession(), + IResumedDMEvent.class); + + fRunCtrl.getExecutor().submit(new Runnable() { + public void run() { + fRunCtrl.resume(fGDBCtrl.getGDBDMContext(), rm); + } + }); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + + try { + eventWaitor.waitForEvent(ServiceEventWaitor.WAIT_FOREVER); + } catch (Exception e) { + Assert.fail("Exception raised:: " + e.getMessage()); + e.printStackTrace(); + return; + } + if (fWait.isOK() == false) + Assert.assertTrue(fWait.getMessage(), false); + Assert.assertFalse("Target is suspended. It should have been running", fRunCtrl.isSuspended(fGDBCtrl.getGDBDMContext())); + fWait.waitReset(); + } + + + + + @Test + public void resumeContainerContext() throws InterruptedException{ + //TestsPlugin.debugMethod("resumeContainerContext()"); + final DataRequestMonitor rm = + new DataRequestMonitor(fRunCtrl.getExecutor(), null) { + @Override + protected void handleCompleted() { + fWait.waitFinished(getStatus()); + } + }; + + final ServiceEventWaitor eventWaitor = + new ServiceEventWaitor( + getGDBLaunch().getSession(), + IResumedDMEvent.class); + + fRunCtrl.getExecutor().submit(new Runnable() { + public void run() { + fRunCtrl.resume(fGDBCtrl.getGDBDMContext(), rm); + } + }); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + try { + eventWaitor.waitForEvent(ServiceEventWaitor.WAIT_FOREVER); + //TestsPlugin.debug("DsfMIRunningEvent received"); + } catch (Exception e) { + Assert.fail("Exception raised:: " + e.getMessage()); + e.printStackTrace(); + return; + } + + if (fWait.isOK() == false) + Assert.assertTrue(fWait.getMessage(), false); + Assert.assertFalse("Target is suspended. It should have been running", fRunCtrl.isSuspended(fGDBCtrl.getGDBDMContext())); + fWait.waitReset(); + } + + // PP: test no longer applies, the resume command now takes a strongly-typed execution context as an argument. + // +// @Test +// public void resumeFrameContext() throws Throwable { +// //TestsPlugin.debugMethod("resumeFrameContext()"); +// final DataRequestMonitor rm = +// new DataRequestMonitor(fRunCtrl.getExecutor(), null) { +// @Override +// protected void handleCompleted() { +// fWait.waitFinished(getStatus()); +// } +// }; +// final ServiceEventWaitor eventWaitor = +// new ServiceEventWaitor( +// getGDBLaunch().getSession(), +// IResumedDMEvent.class); +// +// IExecutionDMContext execDmc = fRunCtrl.createMIExecutionContext(fGDBCtrl.getGDBDMContext(), 1); +// final IFrameDMContext dmc = SyncUtil.SyncGetStackFrame(execDmc, 0); +// fRunCtrl.getExecutor().submit(new Runnable() { +// public void run() { +// fRunCtrl.resume(dmc, rm); +// } +// }); +// fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); +// +// try { +// eventWaitor.waitForEvent(ServiceEventWaitor.WAIT_FOREVER); +// } catch (Exception e) { +// Assert.fail("Exception raised:: " + e.getMessage()); +// e.printStackTrace(); +// return; +// } +// +// if (fWait.isOK() == false) +// Assert.assertTrue(fWait.getMessage(), false); +// Assert.assertFalse("Target is suspended. It should have been running", fRunCtrl.isSuspended(fGDBCtrl.getGDBDMContext())); +// fWait.waitReset(); +// } + +// @Test +// public void resumeAndSuspend() throws InterruptedException{ +// final DataRequestMonitor rm = +// new DataRequestMonitor(fRunCtrl.getExecutor(), null) { +// @Override +// protected void handleCompleted() { +// if (getStatus().isOK()) { +// assert true; +// fWait.setReturnInfo(getData()); +// } +// System.out.println("Wait Finished called on getTHreads rm with status " + getStatus().getMessage()); +// fWait.waitFinished(getStatus()); +// } +// }; +// final MIExecutionDMC dmc = new MIExecutionDMC(fRunCtrl, 1); +// fRunCtrl.getExecutor().submit(new Runnable() { +// public void run() { +// fRunCtrl.resume(dmc, rm); +// } +// }); +// fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); +// if (fWait.isOK() == false) +// Assert.assertTrue(fWait.getMessage(), false); +// System.out.println("Message from isSuspended " +fRunCtrl.isSuspended(dmc)); +// Assert.assertFalse("Target is suspended. It should have been running", fRunCtrl.isSuspended(dmc)); +// fWait.waitReset(); +// +// final DataRequestMonitor rmSuspend = +// new DataRequestMonitor(fRunCtrl.getExecutor(), null) { +// @Override +// protected void handleCompleted() { +// if (getStatus().isOK()) { +// assert true; +// fWait.setReturnInfo(getData()); +// } +// System.out.println("Wait Finished called on getTHreads rm with status " + getStatus().getMessage()); +// fWait.waitFinished(getStatus()); +// } +// }; +// +// final ServiceEventWaitor eventWaitor = +// new ServiceEventWaitor( +// getGDBLaunch().getSession(), +// DsfMIStoppedEvent.class); +// +// fRunCtrl.getExecutor().submit(new Runnable() { +// public void run() { +// fRunCtrl.suspend(dmc, rmSuspend); +// } +// }); +// fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); +// try { +// eventWaitor.waitForEvent(ServiceEventWaitor.WAIT_FOREVER); +// } catch (Exception e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } +// +// if (fWait.isOK() == false) +// Assert.assertTrue(fWait.getMessage(), false); +// System.out.println("Message from isSuspended !!! " +fRunCtrl.isSuspended(dmc)); +// Assert.assertTrue("Target is running. It should have been suspended.", fRunCtrl.isSuspended(dmc)); +// fWait.waitReset(); +// } +} diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/AsyncCompletionWaitor.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/AsyncCompletionWaitor.java new file mode 100644 index 00000000000..c66ab38e789 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/AsyncCompletionWaitor.java @@ -0,0 +1,125 @@ +/******************************************************************************* + * Copyright (c) 2007 Ericsson 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: + * Ericsson - Initial Implementation + *******************************************************************************/ +package org.eclipse.dd.tests.gdb.framework; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.tests.gdb.launching.TestsPlugin; + +public class AsyncCompletionWaitor { + + /* + * Indicates we will wait forever. Otherwise the time specified + * is in milliseconds. + */ + public final static int WAIT_FOREVER = 0; + + /* + * Private control space. + */ + private IStatus fStatus; + private Object fReturnInfo; + private boolean fWaitFinished; + private int fNumWaiting; + + /* + * Main constructor. + */ + public AsyncCompletionWaitor() { + waitReset(); + } + + /* + * A timeout of WAIT_FOREVER indicates we wait until the operation is + * completed by a call to waitFinished. Or if we are interrupted + * with an exception. + */ + public synchronized void waitUntilDone(int timeout) throws InterruptedException { + if (fWaitFinished) return; + + wait(timeout); + } + + + /* + * Indicates that we are done with the operation and the code + * waiting ( waitUntilDone ) will be allowed to continue. + */ + public void waitFinished() { + waitFinished(new Status(IStatus.OK, TestsPlugin.PLUGIN_ID, "")); + } + + public synchronized void waitFinished(IStatus status) { + + if (fWaitFinished) { + ((MultiStatus)fStatus).merge( + new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, + "waitFinished called too many times!", null)); + } + + ((MultiStatus)fStatus).merge(status); + + if (fNumWaiting == 0 || --fNumWaiting == 0) { + fWaitFinished = true; + notifyAll(); + } + } + + /* + * Resets the state so we allow ourselves to be reused instead + * of having to create a new wait object each time. + */ + public synchronized void waitReset() { + fWaitFinished = false; + fStatus = new MultiStatus(TestsPlugin.PLUGIN_ID, 0, "", null); //$NON-NLS-1$ + fReturnInfo = null; + fNumWaiting = 0; + } + + public boolean isOK() { + if ( fStatus == null ) { + // We timed out + return false; + } + + return fStatus.isOK(); + } + + public String getMessage() { + if ( fStatus == null ) { + return "Timed out"; //$NON-NLS-1$ + } + + // Build a concatenation of all messages + String fullMessage = ""; + IStatus[] children = fStatus.getChildren(); + for (int i=0; i 0) { + fullMessage += "\"" + children[i].getMessage() + "\", ";//$NON-NLS-1$//$NON-NLS-2$ + } + } + // Remove the trailing comma and space before returning (as long as they are there) + return fullMessage.length() <= 2 ? fullMessage : fullMessage.substring(0, fullMessage.length() - 2); + } + + public void setReturnInfo(Object info) { + fReturnInfo = info ; + } + + public Object getReturnInfo() { + return fReturnInfo; + } + + public void increment() { + fNumWaiting++; + } +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BackgroundRunner.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BackgroundRunner.java new file mode 100644 index 00000000000..ef85d412722 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BackgroundRunner.java @@ -0,0 +1,135 @@ +/******************************************************************************* + * Copyright (c) 2007 Ericsson 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: + * Ericsson - Initial Implementation + *******************************************************************************/ +package org.eclipse.dd.tests.gdb.framework; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.QualifiedName; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.dd.tests.gdb.launching.TestsPlugin; +import org.eclipse.swt.widgets.Display; +import org.junit.internal.runners.InitializationError; +import org.junit.internal.runners.TestClassRunner; +import org.junit.runner.notification.RunNotifier; + +/** + * This runner starts an eclipse job ro run the tests, so as + * to release the UI thread. + */ +@SuppressWarnings("restriction") +public class BackgroundRunner extends TestClassRunner { + + public BackgroundRunner(Class klass) throws InitializationError { + super(klass); + } + + final static QualifiedName BACKGROUND_TEST_EXECUTION_FINISHED = new QualifiedName(TestsPlugin.getDefault().getBundle().getSymbolicName(), "background_test_execution_finished"); //$NON-NLS-1$ + + void invokeSuperRunImpl(RunNotifier notifier) { + super.run(notifier); + } + + /* + * This method overrides the one from TestClassRunner. + * What we do here is start a background job which will call + * TestClassRunner.run; this enables us to release + * the main UI thread. + * + * This has been adapted from the JUnits tests of TargetManagement + * (RSECoreTestCase and RSEWaitAndDispatchUtil) + */ + @Override + public void run(final RunNotifier notifier) { + + // Start the test in a background thread + Job job = new Job("GDB/MI JUnit Test Case Execution Job") { + @Override + protected IStatus run(IProgressMonitor monitor) { + invokeSuperRunImpl(notifier); + monitor.done(); + setProperty(BACKGROUND_TEST_EXECUTION_FINISHED, Boolean.TRUE); + + // The job never fails. The test result is the real result. + return Status.OK_STATUS; + } + }; + + // The job is not complete yet + job.setProperty(BACKGROUND_TEST_EXECUTION_FINISHED, Boolean.FALSE); + // schedule the job to run immediatelly + job.schedule(); + + // wait till the job finishes executing + waitAndDispatch(0, new BackgroundTestExecutionJobWaiter(job)); + } + + public interface IInterruptCondition { + public boolean isTrue(); + public void dispose(); + } + + private final static class BackgroundTestExecutionJobWaiter implements IInterruptCondition { + private final Job job; + + public BackgroundTestExecutionJobWaiter(Job job) { + assert job != null; + this.job = job; + } + + public boolean isTrue() { + // Interrupt the wait method if the job signaled that it has finished. + return ((Boolean)job.getProperty(BACKGROUND_TEST_EXECUTION_FINISHED)).booleanValue(); + } + + public void dispose() { + // nothing to do + } + } + + public static boolean waitAndDispatch(long timeout, IInterruptCondition condition) { + assert timeout >= 0 && condition != null; + + boolean isTimedOut= false; + if (timeout >= 0 && condition != null) { + long start = System.currentTimeMillis(); + Display display = Display.findDisplay(Thread.currentThread()); + if (display != null) { + // ok, we are running within a display thread --> keep the + // display event dispatching running. + long current = System.currentTimeMillis(); + while (timeout == 0 || (current - start) < timeout) { + if (condition.isTrue()) break; + if (!display.readAndDispatch()) display.sleep(); + current = System.currentTimeMillis(); + } + isTimedOut = (current - start) >= timeout && timeout > 0; + } else { + // ok, we are not running within a display thread --> we can + // just block the thread here + long current = System.currentTimeMillis(); + while (timeout == 0 || (current - start) < timeout) { + if (condition.isTrue()) break; + try { Thread.sleep(50); } catch (InterruptedException e) { /* ignored on purpose */ } + current = System.currentTimeMillis(); + } + isTimedOut = (current - start) >= timeout && timeout > 0; + } + } + + // Signal the interrupt condition that we are done here + // and it can cleanup whatever necessary. + condition.dispose(); + + return isTimedOut; + } + +} diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java new file mode 100644 index 00000000000..7e86c586dec --- /dev/null +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright (c) 2007 Ericsson 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: + * Ericsson - Initial Implementation + *******************************************************************************/ +package org.eclipse.dd.tests.gdb.framework; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.dd.gdb.launching.GdbLaunch; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchConfigurationType; +import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; +import org.eclipse.debug.core.ILaunchManager; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; + +/** + * This is the base class for the GDB/MI Unit tests. + * It provides the @Before and @After methods which setup + * and teardown the launch, for each test. + * If these methods are overwridden by a subclass, the new method + * must call super.baseSetup or super.baseTeardown itself, if this + * code is to be run. + */ +public class BaseTestCase { + + private static final String DEFAULT_TEST_APP = "data/launch/bin/GDBMIGenericTestApp"; + + private static GdbLaunch fLaunch; + private static Map attrs = new HashMap(); + + public GdbLaunch getGDBLaunch() { return fLaunch; } + + public static void setLaunchAttribute(String key, Object value) { + attrs.put(key, value); + } + + @BeforeClass + public static void baseBeforeClassMethod() { + // Setup information for the launcher + attrs.put(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, DEFAULT_TEST_APP); + + attrs.put(ICDTLaunchConfigurationConstants.ATTR_USE_TERMINAL, true); + attrs.put(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN, true); + attrs.put(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN_SYMBOL, ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_SYMBOL_DEFAULT); + } + + @Before + public void baseBeforeMethod() throws Exception { + System.out.println("===================================================================="); + System.out.println("Launching test application: " + attrs.get(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME)); + System.out.println("===================================================================="); + + ILaunchManager launchMgr = DebugPlugin.getDefault().getLaunchManager(); + ILaunchConfigurationType lcType = launchMgr.getLaunchConfigurationType("org.eclipse.dd.tests.gdb.TestLaunch"); + assert lcType != null; + + ILaunchConfigurationWorkingCopy lcWorkingCopy = lcType.newInstance( + null, + launchMgr.generateUniqueLaunchConfigurationNameFrom("Test Launch")); //$NON-NLS-1$ + assert lcWorkingCopy != null; + lcWorkingCopy.setAttributes(attrs); + + final ILaunchConfiguration lc = lcWorkingCopy.doSave(); + assert lc != null; + + fLaunch = (GdbLaunch)lc.launch(ILaunchManager.DEBUG_MODE, new NullProgressMonitor()); + assert fLaunch != null; + + // Now initialize our SyncUtility, since we have the launcher + SyncUtil.initialize(fLaunch.getSession()); + } + + @After + public void baseAfterMethod() throws Exception { + System.out.println("===================================================================="); + System.out.println("Tearing down test application: " + attrs.get(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME)); + System.out.println("===================================================================="); + if (fLaunch != null) { + fLaunch.terminate(); + fLaunch = null; + } + } + + @AfterClass + public static void baseAfterClassMehod() throws Exception { + } +} diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/ServiceEventWaitor.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/ServiceEventWaitor.java new file mode 100644 index 00000000000..07e1ee77f75 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/ServiceEventWaitor.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright (c) 2007 Ericsson 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: + * Ericsson - Initial Implementation + *******************************************************************************/ +package org.eclipse.dd.tests.gdb.framework; + +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; +import org.eclipse.dd.dsf.service.DsfSession; + +/* + * This class provides a way to wait for an asynchronous ServerEvent + * to occur. The user of this class specifies which event is of + * interest using the proper constructor or the registerForEvent() method. + * waitForEvent() can then be called to block until the event occurs or + * the timeout elapses. + * + * Note that if the event occurs after regsiterForEvent() is called but + * before waitForEvent() is called, waitForEvent() will return immediatly + * since it will know the event has already occured. + */ + +public class ServiceEventWaitor { + /* + * Indicates we will wait forever. Otherwise the time specified + * is in milliseconds. + */ + public final static int WAIT_FOREVER = 0 ; + + /* The type of event to wait for */ + private Class fEventTypeClass; + private DsfSession fSession; + private V fEvent; + + + /* Empty contructor. registerForEvent() should be called when + * this constructor is used. + */ + public ServiceEventWaitor(DsfSession session) { + fSession = session; + } + + /* Contructor that takes the eventClass as parameter. This is a shortcut + * that avoids calling registerForEvent() + */ + public ServiceEventWaitor(DsfSession session, Class eventClass) { + this(session); + registerForEvent(eventClass); + } + + /* Specify which event to wait for, and add ourselves as + * a listener with the session + */ + public void registerForEvent(Class eventClass) { + fEventTypeClass = eventClass; + fEvent = null; + fSession.addServiceEventListener(this, null); + } + + @Override + protected void finalize() throws Throwable { + super.finalize(); + if (fEventTypeClass != null) fSession.removeServiceEventListener(this); + } + + /* Block until 'timeout' or the previously specified event has been + * received. The reason we don's specify the event as a parameter + * is that we must be ready for the event to occur event before + * this method is called. + */ + public synchronized V waitForEvent(int timeout) throws Exception { + if (fEventTypeClass == null) { + throw new Exception("Event to wait for has not been specified!"); + } + // The event might have already been received + if (fEvent != null) return fEvent; + + wait(timeout); + + if (fEvent == null) { + throw new Exception("Timed out waiting for ServiceEvent: " + fEventTypeClass.getName()); + } + return fEvent; + } + + /* + * Listen to all possible events by having the base class be the parameter. + * and then igure out if that event is the one we were waiting for. + */ + @DsfServiceEventHandler + public void eventDispatched(V event) { + if (fEventTypeClass.isAssignableFrom(event.getClass())) { + synchronized(this) { + fEvent = event; + notifyAll(); + } + } + } +} diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/SyncUtil.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/SyncUtil.java new file mode 100644 index 00000000000..006d6e9df81 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/SyncUtil.java @@ -0,0 +1,314 @@ +/******************************************************************************* + * Copyright (c) 2007 Ericsson 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: + * Ericsson AB - Initial implementation of Test cases + *******************************************************************************/ +package org.eclipse.dd.tests.gdb.framework; + +import static org.junit.Assert.assertTrue; + +import java.util.concurrent.Callable; + +import junit.framework.Assert; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.Query; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.IExpressions; +import org.eclipse.dd.dsf.debug.service.IFormattedValues; +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.IFormattedDataDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.StepType; +import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.gdb.service.command.GDBControl; +import org.eclipse.dd.mi.service.MIRunControl; +import org.eclipse.dd.mi.service.MIStack; +import org.eclipse.dd.mi.service.command.commands.MIBreakDelete; +import org.eclipse.dd.mi.service.command.commands.MIBreakInsert; +import org.eclipse.dd.mi.service.command.commands.MIBreakList; +import org.eclipse.dd.mi.service.command.commands.MIExecContinue; +import org.eclipse.dd.mi.service.command.commands.MIExecFinish; +import org.eclipse.dd.mi.service.command.commands.MIExecNext; +import org.eclipse.dd.mi.service.command.commands.MIExecStep; +import org.eclipse.dd.mi.service.command.commands.MIExecUntil; +import org.eclipse.dd.mi.service.command.events.MIStoppedEvent; +import org.eclipse.dd.mi.service.command.output.MIBreakInsertInfo; +import org.eclipse.dd.mi.service.command.output.MIBreakListInfo; +import org.eclipse.dd.mi.service.command.output.MIBreakpoint; +import org.eclipse.dd.mi.service.command.output.MIInfo; +import org.eclipse.dd.tests.gdb.launching.TestsPlugin; + +public class SyncUtil { + + private static GDBControl fGDBControl; + private static MIRunControl fRunControl; + private static MIStack fStack; + private static IExpressions fExpressions; + private static DsfSession fSession; + + // Initialize some common things, once the session has been established + public static void initialize(DsfSession session) { + fSession = session; + + DsfServicesTracker tracker = + new DsfServicesTracker(TestsPlugin.getBundleContext(), + fSession.getId()); + + fGDBControl = tracker.getService(GDBControl.class); + fRunControl = tracker.getService(MIRunControl.class); + fStack = tracker.getService(MIStack.class); + fExpressions = tracker.getService(IExpressions.class); + } + + public static MIStoppedEvent SyncStep(final StepType stepType, int numSteps) throws Throwable { + MIStoppedEvent retVal = null; + for (int i=0; i eventWaitor = + new ServiceEventWaitor( + fSession, + MIStoppedEvent.class); + + fRunControl.getExecutor().submit(new Runnable() { + public void run() { + // No need for a RequestMonitor since we will wait for the + // ServiceEvent telling us the program has been suspended again + switch(stepType) { + case STEP_INTO: + fGDBControl.queueCommand(new MIExecStep(dmc), null); + break; + case STEP_OVER: + fGDBControl.queueCommand(new MIExecNext(dmc), null); + break; + case STEP_RETURN: + fGDBControl.queueCommand(new MIExecFinish(fStack.createFrameDMContext(dmc, 0)), null); + break; + default: + Assert.assertTrue("Unsupported step type; " + stepType.toString(), false); + } + } + }); + + // Wait for the execution to suspend after the step + return eventWaitor.waitForEvent(ServiceEventWaitor.WAIT_FOREVER); + } + + public static MIStoppedEvent SyncRunToLine(final IExecutionDMContext dmc, final String fileName, final String lineNo, + final boolean skipBreakpoints) throws Throwable { + + final ServiceEventWaitor eventWaitor = + new ServiceEventWaitor( + fSession, + MIStoppedEvent.class); + + fRunControl.getExecutor().submit(new Runnable() { + public void run() { + // No need for a RequestMonitor since we will wait for the + // ServiceEvent telling us the program has been suspended again + + fGDBControl.queueCommand( + new MIExecUntil(dmc, fileName + ":" + lineNo), //$NON-NLS-1$ + null); + } + }); + + // Wait for the execution to suspend after the step + return eventWaitor.waitForEvent(ServiceEventWaitor.WAIT_FOREVER); + } + + public static MIStoppedEvent SyncRunToLine(final String fileName, final String lineNo, + final boolean skipBreakpoints) throws Throwable { + return SyncRunToLine(fGDBControl.getGDBDMContext(), fileName, lineNo, skipBreakpoints); + } + + public static MIStoppedEvent SyncRunToLine(final String fileName, final String lineNo) throws Throwable { + return SyncRunToLine(fGDBControl.getGDBDMContext(), fileName, lineNo, false); + } + + + public static int SyncAddBreakpoint(final String location) throws Throwable { + return SyncAddBreakpoint(location, true); + } + + public static int SyncAddBreakpoint(final String location, boolean temporary) + throws Throwable { + + final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); + + DataRequestMonitor addBreakDone = + new DataRequestMonitor(fRunControl.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + wait.setReturnInfo(getData()); + } + + wait.waitFinished(getStatus()); + } + }; + + fGDBControl.queueCommand( + new MIBreakInsert(fGDBControl.getGDBDMContext(), temporary, false, null, 0, location, 0), + addBreakDone); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + MIBreakInsertInfo info = (MIBreakInsertInfo) wait.getReturnInfo(); + return info.getMIBreakpoints()[0].getNumber(); + } + + + public static int[] SyncGetBreakpointList() throws Throwable { + + final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); + + DataRequestMonitor listDRM = + new DataRequestMonitor(fRunControl.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + wait.setReturnInfo(getData()); + } + wait.waitFinished(getStatus()); + } + }; + + fGDBControl.queueCommand(new MIBreakList(fGDBControl.getGDBDMContext()), listDRM); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + + MIBreakpoint[] breakpoints = listDRM.getData().getMIBreakpoints(); + int[] result = new int[breakpoints.length]; + for (int i = 0; i < breakpoints.length; i++) { + result[i] = breakpoints[i].getNumber(); + } + return result; + } + + public static void SyncDeleteBreakpoint(int breakpointIndex) throws Throwable { + SyncDeleteBreakpoint(new int[] {breakpointIndex}); + } + + public static void SyncDeleteBreakpoint(int[] breakpointIndices) throws Throwable { + + final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); + + DataRequestMonitor deleteBreakDone = + new DataRequestMonitor(fRunControl.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + wait.setReturnInfo(getData()); + } + + wait.waitFinished(getStatus()); + } + }; + + fGDBControl.queueCommand( + new MIBreakDelete(fGDBControl.getGDBDMContext(), breakpointIndices), //$NON-NLS-1$ + deleteBreakDone); + + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(wait.getMessage(), wait.isOK()); + } + + + public static MIStoppedEvent SyncResumeUntilStopped(final IExecutionDMContext dmc) throws Throwable { + final ServiceEventWaitor eventWaitor = + new ServiceEventWaitor( + fSession, + MIStoppedEvent.class); + + fRunControl.getExecutor().submit(new Runnable() { + public void run() { + // No need for a RequestMonitor since we will wait for the + // ServiceEvent telling us the program has been suspended again + fGDBControl.queueCommand( + new MIExecContinue(dmc), + null); + } + }); + + // Wait for the execution to suspend after the step + return eventWaitor.waitForEvent(ServiceEventWaitor.WAIT_FOREVER); + } + + public static MIStoppedEvent SyncResumeUntilStopped() throws Throwable { + return SyncResumeUntilStopped(fGDBControl.getGDBDMContext()); + } + + public static MIStoppedEvent SyncRunToLocation(final String location) throws Throwable { + // Set a temporary breakpoint and run to it. + // Note that if there were other breakpoints set ahead of this one, + // they will stop execution earlier than planned + SyncAddBreakpoint(location, true); + return SyncResumeUntilStopped(); + } + + public static IFrameDMContext SyncGetStackFrame(final IExecutionDMContext execCtx, final int level) throws Throwable { + class StackFrameQuery extends Query { + @Override + protected void execute(final DataRequestMonitor rm) { + fStack.getFrames(execCtx, new DataRequestMonitor(fSession.getExecutor(), rm) { + @Override + protected void handleOK() { + if (getData().length > level) { + rm.setData(getData()[level]); + } else { + rm.setStatus(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, "Frame not available")); + } + rm.done(); + } + }); + } + } + + StackFrameQuery sfQuery = new StackFrameQuery(); + fSession.getExecutor().execute(sfQuery); + return sfQuery.get(); + } + + public static IExpressionDMContext SyncCreateExpression(final IDMContext parentCtx, final String expression) + throws Throwable { + Callable callable = new Callable() { + public IExpressionDMContext call() throws Exception { + return fExpressions.createExpression(parentCtx, expression); + } + }; + return fSession.getExecutor().submit(callable).get(); + } + + public static FormattedValueDMContext SyncGetFormattedValue( + final IFormattedValues service, final IFormattedDataDMContext dmc, final String formatId) throws Throwable + { + Callable callable = new Callable() { + public FormattedValueDMContext call() throws Exception { + return service.getFormattedValueContext(dmc, formatId); + } + }; + return fSession.getExecutor().submit(callable).get(); + } +} diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/LaunchSequence.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/LaunchSequence.java new file mode 100644 index 00000000000..1519319ee3a --- /dev/null +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/LaunchSequence.java @@ -0,0 +1,262 @@ +/******************************************************************************* + * 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.tests.gdb.launching; + +import java.util.concurrent.TimeUnit; + +import org.eclipse.cdt.debug.core.CDebugCorePlugin; +import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; +import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector; +import org.eclipse.cdt.debug.mi.core.IMILaunchConfigurationConstants; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.concurrent.Sequence; +import org.eclipse.dd.dsf.debug.service.StepQueueManager; +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.gdb.launching.GdbLaunch; +import org.eclipse.dd.gdb.service.GDBRunControl; +import org.eclipse.dd.gdb.service.command.GDBControl; +import org.eclipse.dd.mi.service.CSourceLookup; +import org.eclipse.dd.mi.service.ExpressionService; +import org.eclipse.dd.mi.service.MIBreakpoints; +import org.eclipse.dd.mi.service.MIBreakpointsManager; +import org.eclipse.dd.mi.service.MIMemory; +import org.eclipse.dd.mi.service.MIRegisters; +import org.eclipse.dd.mi.service.MIStack; +import org.eclipse.dd.mi.service.command.commands.MIBreakInsert; +import org.eclipse.dd.mi.service.command.commands.MIExecRun; +import org.eclipse.dd.mi.service.command.events.MIStoppedEvent; +import org.eclipse.dd.mi.service.command.output.MIBreakInsertInfo; +import org.eclipse.dd.mi.service.command.output.MIInfo; +import org.eclipse.debug.core.DebugException; + +public class LaunchSequence extends Sequence { + + public class EntryPointHitEventListener { + boolean fAborted = false; + boolean fFinished = false; + final RequestMonitor fRequestMonitor; + + EntryPointHitEventListener(RequestMonitor requestMonitor) { + fRequestMonitor = requestMonitor; + } + + @DsfServiceEventHandler + public void eventDispatched(@SuppressWarnings("unused") + MIStoppedEvent e) { + fFinished = true; + if (!fAborted) { + fSession.removeServiceEventListener(this); + fRequestMonitor.done(); + } + } + } + + + Step[] fSteps = new Step[] { + // Create and initialize the Connection service. + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + // + // Create the connection. + // + fCommandControl = new GDBControl( + fSession, getGDBPath(), fExecPath, GDBControl.SessionType.RUN, 30); + fCommandControl.initialize(requestMonitor); + } + }, + /* + * If needed, insert breakpoint at main and run to it. + */ + new Step() { + private boolean fStopInMain = false; + private String fStopSymbol = null; + + /** + * @return The return value actually indicates whether the get operation succeeded, + * not whether to stop. + */ + private boolean readStopAtMain(RequestMonitor requestMonitor) { + try { + fStopInMain = fLaunch.getLaunchConfiguration().getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN, false ); + } catch (CoreException e) { + requestMonitor.setStatus(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, -1, "Cannot retrieve the entry point symbol", e)); //$NON-NLS-1$ + requestMonitor.done(); + return false; + } + return true; + } + + private boolean readStopSymbol(RequestMonitor requestMonitor) { + try { + fStopSymbol = fLaunch.getLaunchConfiguration().getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN_SYMBOL, ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_SYMBOL_DEFAULT ); + } catch (CoreException e) { + requestMonitor.setStatus(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, DebugException.CONFIGURATION_INVALID, "Cannot retrieve the entry point symbol", e)); //$NON-NLS-1$ + requestMonitor.done(); + return false; + } + return true; + } + + @Override + public void execute(final RequestMonitor requestMonitor) { + if (!readStopAtMain(requestMonitor)) return; + if (!fStopInMain) { + requestMonitor.done(); + return; + } + + if (!readStopSymbol(requestMonitor)) return; + + // Create a listener to wait for the stopped event, and register as even handler. + // This handler will execute the requestMonitor. + final EntryPointHitEventListener entryPointHitListener = new EntryPointHitEventListener(requestMonitor); + fSession.addServiceEventListener(entryPointHitListener, null); + + // Create a time-out, to abort if breakpoint not hit. + fSession.getExecutor().schedule( + new Runnable() { public void run() { + // Only process the event if we have not finished yet (hit the breakpoint). + if (!entryPointHitListener.fFinished) { + // Mark the listener as aborted, and unregister it as event listener. + entryPointHitListener.fAborted = true; + fSession.removeServiceEventListener(entryPointHitListener); + + // Submit the error result for the step. + requestMonitor.setStatus(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, DebugException.TARGET_REQUEST_FAILED, "Timed out running to entry point.", null)); //$NON-NLS-1$ + requestMonitor.done(); + } + }}, + 60, TimeUnit.SECONDS); + + // Insert a breakpoint at the requested stop symbol. + fCommandControl.queueCommand( + new MIBreakInsert(fCommandControl.getGDBDMContext(), true, false, null, 0, fStopSymbol, 0), + new DataRequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleOK() { + + // After the break-insert is done, execute the -exec-run command. + fCommandControl.queueCommand( + new MIExecRun(fCommandControl.getGDBDMContext(), new String[0]), + new DataRequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleOK() { + // Note : Do we not need to do something with the original requestMonitor? + // Do nothing. Execution was resumed and the EntryPointHitEventListener + // will resume execution + } + } + ); + } + }); + } + }, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new GDBRunControl(fSession).initialize(requestMonitor); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new StepQueueManager(fSession).initialize(requestMonitor); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new MIMemory(fSession).initialize(requestMonitor); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new MIStack(fSession).initialize(requestMonitor); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new ExpressionService(fSession).initialize(requestMonitor); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + fSourceLookup = new CSourceLookup(fSession); + fSourceLookup.initialize(requestMonitor); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + fSourceLookup.setSourceLookupDirector( + fCommandControl.getGDBDMContext(), + ((CSourceLookupDirector)fLaunch.getSourceLocator())); + requestMonitor.done(); + }}, + new Step() { @Override + public void execute(final RequestMonitor requestMonitor) { + // Create the low-level breakpoint service + final MIBreakpoints bpService = new MIBreakpoints(fSession); + bpService.initialize(new RequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleOK() { + requestMonitor.done(); + } + }); + }}, + new Step() { @Override + public void execute(final RequestMonitor requestMonitor) { + // Create high-level breakpoint service and install breakpoints + // for the GDB debug context. + final MIBreakpointsManager bpmService = new MIBreakpointsManager(fSession, CDebugCorePlugin.PLUGIN_ID); + bpmService.initialize(new RequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleOK() { + bpmService.startTrackingBreakpoints(fCommandControl.getGDBDMContext(), requestMonitor); + } + }); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new MIRegisters(fSession).initialize(requestMonitor); + }}, + /*new Step() { public void execute(RequestMonitor requestMonitor) { + new GDBVariables(fSession).initialize(requestMonitor); + }},*/ + }; + + final DsfSession fSession; + final GdbLaunch fLaunch; + final IPath fExecPath; + + GDBControl fCommandControl; + CSourceLookup fSourceLookup; + + public LaunchSequence(DsfSession session, GdbLaunch launch, IPath execPath) { + super(session.getExecutor()); + fSession = session; + fLaunch = launch; + fExecPath = execPath; + } + + @Override + public Step[] getSteps() { + return fSteps; + } + + private IPath getGDBPath() { + IPath retVal = new Path("gdb.exe"); //$NON-NLS-1$ + try { + retVal = new Path( fLaunch.getLaunchConfiguration().getAttribute( IMILaunchConfigurationConstants.ATTR_DEBUG_NAME, IMILaunchConfigurationConstants.DEBUGGER_DEBUG_NAME_DEFAULT ) ); + } catch (CoreException e) { + } + return retVal; + } + +} diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/ShutdownSequence.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/ShutdownSequence.java new file mode 100644 index 00000000000..787826a4a29 --- /dev/null +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/ShutdownSequence.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * 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.tests.gdb.launching; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.concurrent.Sequence; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.gdb.service.GDBRunControl; +import org.eclipse.dd.gdb.service.command.GDBControl; +import org.eclipse.dd.mi.service.CSourceLookup; +import org.eclipse.dd.mi.service.ExpressionService; +import org.eclipse.dd.mi.service.MIBreakpoints; +import org.eclipse.dd.mi.service.MIBreakpointsManager; +import org.eclipse.dd.mi.service.MIMemory; +import org.eclipse.dd.mi.service.MIRegisters; +import org.eclipse.dd.mi.service.MIStack; + + +public class ShutdownSequence extends Sequence { + + String fSessionId; + String fApplicationName; + String fDebugModelId; + DsfServicesTracker fTracker; + + + public ShutdownSequence(DsfExecutor executor, String sessionId, RequestMonitor requestMonitor) { + super(executor, requestMonitor); + fSessionId = sessionId; + } + + @Override + public Step[] getSteps() { return fSteps; } + + private final Step[] fSteps = new Step[] { + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + fTracker = new DsfServicesTracker(TestsPlugin.getBundleContext(), fSessionId); + requestMonitor.done(); + } + + @Override + public void rollBack(RequestMonitor requestMonitor) { + fTracker.dispose(); + fTracker = null; + requestMonitor.done(); + } + }, + new Step() { @Override public void execute(RequestMonitor requestMonitor) { shutdownService(MIRegisters.class, requestMonitor); }}, + new Step() { + // Uninstall the breakpoints before the service is shut down. + @Override + public void execute(RequestMonitor requestMonitor) { + MIBreakpointsManager bpm = fTracker.getService(MIBreakpointsManager.class); + GDBControl commandControl = fTracker.getService(GDBControl.class); + if (bpm != null && commandControl != null) { + bpm.stopTrackingBreakpoints(commandControl.getGDBDMContext(), requestMonitor); + } else { + requestMonitor.setStatus(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, + "Needed services not found.", null)); //$NON-NLS-1$ + requestMonitor.done(); + } + } + }, + new Step() { @Override public void execute(RequestMonitor requestMonitor) { shutdownService(MIBreakpointsManager.class, requestMonitor); }}, + new Step() { @Override public void execute(RequestMonitor requestMonitor) { shutdownService(MIBreakpoints.class, requestMonitor); }}, + new Step() { @Override public void execute(RequestMonitor requestMonitor) { shutdownService(CSourceLookup.class, requestMonitor); }}, + new Step() { @Override public void execute(RequestMonitor requestMonitor) { shutdownService(ExpressionService.class, requestMonitor); }}, + new Step() { @Override public void execute(RequestMonitor requestMonitor) { shutdownService(MIStack.class, requestMonitor); }}, + new Step() { @Override public void execute(RequestMonitor requestMonitor) { shutdownService(MIMemory.class, requestMonitor); }}, + new Step() { @Override public void execute(RequestMonitor requestMonitor) { shutdownService(GDBRunControl.class, requestMonitor); }}, + new Step() { @Override public void execute(RequestMonitor requestMonitor) { shutdownService(GDBControl.class, requestMonitor); }}, + new Step() { @Override public void execute(RequestMonitor requestMonitor) { + fTracker.dispose(); + fTracker = null; + requestMonitor.done(); + }} + }; + + @SuppressWarnings("unchecked") + private void shutdownService(Class clazz, RequestMonitor requestMonitor) { + IDsfService service = fTracker.getService(clazz); + if (service != null) { + service.shutdown(requestMonitor); + } + else { + requestMonitor.setStatus(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, + "Service '" + clazz.getName() + "' not found.", null)); //$NON-NLS-1$//$NON-NLS-2$ + requestMonitor.done(); + } + } +} diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java new file mode 100644 index 00000000000..9ff059d98fe --- /dev/null +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java @@ -0,0 +1,302 @@ +/******************************************************************************* + * Copyright (c) 2004, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.tests.gdb.launching; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.atomic.AtomicReference; + +import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; +import org.eclipse.cdt.launch.AbstractCLaunchDelegate; +import org.eclipse.cdt.launch.internal.ui.LaunchMessages; +import org.eclipse.cdt.launch.internal.ui.LaunchUIPlugin; +import org.eclipse.cdt.utils.pty.PTY; +import org.eclipse.cdt.utils.spawner.ProcessFactory; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.dd.dsf.debug.model.DsfMemoryBlockRetrieval; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.gdb.launching.GdbLaunch; +import org.eclipse.dd.gdb.service.command.GDBControl; +import org.eclipse.dd.mi.service.command.AbstractCLIProcess; +import org.eclipse.dd.mi.service.command.MIInferiorProcess; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchManager; +import org.eclipse.debug.core.IStatusHandler; +import org.eclipse.debug.core.model.ILaunchConfigurationDelegate2; +import org.eclipse.debug.core.model.IMemoryBlockRetrieval; +import org.eclipse.debug.core.model.IPersistableSourceLocator; +import org.eclipse.debug.core.model.ISourceLocator; +import org.eclipse.debug.core.sourcelookup.IPersistableSourceLocator2; + +/** + * The launch configuration delegate for the CDI debugger session types. + */ +@ThreadSafe +public class TestLaunchDelegate extends AbstractCLaunchDelegate + implements ILaunchConfigurationDelegate2 +{ + public final static String GDB_DEBUG_MODEL_ID = "org.eclipse.dd.tests.gdb"; //$NON-NLS-1$ + + /* (non-Javadoc) + * @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#launch(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.debug.core.ILaunch, org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public void launch( ILaunchConfiguration config, String mode, ILaunch launch, IProgressMonitor monitor ) throws CoreException { + if ( monitor == null ) { + monitor = new NullProgressMonitor(); + } + if ( mode.equals( ILaunchManager.DEBUG_MODE ) ) { + launchDebugger( config, launch, monitor ); + } + } + + private void launchDebugger( ILaunchConfiguration config, ILaunch launch, IProgressMonitor monitor ) throws CoreException { + monitor.beginTask("Launching debugger session", 10); //$NON-NLS-1$ + if ( monitor.isCanceled() ) { + return; + } + try { + String debugMode = config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN ); + if ( debugMode.equals( ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN ) ) { + launchLocalDebugSession( config, launch, monitor ); + } + } + finally { + monitor.done(); + } + } + + private void launchLocalDebugSession( ILaunchConfiguration config, ILaunch l, IProgressMonitor monitor ) throws CoreException { + if ( monitor.isCanceled() ) { + return; + } + final GdbLaunch launch = (GdbLaunch)l; + + monitor.subTask("Debugging using GDB/MI reference for DSF"); //$NON-NLS-1$ + IPath exePath = new Path(getProgramName(config)); + verifyBinary(exePath); + + setDefaultSourceLocator(launch, config); + + monitor.worked( 1 ); + + // Create and invoke the launch sequence to create the debug control and services + final LaunchSequence launchSequence = + new LaunchSequence(launch.getSession(), launch, exePath); + launch.getSession().getExecutor().execute(launchSequence); + try { + launchSequence.get(); + } catch (InterruptedException e1) { + throw new DebugException(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, "Interrupted Exception in dispatch thread", e1)); //$NON-NLS-1$ + } catch (ExecutionException e1) { + throw new DebugException(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Error in launch sequence", e1.getCause())); //$NON-NLS-1$ + } + + launch.initializeControl(); + + // Add the CLI and "inferior" process objects to the launch. + final AtomicReference cliProcessRef = new AtomicReference(); + final AtomicReference inferiorProcessRef = new AtomicReference(); + try { + launch.getDsfExecutor().submit( new Callable() { + public Object call() throws CoreException { + DsfServicesTracker tracker = new DsfServicesTracker(TestsPlugin.getBundleContext(), launch.getSession().getId()); + GDBControl gdb = tracker.getService(GDBControl.class); + if (gdb != null) { + cliProcessRef.set(gdb.getCLIProcess()); + inferiorProcessRef.set(gdb.getInferiorProcess()); + } + tracker.dispose(); + return null; + } + }).get(); + launch.addProcess(DebugPlugin.newProcess(launch, cliProcessRef.get(), "gdb")); //$NON-NLS-1$ + launch.addProcess(DebugPlugin.newProcess(launch, inferiorProcessRef.get(), exePath.lastSegment())); + } catch (InterruptedException e) { + throw new CoreException(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, 0, "Interrupted while waiting for get process callable.", e)); //$NON-NLS-1$ + } catch (ExecutionException e) { + throw (CoreException)e.getCause(); + } catch (RejectedExecutionException e) { + throw new CoreException(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, 0, "Debugger shut down before launch was completed.", e)); //$NON-NLS-1$ + } + + // Create a memory retrieval and register it with session + try { + launch.getDsfExecutor().submit( new Callable() { + public Object call() throws CoreException { + DsfServicesTracker tracker = new DsfServicesTracker(TestsPlugin.getBundleContext(), launch.getSession().getId()); + GDBControl gdbControl = tracker.getService(GDBControl.class); + if (gdbControl != null) { + IMemoryBlockRetrieval memRetrieval = new DsfMemoryBlockRetrieval( + GDB_DEBUG_MODEL_ID, gdbControl.getGDBDMContext()); + launch.getSession().registerModelAdapter(IMemoryBlockRetrieval.class, memRetrieval); + } + tracker.dispose(); + return null; + } + }).get(); + } catch (InterruptedException e) { + throw new CoreException(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, 0, "Interrupted while waiting for get process callable.", e)); //$NON-NLS-1$ + } catch (ExecutionException e) { + throw (CoreException)e.getCause(); + } catch (RejectedExecutionException e) { + throw new CoreException(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, 0, "Debugger shut down before launch was completed.", e)); //$NON-NLS-1$ + } + } + + /* + * Verify that the specified file exists on the file system. + */ + private void verifyBinary(IPath exePath) throws CoreException { + try { + new FileReader(exePath.toFile()); + } catch (Exception e) { + Throwable exception = new FileNotFoundException(exePath.toOSString() + " does not exist"); //$NON-NLS-1$ + int code = ICDTLaunchConfigurationConstants.ERR_PROGRAM_NOT_BINARY; + throw new CoreException(new Status(IStatus.ERROR, getPluginID(), code, exception == null ? "" : exception.getLocalizedMessage(), //$NON-NLS-1$ + exception)); + } + } + + + /* (non-Javadoc) + * @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#getPluginID() + */ + @Override + protected String getPluginID() { + return LaunchUIPlugin.getUniqueIdentifier(); + } + + /** + * Performs a runtime exec on the given command line in the context of the + * specified working directory, and returns the resulting process. If the + * current runtime does not support the specification of a working + * directory, the status handler for error code + * ERR_WORKING_DIRECTORY_NOT_SUPPORTED is queried to see if + * the exec should be re-executed without specifying a working directory. + * + * @param cmdLine + * the command line + * @param workingDirectory + * the working directory, or null + * @return the resulting process or null if the exec is + * cancelled + * @see Runtime + */ + protected Process exec( String[] cmdLine, String[] environ, File workingDirectory, boolean usePty ) throws CoreException { + Process p = null; + try { + if ( workingDirectory == null ) { + p = ProcessFactory.getFactory().exec( cmdLine, environ ); + } + else { + if ( usePty && PTY.isSupported() ) { + p = ProcessFactory.getFactory().exec( cmdLine, environ, workingDirectory, new PTY() ); + } + else { + p = ProcessFactory.getFactory().exec( cmdLine, environ, workingDirectory ); + } + } + } + catch( IOException e ) { + if ( p != null ) { + p.destroy(); + } + abort( "Error starting process.", e, ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR ); //$NON-NLS-1$ + } + catch( NoSuchMethodError e ) { + // attempting launches on 1.2.* - no ability to set working + // directory + IStatus status = new Status( IStatus.ERROR, LaunchUIPlugin.getUniqueIdentifier(), ICDTLaunchConfigurationConstants.ERR_WORKING_DIRECTORY_NOT_SUPPORTED, LaunchMessages.getString( "LocalDsfLaunchDelegate.9" ), e ); //$NON-NLS-1$ + IStatusHandler handler = DebugPlugin.getDefault().getStatusHandler( status ); + if ( handler != null ) { + Object result = handler.handleStatus( status, this ); + if ( result instanceof Boolean && ((Boolean)result).booleanValue() ) { + p = exec( cmdLine, environ, null, usePty ); + } + } + } + return p; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#preLaunchCheck(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public boolean preLaunchCheck( ILaunchConfiguration config, String mode, IProgressMonitor monitor ) throws CoreException { + // no pre launch check for core file + if ( mode.equals( ILaunchManager.DEBUG_MODE ) ) { + if ( ICDTLaunchConfigurationConstants.DEBUGGER_MODE_CORE.equals( config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN ) ) ) + return true; + } + return super.preLaunchCheck( config, mode, monitor ); +// return true; + } + + /////////////////////////////////////////////////////////////////////////// + // ILaunchConfigurationDelegate2 + @Override + public boolean buildForLaunch(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException { + return false; + } + + @Override + public boolean finalLaunchCheck(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException { + return true; + } + + @Override + public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) throws CoreException { + // Need to configure the source locator before creating the launch + // because once the launch is created and added to launch manager, + // the adapters will be created for the whole session, including + // the source lookup adapter. + ISourceLocator locator = getSourceLocator(configuration); + + return new GdbLaunch(configuration, mode, locator); + } + + private ISourceLocator getSourceLocator(ILaunchConfiguration configuration) throws CoreException { + String type = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_ID, (String)null); + if (type == null) { + type = configuration.getType().getSourceLocatorId(); + } + if (type != null) { + IPersistableSourceLocator locator = DebugPlugin.getDefault().getLaunchManager().newSourceLocator(type); + String memento = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_MEMENTO, (String)null); + if (memento == null) { + locator.initializeDefaults(configuration); + } else { + if(locator instanceof IPersistableSourceLocator2) + ((IPersistableSourceLocator2)locator).initializeFromMemento(memento, configuration); + else + locator.initializeFromMemento(memento); + } + return locator; + } + return null; + } +} diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestsPlugin.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestsPlugin.java new file mode 100644 index 00000000000..fb23fddcfcd --- /dev/null +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestsPlugin.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.tests.gdb.launching; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +import org.eclipse.core.runtime.Plugin; +import org.osgi.framework.BundleContext; + +/** + * The main plugin class to be used in the desktop. + */ +public class TestsPlugin extends Plugin { + //The shared instance. + private static TestsPlugin plugin; + //Resource bundle. + private ResourceBundle resourceBundle; + private static BundleContext bundleContext; + + public static final String PLUGIN_ID = "org.eclipse.dd.tests.gdb"; //$NON-NLS-1$ + + /** + * The constructor. + */ + public TestsPlugin() { + super(); + plugin = this; + try { + resourceBundle = ResourceBundle.getBundle("org.eclipse.dd.tests.gdb.TestsPluginResources"); //$NON-NLS-1$ + } + catch (MissingResourceException x) { + resourceBundle = null; + } + } + /** + * This method is called upon plug-in activation + */ + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + bundleContext = context; + } + /** + * This method is called when the plug-in is stopped + */ + @Override + public void stop(BundleContext context) throws Exception { + super.stop(context); + } + /** + * Returns the shared instance. + */ + public static TestsPlugin getDefault() { + return plugin; + } + + /** + * Returns the string from the plugin's resource bundle, + * or 'key' if not found. + */ + public static String getResourceString(String key) { + ResourceBundle bundle = TestsPlugin.getDefault().getResourceBundle(); + try { + return (bundle != null) ? bundle.getString(key) : key; + } + catch (MissingResourceException e) { + return key; + } + } + /** + * Returns the plugin's resource bundle, + */ + public ResourceBundle getResourceBundle() { + return resourceBundle; + } + /** + * Returns the plugin's bundle context, + */ + public static BundleContext getBundleContext() { + return bundleContext; + } + /** + * Convenience method which returns the unique identifier of this plugin. + */ + public static String getUniqueIdentifier() { + return getDefault().getBundle().getSymbolicName(); + } +} From 4a5303b056dd4165c34c23cefed7a76cee2f9c54 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 14 Feb 2008 19:57:21 +0000 Subject: [PATCH 245/834] [179102] Fixed debug tracing option in org.eclipse.dd.mi. --- plugins/org.eclipse.dd.mi/.options | 2 +- .../src/org/eclipse/dd/mi/internal/MIPlugin.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/org.eclipse.dd.mi/.options b/plugins/org.eclipse.dd.mi/.options index 1d23c88ae93..7d8a261f5a3 100644 --- a/plugins/org.eclipse.dd.mi/.options +++ b/plugins/org.eclipse.dd.mi/.options @@ -1 +1 @@ -org.eclipse.dd.mi.core/debug = false +org.eclipse.dd.mi/debug = false diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/internal/MIPlugin.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/internal/MIPlugin.java index c7804d164c3..4d54348f690 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/internal/MIPlugin.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/internal/MIPlugin.java @@ -43,7 +43,7 @@ public class MIPlugin extends Plugin { public void start(BundleContext context) throws Exception { fgBundleContext = context; super.start(context); - DEBUG = "true".equals(Platform.getDebugOption("org.eclipse.dd.mi.core/debug")); //$NON-NLS-1$//$NON-NLS-2$ + DEBUG = "true".equals(Platform.getDebugOption("org.eclipse.dd.mi/debug")); //$NON-NLS-1$//$NON-NLS-2$ } /** From f001078afe41fb5e78d0ef3a545ae253a49a6e3e Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 14 Feb 2008 21:49:28 +0000 Subject: [PATCH 246/834] [213657] Left over string changes. --- .../META-INF/MANIFEST.MF | 3 +- .../pda/launch/PDAServicesInitSequence.java | 18 +- .../launch/PDAServicesShutdownSequence.java | 17 +- .../pda/service/runcontrol/PDARunControl.java | 21 +- .../pda/service/stack/FrameDMContext.java | 51 ++++ .../pda/service/stack/FrameDMData.java | 47 ++++ .../examples/pda/service/stack/PDAStack.java | 248 ++++++++++++++++++ .../pda/service/stack/VariableDMContext.java | 46 ++++ .../pda/service/stack/VariableDMData.java | 33 +++ plugins/org.eclipse.dd.gdb.ui/plugin.xml | 4 +- plugins/org.eclipse.dd.gdb/plugin.xml | 4 +- .../dd/gdb/launching/GdbLaunchDelegate.java | 2 +- .../dd/mi/service/MIBreakpointsManager.java | 2 +- plugins/org.eclipse.dd.tests.dsf/plugin.xml | 8 +- .../dd/tests/dsf/events/EventTest.java | 2 +- .../service/MultiInstanceTestService.java | 2 +- .../dsf}/service/ServiceTests.java | 2 +- .../dsf}/service/SimpleTestService.java | 2 +- 18 files changed, 456 insertions(+), 56 deletions(-) create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/FrameDMContext.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/FrameDMData.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/PDAStack.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/VariableDMContext.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/VariableDMData.java rename plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/{dsf/tests => tests/dsf}/service/MultiInstanceTestService.java (98%) rename plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/{dsf/tests => tests/dsf}/service/ServiceTests.java (99%) rename plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/{dsf/tests => tests/dsf}/service/SimpleTestService.java (97%) diff --git a/plugins/org.eclipse.dd.examples.pda/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.examples.pda/META-INF/MANIFEST.MF index 9be4b200732..b3991100053 100644 --- a/plugins/org.eclipse.dd.examples.pda/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.examples.pda/META-INF/MANIFEST.MF @@ -10,7 +10,8 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.debug.core, org.eclipse.dd.dsf;bundle-version="1.0.0", org.eclipse.dd.dsf.debug;bundle-version="1.0.0", - org.junit4;bundle-version="4.3.1" + org.junit4;bundle-version="4.3.1", + org.eclipse.cdt.core;bundle-version="5.0.0" Eclipse-LazyStart: true Export-Package: org.eclipse.dd.examples.pda, org.eclipse.dd.examples.pda.breakpoints, diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java index 56b09b8c673..60bed1a808c 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java @@ -19,6 +19,7 @@ import org.eclipse.dd.examples.pda.service.breakpoints.PDABreakpointAttributeTra import org.eclipse.dd.examples.pda.service.breakpoints.PDABreakpoints; import org.eclipse.dd.examples.pda.service.command.PDACommandControl; import org.eclipse.dd.examples.pda.service.runcontrol.PDARunControl; +import org.eclipse.dd.examples.pda.service.stack.PDAStack; import org.eclipse.debug.examples.core.pda.sourcelookup.PDASourceLookupDirector; public class PDAServicesInitSequence extends Sequence { @@ -65,19 +66,12 @@ public class PDAServicesInitSequence extends Sequence { }); } }, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new PDAStack(fSession).initialize(requestMonitor); + } + }, /*new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - new MIMemory(fSession).initialize(requestMonitor); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - new MIModules(fSession).initialize(requestMonitor); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - new MIStack(fSession).initialize(requestMonitor); - }}, - new Step() { @Override public void execute(RequestMonitor requestMonitor) { new ExpressionService(fSession).initialize(requestMonitor); }}, diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java index 9ad48dd1320..db75615afc4 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java @@ -23,6 +23,7 @@ import org.eclipse.dd.examples.pda.PDAPlugin; import org.eclipse.dd.examples.pda.service.breakpoints.PDABreakpoints; import org.eclipse.dd.examples.pda.service.command.PDACommandControl; import org.eclipse.dd.examples.pda.service.runcontrol.PDARunControl; +import org.eclipse.dd.examples.pda.service.stack.PDAStack; public class PDAServicesShutdownSequence extends Sequence { @@ -79,23 +80,13 @@ public class PDAServicesShutdownSequence extends Sequence { public void execute(RequestMonitor requestMonitor) { shutdownService(ExpressionService.class, requestMonitor); } - }, new Step() { - @Override - public void execute(RequestMonitor requestMonitor) { - shutdownService(MIStack.class, requestMonitor); - } - }, new Step() { - @Override - public void execute(RequestMonitor requestMonitor) { - shutdownService(MIModules.class, requestMonitor); - } - }, + },*/ new Step() { @Override public void execute(RequestMonitor requestMonitor) { - shutdownService(MIMemory.class, requestMonitor); + shutdownService(PDAStack.class, requestMonitor); } - }, */ + }, new Step() { @Override public void execute(RequestMonitor requestMonitor) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/PDARunControl.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/PDARunControl.java index 3d075bbfc95..48fb112f4aa 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/PDARunControl.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/PDARunControl.java @@ -51,7 +51,6 @@ import org.osgi.framework.BundleContext; public class PDARunControl extends AbstractDsfService implements IRunControl, IEventListener { - private PDACommandControl fCommandControl; private CommandCache fCommandCache; @@ -66,6 +65,11 @@ public class PDARunControl extends AbstractDsfService super(session); } + @Override + protected BundleContext getBundleContext() { + return PDAPlugin.getBundleContext(); + } + @Override public void initialize(final RequestMonitor rm) { super.initialize( @@ -97,8 +101,6 @@ public class PDARunControl extends AbstractDsfService super.shutdown(rm); } - public boolean isValid() { return true; } - @SuppressWarnings("unchecked") public void getModelData(IDMContext dmc, DataRequestMonitor rm) { if (dmc instanceof IExecutionDMContext) { @@ -109,9 +111,6 @@ public class PDARunControl extends AbstractDsfService } } - public CommandCache getCache() { return fCommandCache; } - - public void eventReceived(Object output) { if (!(output instanceof String)) return; String event = (String)output; @@ -142,7 +141,6 @@ public class PDARunControl extends AbstractDsfService fResumePending = false; fStateChangeReason = e.getReason(); fCommandCache.setTargetAvailable(false); - //fStateChangeTriggeringContext = e.getTriggeringContext(); if (e.getReason().equals(StateChangeReason.STEP)) { fStepping = true; } else { @@ -162,15 +160,6 @@ public class PDARunControl extends AbstractDsfService } - /////////////////////////////////////////////////////////////////////////// - // AbstractService - @Override - protected BundleContext getBundleContext() { - return PDAPlugin.getBundleContext(); - } - - /////////////////////////////////////////////////////////////////////////// - // IRunControl public boolean canResume(IExecutionDMContext context) { return isSuspended(context) && !fResumePending; } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/FrameDMContext.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/FrameDMContext.java new file mode 100644 index 00000000000..7947f0aea5d --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/FrameDMContext.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.stack; + +import org.eclipse.dd.dsf.datamodel.AbstractDMContext; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; +import org.eclipse.dd.examples.pda.service.stack.PDAStack.PDAFrame; + +/** + * + */ +class FrameDMContext extends AbstractDMContext implements IFrameDMContext { + + private final int fLevel; + private final PDAFrame fFrame; + + FrameDMContext(String sessionId, IExecutionDMContext execDmc, int level, PDAFrame frame) { + super(sessionId, new IDMContext[] { execDmc }); + fLevel = level; + fFrame = frame; + } + + PDAFrame getFrame() { return fFrame; } + + public int getLevel() { return fLevel; } + + @Override + public boolean equals(Object other) { + return super.baseEquals(other) && ((FrameDMContext)other).fLevel == fLevel; + } + + @Override + public int hashCode() { + return super.baseHashCode() ^ fLevel; + } + + @Override + public String toString() { + return baseToString() + ".frame[" + fLevel + "]"; //$NON-NLS-1$ //$NON-NLS-2$ + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/FrameDMData.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/FrameDMData.java new file mode 100644 index 00000000000..c3272d64564 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/FrameDMData.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.stack; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMData; +import org.eclipse.dd.examples.pda.service.stack.PDAStack.PDAFrame; + +/** + * + */ +public class FrameDMData implements IFrameDMData { + + final private PDAFrame fFrame; + + FrameDMData(PDAFrame frame) { + fFrame = frame; + } + + public String getFile() { + return fFrame.fFilePath; + } + + public String getFunction() { + return fFrame.fFunction; + } + + public int getLine() { + return fFrame.fLine; + } + + public int getColumn() { + return 0; + } + + public IAddress getAddress() { + return null; + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/PDAStack.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/PDAStack.java new file mode 100644 index 00000000000..e11c64dfa54 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/PDAStack.java @@ -0,0 +1,248 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.stack; + +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.List; +import java.util.StringTokenizer; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.IStack; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason; +import org.eclipse.dd.dsf.debug.service.command.CommandCache; +import org.eclipse.dd.dsf.service.AbstractDsfService; +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.examples.pda.PDAPlugin; +import org.eclipse.dd.examples.pda.service.command.PDACommand; +import org.eclipse.dd.examples.pda.service.command.PDACommandControl; +import org.eclipse.dd.examples.pda.service.command.PDACommandResult; +import org.osgi.framework.BundleContext; + +/** + * + */ +public class PDAStack extends AbstractDsfService implements IStack { + + private PDACommandControl fCommandControl; + private IRunControl fRunControl; + + private CommandCache fCommandCache; + + public PDAStack(DsfSession session) { + super(session); + } + + @Override + protected BundleContext getBundleContext() { + return PDAPlugin.getBundleContext(); + } + + @Override + public void initialize(final RequestMonitor rm) { + super.initialize( + new RequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + doInitialize(rm); + }}); + } + + private void doInitialize(final RequestMonitor rm) { + fCommandControl = getServicesTracker().getService(PDACommandControl.class); + fRunControl = getServicesTracker().getService(IRunControl.class); + fCommandCache = new CommandCache(fCommandControl); + + getSession().addServiceEventListener(this, null); + + register(new String[]{IStack.class.getName(), PDAStack.class.getName()}, new Hashtable()); + + rm.done(); + } + + @Override + public void shutdown(final RequestMonitor rm) { + getSession().removeServiceEventListener(this); + fCommandCache.reset(); + super.shutdown(rm); + } + + public void getArguments(IFrameDMContext frameCtx, DataRequestMonitor rm) { + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.NOT_SUPPORTED, "PDA debugger does not support function arguments.", null)); //$NON-NLS-1$ + rm.done(); + } + + public void getFrameData(IFrameDMContext frameCtx, DataRequestMonitor rm) { + if ( !(frameCtx instanceof FrameDMContext) ) { + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context " + frameCtx, null)); //$NON-NLS-1$ + rm.done(); + return; + } + + PDAFrame pdaFrame = ((FrameDMContext)frameCtx).getFrame(); + rm.setData(new FrameDMData(pdaFrame)); + rm.done(); + } + + public void getFrames(IDMContext context, final DataRequestMonitor rm) { + final IExecutionDMContext execCtx = DMContexts.getAncestorOfType(context, IExecutionDMContext.class); + if (execCtx == null) { + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context " + context, null)); //$NON-NLS-1$ + rm.done(); + return; + } + + fCommandControl.queueCommand( + new PDACommand(execCtx, "stack"), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + PDAFrame[] frames = parseStackResponse(getData().fResponseText); + IFrameDMContext[] frameCtxs = new IFrameDMContext[frames.length]; + for (int i = 0; i < frames.length; i++) { + frameCtxs[i] = new FrameDMContext(getSession().getId(), execCtx, i, frames[i]); + } + rm.setData(frameCtxs); + rm.done(); + } + }); + } + + public void getLocals(IFrameDMContext frameCtx, DataRequestMonitor rm) { + if ( !(frameCtx instanceof FrameDMContext) ) { + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context " + frameCtx, null)); //$NON-NLS-1$ + rm.done(); + return; + } + + PDAFrame pdaFrame = ((FrameDMContext)frameCtx).getFrame(); + IVariableDMContext[] variableCtxs = new IVariableDMContext[pdaFrame.fVariables.length]; + for (int i = 0; i < pdaFrame.fVariables.length; i++) { + variableCtxs[i] = new VariableDMContext(getSession().getId(), frameCtx, pdaFrame.fVariables[i]); + } + rm.setData(variableCtxs); + rm.done(); + } + + public void getStackDepth(IDMContext context, int maxDepth, final DataRequestMonitor rm) { + getFrames( + context, + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + rm.setData(getData().length); + rm.done(); + } + }); + } + + public void getTopFrame(IDMContext context, final DataRequestMonitor rm) { + getFrames( + context, + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + rm.setData(getData()[0]); + rm.done(); + } + }); + } + + public void getVariableData(IVariableDMContext variableCtx, DataRequestMonitor rm) { + if ( !(variableCtx instanceof VariableDMContext) ) { + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context " + variableCtx, null)); //$NON-NLS-1$ + rm.done(); + return; + } + + String variable = ((VariableDMContext)variableCtx).getVariable(); + + rm.setData(new VariableDMData(variable)); + rm.done(); + } + + public boolean isStackAvailable(IDMContext context) { + IExecutionDMContext execCtx = DMContexts.getAncestorOfType(context, IExecutionDMContext.class); + return execCtx != null && (fRunControl.isSuspended(execCtx) || (fRunControl.isStepping(execCtx))); + } + + @Deprecated + public void getModelData(IDMContext dmc, DataRequestMonitor rm) { + if (dmc instanceof IFrameDMContext) { + getFrameData((IFrameDMContext)dmc, (DataRequestMonitor)rm); + // getFrameData invokes rm + } else if (dmc instanceof IVariableDMContext) { + getVariableData((IVariableDMContext)dmc, (DataRequestMonitor)rm); + // getVariablesData invokes rm + } else { + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Unknown context type", null)); //$NON-NLS-1$ + rm.done(); + } + } + + @DsfServiceEventHandler + public void eventDispatched(IResumedDMEvent e) { + fCommandCache.setTargetAvailable(false); + if (!e.getReason().equals(StateChangeReason.STEP)) { + fCommandCache.reset(); + } + } + + + @DsfServiceEventHandler + public void eventDispatched(ISuspendedDMEvent e) { + fCommandCache.setTargetAvailable(true); + fCommandCache.reset(); + } + + public static class PDAFrame { + PDAFrame(String frameString) { + StringTokenizer st = new StringTokenizer(frameString, "|"); + + fFilePath = st.nextToken(); + fLine = Integer.parseInt(st.nextToken()); + fFunction = st.nextToken(); + + List variablesList = new ArrayList(); + while (st.hasMoreTokens()) { + variablesList.add(st.nextToken()); + } + fVariables = variablesList.toArray(new String[variablesList.size()]); + } + + final public String fFilePath; + final public int fLine; + final public String fFunction; + final public String[] fVariables; + } + + private PDAFrame[] parseStackResponse(String response) { + StringTokenizer st = new StringTokenizer(response, "#"); + List framesList = new ArrayList(); + + while (st.hasMoreTokens()) { + framesList.add(new PDAFrame(st.nextToken())); + } + return framesList.toArray(new PDAFrame[framesList.size()]); + } + +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/VariableDMContext.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/VariableDMContext.java new file mode 100644 index 00000000000..7ed5b51ff5d --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/VariableDMContext.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.stack; + +import org.eclipse.dd.dsf.datamodel.AbstractDMContext; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; +import org.eclipse.dd.dsf.debug.service.IStack.IVariableDMContext; + +/** + * + */ +class VariableDMContext extends AbstractDMContext implements IVariableDMContext { + + private final String fVariable; + + VariableDMContext(String sessionId, IFrameDMContext frameCtx, String variable) { + super(sessionId, new IDMContext[] { frameCtx }); + fVariable = variable; + } + + String getVariable() { return fVariable; } + + @Override + public boolean equals(Object other) { + return super.baseEquals(other) && ((VariableDMContext)other).fVariable.equals(fVariable); + } + + @Override + public int hashCode() { + return super.baseHashCode() + fVariable.hashCode(); + } + + @Override + public String toString() { + return baseToString() + ".variable(" + fVariable + ")"; //$NON-NLS-1$ //$NON-NLS-2$ + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/VariableDMData.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/VariableDMData.java new file mode 100644 index 00000000000..03087fd6012 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/VariableDMData.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.stack; + +import org.eclipse.dd.dsf.debug.service.IStack.IVariableDMData; + +/** + * + */ +public class VariableDMData implements IVariableDMData { + + final private String fVariable; + + VariableDMData(String variable) { + fVariable = variable; + } + + public String getName() { + return fVariable; + } + + public String getValue() { + return null; + } +} diff --git a/plugins/org.eclipse.dd.gdb.ui/plugin.xml b/plugins/org.eclipse.dd.gdb.ui/plugin.xml index 960e5e8b303..7bf1874e464 100644 --- a/plugins/org.eclipse.dd.gdb.ui/plugin.xml +++ b/plugins/org.eclipse.dd.gdb.ui/plugin.xml @@ -42,9 +42,9 @@ - + diff --git a/plugins/org.eclipse.dd.gdb/plugin.xml b/plugins/org.eclipse.dd.gdb/plugin.xml index b57c16f117e..d302c281fab 100644 --- a/plugins/org.eclipse.dd.gdb/plugin.xml +++ b/plugins/org.eclipse.dd.gdb/plugin.xml @@ -17,8 +17,8 @@ point="org.eclipse.cdt.debug.core.BreakpointExtension"> diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunchDelegate.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunchDelegate.java index 0535874e5cf..ae3f5ff78ee 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunchDelegate.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunchDelegate.java @@ -57,7 +57,7 @@ import org.eclipse.debug.core.sourcelookup.IPersistableSourceLocator2; public class GdbLaunchDelegate extends AbstractCLaunchDelegate implements ILaunchConfigurationDelegate2 { - public final static String GDB_DEBUG_MODEL_ID = "org.eclipse.dd.dsf.gdb"; //$NON-NLS-1$ + public final static String GDB_DEBUG_MODEL_ID = "org.eclipse.dd.gdb"; //$NON-NLS-1$ /* (non-Javadoc) * @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#launch(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.debug.core.ILaunch, org.eclipse.core.runtime.IProgressMonitor) diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointsManager.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointsManager.java index a4faefb1d5c..723027b914a 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointsManager.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointsManager.java @@ -79,7 +79,7 @@ import org.osgi.framework.BundleContext; public class MIBreakpointsManager extends AbstractDsfService implements IBreakpointManagerListener, IBreakpointListener { // Note: Find a way to import this (careful of circular dependencies) - public final static String GDB_DEBUG_MODEL_ID = "org.eclipse.dd.dsf.gdb"; //$NON-NLS-1$ + public final static String GDB_DEBUG_MODEL_ID = "org.eclipse.dd.gdb"; //$NON-NLS-1$ // Extra breakpoint attributes private static final String ATTR_DEBUGGER_PATH = MIPlugin.PLUGIN_ID + ".debuggerPath"; //$NON-NLS-1$ diff --git a/plugins/org.eclipse.dd.tests.dsf/plugin.xml b/plugins/org.eclipse.dd.tests.dsf/plugin.xml index aa2732002b6..551bb87dde1 100644 --- a/plugins/org.eclipse.dd.tests.dsf/plugin.xml +++ b/plugins/org.eclipse.dd.tests.dsf/plugin.xml @@ -6,13 +6,13 @@ point="org.eclipse.ui.views"> + id="org.eclipse.dd.tests.dsf.model"> + category="org.eclipse.dd.tests.dsf.model" + class="org.eclipse.dd.tests.dsf.model.ModelTestsView" + id="org.eclipse.dd.tests.dsf.model.ModelTestView"> diff --git a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/EventTest.java b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/EventTest.java index 102be68b751..91620c16350 100644 --- a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/EventTest.java +++ b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/EventTest.java @@ -35,7 +35,7 @@ public class EventTest { fExecutor = new TestDsfExecutor(); fExecutor.submit(new DsfRunnable() { public void run() { - fSession = DsfSession.startSession(fExecutor, "org.eclipse.dd.dsf.tests"); //$NON-NLS-1$ + fSession = DsfSession.startSession(fExecutor, "org.eclipse.dd.tests.dsf"); //$NON-NLS-1$ }}).get(); StartupSequence startupSeq = new StartupSequence(fSession); diff --git a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/dsf/tests/service/MultiInstanceTestService.java b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/service/MultiInstanceTestService.java similarity index 98% rename from plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/dsf/tests/service/MultiInstanceTestService.java rename to plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/service/MultiInstanceTestService.java index 2b70cf6bed1..2addfb41af7 100644 --- a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/dsf/tests/service/MultiInstanceTestService.java +++ b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/service/MultiInstanceTestService.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.tests.service; +package org.eclipse.dd.tests.dsf.service; import java.util.Hashtable; diff --git a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/dsf/tests/service/ServiceTests.java b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/service/ServiceTests.java similarity index 99% rename from plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/dsf/tests/service/ServiceTests.java rename to plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/service/ServiceTests.java index 102c72e8b09..04a7dcf42ee 100644 --- a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/dsf/tests/service/ServiceTests.java +++ b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/service/ServiceTests.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.tests.service; +package org.eclipse.dd.tests.dsf.service; import java.lang.reflect.Constructor; import java.util.concurrent.ExecutionException; diff --git a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/dsf/tests/service/SimpleTestService.java b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/service/SimpleTestService.java similarity index 97% rename from plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/dsf/tests/service/SimpleTestService.java rename to plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/service/SimpleTestService.java index 902bf0885cb..f0e29b2f309 100644 --- a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/dsf/tests/service/SimpleTestService.java +++ b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/service/SimpleTestService.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.tests.service; +package org.eclipse.dd.tests.dsf.service; import java.util.Hashtable; From a8a36358d9ac244c1a84fc7693f1c23ee3eb66c1 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 14 Feb 2008 22:00:22 +0000 Subject: [PATCH 247/834] [219026] Got rid of "null" at end of frame label if address is not available. --- .../dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java index 0ceca2adc27..0a73e96939f 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java @@ -262,7 +262,9 @@ public class StackFramesVMNode extends AbstractDMVMNode } // Add the address - label.append(dmData.getAddress()); + if (dmData.getAddress() != null) { + label.append(dmData.getAddress()); + } // Set the label to the result listener update.setLabel(label.toString(), 0); From a1242031aae9041b8a1c03fe32553456cf377f43 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 15 Feb 2008 01:09:36 +0000 Subject: [PATCH 248/834] [208921] Fix to return arguments and locals for IStack.getLocals(). --- .../eclipse/dd/dsf/debug/service/IStack.java | 2 +- .../org/eclipse/dd/mi/service/MIStack.java | 31 +++++++++++++++++-- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java index 9b88df3a679..24a8e5c39ee 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java @@ -99,7 +99,7 @@ public interface IStack extends IDMService { void getArguments(IFrameDMContext frameCtx, DataRequestMonitor rm); /** - * Retrieves variables local to the stack frame. + * Retrieves variables local to the stack frame, including arguments. */ void getLocals(IFrameDMContext frameCtx, DataRequestMonitor rm); diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIStack.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIStack.java index f18f53765ac..59582892581 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIStack.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIStack.java @@ -11,13 +11,17 @@ *******************************************************************************/ package org.eclipse.dd.mi.service; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Hashtable; +import java.util.List; import org.eclipse.cdt.core.IAddress; import org.eclipse.cdt.utils.Addr32; import org.eclipse.cdt.utils.Addr64; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.AbstractDMContext; @@ -512,13 +516,36 @@ public class MIStack extends AbstractDsfService public void getLocals(final IFrameDMContext frameDmc, final DataRequestMonitor rm) { + + final List localsList = new ArrayList(); + + final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + rm.setData( localsList.toArray(new IVariableDMContext[localsList.size()]) ); + rm.done(); + } + }; + countingRm.setDoneCount(2); + + getArguments( + frameDmc, + new DataRequestMonitor(getExecutor(), countingRm) { + @Override + protected void handleOK() { + localsList.addAll( Arrays.asList(getData()) ); + countingRm.done(); + } + }); + fRunControl.getCache().execute( new MIStackListLocals(frameDmc, true), new DataRequestMonitor(getExecutor(), rm) { @Override protected void handleOK() { - rm.setData(makeVariableDMCs(frameDmc, MIVariableDMC.Type.LOCAL, getData().getLocals().length)); - rm.done(); + localsList.addAll( Arrays.asList( + makeVariableDMCs(frameDmc, MIVariableDMC.Type.LOCAL, getData().getLocals().length)) ); + countingRm.done(); } }); } From 9dc357f09b5602fb06e43144710b605d66654ca6 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Fri, 15 Feb 2008 06:51:53 +0000 Subject: [PATCH 249/834] [213657] test -> tests --- features/org.eclipse.dd.dsf.test-feature/feature.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/org.eclipse.dd.dsf.test-feature/feature.xml b/features/org.eclipse.dd.dsf.test-feature/feature.xml index 0b547d277e5..bd37acea849 100644 --- a/features/org.eclipse.dd.dsf.test-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.test-feature/feature.xml @@ -30,14 +30,14 @@ Tests Date: Fri, 15 Feb 2008 19:50:57 +0000 Subject: [PATCH 250/834] [202109] Fixed a bug in the update modes cache which caused occasional invalid updates. --- .../DefaultVMContentProviderStrategy.java | 7 ++++++- .../dd/dsf/ui/viewmodel/VMViewerUpdate.java | 7 ++++++- .../update/AbstractCachingVMProvider.java | 19 +++++++++++++++---- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMContentProviderStrategy.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMContentProviderStrategy.java index 6009f7b16c9..fe27ec0e719 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMContentProviderStrategy.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMContentProviderStrategy.java @@ -319,7 +319,12 @@ public class DefaultVMContentProviderStrategy implements IElementContentProvider elementsMultiRequestMon.add(new DataRequestMonitor>(getVMProvider().getExecutor(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + // Workaround for a bug caused by an optimization in the viewer: + // The viewer may request more children then there are at a given level. + // This caues the update to return with an error. + // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=202109 + // Instead of checking getStatus().isOK(), check getData() != null. + if (getData() != null) { for (int i = 0; i < elementsLength; i++) { update.setChild(getData().get(i), elementsStartIdx + nodeStartIdx + i); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java index d3b383bfd3a..03d907edec6 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java @@ -173,7 +173,12 @@ public class VMViewerUpdate implements IViewerUpdate { fRequestMonitor.setStatus(new Status( IStatus.CANCEL, DsfUIPlugin.PLUGIN_ID," Update was cancelled") ); //$NON-NLS-1$ } fRequestMonitor.done(); - } catch (RejectedExecutionException e) { // Ignore + } catch (RejectedExecutionException e) { + // If the request monitor cannot be invoked still, try to complete the update to avoid + // leaving the viewer in an inconsistent state. + if (fClientUpdate != null) { + fClientUpdate.done(); + } } } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java index 3851620e4db..fa14d97b2a1 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java @@ -356,6 +356,11 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa @Override protected void handleCompleted() { + // Workaround for a bug caused by an optimization in the viewer: + // The viewer may request more children then there are at a given level. + // This caues the update to return with an error. + // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=202109 + // Instead of checking getStatus().isOK(), check getData() != null. if(getData() != null) { // Check if the udpate retrieved all children by specifying "offset = -1, length = -1" int updateOffset = update.getOffset(); @@ -404,7 +409,16 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa for (int i = update.getOffset(); i < update.getOffset() + update.getLength(); i++) { childrenMissingFromCache.add(i); } - childrenMissingFromCache.removeAll(entry.fChildren.keySet()); + + // Fill in the known children from cache. + for(int position = update.getOffset(); position < update.getOffset() + update.getLength(); position++) { + Object child = entry.fChildren.get(position); + if (child != null) { + update.setChild(entry.fChildren.get(position), position); + } else { + childrenMissingFromCache.remove(position); + } + } if (childrenMissingFromCache.size() > 0) { // perform a partial update; we only have some of the children of the update request @@ -445,9 +459,6 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa multiRm.setDoneCount(partialUpdates.size()); } else { // we have all of the children in cache; return from cache - for(int position = update.getOffset(); position < update.getOffset() + update.getLength(); position++) { - update.setChild(entry.fChildren.get(position), position); - } update.done(); } } From e83d9b7f3575e592cd8b62f64dab33d687fe3223 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 15 Feb 2008 20:42:24 +0000 Subject: [PATCH 251/834] [202109] Fixed a bug in the update modes cache which caused occasional invalid updates. --- .../dsf/ui/viewmodel/DefaultVMContentProviderStrategy.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMContentProviderStrategy.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMContentProviderStrategy.java index fe27ec0e719..b58052fe967 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMContentProviderStrategy.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMContentProviderStrategy.java @@ -325,8 +325,11 @@ public class DefaultVMContentProviderStrategy implements IElementContentProvider // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=202109 // Instead of checking getStatus().isOK(), check getData() != null. if (getData() != null) { - for (int i = 0; i < elementsLength; i++) { - update.setChild(getData().get(i), elementsStartIdx + nodeStartIdx + i); + for (int i = 0; i < elementsLength && i < getData().size(); i++) { + Object child = getData().get(i); + if (child != null) { + update.setChild(getData().get(i), elementsStartIdx + nodeStartIdx + i); + } } } elementsMultiRequestMon.requestMonitorDone(this); From 88dede0e91b82821668301d3eae023196c349493 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Mon, 18 Feb 2008 19:40:49 +0000 Subject: [PATCH 252/834] M5: gdb feature has dependency on 0.9.0 sdk feature. changed to 1.0.0 with match="greaterOrEqual" --- features/org.eclipse.dd.dsf.gdb-feature/feature.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/org.eclipse.dd.dsf.gdb-feature/feature.xml b/features/org.eclipse.dd.dsf.gdb-feature/feature.xml index ac38a161555..5816da5c375 100644 --- a/features/org.eclipse.dd.dsf.gdb-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.gdb-feature/feature.xml @@ -25,7 +25,7 @@ GDB-MI Implementation - + Date: Mon, 18 Feb 2008 22:57:54 +0000 Subject: [PATCH 253/834] Fix for bug 218657. --- .../org/eclipse/dd/mi/service/MIMemory.java | 15 +++- .../data/launch/bin/BreakpointTestApp.exe | Bin 40216 -> 0 bytes .../data/launch/bin/ExpressionTestApp.exe | Bin 16921 -> 0 bytes .../data/launch/bin/GDBMIGenericTestApp.exe | Bin 9594 -> 0 bytes .../data/launch/bin/MemoryTestApp.exe | Bin 39963 -> 0 bytes .../data/launch/bin/MultiThread.exe | Bin 9106 -> 0 bytes .../data/launch/bin/SpecialTestApp.exe | Bin 9581 -> 0 bytes .../dd/tests/gdb/MIBreakpointsTest.java | 76 +++++++++--------- 8 files changed, 51 insertions(+), 40 deletions(-) delete mode 100755 plugins/org.eclipse.dd.tests.gdb/data/launch/bin/BreakpointTestApp.exe delete mode 100755 plugins/org.eclipse.dd.tests.gdb/data/launch/bin/ExpressionTestApp.exe delete mode 100755 plugins/org.eclipse.dd.tests.gdb/data/launch/bin/GDBMIGenericTestApp.exe delete mode 100755 plugins/org.eclipse.dd.tests.gdb/data/launch/bin/MemoryTestApp.exe delete mode 100755 plugins/org.eclipse.dd.tests.gdb/data/launch/bin/MultiThread.exe delete mode 100755 plugins/org.eclipse.dd.tests.gdb/data/launch/bin/SpecialTestApp.exe diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIMemory.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIMemory.java index d900414065d..ef259a8ae72 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIMemory.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIMemory.java @@ -810,8 +810,19 @@ public class MIMemory extends AbstractDsfService implements IMemory { new DataRequestMonitor(getExecutor(), rm) { @Override public void handleOK() { - fMemoryCache.updateMemoryCache(address, count, getData()); - getSession().dispatchEvent(new MemoryChangedEvent(memoryDMC, addresses), getProperties()); + MemoryByte[] oldBlock = fMemoryCache.getMemoryBlockFromCache(address, count); + MemoryByte[] newBlock = getData(); + boolean blocksDiffer = false; + for (int i = 0; i < oldBlock.length; i++) { + if (oldBlock[i].getValue() != newBlock[i].getValue()) { + blocksDiffer = true; + break; + } + } + if (blocksDiffer) { + fMemoryCache.updateMemoryCache(address, count, newBlock); + getSession().dispatchEvent(new MemoryChangedEvent(memoryDMC, addresses), getProperties()); + } rm.done(); } }); diff --git a/plugins/org.eclipse.dd.tests.gdb/data/launch/bin/BreakpointTestApp.exe b/plugins/org.eclipse.dd.tests.gdb/data/launch/bin/BreakpointTestApp.exe deleted file mode 100755 index 6eb8b78a5b9965ec3247979c002e09ec99a468e6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40216 zcmd^o33Ob=nQq-y%Whk;EK9a*gt}YCiwwq+Wi4K?!IIs!g^i6j@B(RC-7Tr@R<}^M zybuX2q z?UsZcUe0;%oYzNJb?e{juk}{dt$R&m(>lj-l>PZsnPTkL>-~Xtgu8Chn0D2u0&0P3 zQghV=fQV~90vcSx0H$)l{J6@9L%jW3;BnO=&Wkw8<|RM!;(BVLQoP8osx@9<9{~>6 zN-zvTDfJTXL+}#lUjmNTD~R(Vo;rAK0M7>K=GBNeFN?eI-}8x;;9q$oWaF9(950LC z3Ou5tepY@T@t==T*9+kvnK7wxjYM%;vL1R>*XCjJ{7BoUsi{iAKe>D&zHlL()2X7-{=sY} zn#;$A^U^E!m&S<&(o}(y?4FnN!g{o44nerLwtbZ!DK=@5!X{Yg!`*#)7XE zc(nh}q3BR@IG4@D(y9F6=z+ylJE%3{u0I}+<``=wd?-IKoQx$H7rMBytY-_%N~AK; zkz6tXL*s{H(O5otD3wP9e2^hl55`g%wPx3@uI`>_Yjc}gzp1Ai(P&$9yS|Sufnb5+ zjuiMY@0go@T;<3?2N32X^J6itAANB@vb0=1V_^9+-;Zo9Q!gOSAL;KxX!EZ+m72m5 z@}CBl3#U+|eCodu=kM9u{ecNk`Vzv4Q1l8z#9w2G%z2$5G`_)*1?-~;QJ8k#^zTPs z3LO6wAjjX}zaN9?$w$$iw#G=;s5JOL{9whZU)DyZ}{QJi;tBP?|@0u-+dg-$_?Mh*E~oaxS900e=cDs zzHe!&ACJ&i>cxg*kvASYvYPU7_qhLt)gRODIvRPyx%R3zn5?UR_T(cX+2slz+xZ5_ z-+dh!_5Dr$50TZ&_R~??CWGmw$m?FBm!Ev(mQ8d0aN3E>-+-2_@D0pmNjtt3&N%*6 z{<{kQBsE7L_3ys)me?C6t+Q@|z@4ujz3L5Tr1jdXUS~FpECB!NJK*s%-#l^R@wIaU z0a%HUHCzF=2bpsG<^Of!gtadK9ZEeYIzI(XF5C)I5CkCod+8&$yy_L-v7N6VlNYw0xaqN5?kE4T zNcGXjott3du}CEX|FKBmCjZjJfFl#qT7Tag3%cqx}(};V< zzX4-cBbzByfpTd$EB*d=!&SsJ;(7yRJAzPkRRwPFbx%PR z72HaM-SG6xF>t#8V=kcV7x6I))hEbj?-}yP+_4vJNP9vJayC` z;QjXyvJauL93wD9loCzfjxxW312Qx<<3UqRc znS8Q8X#kYZF)@vUv62KPo)-(W0N#lkAJi)UMBf?$13nm{d=q^aX&|e+Gr`A^oUgnL z3Y5Rx*MV4|+_#m%MBfSo02(Qq5OXH@KhNN_WBgxU#xYm<7Tl|warsm?{`(ziR&m$T zJCaH#^#4RlKL<05mNa*0z@q$cGTD-9Th@tDY;U|Jo*QY259d?O+fRkBAPjs8b)~Uu zdn1NDOPf0uE9XcIY4s_NKK;%k_@6;r#QY}VnuQBbQm_2o7^&?a%EBo-lDT}>&`@(c zu384NgUObm*uiAFM<12o z`WGa4*Z)XxV;w4XVA9Q95**tm!F$pYeCa(BeEG`~{KHQrxc`47c%TU#K%jcX1rnTd ze;s2hpJ7n5=2Z#SI_Mh$HIbPdNfqXZvaBf-a#5`6p` z2|n?D3I6Kq65MfIf;*?4PQJTVN^tjH2|js9g1^2?g1`Be1fP0Ag1@b3Aj4;uNN`V7 zf-k&Ff-inXg1>)Kg8Tkcf-hAC$?)Yx68ysj65OAb;DPr@@Zf_IeC3A{eD#kKJk$^( z-`Bb%_-7`h|KmAT(|2z{NQeejS zC!*C2%=kgK#D3T!xTiKt@UQnt@N~ZfKYot{&-?(v%~4Ku^n&P+3YIyG(VhV?%^^ilIZjRdEOb@1gx7AyEq;@SlLzqJo{Xkox+GXP zzVSncR;-9dnbKIgfQ)A|xqKsyJL~L5F?6*38a_G!8a^rojps5If36*Wc?+h;%ix@f zodFJFF!ix+FyEJs_2-noeraWNd$c#3O~=wh12N?=nnWE0s?N1FIL_`#fV5+8fq)#2uT1JL2DH9h-T2(BuZzPxROC{3@b+0I= z9v%OV7$#+01FjciI1SWid=X7%66(kizp8l1x@pT$GBcP>peEGsr?Ii2A?+Ym0uj)Q z$r?!qLa{$PlGl#O4`Vo>Jwq*7BdVaKev-)yWJsO@{q-N9lKyNq(TiCjvA8!T_mY}q zwvTX~F|kyd5v?2Yp@TvS;(M+5?aAc+L~0n~AEfx+WWN?29~st(VY*#!#IBHQ>wn+H^zKgYb*2&C;Q@AJkCT^2U;wr%$W&b?r7OZm=;!@*7X}dl)eL(b9xl{lA_0an=VIwICd1*@O6lvfU-WEZyd?wQvI1^ zqLHIM-^7NeAuZ_t1qd2mAQc-M49G(q);VZP@)3WiZ+K7z zvOgERG>1aOIOI}fh+{&M=Ck`%;0a;W4JRp8m}5nvlf%Q=VLT^GW9!sXqY8bP$id`b zd;q95605x(FhSRfmPUWje+NLbC%9?Ti3m(cXEXi9DfUmCVA5|AYTP2;C@+TxGx@e9 z=(sA+rU6=lh#^Iw+yij631%XAFCU2|$a>DJFbDChjIt|lU5R0^W+bVfYJlo&C+%%P zAOVQ;A&!6#k{W<~YLLV6%G)Kru4hw3O>TY{aA!g zq|P8_2?9;3ku=l58(g@M&obaf0q0@|tmb-yn5*ey@%s#xGGLZ0~MtcJLe;V7!h$RK2%?Xb@I=B%xb9>~Xf(@B?Mk@Ibo4&R)0)$EOi zrH`p-cFqwK)>lVa4phYwXQKc%K%3EYj9bVj#OT zq)k<_VGVc^{Gi zUrye|#Ljv*uueRkjInK0lmFG{)Di^2e6SAj3EJsH!-3(=jXQn)$$VT*en3iw)zfM*^#0_pc;wX* z1w)y@FdyJW0ElXQo(_Oobdo}Rx_A0GZc&r}C<*uUHeo*WJAG`>)Z~~?cQ!2h(gWy! z;+YVq1xTm`y;&ki>k4zyz(Ms*?pKrF?KPTBt?qcjm6#GBOkov2^VK1qn)?g_`i_CFlS<%TxJMQdwJNDG-_oCLS^EnMJmjx8s|V? zE*{H(>~61hlI(Axrl~Mza-0K(=re}MgXa_v@UFVlnCfb^unRP?k@f|zw1UXFoF_`- zDe!<=Hm#!x4?!tDAL^%*Y0H=nbmUF>f$T^wmPzEIx#W##A?P{klZ;dX1YdxDxdnG;WsQ3MTYu za6=O+ODdm2m(4+zns&a1H#TLG{V@-GqlV8Fllz8a@n|B|kLPnWZ4+BV-<$~DB zTXNWciH0_lya2saLtDi95{oX=xWxuntfW^XTLoESSwiEM7+f)9pGLM>sRdgGHKyIN z6)+i%=};lgM6!Nz9tKr!+Ew(v9$@RXuruS$-H35gw{i)hpG-Ns<2Ziaq8Zt|01oA!&X&@w(OQ3tNy;Xx63F;rr zV<@F+KfngsH)k$kSKygT)qaq*5`|7-Zd|rgM6-BsL_a+Ha`JP~Pz-NuVbae=-^{^U z?Sq`;bwcN1lGfqWI=!T7|54(#ocWc1YC|uCU{e4CxIaN41xyA2tQ6LL*vLm*r_E9ME^u05ygpR2c8j& zkBeEFD8#vDT`n~8B`=aQ(0pbyN&SxQk!gtTjHQ_qi^>PFWrkA)7~MrV7z=Zv+Ud<_ z55`s1e1{Lp=3y^<1u-0G5cPylqX>k_eCP>($|cCDs$csgTFd|XanO+71Hc3fHaYEw zr>!t2!JR&Il@$B55lf<4VF>@h#Y5`Lrl%oLtW+Hv0cnI z&gEhR=!|neX~-li4F%UJ^r(V%yk@kpq?y9N6$}g)TwT|e=8);*xx_&_qwC&r$hZW8 zaf2)FePfz#WOAW|#75@VOYJvgTu5;axFYQcR+6a)AY5Ysg^}}sSB@s&>Wgy_3!~XV zJcTVY`6l&ODu!fPh>J6zf*4fZ_j+m@RjCjcZ3I0yq^ds5meQ$peXT-V%n>wakgDz* zh36`d;D-*Ys&|c&&eb15=Y~+UpZ|G@_%N4+h}TU})v_{8QCuc!r40&k?TEBeOMYJv zr9xazA|@kge1C}*Qhrs4i%pt{Dg9_kN(>Q~qBIfHbMu&z!Wly(jz^8@_j;a4PmKxs z>C6xpwJ2BI@b3lN#nmeOC4j(ga+vR| z`o6YQl0xAsbhkkd^$sI{j(hMVQlW1e{IKx<$b;AX&lxEq2@9dxibr)GQ}^YhDHTpM7KLyEJZPA&hd<{U{AsRL@peZ{1J zMGhTOT!hrLnqhJ#c`#bC(1j(gF_zQNZJec7_ArH6vJUuXucM8v!n0!cms+sHBz^cG z{AubF>hNuj#J#ms=AX^rvC<#ry0W21)%vuf{VTb|3Ti4Kmz_1$2;1K;IAt;~Q9?GC z%hJu!_I4Ghi#J_9lFh5S1RFSx;W2-p>XJInVTE`>XJsfH@dY zaw~J)Ayaz@WLt+|afplRpup@`-TQTW$nlK|ah09$l&brXZo@U4%kG4yRh>+>+Zh(F z!#h}Vj-fWGx=Cf8)dyLEU{%-cHIu8tT(Fn2T{pW-yst;4RHbHd8J`nVNmaKOvnrIO z!d%qnP%nu|fVvNwSsyVf%!Pg@&6-j-r;M58)Y7~1PldVukC7Mqv$}m{g~aF@8s@$L z4$L^z%c;5p-oDWt>!~pJ4S-ArgmoDshK+)rdXuJX7Izgmm*+53t?H`EwBT6a}9t4y26|Eg6M{90u>aROKQmE$XqcELet zkg>Zhp-!Jo5la@7L&9mR+kSwJ7SbimX=}fnQi+|@<y(*ctBJEC*rnkl<)tv1`o#ANHmYFUv8QFK?#skJW@sU&=X&+VR zYZRK$)s9R2b1prJ*w)1b>d1xheK1lBl|n3)a_KVqV9-If#7>sxWrMLpm?*mB{-49X2Hpncwr#^%c*%=J^o-W21f$z>+NS~NTntCdjX5=>K>0k&g~bg_?*>}# zTy1g;llF5{24^=21pVA#)au^>?grjAaHm1TI%o{~pTqyQo7OAEZBqU-maWKe1tM7C z++L;>;f`|-wk2^B=nxibRB)<87MNHz8LuCiB~c8KaIc(|zodnRUIl9$=Hd3-QUgIo zF{{g*n)gz&T3NTyOI}BE4>cTU$UjPQJ^#OQjo}%F!eG78&SUzQ0xTYJN>q!DO`y@)qSN)42$GX{m6YloF$P?3Ei ztyt2F5Txf|SKe;KrBj0#*#yt?7$YF?k6{W0sFgo9yopq9ANB!(eZ4iK6=qm)gvnu1 zbB)j`nYzgMA&Up3;Duz>nH~oKwFYeaz*E??q5JDq>kXegF$H%Q_y~9lzH1F1UXjCm zwF>rXP8I&b}bX>G&S9h%9-{NWrJJr_Np7Y{egbo8sXrk>6gB{}Sc%pE~!QuKcUUlMnj}tkMkgpE~zJ zm-X85SgE_Uz%1Rk&fq_i8QvWnk*!~$Z)p*9xCWtcF^6@<(1l#QF2!rr*)5u#6(|Zf zCsgRm#)u^l;ex%D>pbUq2ibJYrQ04&4i4dcM%^fUN*aaLeUyA`0tkHpTP@qKvB1#7 z)*{(r*?zl=xZfh~fgIKTkc)WKizp;SwZGt!{L9!Ry5Vl0u-I4>`l+Q8M~XYN8FO8d z=Zi=*cD;)|Zn4740<3k+N|WSj?_;V8{v3NsrCBnaMAt`1^mVlP!GG62jBSr>L({GP z9!a*6CHY<7bV*-!NmYXX@w5cLi=UQT&_c+rnNQtRrg8{ z;ZzdBLYI<--u5irF;YqkK2r;9D>UA&xEo!fGmJ1pRV3;@QVkpP7HVmoIu83jjpF1A z{Dqga-N-D^a@(+LVfhk@6%$u!q3w*7id#bF(5QZ>g~BsjD$HnL*r^okXts@ zn#paFer4^~_ zw~+nXe`&&@P2*MezjI07bV`%Lt6U!v~A#{w&-ZcU5XE~Gnc((4*`O=A<$1M2c zG&kKY{hrbE=tsQG4jU*>Gu(C1mCt@^nS!?#D;(QrQ|0G5{-NM%O1?!Os>8-Z#p*!lgUGU$|VqAA_sJ#V((>Y@W8vBq)?N zel`i>z`eL|3csg>Znmt!)BUdv^5U(Y*yV*iVnU3s)8>wH~BCsZ-nBBfQhnC1l_+QC8tnT z@Q;SDozYUdvsZ%-3v`7gXcc_ZFtoN6A;8M1TvtUuS^Kz+I`q#r!HjYet|Y~-zx88C z_g}fJ!TJftSHjA+v)EZ~@1nYYSm0Vv#3fnn^{}f?b(eR!Rz6>3B?dfR7RgCwit0Lt zEHn8uwa%#N7(S_WT?Z^z==VmC;X0{1y6&;8!QNtpZ;`OBUs$G4fWtwS1a0N`2@7^3 zVNW25!6QabYa0`Ww}OUqdAx_C2kS+CDfquDX4ylh8I7gvCr|2~Rz~m>-{>c&n5@)olsXG|y=dlrgxpTHhgq1eH#|%A?v|vU zOnDlui)GWJ-Pt`|L1Yv>ev5? zY!!Ih8@Rm-sLJ36nq<8~FV%gJQn(`tFgtIlf*;aQ|N0mk!w>Uya^IYQYWw6yr6{>F z__3)EKp@wIH>^Na37vP;XIEx7Tui{)E6SDPE7gwEgHe*Z?tzg>b~x6Lf!T$q-WULJ zjaFVhA4L*T)aN+o>t&QL73gK)<pNtAcnoHZD`D>3VwkZZ(pCK}kG*ZsT)=_bso|2aqdIT#a8fqk zlU2dTJiJ^)C9lPLxqt29*0beNY(jELRq#6nK})zCt&L#b7ZJ+rvsk2uU(KQOwKs64 zfF2?~RS?v=7=jD}#_-|DCa1aA@bx1hD)>x+iL31dvJK!EnGYr&P8lJaVe)5121eG{ zJ%t?{p=u76Oi5YJ5x2nggoO;Z3x@03EQ?T`$Biji`Ni%5IQ4~s7)gRbSc_~Tv=wU> zuvoxoyTu~(IWzEPfz|wa^TpWw&6gQ|IhBEH%CD5DH;57sZlq4UQ-gPMLYI0HE(`Jm zTXp+JyYEHRWxPE)CKYU;USRh`!7^z4RbEYj0`4+akNNy|8*|ZcL7gGU|xmO-$jd|Y5f<-OEclY zd(anXP+)Tvn8KOWehaDI{2=bb*)v^8<0kAHQQ^zIcC`Uy%{p)TJhUvb|06Xx1j>-Z zRB`VI&%228&{^6yTe8ch3>oI)B8m*=e2o5dwihR>gk?*G>j)Mzjd6*${EUX4stPxSumHsW1>{BL0S4*KczR{t>qcpH@49S67KxLFiy zfA~wfX~-mSdQ$iidAEdZgB+d{eyliEsl?a^=bSqW;&cIjvXny?^2OX^QbVmy?N#`% zb}r#P>T&qH%vKL();f#%0roctLP;x6;-@ISPyv>t6723%TySR-?$o@S%uMEok>XbW zQA8Vf8ST-f2WO*)>S8vwe{>vREMp%*uRHU=xK(Rh_4GDqMk=vs zl>?F_U+_l3`%_V#bwqp6PqcFMQ$!~fs7AU1wQBx$ElD32;1zaaEMeR=R7&cVw{;!m zv7-u4_Mte4mfC)pt#_wy?Q`)J1-y*zneA%pwJyH0fEU!xyNJ445~adbF4nZoTOV>c zt6iLER_FeXC~3B9Wn^KiruLAxU>EFFE7$DMu95A4(Hu%bRJYxAV+d(=Hx3pk;TVpz ztsB&;PaBDLI@Yv0DHgHWV+cj-Q2!nRa19rqf1nvVVgUK zf>xcMvJmFBfm-~98!z0rd3zKUGvcP8Ruo+VZEDp}i6Y(0hnvRIV)lb_xlLD0t72>g ztomxzGe!XxQ}Y-GX+{i0##2y42L(p9+;oU_o`g_E?Kw<{wB43h8UYnvaxxu4r*#<7 zvV%_N2F2>qj>d|SpuY?M8#>TTFJKL(@{831`jOYgAm}9l;jR8b-o6*NLAee3d7M`{ z-Za3N6feol>b|!^$MFUQ&x@J$#GT;4`!D2s9=H(C7;{oN&7x*~{b?lAsg?I!c_x_( z@$@l=Z+_rp#7s`jdXYFo!Q;wQhzFDL?FNlMPM|$QX!@HeucB#Wg?Aiu1{j;##RZ&eq>nvo`s@_+4cqgr ziwmcs$%FDJ(nuVK= znby^!ah-P~4s#=iqgGGcWq~(aVC`){sqSsW*iqS8YMv~!cwa3TW8bOldPs19r+5E+ zLX>ph;T5&$Ts80GEO)0OYbXy{`YBS&>iQ*R{Q*72ygMnx^Qyym_6%`<_TSPHljyF6 zyRD2*pSp~c`Z67;W#~qzD@#FHWcR##PEpX{V5u<=x-#xNbs1wBhe>b{$zY&lw}=KbTT8aI>{U%c@1CllcG9D0 zu+%c^yo2RFLLr8ee>h(zb3Aw}hw;VA;Wrz) zaIX2|;N8RH5bYxw4#IU>j6NXnZgUpL0v>jOL(sB*)0Xb8P0?tN?8esz%{zw$2z@_i8`D^}ph@mSZkZC$&g+k5szaCWFnqhMDu zH~JgVRriC`ad0fE=OBA$>JJ2};zJ0Pvw#QRbNy20giff$4TzVQ@%tnTcnUt#WKp+k z6uwrHj7Af=EOxtR5}1^f7Z@Fjd0`~ zUhT;B3`RONiJjJI?B9&Or{TBb(Dy}Jmkh*k=xPQ_F>rZA?LLdicKY*Z(i;AAe6}{S zT|Sb+4C?0C<^tdE;qQi5$LCv2K7AH*M7_f(6C0ak*U;!RCEnV`1>>{5rHu>6=NsR~ z%f?|!zO{|9@!8(e#>Du1W7#+``hBizPQH$ivRo`uy*&p}tXlO6H*&Cb&%p?0mJdcE z?WBvC_r&(;<%yHA$fPbOIo#LxEWcjOIAwlwWH+WOd18*^{9l?x9b>j~0cRWCHo#F0 zUq#$I8~IDb@f@$=|1Uh>H#DP3*uM`Iyk0r~hT%rKSL%G4r)AfdIbU``zO+6!yMBUm zKX^2qKg|=g>nAxUFb3D4!2WLB*H<}z1ECsJot6W&>uVf-=0?LBG4YvK^)sAWmvePm zpRrwkn)571?wan%;MusZZ*Z>1h*N{`YC;oLG&oV8GG<{eUr1p z6{!Lla|Cz&Sx&@FpsLQ;!?^1gIp?{Ss>Z>`sIJxdYyq}<|Mv-NcY=4eEm}A zzg>~%52k7S3McC(((g3zB<{311G|2c^CL+3x48DYISsphi}M78Xeb|A9kLAK^j!uz{9%Jcu-OG z?{(e_+XsZy!HIvE3Rd&mbicA#KM!(v)FGINdJw%3Rxg}vI(v|m?V~9L<5K!CDanJ_ z=XZ>z6pTyh&q}AI=68;!6pTw5$R0AJOGlA*YLrV`oz*Ay&0jW(v_mj1Wn)&3Q&IDm zkERriOSw9W#kQdVHGjouO2Jr4f90llCO@23^UoPgDHu!X+cYHaRnA{Inouy7&<}s2 zyI1p9jV2U~B~+Cuw758RVi2dbqXaaa#@#1;;>A0QBZG3Vu`KnvBoXt-T;M}lY6_0Q z#EmE{zUryv z_W`*yg)75JwU9?0AvCVnagnqNLhgVkh((gW)`^p%b`F+%j?W7rA{a) zo>(v^5O5hM$!$4hOs)kZ&k3pUi;{{8EwFL{;0;r7`hKmzNm5noFm0M(Y6DWRZ1NJA zR6Rv2FDC#Wduw*itCZxHldGm2gzdON@@U<3XsjY)2E@TX5QlWv84s1;xH>>5EvX>M zOhB2!V(6@9m;@DqA=zo7(T&y{u8JF1S5X#8PPecgIV7e*`#(5URUl6=pXU(?06D@Q z5K=}^BgvJTJs(4-WM6W)``2zHyf*ZYo6Ry9Ib~silZBXTw=7 zU_Q&{tWpb`l})v_=WG{XY+f`AmNk0}hYR3N+TJq5NM1YxG_BPp;Y(`O`dXW(ZM3@( zZ8w6X6@{#JGwmF2!D2~U>Cvalgf1tm zO5hrLuE!EmYv_66G^WWbVYQc*_H=mxZZf({6lveCDS?uIZ3#bN5f7ct8Ew+KLXB}X ztw-8TlfiWcmXV8RqkQiw zF^);z?O~>Kra3jvYK(CAl9qHR$UvvCh!&OI?#eXnEg3nPq|YN(+cK z8(|i38CyNdjTOYLtZYDHdJ6!ZcX51GxR#g%Z^)A*37fEXX~g;rhjuNQm=XPe7K*cl z4iso@R-!de6`&%Qe%WXEb%D{Q>@Uc)+|ZORaC@MGqiKU{G~GS^hhGvg3oPhtolFXFI9;z z8s$zwrm;g)jumM+ML}U%>&3SwUXb| z%r8o1@EQ@2INgvRiv*p%0}=8QVA;teVBP_Y0V=6eSwo!4Y9KzoX>Yk`nFAEHAiADw zeOfCx-)+h7EDlV6X!q{jcYM|FD+~V0@07)T3!GJbh&2Qn`+QZX z$p=s@{*o;YpHARd8pSW-mQ8ZpMrJXalp4ovcJ#NG`R!-4LRSXNH>RhP89yee6QTXY zw1sowW$74juB*)Tzrp7JT>DLHi?ne2J?m1q{g$&C;4=&8~`f+$l-o?iW9)dYJB5L{<&}xjq$awQ|KCsKY+{6->`CL zqWlI>K`-TdUXj5;n?+?-$+NiGR%>=3aY`bUh)Ow)Xo6+7`n7WsGNL7#w~dr0w;OIb z#ic)jCZb)=rDk3*Qm7$Hw#(>`!Qs2d`aC)n?cz~;(E%LXK5S&m2Hj$DZJ2Vyo>w`= zpv1=I?)U#9%IvEtN+w>~kX^t?n`gs6WaZPUu$ZD*yqg-ZXNVs_l=i{yen4vU!C0QJ z8G2o+&%DyR6|rxq)SXMs+$ucEQ=N_93ZKXmBlNomvIEdMNla%Rnf=UOm3oJZY(SR{ zP^CKCFojhL>ySxf1NEkvNtWrUhKbf(eEVD>vr|Q zG=8e^mC2%2u;OepB}`kHGpi@XrD7Q}Q9eN#QFa}Cl_^6~oJ*|k)Dy@B;=Pv^sq8Ry zK%cQv!n}-m$I@=xW-8G#>_E)n#Sxp=E*M+Z={|7|vd)sxJZbywhAwU|)5U^yw>W*R ziwot+F`E8dPw4~Mc3O4 zt-Cq7C#9u00iAl$pw#vyocy$k7cCOSo?>r{i?-W6L5{AA>rH;RlVVzujS0WHyDW(m}FA>QsmIH4)Yl^xpj&J43Lb>3avYVZ)iwjLcq-a#bWS2BU zMe^I(Tt<|6nN7K^q4HGGA_mj$^LV~On=&e`Sfm2X?5=jdjXRbgwmqdqIwDQ0T^1jU zi*G(ay*9q6LDL&!jd?|_K*3#0%|cG8*&VXr7LjoS2QfaC_cO#Wf%gH19FzFe2p$E-l^{c z3?G;Kf`}&&e^TT948N=I0}Q7iUEX9=AwE@Lc|XHx`W`b4m;{vjg53Ftb6+%*%Ck|)8tV6u_DHwjz8CzqDB2nOmlWEfH zo1t`GHFIRAnsG2W{&S-SP+56@tT{Ol#pkTBcX%KHP8(CrI5`?$q-;*;U|$?ah>YPW z1nO`SJO4F{Y%Ql3#~3%G3J&rs*v*M#??`_XZ_VKwX_O+-p^;v_U){t}IkFZP>+QuS zs%;D_kx6?m*4YTWWp6QNvbRQ!&V*C=e>!N8$H;t)(XT}wA%aO?_eUImb8z7aN9ZbklCU%pq8rK?Jx?W>1>2>}9SF5>LZh!W6BLFCyqIb_xe_#)oY5=o( zX%8>%=X%r7r9qbl-DQALFY(mNUq3Fa0t@VWp!*)^SP85=(lI`S%hEjsx~D+5*wA6- zOXQL6FfQ6kJ*-=P2$+d``?GrU09d*P&@})-9ri~$Uf1BVbhm=;Rsi441ehOv$KMUO zEFJ6eEM#_rVDvxA;_nzP(oqEKb35qVN)MQ&`+$dTCFoXyZZ2T}7T zFX&i??9bu?xUu)db)YiW?6Xt_-1HK<^&{w8;cNS|GR`QWyZ=gA&a-5$uI3WD?_H~X zZwcvR{>~|(yZt)QjiGm430>l5g*T+M4F0#bTTAHfMTOZ=AangU4KU`J{k;yls1*XB zy=CaBu4)Js>pA4_e8AV>Vmerdk)1{IF8rucPk0nqc_170W4ljanbFGjUB|U%w&Oak z1+u-?aqUI6%Q~(L9@}3XXU)N~2HHCv*N$a-s^bzUwwpT6RG@ylaTF^2*bXu*lb!(W zk{j1Gg6*2dV_gA1wqH7qWpMoLxT8$r-3k2I9x*Hv&nd-rN5`2fx_!}c_6+bh>b;KZ zo{{Z^j_X+^whKBwgMniG*YP@uv!3g?Zpm4nb$piKS#NdxG>O}PW!O{Z{go;9)`eeL zQ47uVa7CirdsY zQ4>+cz43a)ZFzQlGt?Z!ZFy~k|C$l!ZwD^cjtz*f#y)H|MAM*uC*ng$FI$2d=uaYU z>nG#f&u4#)xOrzu{C$YCzOrSRhWh$p#BF`9QB{g>Yx2h(h1CB|6TcJbV*D2-&Ic>T z%g|&k^T?|~+@_}*=?NpwE#`2Z*ncMC0aIS4`DUq3#E&37DUmlt@z5PRm(BECgm|@~ zuSWj$B5vodiQkX7o#STwFyd>GUl51Z=XWQrF5$lc@hee2-#|$FKaKD=ru@|SrYOD| zY3INx?^}r5_OXWTW2`r|NFJQFWBWx5zMGRs4&_=>ZOb}alIgw{ykIb#$E3cQ-)6vv zAS_s(!n8A`EW)Bqyd|C+X)z0ualY}_k2xQ{ynwF{0i4T^^z}hxG`eQTmTl2ZJ==Fg zqlm37ik-j4MRC3&jqfWZnmd+uEK@@aI>C_0nj;RP^6(``@aadi#K_>_VXGjrd2KyrpRutmK; zg)cP?ui;4pc-)Ql4MhhIA`rHsNv`%Dn7pPna=<9wwJX}z+z!h{m)MM*?x{?{uEl!l z$ekt=32R47C|(XhDJmqm@KQ?Adn29%(vi?p{Jv2%if4M8YWwO>@f$?i?Maydz?bz7 z9g1QPa4ws{ISKfh!hyxBSFhQ%3zHd9dKcN#xvaC92NMp(qxpf6%>L%yLs$pFR#C}H G^}hj;jg3VB diff --git a/plugins/org.eclipse.dd.tests.gdb/data/launch/bin/ExpressionTestApp.exe b/plugins/org.eclipse.dd.tests.gdb/data/launch/bin/ExpressionTestApp.exe deleted file mode 100755 index 9051861f97e3df5a0af67b67b7fd41de2c10e4df..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16921 zcmd^Gdwf*Yoj-TxPPmYSghT-qbRrO-vP&MHyI> zHQx#yM414IJm8s#ZpuJ6-v&8iEoer{Xq!<6rbXO468RxAy{J}l$@>;$h<72uy@<@0 zau>kM(0>^+#zD}Glrs;;CD31jycxZq8MSQ1Z?oYr(ua4L7ULO^F>3ir$U&YIwEg;c zS7&`ZJR{zf$ZhpylD;OD7Ou&%Exvki%?Y%&Y0`u3w3*_qgu4=fTqY70 zsa%$(p^vmO_szksglJp0u603spwTx|EMC^Wpe@h@BX)41M%lB~pX^4mPF{Lq6ROoM z9<=o+PXX6;S>4rD$<}z(mhbJ36zT(jf1Jx8s9+mLMF zFdwVHe14x8n)L!ShNc|ClO~6z&{B-(yKf93OrgaXW$zx6G%d&I&bxah%^YImN$&#P z_`B|22%@-eiexJ0uqTm1W95mn&k5?)lJmCLiGn7TYe=jZd`}ZsHG%4Pt^`1K5 zKhbr-|1os`WE}8+BzpZX@9-b)^&i~ff4$fL$qxS;{r-1WpaA{;0W={D9raHl7;Hwj z@An`3&7Qe61B*~EwkHk!{zFuhrL%d}aFzqM-+$sDWVT4vNA*s>wZng6r~ia5{h#4L z^Vo2jC437tN*@NEgW6v*%~Y_b$k8CWzk?n@ln>Ey`!Wqka8&ma)#!dsnrX0 zbL#rH9ld)DDwp2r{NP_XNB|bMxTHrs4YDsBKjN9K5S{APfg>BhZ7Jr$2u%a98nv#? zb<~nAW(fukqkae8#$$us`%yE}m0tfblo?e@lf8ac9|&bwmECI>OlT8fTp)Z_( z#g!PFXuKtGZJ-jva^Mp_dOpVE9z1lr|GmOxdw*Zyvc2!5;;Vd&{sfOnd|ZhK(!mcg zuvXz=;x_*v@dOpW#m6Ij?B?STA8+ze!%|M`;re*)bh&1sd=Mb8M<_KB{qJI z4X?K$+!7q->+rtE3r-B+wZSPRhV{}PJ{d~h2Z%S8nEoZa?*R9J9tHSgL=Hce=S)Nf zdU6o&26jy^BG*!=Uoj4GHtZ8`0OXp2QwZ0Bgs6(-AncO@~g zUf)3c9^#XTnoszGt#=+XM0n|{&gyk1Zf%JIe+>oss?C3F!us%KN50xpw<{g%OW)oS z4IAP($|&&Kun_tBpy8&~Le#Yh@&1dC)`-PzZF9ZTu>8Bw+w5!fHF>A4>C7dvIYrHA z$VsaCLh=7vlhrP!Bf3N%p6qo(yn}YS0FeEW{fqsP{X_@8z+B=ybZey_zTLDAsUaX$ zIA&bpeJoOyd^7CGro^nOILcC;)FaNkw;=|K*OnA{VOV8$XtWSBU?-jo1>>0}aS(VG z1ACdI#Z@p(vMtsX52qsu(PuM0m+s0l{>>fq)`qc{uWiOQs!MA)WQfl~5kPU4)8 zk;fETN35|KZOKF^mqvzJ@poD$*Vzd#Hwibk8BEj~hDVudfUxQVCYa;A$ zO1Lq3rMsU_nK0R*kPd&?li#rirVga6}F_jF2`pz5% zrh10!quemgX!6Zcj2YQ%C; zku_|c^IE3IT!@bIAsqA&!D>u7TV}2V=~kYWjkpCwC!DS@##v!>1SW7z5+fs6XYtg@ zHOX{~5#Li#MaHeoa<+!Q1D1_|*Mu_~L+g-{_zlXZhI znwdLX7Znde!O-s*{p(#Ah5o%p}^=C^v=88w5B72f`<#0hs!GCg~`wGGe=ini*j_4ayINTaE7y<~yfw;ROf|q-WhyRA z`o;>d8^EMNmfohzOjcl-Y^N$ND`X?&U*EPu>*jC*?5Jq)c_fOa}4wys4DK)EBg=Fka zVnVz};i)rfpl}`{74Egm3U9gcl)31osPS!N(nwcrj>?1fFGqaG&f|XDZe=i#;-LMG z8f)k~T(nAyj&&oK-NwT(Je!7#1*)}ZdlOv7I*vYx{9mYEP z=;JUi2TQSeySv6=`+mgB^Y$Ni*#AM^eoEUfSz8-VY43{#s&>8u%a0+(V4WlSX?sMo zvY(+zci+*^3zG|U=6WXIooh`|#l^X!H1?9+cn*18Qm84#Ryi@3e#Cp36Rhu7r9i!N zQSY#&R{F;CFg2@SN^+H@gRt@zBIh$&`nj6-QODc~lv+Xs|DxC{wQW$gXy-WMQP>)h zLULcAu>r5pf8*Q#kTi@}D2MPb*Fq{=l3NLxOJST0v*9pa39O%~=Ft4eIay74K@Udb zJZ8KbUVNy$XvEs?FuizHR+R05E!~2jm>Zu7HzDWbb215tp-lp!zSh7x$tfVVu~KlMb_|e zCOmwX9{!ip!}q+9(nB>#o^n+PV-U{CK6%P%ly5%xH4pJS@U4nFJ4Yv7p5O8re?UKV zOays}GBO_qqKF4sz^O2T0yd+oe#oWdAMFBiDS2GZXp>CYZU5JRrmHVriFM^iQV9hg z%gv-}8oj+VOar;A{%Z47wlQRxLp+9T#~~+=p{%6FA*(XOo;}Aup&Xip8XsYth3{ns zJj0B^73etRJ<_;GIWi8-G0IRci?BG`kb7FAN-FbAl6x61RukuNpF4N1aES?ew`;g* z(J&@Bw!DU1!;q)!Dyy@oJ406{iQ@NC;GNTTZkT)=t839XkU+e2~c}?JqA@_8b3r8O+z#P zCA;gyUuAb~j4`UqYVe#gy0+Xs`W*P_nk?L-%gg6u;&21C6lykuJGcC@^7h&*DqNWM zJQs*|o+}z-M0MGkGPiY(HN~pMIuaah(}GR#Kh-AgOVrYcrw+F2kzrYtC`S$$^tBK% zZ)S-Tj7m77a-WU7M>@$S$VW|pf!U*omMau{K_5(9QK8a(rNtU!)EF&T_En-Jwk?)p zbfI7*t4dO}*XnfDo_q~Zag41fD+T5YiZxJlWKio94lfF7XOyF&YS07Dl%+?_jdkSh zDKa_E_Sw^3%e==sY6t1gva179*3Q}a48hRepEE~RsH)Bhg(|qB;&P0diOpiMv^-36 zVp7AzG?5K!d^EZePkGCQqg!+(y0X3yM7ZCA=n_}sd6L@cc5m$Q)#(xPK<9ArG|XLY z)YaF`TVEHA*4MAEtE+Pv$OuB7bGs)&IM3x#9G-Z)XWHtnGBDqhzRelVH!4b9*!z?at+L-PbmBb$2vG4|mLu zM(3#*i_V)D#p8=(sc1Lsb6CLxd+C3c|9lLk$#!~}e>pNT{QQU60``2s=PBnH@@N0m3 zq>-6wVsCFEBF>JsjectMx+Pn6swd`{sO;US3^bV>hG$xXtS z6mAi!*|?y46ujRlxk>oG!Y#s&C0@||1T>Gt=&w8)Ljmb8UrALGFX&c-9;4(YVXeX~ z!l@E3=uQKDp^}?~7c1N%yh7py-4@WTN^TOiDcmC5Ch>yq4WMsSa+C08g5W@p*(r3M=e)prPa zlak|taE!zYc56V7RdSPX0-_;S5=^w&gy$*TBIE@DXLcNg2mtbP7;@gVnMi3As`I%4nBC){6 zG_Df_Vqv7zl<2To3pmjhp z8J6OSzA5iZ@vhWc(8KOGpD+Dp+v@Ud!aW?I|mu-j$u2Z*5gaY!hu&7$+X}rURIr2AdlWS7!F|DNiu`?p&WoyA?}xy(-a+Uc{1m;X9eTWI zeF%EmhSMJJ53((oul&6P^agDnfJ{R_`Vn=$yyLzfJMvO{q+f98@y_2t=#|zp_5R(V zHvqi>=!L=4L6`kCFo@GX-YH*(!J=i<)jqrdoc`%Ry$c)+jlK&7jZ=3kI_FlM2vFNT z4&13X2)%YXVFxYaheM51GzT5-X5HyPYuOnkdQW;W=dhF6LF=7gqW9|gxC=Lop07mD znj*wa4n18jmzC(WD_O8DiD;CE%cbJA|ao}%^$Z^}H<@~N_ zl{4pYMJtavUn^Qw0Ow^zs|-2+Dw-ol2z@6NmpvrS`ILy;?oFIG70ptpJFkjHr$^vC zsAzOr1kQJgMyEsIyryXG9@X7PMRR6HpS9N=ZvF-bf%6fe+n)V6?Q5_(d8JWybY4|w*T52UB%DJ8Ejp?M=s z2kNIm@Su-8m#7q9(n3JWdjUD$lWpKvRrdqx_Aszg`A5*YJq)~Io&+s_TO;+)5+>7ZV_`_2n~}ZPT#okt8?^H`dj_UFU4PZ6kI|s@xg7PUg60<>ZIA0eeU3%> z0?_(=jC40>eV$1A4$%4>l=OX|`58&udjzyT*Q5Ly(E9w6^oyX6+WljUYrOb1XnDsT zfbI8N(ELeT7ijAL0W`mlp*p1e6VUpcl=2E>tj`5WpAVX!z_dRzfar5Q%C85l&jm@} z3z{FiwElO2=<`|19|O(tiR>}^elYYDXnt+e`g?)s^J4110J;KlCSZB~1GGK|ru-ey z{G7*kAmtx`UhS~|A!vObOMThVp{swhIUXIK9|=``oF#uG%8z?UChc7Wxjvs|`URl% zc`E78fp(VXI?%f?pYaz>>~FV#*5|d<|0d|Cb^mo$iXVX1=bM!O2(*6R)o|w%?ChE$ zH^Qrg&sU$>mI+5v8F}lrJ`&$pFMqy?gL?Z6lz^LBe4ROkqsd|K?uLT#xZ{VZ{3w&j z<~DAG$v~iO_3~>1%i341=I>Pl3yY{L+wvl8ep9^u9`?<;bk=N_(C${)}aGt+p%s@$ndtA9!9`N3n@??Qpa z%a$)_T^3lrXwfSF>cHyO1s9S-f+qv&x3=oW zx;n$Pe}jt~&;fZA!LRo`1GY6k^|Ay6CAamuME-6={yyWW-Of3cUma@idAE!IE)Cttdgs|JBfg{#^Tuve|>8 diff --git a/plugins/org.eclipse.dd.tests.gdb/data/launch/bin/GDBMIGenericTestApp.exe b/plugins/org.eclipse.dd.tests.gdb/data/launch/bin/GDBMIGenericTestApp.exe deleted file mode 100755 index 6f604184d78dca9158a4d9a3929e29ae829b8b72..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9594 zcmd^FYiwM{b)NfJ>dIPC6e&w|q&iEBl4;1gs|TepmK;+eDUmj~hhrmh7$sE+p%R=|5fqVYqfyaEoCjPN5n8))EjuVs!$#U4{ZaK{fU4D&DI8aT zg|Oc@kL8k=*uQTV)%-t^y4DYZkOPF8_N02)C71!%VI<-_ux?W7H)&NE3Tv=*SCy_Q1crgzT)qwwRDW=97j%O8O5q{aq++MgHrW z{(+`XYZ_gX^6zLm(DL8Y^fxrU5p)hVa{~>hzQ;*pY}uE^Vv!ISvucz{uUW$Z+bn`0 zJ60+N)hJbof6T#7SR5PYDAeT+2 zgDR=@sdB}`>VOI%vlG_)JlWb(zJRt+;^v{Vj@qFjrrVl-VSRYNg)tdfsHR0kc< zCtEa@$`?i7p+noY4+ZP}jbi8U(DuGy11d7Pb?BH3Trm!8(#E`5`X|j)Bp`q5`$sTk zuK2M6LvD*Q@@9S(=kp6W+kdTjEt0my>l*KU+x40-#_dSwAzi@~W1L`$!R=&<8oHRm zVD4rL16#)wMso1<+vC@~$-jiU$rhBKTmx%*{gRm8)B?oxswH@`s_9j%A;;|1E7J(8 zSW}L&t8Yk}HRjmtt1n5KHRsw%KQC#vAeSJ0Ueatyu8Z_pNwY;cj@s3eppnY3{y!f* z{V(JHKDFn-zTEj!Ks=Af-iLCXNG6W~`0m-W=)?Z;Ywjcq9DeH3=iy5xp1uLusW+q8 z z_jG@!J25bI+U=bD$6roQpB}hAF>oEs_~rgi>1vR=mZO zhaWkUx^W3LK62?yv|60GcqiKi`m+!1pL`VAr!MWqN*lknVsaUZof*F_YnxJ;y9TCS zesap5I5>qtTC;xo^s8rHVEKuGmhsCLnuDgsRZ~6GJiT=MRrk|RPSyT-{FN1l9}OP4 zG_j(SLyG$L|AbB$6Yz{ouTMwu@ps(mHzu6%>(jM&$6s*|Kf-o4&e4mDVQOVG=wZwZ zeHrb3U#(co7qf|-VKJ=a(}`{6vPec_U)dIG8Fk6U8CYwdu1TeEk{-o7xl?JH~dcbo!W1%ShvhSH@iri&zX|HtFwjc<21$m(!)^kkVi0zKk`D^fl0Y2fT&2 z0FnK<6_J50iNhx8>w6ISKEfD^Wr!D`pZW7h>07xd`95Wep(yPEA6+Q1>=e?ipppHR z1K*{lP&0h_?T9|&XApNGK8jdGG?*6RclPz&ljy=L@2*6*zuw=F=sGx3D@HX%tzB1> zRQFxt|20zFjX|@;IXr10LOh3YT#b~rLtCKja86BFfs8Fa2@_QKx*cl(?b{Z&!mO11 z7tq7`e@xq;hKUY|BgMK;AO^GFhZNDsRAui$+aDpy_a8-Pq=-4`vt+y3cG@G?hxj6* zeHagSp52GU^6VU0^X!KdbAZeyo0}dx=H!c!aAWo+P+rX5%VeH?4-zo7mSIpVT|`@K$J4c>M?@|;Qp*=I>X}Jq`5s@p!QZ49YokgSCi5G6He;pdKZ(1j;lmCOUvc&<}noD@{6~?I|uy4(p zk604!&i?HW4rzCI03Hw?(NCvEGFKW4ljYR0u#h}fsvN17Q|XXiGFhr*{V-j~m#d+l z$@uh|RX>{1Z zED7fhJ&-+mXg3IFwPtPgf>I&F8LftqaJnp>#_W~7P*X>p}N==xB0j=nFXntfe`^gWQ#1ETjvsbMF+3{u{I5EZ=Wke{RFE~KDYx}*E)@77kIyp4=(;j ze6Y3HYH4c4b5(QO0;hR-GuqlIoaO}!K7%)_gRG~rE@rm*o&{SL47J@Cx3Lq8trkOk z=~|0LOVhz7$6M~L^4hp%o6+e(C-~606pB=7rBzqp&QuUvBo?5`CMHxoug$XBSUZYA zD>jKzLu{z62er>vwcld&VpG_Fhn~2`Ll^N2aZl4mwap!9b`pR^J~;QqO|uqTtyV8~ z1TE;NZYg_tlkTkq*A~A;ne~42LOkUa5T?=+`C>lu(+~;qZA4q_!t(>LUv;{L(C=K@ zkBHgaL%=O}Bs=c?Tt_yWOn$DTqr=Ae*@BRpB4;Ip_u4VV;r7VcsNr@Kn13VN_UujD zR;yN$`C__I!$M6q5Xq4|j{TB@tw1uHPABu-a$kUpoVD3vEh)FK^|Ina-p{C%Hwq;m z>qg#em~3>S99F@_P7HudIEuUjH2TCPx5R6^SgUyt*elz<|FAtDy*LWlZ*qjWqVx!J zN9fGA>VwLiA>L;7VOHl4o_#RtPk0UICN|jYH$Uvyq^(5lANaPHJD!i&@5r}${ncLI z637?$jI7S5+M8@pK8ESd-nG%)a=!Ep&@BDzE1Vl9A#$0@^&<8%!2*+PraayOB9D1I zPTHa-ohPy?a2%PVUH=r3Cj1T}4fimjhSkrSoSpwgG7{l8TX;e{Z&g3v2 zVWlkmVkruJ+)S;FQd!}{Z2erSniGEJL=lBmiY<+l9K{PgUn~<1fq0cE7b4+v zMg?}1coq4hARsDnS1J537mQX?V_}fXproOMpN>k{E%+Ig{B{~bs7#IJ)2OZlHF)?^ zx6(6G1v*_C8w)Y9ekL5LWrI{DRm|eDPm|@^2o%iF`Qm8F$WkLCmGG#caQPaVylkBz zFj^*yx30q-%EYJIc=YZ=3k7XH%VcdeK3{>4KyawEP@OaOFti`RvtIJpHij(X zd_?kiZ*d+tE&`*EIMTdBF*x3HTmX*uAH?x)#o%~yWm{Pf*VYx_cx*Mn)Ej|eaMyvm z4%|rtLP{LtmkF(n_zHH zgJEzNfa7-vjYcM-UYzzrG@QiJ;wjYBsDujlyPr0#4Qa6fFo#es`|2#y!U zte5(D0lEY@Qx{nE{9hrDCP|$94g=hj<{^G`cLlg!3Un|s4;hoED1kT5vm8(zjBLpq+$9+1Mk55)Wbc@Rdk+^h4vkR< zgY)O$ZosM051C-bWy>5~4~+CR143%_?U;k(g=XJPaC_(A27w!Fz?t#my%KHDgtNf$ zo0AD9%e0|;!oz0vF*uFY;NOSHesB%bw>0X@-GT2@4Gg0Xunz?KeKOS-QRUwit!kzp zSF}<{f30XWioEYtwDNkq2UfJ2Xmd~N$Tx`cr%Eni(r+r7y-@eSistr2`9VeVO#s`2 zzf-hY5%g<{=Jo~chaXWijz|b*-{J8490L6jQ%8TDqTf+8X9Z)*`(6Y`e&NHqtJCVu zNPnT^%A=Y4WJlj}bNws1`l!rxu4v`Sxt&P2#>I7l6Fo21Rd5uY$wnL2`R>zUxp z^3W{Llg>iBIWlm zB%s@+|9zvOzJH}a-w@oa{{Mp5)AP;x-v=$f2Owqr^l##8M*m{56m(;I=&usmzNmlh zc<`dn1opQ)hyEI9V?UO?O#A_8GakZj6@Na5ei^i}N6Wrd{1mjYw*>nCGtj&d;Yw{q zd)@|Z)(`1xpiM|1^Zp!q5nKY-6IVXJcP|BP)?2G+7ArtAd>7^T4d>IKa}D@G(55{t zXwN~7H{av4n%;o2EPotykDkB9cDpzQnx9VdQoc}pL*wZ?iT@sGvz}Too<9QJugjBu zQRB_`{MY8-{~mPX_x&l*x9Rz7wHFG0lQw5Yj#nHs_i3ma^}|1)I_7DkiuvpWv2`drC`hY(yue2nAXO)vM;sY0RQPX@eys7AHXQK$@pz5~1W z1;a!85AeSSLH{i3{=T{hhm~?6jKYk+=~J6}M41WyyO1db*+OX~RS4waCrH(f3w1=w z)W*h6m6MyotoNv*$5?|BLEAvYJn&f(qLw+#oockI|d za3DCaZTs*5M}Xsvvsfi{BH*p?EQXvK5%fR2YukfEeS&8>^)Cs)jgR{r+pMJ$ohz ztz5tF-tW8fWoPa6f3N>~?zPrl`+d>%YaPc?_UBU-im{un_6Ir;?)!kobf_j3Q1eu? znyn@PL|n%K(BKjVFjWHP$5lZb;vH84k1L2cFXAYhm;A_!>z;{9@gl#f)p&t@6gXTf zz;H2?QZMm71doCKG2nQ;fjBSXse{*9;5iGrc{L%<%i=cuypXI0fAzKg0I%7=@v`{M zz#}^9XXUqM(!H&j17m)J(?7zrSbqSH7_B-=D;7$?p*p+lH_X7wxjYCfr191R>+?CjK;( zlKyEE|0I+$zRtw&K*)Fk*JUUlZ^KZ={{dG3ex&VF)p1I}Klws3F@HXt)2U*y{=w`} zEMJJ{3bB}qoxLZvCDotK7gD*^nRq^*%B$Fpjav&#)7gBiH=a**^bDm7tJ|V`#)7XA zc&vZlzSwXom(LExGwH(q*q(({JE%3{u0N58OU09n3thrk)^iTbN~VWm zBl%Pkh9>sKWAQ?2U%G$@_#i{99*n1l)avcqySjT~Z7uEU%=JCph{oDmI`n;P5d;eq zccj3NdB@!JwkXm z*MY;IhKR#&^WVK-dhRK8WbuQbI5Ov9{HOdQb0~R$x4-=H5&Y&*!vJx=d_m&WG(dBI z`J}|DabO1H_e-3b2bvhaOX9R(U>@T)A&yYBy?)X4KRNibH#TkCGO+6Xz;437&F>lb z)HVLV;rl@JhnsGKy;~3d+JBhz7hL(&8)#b&-SReY*SuJ$Jluzy?H4@v)J^i!X*;m; z$Izq-)xT;y_@w{uUqj@`i+3|PRC~>fBfomOl6VJ9n*Q#G(X3qaWTEb1>cGvUXZ*7X zJMx01seL9&U#VX;9*VyG^a1rT$j99?{%h37wYv^R-*&FN{B0)dihq0VDUs}Qg$|wj zHps8Lij4aHdjE&X>ScQs+HPDw+Yg5vx#Vp~*nIeXNZw(3Q%pO5=Z*2Vjny-*kG_5V zxo;i3{B38X?aIsFqC-dK!Ekjad>8x6kt5HnnH_i;2}Q`ds(_mf_a2@FoK08YtK@r_ z<@E5Up~i(&THC z5B>p+*GJ#bHz!Bm_}b-f_zs=>1~P4a+mY*^zVR#MKNPJ!_>6Ns3_TRBM&Lgb4P5V^ zeWd>2)Ba_bzcKQogI{mF;G)>hrw%pFW)?%=)<-{!oI!!OTf(=F6siyY%75gALlp<# zIx_NygJ1Vwu#?{RmYK(Vpa&M zWXbym!X1d?_OJf2zqd?_kfv^2TX6N_%Hg^Sm&HFw+A~+LUfwhhUGm9I9cY*rHO)J> zcVwtAqGJmdj!3NIWcB|wr8*T(^QjNvzqAbMLHKblV+dIeSZITHpLxog-$^a<#MiI+9Z8_7-i{)67@?H`^ zoAOWettK$wgMQ_k=zEU_vX(m&d>oMZDl4Es`73>k5eroMHZz#$TaExgBV|2e&IJGG z8Juv4|0^pvbgDcD_v!{*KGlu?en(nU+_mI{7!G2D7>S+fw;L*YI#lBB5FbvV*DC;rQNErgd*Nw>v)^Po!Ft`M%a{ zuD>Of$fSq!sg`82r2w9MOMkMrH5o6&TQl*Ip~OIIK9^9wFTxHCCx=F2$yD!1zp7}d zsAwfn`8{AD`&7mJ%HcvTneOY071V^=UIfhqokNxR^ra~RzxN9OCq7EFmd}YfC^09F%cCZFmdN131XWi=pAA(DY*xYY+zDqC)&%vr2gF! z4BQ|=`W^{(JuboSmnF#jUV_1D6t=*mp>_$f=Sh$sk)Uv=1bd#6VDB#^*cU|W8kltH z0tw!`R)Wj6OK|xm61?v^39kB#1P7m#;OZYq@cutaaBUsxa$wR8DKL+Zr3l@Ub%__;_4`+utj}9Uqk76OTx6=g%bgWYvjexNE5dcb_N0 zrwS7M{T&kA^MnMS{*eUtPDBeBnD)6A3GTZjoX7{2saVEzz=#k=uY;FZRp3{|6^^r=Y`ZC#g0WH!{HaCc;$^Ds> z@;BaBZ2;+^WD3v0gXtkWcB=PTaJ)C4LT{pMd^nd9fTN}~Oi&6B$!R{C=F&s`qU=<( zT+5eJZLE-srwe&)f(Dn_)db6G_Mn6FhmIWgGYouuvy@XC+YlR8p$g|zv}XWJbx09X zj#C#q1>IDT@Zj0F#cy&hwFi&hsaP7OOM-Rdo7lH+`SMtdDUD}}$V7H1UudFnr<~d( zhK{yh!$&7T!$+l{>2#*zueIZEZ^5)g1)Nj08Dq{^4`wgc4i@?{@&3H>H!P`+ZH@J2 zvzd5icp$DEMw2P@VZ7-}@56k9pSJ_4eJa2kj!$x!%}}+BWm0_w)x^7OqM)8syvwEg z2MX$dh{`9@C?V;-bV3~vk@vD%dVY6$crPNNU<9)* zy(4|w-F@`faea08D)KF3# zIN(=R4_P;zGn^V4%qCG28g|pz`0%iH5G#QQ=*4`CqywSYpB*V^#}slH4rtF%OV)@g zYN?-OG6NY>pg@1aEmYE<%_e&>u_G4u#^qj8lgjoHt}`Z{&M=~NLq2p+NKyPnR{Yjf zYIic7gZPIjzBkpcMJGmbIx$SQ>y5mocI8Z&jX?zyAbI9Y=aiRn8iKz1y*{NH8hm3+ ziM6#sPcGG$$l?hms@l+EITgEU@gO0bLx);$3pnXt*<2Os+eEil+K^i!I+YJ(2_!$XO&qy%v zO9|5c^OTzMerUjKU~0cj_;9?yajbG$g>NQuFg2JM0BW_wg0})D=%8q6@`wB%2WaL5H*Go* zfeD%HP=9HP{Szmc^qYhlw}>|?E8)SRLi-|gT-B%204+hpkRnj&0l3-(GZDO(jKq^< zJ?%Fz2l1?ova4@eiea#3B&nZjfa>fZ?T1bP5`YAs+X%Ro)BqIHgB*@m-zM?3J?o=t za?4e~om7ERz~@1M-C9+JZb~<=Rn-oSMhU4Uo^!h~jP_O4RMUa^i*Q!MsyYJ?6yZ|w zs)7blEr`82bZNR|R!uXQS`S8aOgD&W9)u{VH;5U6K$B`D9dF=`E?mfG7;uw-^YJ}a zbAv(5*7Whj?vY_5>O_N@SL6{{jRt;dZEP@}+l}5?RfV1Tc*yY0T38!H5kNy))#S7Z zqyv6TXD}pDRVNuoE;X)Qq^jl`(2CkvHj`uq;`v%t&2vshp7>_1g1C`f4Ao_15He47 zSm%7R*3`!K6ym*^l*_Qd`5H=xZ`Rsc_C`7BW2#!5C1S#vwK0|hRkg@DQvhc{o6&Td zvqm(nuZ_iqtE@Xgw$Auuv(Alo&hT~)0$kP9`WLsgw=AQx-MVpVmP!;0ja zm4utv|5TlA(mGHZ8yVsv07S2MHi$(T7EWCpPiJwQwHJjN1$9Eg`30oRW*gNKYg2)m z4Rf~1{UYVB*)%s6+nX3rHPSNbNUy5dLTc5F;?Krg)oe877mz*i%t%VrY&{hezFB@X z?|R&@Jvo`rq!nuR!y>$0RZlq)}Z%!m9gcvy>2`3y!L;`bu+bD76n+{*W#}(30l>q3U5>eEiK~MAc(D z4FQNfEW+ufdCX4NdTDZjo5v?(7uu{U`;ZLya`JX2cE;7fI*Cjw&bCoa{;tmn5(L3~ zunzMH+UY~Xf#J>M?@+73NBB_f^q~h=lfUotBKVjMgtWAiU-6>CeDrqu`Z6Q=0X6w$ zFB6}}oxc85A)zKeBqhV@Szs~r{^UnI@`6OcP$n?K2Y3+xqB@_a1E3b2q%fcEoj#6R z)Z{-&!acoBgb)2r9~(3^IquV)4a>gt0Q#SJCd_F85^6zzDHEi1ML22Tp!%kEtI5}S zjb>A;JDv#VYe`d(q&?xKlBwK~zXlYIl0Hs5IDLf_ddkT+`Y6OYh%*t6_T0l>&&?Mg zyV}W5Xn2Iv6okS@4IUq<8JxIqF!*HeIQf?-11!iY!ifxLc!ZhqQzQDtqB}Xi;p8yc zvV1b{!z|rZGUR*^u zUqaj-K`!#7Q+M;!p}Xo+oxgMc-kw#rj$`j5xPLoO$$_nQ#H<>zI-A+1hTum*2zfa3Dh(d;Y^OR#}Iwi z5P9&N;sM@OmmX7HPz&Qk5QvSmFLrv5CAn<2QO2|XIz*o?}OE~L?AbC9K`o~_|c%|ogF zxCg#Y!)J@heYtodmQ45K`CLt1&(_d4YhH5+bc2ST+&mmh&XVXKCp3V12Qxf-#6l3+Spa@c>NhPIHr2;HfntzvzdMHg$_ zLW3(+(yNhef-JKvsd0-8u9UG)BipUiqAi0O(_z_)m?4c>tiqg$Wc}nk465GL%jtbR zz}A)iR7azvFit&inDik(OL3(gmIhazi)O9T3`&C=`VgD_1I%U?2Gyy-Ynuz0#ld5I z@H*B|DYt_$Oy8*B^%~$O1&VS`1#i%h03n0P_UoZU>OPDNo+iy&;) z?m^H<8Ih+*WoR532s=T-K=d4mL=-2M9e748J}hQwqA=&0b-B>UUwe_9f#x%tN$S7o z9+`#|+uop9R5^%UFPtjC=q|>=ScDVRPH!Q*H=%0gI($$z4||b4#BiWN)U!T~A`m9? zp(k>;OORJJ|KXEpkpK1Lpdq~%fC(6Ea@r41TMjW7zNV-(bw>2X2WfBke=J42}YEGANyy?zgf!l&a!+FfE2BH_EZS0;z&x-f_l5w0F^yuxIC ze{?2rRY9XUDysQ`heAcT*5Kq_zwS3)6WhgX<6JIAfX+DgQ-(~k(ok@nLXRqF#~+Lq zmNZisxPpP4~)Wdl}GTy`&G^RM@i@EkD&9zDB3?^ zHhaZKxGY4xZh~r-R%nXSGNId`FxQSqE4Ad!q9_&SauP8^lE$0MtdR1n!dz_9L`><& z%2Hy8xD=&{n4TNPloZ)zh{W-zG5uc86X~fjAwQiN=AstmiW`1jv|U`SB40A-LN*Dl zj_z|L7l=W1r6G~;x>S9t=Ibw%F34L6SQGS1zt7X*2xw@J+$`c{P5iX@^8szJ3 zj(*;8Rhp)d3vHTc1XOoApO-O58C96;aHNu1#F~e6>Zny4$GD1cl@3IOEQ;zWrY&NP zRS_=SIeR%h$c(8nI8h@1G(Xq%G!=8^IHx>Snu^PQLM6{kHPgl+o6}^-FrZR3$9t)y z=4fHvLS_4bf~Nwa3%E#-rgDCw1Q)(saHw*a@2q)2TPjJRa25W9K@a!lkUxh#coM1b z;|8A-{_lA3n*TL}N7t=te&s<6d&GxjKJ6*0pI{Q_>enUR$8}D3X-iGIy@jiT4i@Ls z^v`2{ewmAF2Q0czaW>Qm^1o`yk~Ep#qozMlN(xwX-#*1fNKLC5CJ&|d#>y7Du*5aS zavHjgQ}oInrZCIa0srcCw6RrqR_y*(3wD^KkL2M`Q=d?WKjcWh+XA=lxaWcEB7AD7hQCexIp51hTC|urSO;bx>gTtNv!) z9&&u6!dzu1Jgw?KtlMx6=dwHD8C5Tn?RJKR>+lYioa3lXs(w<1XZ1mrAXwFPd(Gsk z2p8<7Y}e1M5bx_zDOIT%>xsm~R7%xffLRsFQV}ldbEucXBtZSGX4XfHig2Od$*`u> z&#GW1IYD|?{;3Gp|1t7ne^$S%qL>(6LnGW5z=0WudU;j9$J;l$V?7n&z5$TQfUthZ zh+(6kr{0)8HG{hfoJ;bUsaEwh720y0YDvE&eZG^!6osn)y>5Xc+dr^fL?T`G z!`$DXY0&x9KcV}cGNK4~KREgQ*l>?h{!>$swDY+mLf0KQQPp2+{73!Xj)~hLKqiBz z`b&)egh*Q32=_@i8J&rzRFpSuVQ!p|at9kfsVlLl4|6MpNg_}$6;a{{lSb~ouxSL< zE4q4@B{IzI7@7*T;fuQ8cWG4kbr+3Q?D_|E%TvV9;PwwE7L~eoBZ{q*-Ii1*&ZLM%vnwItgjMbTij5Z1CCqB? z7^Kwi0XwV9sUyNs9q)Hxs|_sp9bnYr`-r%rq;pWS&N4J+A-3f$62+5AY!k_=S?kc@ ztSfd-ZS5u8J&EWNLmJ(ZP|QWA?uWD@$mFV)we!5fHXggMbqPg}T4}RH+U+7uZ;eT* zSzAjw!_lTKHCs%jMPG< z5dQ+nR!g`E*crsK_N@5P(!6vqz7G>+m!|NJ3L6KLWYu{cWypq?+z9q<%<4aiUCUfr zShWQXEU`;GxD*M+C?>mK&DwnwX-ff%#J&Cq(J$c>%tNSrgsA^bFMHshDrO`X@j#H1VVmpFlzH}0(T>C z8@bb;+D}G1|4ZRB0In2YY`6UK|jAB+-ICVErvRY9$-%DOkat}2eXvjZI zay|dQ;ta!+gThdQ(a;GE06@X*AT27$8R9f{hG2d$)MV(FfnLMFat%g_MV7lQ3)gf* zvpq?`W}jp^`O0q^a;%%}R-t*tBoF{<2o~$rib<#H#3lw(n8pjW8p%sxihx+z5>k?_ zF}k*~I;)l2z1-NDG=xb)6--UfZU_aBE(FQXtILhR(sJTYylvFJ+e#qhhDYS{KI@1#Xpw@tG z7kG-BHgtcza<$=;C#KN(MLq)Ff$ws|hqv4?U#&vDnv+F9gTT8h;c65oaW-3>{u()N zVLchqJZY&igKRqF(rt~U z28Z!VqHYxKK9i+zRWBtUngBvyz*ftS_gY~132TvTvFy0jMSR5~?u8uH@sNx7x))JQ zi0b%}OY-fpNp!>A;ag}d3cqUU#F63-ZAOzz@{|GO@HOSpd zFCZNzOhex>@)pGlV+rg&*Ao7RmZ#}P3G6yRy7}za{!|J~}%bDcIvvrTomrm?FX2Bn)xjEgX-!YmV{fM{OVFTr9hP(1EZ%ZjJ zl2FR&wz{h8Qzt`lMn96R0LwdCPYsSXr-uWc-AL22(+Pwa#XhOzYt8wxoTe2><% z%mu-5wulPHl1_5W@xf_-(pAfhT*mQP&XR`;HVHEL5g#ALXZKp(@I;#)&HGM1`<`VA z-BhY@Y@bb9Vv-ZOtCW0PpRMU7%cs~DJ#JXiL#WP$=ut*sn`DIKX@X<`R?Lj9+g!n~ zl?vW9%DKX&JHc07t~bZvDs!>R=PjGlmzo5HGse#*K^(Z37Ea;!l+d#+Yv@G3E)E{n z(S=TT#s^)dMP*E5Io;!+S6#-{rHseq`Gh=P+0rb|H=X`6q#v)YU^`*x0xfv4MEU43 zs^ZWd)qSytXLkwDG1)T86xIDzkHq)=^%6OshAQ_5?%@VWw2 z*I!)T-;d%Qx6}#0l##CZY1R$?N-5~B^~aRo$emH1mJ%rcbVYv7RZ;&gRg7|DQH7_@ z&R=1ZGXLG{DXABwYE;*UTn($A>lO_|Jmybt4SGj^7_ zD65SaNOkMT7;=l1B)a4b+R7;wysapcx8YAqy>Ekmi%>jKpkBu@iEbtcb-&6sLqGF& zUqV5gs8Qi3nN&O{c9`iUG@Y-YFR?>$DR6GPrB>fg&ivl^unPY{x0oG_MYrHt*tYV_ zX4U--(ZM%BRp@o*CLc!SjZi!hFj4l2p!;=Fatc+2{$vO{7%iupw+eJvpersxtI%Hz zLtA?Z0<4_MbyXzD+Q)6w;cwXlGs;Q0vJ|`i){i0GA9Gnl4HJy7gq3Y)sk7YPMRk9x z$ThEoOS0PQVOO8(cDh_Ee^O#420UIC$w_94>RLjUf8XW)(m34XCw}^BB)-AnXx{QJlEmXI zvZJScyX6kgvuQ8oK6=tWY(<1#8QXw&O8E;e^RLHd9zWs1HAwhEPC@=J%eusq>v+-f zs5yUu6%k%(Q$L1?qr2b}R!->niMq_TjU%U|3>K?%*AJ|OaL+qfGQKk+Q8;651)QnNLjIdzLL+k`hi++>^$NXIcPpiE zM-pIm-cp4=tfBrh<7^B+!q>@tvjVF9&UH#ra&_qA$9)+Bxh8zpa#WS@83%oKW%jJ| z2v~DzrBZyQ+Hra?N^;jdFfz&J;{6zyZ9?_N0Ela}^78p8lBl9S$2nUsqkOqYF9R=^ z9-|H}r8q4worV8MNIEa;F*rvd^i|!4h!${paNyDtq+g^G)iSlmWzJ)Lhs;lm!K`s* z%$@5DGd4uJs{h$zZ#y&>ao~39xFqbT&g(s#l+E{KRp@CCFBehCYq4JLpL)3UY7MlkP72xazJEYicTmWH#nH*lta9wNR}6x6m5f(!!2aI9*R({hpF z>qkOV=;b04SKA3>8^AF#A51))GD0@PWssCOSBS|m_YmrTawqo^c77G|{w^)S#!3?}vU^Tzqd@(kE z%Y}wtPG#Vl@*8F94Wi70>!=g&)Zm?*@J>&{WkH@`t8Uk5_x%EO886hbK(hjymxM$9 z2LWhg1JIt@gsmGBv8N)kX8jO#MAEdX(5YX3>L4ttzC9U9chrVNVgE2lcKs(Rw1znw zhDHWcIUFq#*?pA@^=;q@3CycV=9_3SG_8MwyfhOTybpbW1_d_OfGIMx%5NdH8z07f zBzv+8X&7rZFz@IsZmOPjQx@q1#>L=UY-LvaCee5^xh9Rc{_I zil%Jdfa88J%Z7tI&bb@rM-t9IKu$g`Xf-*V#O9h^AaW9P&}B~Dd#OTo9CTsV7+CO1 zU{uE)F5)JOkZz^ppIpS97C{cZoss>K>iDTka$gCF&AY0QO3yQt+yUdEYV{9Os7u1aGtb_dUaMq4nZm1J$F zDHWpf5ms@nY!lvtGX+m}|F}t7V&F)XxMlNs6fU{E5=BtwbC3m6ZQ&#XUpGqQ;9@M9 zMpl)mmTewIGz3;SWh_$aRAhB2-_jDXx@3}h#SA(aNPR35RALB#lMrz@pNgz4k+F#9 z%Zw(Are#osZ81`6wo2QT#S4~sRtmk6W(x<7s6oSKkdkGXZ%cE-g%ovhqy8tdFrK+$ zJ({gy*ob%i@xPJfJLIR++x*uOz}t}AZp&|0ij~YC`Lb>raC+80y#MEz@lAyso)dYx zG*#*3*azpFJ`Lh@0e`NXLl^Re++$Kltxj-1{;P9ac#nD<`6jc~gPGB7G5;O=8w8=G zl_&8_6kn_Wi_%GU_h~M;({iWoYBDpKHzUPu{`Vo;$lH+IZfkoF&Jc#5rbS+L-ow#a zOY+eJXD=*5&!6{ z^H80~#`aH+1B_+tBj_z>4j4CRjVoW=0?kMzHm!0%lHv>AD0qJ^$+N|=9`qA!9Q~Bg zNd>Btu0X9kX{(l`j|=b$J2I9q?iwm5^~&4aO?m97B9nb64x%NPfZ2L?`sQ92Usc4* z=$_fGHec@ItBZI+oqGpSS4g5%q{hXXwt4eIE@!Qa6V2-M*NKv5J18RyTQ#+Zyal^x zuUc`&HtibO4j9X$B*b*vT|b79Hh1G-krIyKNZYzWt^AacXs2UMtCMCCn>mJ1v_8d| z;vz9-5i#v7O^CL4i2jwjx~SoPJ)my7}|rWP;^(u^30jHjT44hoEH zxmhgMc@jbu!6i(HwB43h8UYnqbTl18r*#<7vV%_N2F2>qj>d|SkbfoqH@2afp2r$Y z<>#q+^dqnHKyVQW2ygSJd3ytHLvkDP^Ej_cylH?jDPEG9(f#=<9mg9KJTGR(v$ul- z@4t}m2f&4S#+Z}NYZf)*ah41xDDS!QOfnVb>0=Jx{J_bGLwPmhSHu|#9#^KqJeZ7c zH)#A}0__M))?!`z?!_q4<$x~utoE8{cAE+eh(rvtSN-3WEzsuBqk_%{D705-A~g#35%Rzvmw zFA?xHA+}?g8{MPGem5>`$yYmuaq~$d;zU=(g^nD??#R1P{D#LjaG~<5ozFtH zKD!JrOu5fHI64Q%^l)-ZCS>pm4dV-y!*427;Q;d6!Fv(UF0{{2IJMT9YxDtu7m>3# z!*9O}9EO%N*PqkfwLTW>k*)LkM0lr}pH!HI>lvDJ+)kQPNc2$|Kg7V(&ff&)V!q4g z`w*_}AX&Z~=Yz+)wruG-Ken}JM-&Hr%AALCdbum#h^~o&)NyczsprIb=eSD+suCw4 zRL(q}P|w9inZP-sk}Zf=R`7cu^KQT`(_~Ry8ilWeq++pTK8vmCLrKga%G-vH(-_6T zYs`Z(lea?wgyIVzedgey#wh2a(cyHMNgkXJhxah@J%iCsO=9O@n))}QqiFoiIP`td zwnYPRoRB(%brZNes?I%y$#(h+Xnz`iJ3d=G*)ADLW4d!=d}ERCO?01)zaO7(A^G&d z$x*e#C=(l-WsA?~G$r5J#(Cqjy`zou$LAa0#*4>cO1-m<@$uQ-(Z=NXd}G--F#6@I z_Z@xGKW({KqYlw(Oat$YMmtCsH7|AT(rXDvW04tH&PcfL+F5?R z^l;4l=6r3;E%JC9$N9fB<2lCE;yg|bx@~}?8WV_nrw$Jxj)!gy|9|0Oyzvw?3A=Zp zf;TAVM;IGS@0B{A;nCI&70!b$$d}QFTsKT`z5*Ui=g;uC>xN0r5e%3$D6qR5_YF19 zJrJrvwHZ16x}nbDXJ|C63A2<1)iB)&x}2*r`atZ46P(vD%+_=V22aI(L!)ywhKCx2 z_XwJ)qRFW(!hD05BGNG1`C1X?AF`)pH#9rjT#+g;WX{WOIK_#&2~@R1_T=n_1ACG=900brb1#8hLDX#vEAP zu-^F&BwUx!UN=WqH=N@<3n3Z`$D2c}8@4%jA$1z;&)5U78_sj?M2={%YUJVN_>`S$ z*yCIXA-@pOfea7aZrJZU3xhPMwvi`mXYf>^8b0WJ5VlWEiWNAX5A(KaZoBSR7V3vL zj%5}LCaNApFNCEAC!5LcC1uBGO2N34KFlEU)bzQFM^g&MrSxZ|(^7LgM^g&Mr3_^E z8PX-ANINykrLE2C#6pTx`DvOn|;Q=*w`DjYPSW18O z`ovHnmr-+18%-$~OX*ubEH6RMT``(aFqY5{f13x*?uatg7m%eo{{^L$(6Ls@DLjlssYT(hNzEZ4C-IS>B^Wv$t%F^0%< zvZSsjvA(wroeRcUXx#Pa;~j|?9y9UYzeX~M$CkYRIBoNiqRlwEk@IRa{oU}4o!ocO z^KNV#Bk}463`c!xC)y3a^FcH!^ALYG-zFORn|zzdnd;O|sKfs`HNmQiniFea+-y}* zQ&n|3hU*o$4d`3E=TuR%yy~>7p5PhPJ~Ts>b5&1}76+j`E-)@i?x52 z$pBDd)!Tyu{hZ@VTszmeOB6R3BlO)oJh%iY;^didRx6lKu{o>M{1#d`RxRbWGPB)SlP6rK6(AEiG6jWyhZJxH%?qamV2$GUZ8H>G=3F!0!po*|1 zUM^StQa6ie66ux|A&f3BX0@AXr+Et&OWF#LK3yhsIayf-*U-~FmXKOQ&k(0EOBST_z8=8=yc9#lhzh%jH~HPq}?sBT1J zdW!&^cL{vOH%Ls9H{?l?giTn7G-7>*L%Wtt%!qzKi^bVO2a2>dE76*#i%^kEzw9#n zy1-~tb{Az@ZfMFBxjoRq(X>dz&}dpfvj$q!#qrW!?RBv!v9f8XdTJto1v{OEycg|P$DyuOts?k)*7q+5BbYg;`2lKV~}a=(3E3ET8~lCJ0|XL zBZME5P@_HwiHzmfm9WomkVOd&#hO=Ny1!)rIi*(c!U7o+r?VP}FJ#(Vt}f;QMGc6Z$wfJ>6`XSDu%?HMc#Z<8$Lx`U z9(|`t^qJEDau1vV>0^rlqY=<)tiYX1ARF#Lq1P-m7)NxG(tZ&NKs1niS~BN}0RX4y zsag`^@!CE5Q4^Oy3Ro+I0Bx+^E+;7lj3<0AfG^`CnSz#T&I0#%MZ2|cZ&HgcIX?^_ zJO#LiK52@4q4>c!4Jpn7AWqZeOm?$XMU${%a~-0h)*1NFCtrGg;lPI;efs&+Uq1i* z^9x_~`zq%C%X%^qbB*CwGd}n zyRJr|v;6jZ(iUmq_FK~Ba4uhv#==btt-p$eXJz@+>*}L?zg14+lz-%KzW~L_U1TLb zHYNXDIElvi?A9?f`=wu@<#%XUd52>B7*A0z<$K;$!HJh8Wm3s=w%OlmwgPdwA)Sm# zIgDz8rM7x?aDp+aC7RcMlqR=3UpalHzeXmaUCt$D&M#W50ZR6*=&!QjdFvSp`isknAbr$y0+@;HGq8<)8s;)^P?!KEabczZ&&<05UIo%fJc$f)8% ziDvQcF2Lp;eu+@(zuks_)aVncJf9Wxx>O%NrMC@Y15dd-mza4|c$CL08^0C5RVPO1 zmjGldo^_I#&O9<3i@hrKRukC?E<2IRb+%)AsvNdhCWH;tn`S0irkVmUKvixtewUL&WB1!c_3T&ZG1ai%Wr(O^!w|x;OHm%|X3q-M}*xTZw z?RJlHqw5lSw;k@Jn3g5E9jhzlx;pjTe>r%WTLwpCY?D@wX~)t^R5FX@z}wE6qHc@h zJ9)BLE;wK8W@p>NVv`Up8MQFkWzA5D{0=skQDxpLQ*LXhJXN%W!L<84C$HG1j7lpO zpa3iXNbOjH*!Gkc>8LcVcFB7zF1~^Q_1gH722Jl!HRhGH0!4Q%F^e?iW-pe-v?zxS zGFI`af}dj+3==RGDg+pE?BP=*n77nF#yRdFEyHE{KEQBL?u)cTi03rk&u||uM{Q=X z-+&puSKkL1VoyYgx|0_#+!txzK>T+a z?`Qa?zL(t@^no|Yieoe26`vPh#l=U%<8bkT@Xxr2Sc(VA+(so(g|jTJy;<>joF)Ibd1io(X+fh0I>Ots)xW_<3kC8>j5 z2_PXdjwc7G!!hUl*CMjDoL-y}+=6N~$WKhSBvZX3{V}|fh7XWYibRJ;di7>-6Gws1 zT3o!h7vF!jF{~V>?7diLBk-2J#W={`8a1w)k9Kn+2w2YX0HHdr^anZ+!6dEwBaT0g zqw!QCbZ3F?EFhW?w?91E$!{_KE%2LQ^Z=-qM9 zAJ_q=I>4-6+QVx*uD=+%4CpeTyBIL)C7ycu>&JyvTY)_fy5~X1LT=@ej`3k!mhL6c zy#%_2h7L1TB9C-z1ZXSuux|Mw;CS5IpVeCcz|u8>t`P|8us_oAdLJ%JcN6Gt0&qJM zV1D!+f7jr$bgavVVL+o`^gqht?+`B1i4Rz(Q7DR)TI(bo8z@Ux4Z3R3%_hS9th~Ds zw{#0Zw-9tpoBdh3`v4#v+@|jNs6TKI=;$~5vvdytVCn7$-TmX(_lSq?VbDDcIxB-R z?fnzDXI@b6W1xEsbZ;0K0yp2D!M)Y{`P=+~&%-HJhNWZtc@N$Fpt~P*vq@lnq~Y~l zTvpyopnC~)W2Ki3I{i=kehj)FQ=Tn+fHmRb@5i_(&;Cd^*8{M(zXXB3Cv5<8wd|zq zkGlAK3zwJf0O&3gjQ(eF0o>SoV%`Sbqv;}{#Z4=tdkBRf3t!uxr8}vNZZ4DtJn6M` zEoF2IuSB0^g(0Mm`8%zQ?q{HTehj^9%joXE9_wg;*`K}LTt@f84Oro@L75JsYFtbQ>oD6Eue^(IgP%PBD-UF&er)#%tT0;H zzU#Qw%ywMIwLrGlI9xL!iCWaqU>Pr#dcyV!Ns1Oa=DyyKxj2 z{MZgMtdO1n?UEbUHG=J$#$z1-Kek^wj%927?6{*s;l%{}*d8&g5YM3#dHTAaVPz0(-!` zzY6(mS`kuF(n8Z-t{@bD6)Iee;I2YN%HmCB@tI}ulgi>asK5j9tKS_dZIga?WL_D* zwJg58ES^K0V@ZO2YKpq541XiyZ0`wnkRP`rwE5v+r1Ck$ZGJeI(fbPG^e63f)CuYv z2wyY)b<_-Le}C-J_fz0&F;9qKO#QzB{PQ0De@6U4Hy%_}beAbVj+(0K5%=1|_UcJf z9+|#!e=Mb;=0|@Hm&LC{+|EOi|09Uo`AWv0COvi^GhljO!i}AuB>pwTZTWM2$E)8X zZvClzb*chY+#9b)oc$b4a(vTO1aVtlo8Z4w5a(|jE{>blFphoGY>1{p|7OHjA-!w~ z>YzW4xUHXz4;X%+RTHkgW${CZv%a!rnTq;)Gvc;B*QpwHo1y0pKuW9Y zYa`-z{+a2!5OF{91LSC3es?5}xSh8q{*p5OeTZL%^7uAF+WRqtkC^gO=bNJLN8HY1 zlm8zPx9wpa+rxNodVxGBZN>J8R(ymenHtWwrrVcxwx%+Dt$5olSHS$cnWJXFhaM~_ z9>dfzr7Xb0N}@H9A89oUh6%nt*N=G{ei$8-ssQH;BYk}k8H=sncFvaA`kt-ZVll+l zl*Gp6kio}_k}ZpuEMBUH8FYdnnKkDH#N=U1&a=~xWXX}i!TnZ2bmN+$d>dK2 zrE5bpW@A)l?~799Nlv7`o78h1W7Hzsm@hxXc678I^UD|MG^RN)ql33DvdkZ(Qoko* zMW3^F?bhhF*tV|j^-;Q&M0lXg#rMZ}#CQon=SghM`5U`7^sH8VAT{}fuVd|tWA=-m zyIQsC%=JCpt7D5=+FIHG zDz}=i?Bmfk);Am**o#2eN+zi~dSLSEw&)(Cc>DHPdrJo_7hPgAcA=+-igqp3Q$OxB zmq=JMT0-e^21-yd!NnIwO5W-4B#@4T5qMs=sVsT_MtisHy`ES~9`f;Jx_$d%*p{2m z4&j^ue2rkw!d0tQZ{LpjiWr@WTzQFEH$wBqM0gz!g A%>V!Z diff --git a/plugins/org.eclipse.dd.tests.gdb/data/launch/bin/MultiThread.exe b/plugins/org.eclipse.dd.tests.gdb/data/launch/bin/MultiThread.exe deleted file mode 100755 index e89bc956e7f0a40120c112e312df3a52a33ab3b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9106 zcmd^Fe{fvYb-wTITj>eOMwY>t;?_^GY($LTO2!6bL$NKdv54?*69)&LSG!NU3#;Aj z?ptFeP@60c5sGK*Nt=YUGl6N6X{X7Qwo{rkO=2pF&4kP_giQY+nYxWLvlO?Z%qSgA z<7WGP_r5FbE@mK^{MV~Fd(L;yx#!+@f1G#keL4{z*=ZPt(8&}LLG;2?mc0S|;&n>1 zK{&z|{o-cPC)$uj-G-B}0m%X=6h)o|ickl<;YsL0OMyw$(KksZmIYmGM?D~x7u`xP z^S%Hb=q?o43Szy~n_#oBpM{Pz15Bcxb&z(!ei!N{Ilv^X+xxR1brj`~K5f~g70{8i zejoIJ?@HQ#ESDXPEu9IsR20g*F*ee zR6_f&hWJi!;$n#3LZ!q{hjkVgG4FtJmKAU%-ip$v*o}q4doK$vR|gj@#9|6FO>`VL@palc*h3lW?XrI zlujnSGSMLOi$SL3CsM=%A_QI%S%E(f{o~nyw#l#+!+X$#R5tHb%6>`|OWAxdhKgws zwrxC-&5NPKhqrAX_6FVC#JwZK+lRdMs6tDFctkly9OVdRQ3RvJu`=YJ>U#(Hhkx}b zhA%3<3z>=f&w_Jo9P(^-5q-Q0naP0Hqu_e%mPoxNei-H{dvo6Y(ibhe4U=USyd4dg zBL}`h&VhIq94)ZOF)?j&Or$PyOv*!(KdWB0Yu|xo?K+gNoj~DNr$v3^Wq7Esp2074 zqQ06nWGKFUv5vHwHD#!K`*n#~V}{Ls`<%qAIkTMj1&P^$j6?jK#B52XpZJW#Y*A)_ z_#`m+d>Z`EhbRB7dTD0w!TlKr^D8repM4Kx4xX~?S{25#XU^a`4pc8&H5NMZsUUpPSs# zXTkU~nqB+puj=)w`{$5*`q0IfE}Ew;b8@7w>->&B`#%R(kdFirV!5*6XLMb0|3( zpHads@tK#Nm@%gg&7jlQ4%R1MIsGEbPsO{d=M7YDPsO{~1~v$7Usip^y7P&d%D+}$ zUUB4M@1g0b6@45c)OX<9d&QdXv}+ji>(H{A zg9d#JBhA>$wKSY}xSBURGALy8X-7p2XLX99S;Y76-?M*0@6~>+B zSkixslP$|4yZl_P;C!@D%B6ap;o#=7Gw$E2eXd%a>V;S1rpOjfe8%uubkipAXV9*r z;LK+-KCxFAkK0ihK)WpKGgx~ZHwVOd%~&dSbQz+ zm$kIhO3Fx_6pfrR+|Lus67LWB(U3DPb&(L$5tPJ*FqUWVKK;e7>V>a>Bb12Drx0_f z2WBV!1k?%Q;=dlm#Qv`#BCrqm{M=G30o?$4vufFtUjyfR!v=A$K#p!Id>r|BgaUoc zfbRr`_-iNb6Lg`?c&7V64}u;6eFF3h=u04NbD8${4h?N~`tdry#o6Evy6c_(L!*^^ zP*G^zKt-Yrw}}7Oma@xk#jh#O;#Y<&@h19m4G`xK=L6>t$5kipw@k4TQ%~7*p1-7( z;GF-axCg_o^u6%I`ExOxhuXAP+7Yqt36R(PPN#|uQI$FH@c=57Z}lHQ*vnVGT*x#O zr==w&3rb8+R7>I%l^LIeU>?Db)ou62AYBwKHnQ>;encU-<(FmLiD{5{8vZLlc zvUYPb7&1dIBS1!*^>wlvr}!I}{KF$NqFQ8B3Ncv1BR8x(7Z;xdmq^CouD!Z3mq7?%*Bn#sOiRT!HR0 z#X;GcY5ZP~c5>usIJ9={`>Yb{{z@*$9#p%uWKzU3g>gStOg!f2VviL{kCuyxq#sL_ z$6|$2+VzvUY_aUSsgxV|<)G}QQ=_p|B1pt?iAp}1iIq!9VSbx!X^&L$U8mAi7umI@*C~mgM$ML8GDb3jj&=X zILMspi&Tx-lrY+;QmK+jh0JuTx-{Pv^RZ!%l+zm?f)EHS#BJiXN(UaGw;TJXYxS9yq4$Th|9QfK^f@gn@n8vqQLA+q^w;3lCG z;)@_t?8fiA%zoWL6(Wp5r~{p1GNwj4jow)A-4FJr)3Mlty}i9A4nzi&d}l;fL3y`{ zgA{Z4_K4gTnwxFNEXlSFU$t$Oaw(S0Cv%mQ9~;dEWg%Ju4@!k=FqkO%WjCW@d(`B@ zi!3(mWoPY}=`Ky%vA_FTB=-+l2xb>*Jtk}Y?ez%fdDtU-!9_ZZ`A*=AF4AM@ZsC54 zdpUH`<95Ry5!v&5#P`@D%KaAY^d3=f5yPQYp^_m>hVl0a;xY=(hr;>jCu7@!Za$xG zuM&$t!2D@`6}7z8oBZ?HxJxiaV3Es7FZPjPnaFH%Zew90x3k<*o1!8kEJS%-@dc%~ z$e&fRP5zRU7i<9+_SKxo{{!Njy#d6T`W8qUHP~@@SAjUJmm2iKEl-RGiBa&Nq zT#mlLtMxd3#{i%z@bxNOKjV#+663y?Nui`h!c7K+QW@1L_DB*+xJ-;^lc=r$H~4X- zZ{=sS4C`cJeB8$*a8v$hCG90jiF_KDJ0UDqM&V!qXY*qPtxJrKmi%KH;j+!wvTU6O z=q)Yg3TTO{C#*&f!~61^V8NBhJ*K?31mGJ$C%H-i7&_(N4qV) z3;N@kDFeH^!aOiJUuioC`fr?TXvZ_vS76r%nPr)1L)rpTlUbd$F2L?N+x0{&=_j0y3Agv0-B0F`WWwJFevmXaLVDI?)%?6o__o!S#FzcAtc- zleYUDGPIq%Z^q=gn!o28>>kIR%;T_2X=mWt-(QAy?0a5^T!h_xuxYUSn+CfY>}u~} z_pJsyUSQ3@PS*w1yv#dGJ?1=1^ZtD%%+q#k$9WK+m+j+y*ZbD3fO5KZMA$6GX3d9yEP3NT6`M@TBhwT zyiJblLg1{6X%5tAcMf*);3l;TIvYlfcGqGt|A38cvE#jKqur0OX}z%_LyI43vHJzC z*#A~5;Zuv;>T8)*{W(suJiqCr`(;au-4)nf&_>|e$IceJmvL!RxQgAr7Q0Odrn?&K zbpN3mIc8dQ5_X=h44GOaZ&o^fS!fl^FM# zslI@z_^z<3nQ>fU<&g1OVbzPg15;QHEe%$1|!tio74NQ|cnOD5x{!h8yKH>NPR zGAa%#jLCzde!Y>SrI|_4DRD4mGH*>hd z!@5^ky%`xV6y}>leUDRE-TZO=E4++M-T^ACB01Ny!pq6zx>fi_iSF4$Sh7#1rS}^Z` zbfTW;8SW*SXJV`RDXj#jo)=S$_sll%h3!wk^>`TAsr&`79uEU=@)v>SHw$ThqxffV ze$N0y`QKI-qeb7A?}us$0h@LBzQ<|45Yn5SnRtXO{^ zF!ybMz=&6g(d;^TkU1b+H&&h~r~G1B-c!c>+*nM02*znRJd={~P=cF?4{%hx>TPE- zk;^rFWab4#IjD?{!KLR79o)0u8yP-ukl&uY9Zl%Ip?MV!FU6c6_$hbe9UC`^A{oD3 zrwU#=R~Sv?Jb4)M5|!gZ9hp*<@$m^=L45a)1^*iC+`sMqxTg^-)AE8>dD4JE{z`Oe* cd;6x_-LxNg#iSQxD)~p<(c|iSgd7d=fASs4uK)l5 diff --git a/plugins/org.eclipse.dd.tests.gdb/data/launch/bin/SpecialTestApp.exe b/plugins/org.eclipse.dd.tests.gdb/data/launch/bin/SpecialTestApp.exe deleted file mode 100755 index cbe79e76c9bb0e2aa12f6e6609438768c43de0ef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9581 zcmd^FdvH|Oc|Z5DVlhIN5atn7XJrX24{(=r1Rgt?{MWN{?svZL`5;3Gj?Yx9goKa|z%}UvlG&3!!5)`rXij zy(<{|$wGc8S;(v|nZCD$~L(VF^-6;t9J!uU>*kI z=OVHm#GAa7GaqrXjXFdtd16lv9DViApZxdBNX`hXiwOxNK4}>_jn{e9^ClK}HOh%0W?-t5GP1(}hwPh~eXvd=#KK*nmA* zqmfj;D0&VY=-xWuul3f8?Slhbd;E1M$fVZb#bn@&anN@*`pwcmIZQX@J1uLJye;0;_{Nvqcpcg}0Xhe?ofK`{L5jv*MT!#EkYd1e zl45{uBE=xtf99RhcjM!K1#{z#$UnXkqv_2nVsgV0ASRc$;K`yUm$QT%lQ(ZnA}nV~ zIqGg+mpn_%vD!B;OP(d?mXNE*A6m%9KiR_ox?lq9evjwXNE)1UCF?gjD6(}bf@2nV&hwp zIB@9AE9YcT?|bU8ev~Gn`dcldm)$?v24?cDizH)>r{AjHdOb$Hg-i;6u?24A^yO&5 z4_F2gbFaDWlucd-=Img*iz-fj?heqqN8fFSvVgHYz8FPc>zx=y`daV%FM^EqzJF$0 zyF1o9amH;Q|ECWoC(rcW9_zggVg0pj?eWDh59*>P1gw0OR(=E&A;|DmBxMywueKk2 z`fTdX6_oh&m9x}N)i_F?Tr~Q+`K=NU^{nlq%S{++WmM=OdWOD? z<9<)ISj-o*iM{0@olh0^1!2@(E{kL|Qch;V;Rw7Jorpy0Ly+{J)-q=^2O%3Uf_)As z4nhX&nO(wqHXf6XsNQwI%=rR&0+HkCSx~X9-V$?Ns}K6_hWKfF>-<>v3#=jL075Ng zn&p_-uhV-pJ)&tDv>x%ss2j&*7X9c|`n??1o}Ya%S$YMOemnO(<}&CT;Q20ZBhEwQ z`#gZiz?v+?*rdQgGmW6ZVkzy4Z%@*hJvmr1&$r|sR=De*y58If(k!1jx~Ve+ZK%&R!aXf z*kS)4(PL1&?1zJaT@B&m-E0 z@NnnYJs?)x&QUbSeo6^@DXg=(`LSb8z8DENW^Vu&kJ-CP=Gc#dK&Y(@g0t$}KO z#%IjomLj$jY4Q7rw%CfNYe~o;x0#%(B_ zOo!EEx)SBRy&osvv@zu44lmKYH-Y`Yr@ReogmvntXe(RnleM{mCzmpI6@fh~SAN8l zaA$f%FP#?2TxldomQ%-rLh^X2ax^Tb(gD3>vQ)`>LAsDHhk=*Lc=Vc~m(2_%GpQ(* zETpQ%bS@cI(!vh&&jfxXV*mIuYUKQom7C*Mi(x)n3^IvyE>%GX9$sZM$S5&Q)Y;{szX&inVEuktVS@y8hYFJKUYmVkLN=!vUBWRgWiLAOthhg1NM%Fe z)XM{p-6rDHbI<6Pql$2vtP{v+x4F~upqLTP0xgeE%ZF0fI6BQ*Q7;v88|f>}Lak}6 z(a16$(29jM3R%b^tym%zL)BqzX|a~KOvxpDi54fMI7}T2H2xD>(XQ~R^wDZrtCne1 z$8;WPt3}IK#r=^~lgKp7nWIh3#>_P)Z*a&N^#M3i?r+E@`uMSe7&x_x*AzvsO6UtYcELPf1Y8 zUM)GGByb-p6sq8e;%Em*%l$DN&6r>YZ2X{bGQPkMn)i=%U^a z@U@&W_W4|+d_7CfAp3lwaX14%!Tk35GR%L8#VGgNill43fM*9}zl!@U{#x9x)nql+ zEx>bmL-RbRVOay}+Af@idGkJvMb$wvu97Z#w&Brvo97KQKVENR6Bb(`2Dsi@O;|+t z*E#WJ@#XPm?$)Ml#$gk3*jxldDz~z#3vj0kh}|#dp~yNC8lKZ^SLuny4 z(7Xwy&sC-0XY67>Sc8Y1dX0xI;^$+;HPdWEE2^CY;C>I1$LmeCnydv@7d8Wpcu!qZ zzU4h$uMJXL{04Q_FB<0K$x*?z+!Fa>KJwDwgm?+j7CZ2~3--%)w-9={WjP{dbNc|d z+?s5C?6a-eY%=-T*49=VM`#O5?uVQ(KU;JAGs8aL6VogJZw^4`Q==DNcya_wAZS!kG-pz1i=a{#Ua=Gf9&V&o zN2#pvFjl=>D$EHlbFzrcieeulHOH`u=S#&Ij1OHUC=jm_LmRgh4#h7mR zNV*INP9dJ5+oEM4a{Ljy z7V+o$?9TgwSAc7WjCmP|Vcd+U2B*45cmuc#knvstNr~ay?m?vQk>%pvA&11<;7uTw z;YmbuXTbY{Ey%<>2U9NdGaf+X9Rt(6XV?YYE~Hs5Wvm-R7I7{jWxS`j030WQu}2*F zGNQrpUgMj<@xFsN-lZ5EPpYgd%i-L*0UVF1CYW*~2n_BvaJPXwWk8_BF@6!z;P{Q> z6ohO;6WDePrx6W~bGaWC;91-R+F}?(B#!UP`J4gn38YOhxUWE9aPqqYaBOE24DKQX z26q+qt^(I@K%fTqry7UX6ug$>_mU}RQ-k|X4Q?TD3qJ(M3u2Z_d%XB;0nU^K(Ny|x zkw%pyPJVv@ZbHjIB#!mChG^{Z4!aS;+4ji)eGQKHUJHTifXoD982$t*8;0lm0k`I=yo56!~;FD_(0FiL<;(wl|54W~vwWP)jz z&9iWw7^H6)5U8=&Hw$+MxSo69cF)3f;i9v@24~uj_edOjCVUw6?wm_ zc;)qY@2hy#(dJ&(kt>Mur%Eqj(r+rBZ=vpe70<1S@`H-!N`SEkf2VjgBk0!@&#epU zulE^_z_|#)>^mHOmqVaGB6ajvDf%77vsaXVQ9N&*;kS6-i{R*$k^VyQ%A=Y4V@Ka= zbN(y6`k2glu6X6iIiD53gha@1H=vGKDtYs8#3xKrQb%yLo(|3o56%2M-b@EaJUGoD z<;?ghN-oG< zf>O_WSo(X4EqrPH8mQ?H3;ppe@TNa3tT6oOBfoV?{8I5_P<{skLH;Gu|6Z>t@877< z*8=w{|G%MbtSSE&;N|^4D9fjRi~pXn-y{}+udNULRYH$1+MnGXn`#=A?^~Y5KM&rF zAIn}WUIK60L)Z(%w`TFLfj8sPvL6sX25-h&0`GqvJg-4GQx~8|Py9vCRZwoNr7K3N_2J&(Cbb`;-;CsNE`ZS_GyENW>hab}XI^<>k z5PX;Jzb1Q$I0c@cO!HDdU!2o;`cC3s25;t5Bii#Xzz^#DJP!8oad@?8uC*|jM z99#97l7xp4+&+AaquxC)^V6w9q2|v8ymSbo>hLg3`hL&8oqPPjfxY|qp96o}4DN}Z zDHRSYi)Q}VNg(om}4%fpYKs-6()h?J?0jGQzD^zPU;ZQn3` zd%8c<>l==Rne?<(d9spLf0eiA@&E4Y3V-|H&aK^p{?5L>y}kSVecf9Jd-?KgY8=BV zsgpi$foBM0uLytJ!5!V78R!u_#;HF>04Dz>fsY`#1;$} Date: Tue, 19 Feb 2008 17:43:29 +0000 Subject: [PATCH 254/834] [219107] Fixed a logic error in VM cache which caused incomplete updates occasionally. --- .../viewmodel/update/AbstractCachingVMProvider.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java index fa14d97b2a1..ae68fb748fb 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java @@ -358,7 +358,7 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa { // Workaround for a bug caused by an optimization in the viewer: // The viewer may request more children then there are at a given level. - // This caues the update to return with an error. + // This causes the update to return with an error. // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=202109 // Instead of checking getStatus().isOK(), check getData() != null. if(getData() != null) { @@ -382,9 +382,10 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa for(int j = 0; j < getData().size(); j++) { int offset = updateOffset + j; Object child = getData().get(j); - - entry.fChildren.put(offset, child); - update.setChild(child, offset); + if (child != null) { + entry.fChildren.put(offset, child); + update.setChild(child, offset); + } } } update.done(); @@ -411,11 +412,10 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa } // Fill in the known children from cache. - for(int position = update.getOffset(); position < update.getOffset() + update.getLength(); position++) { + for(Integer position = update.getOffset(); position < update.getOffset() + update.getLength(); position++) { Object child = entry.fChildren.get(position); if (child != null) { update.setChild(entry.fChildren.get(position), position); - } else { childrenMissingFromCache.remove(position); } } From 46ad3b30d5dd23a6b22b6812a405487901ec4770 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 19 Feb 2008 21:20:04 +0000 Subject: [PATCH 255/834] [219500] Added a guard for a disposed session to avoid a RejectedExecutionException. --- .../dd/dsf/debug/service/StepQueueManager.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/StepQueueManager.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/StepQueueManager.java index 0d148b08b28..e73bec79996 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/StepQueueManager.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/StepQueueManager.java @@ -237,12 +237,14 @@ public class StepQueueManager extends AbstractDsfService new DsfRunnable() { public void run() { fTimedOutFutures.remove(e.getDMContext()); - // Issue the stepping time-out event. - getSession().dispatchEvent( - new ISteppingTimedOutEvent() { - public IExecutionDMContext getDMContext() { return e.getDMContext(); } - }, - getProperties()); + if (getSession().isActive()) { + // Issue the stepping time-out event. + getSession().dispatchEvent( + new ISteppingTimedOutEvent() { + public IExecutionDMContext getDMContext() { return e.getDMContext(); } + }, + getProperties()); + } }}, STEPPING_TIMEOUT, TimeUnit.MILLISECONDS) ); From 886229a1a9d5c4e360956ea5001bf74dcb6c4c99 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 19 Feb 2008 23:46:06 +0000 Subject: [PATCH 256/834] [219523] Fixed bug causing the cache to fail if previous command was still in command control's queue. --- .../dd/dsf/debug/service/command/CommandCache.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java index 96093c215dc..f88c8be7480 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java @@ -274,16 +274,22 @@ public class CommandCache implements ICommandListener } /* - * If we are waiting for this command to complete ( but the command has - * been sent to the debug engine), add this request monitor to list of waiting monitors. + * If we are already waiting for this command to complete, + * add this request monitor to list of waiting monitors. */ - for ( CommandInfo sentCommand : fPendingQCommandsSent ) { if ( sentCommand.equals( cachedCmd )) { sentCommand.getRequestMonitorList().add(genericDone); return; } } + for ( CommandInfo notYetSentCommand : fPendingQCommandsNotYetSent ) { + if ( notYetSentCommand.equals( cachedCmd )) { + notYetSentCommand.getRequestMonitorList().add(genericDone); + return; + } + } + /* * We see if this command can be combined into a coalesced one. The From 1416e8c3e9b7d58772830812ead29ecf042539d8 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 20 Feb 2008 00:49:38 +0000 Subject: [PATCH 257/834] [216854] Completed features for EclipseCon tutorial. --- .../eclipse/dd/examples/pda/PDAPlugin.java | 2 +- .../pda/breakpoints/PDALineBreakpoint.java | 2 +- .../pda/breakpoints/PDAWatchpoint.java | 2 +- .../dd/examples/pda/launch/PDALaunch.java | 106 +++++---- .../pda/launch/PDALaunchDelegate.java | 23 +- .../pda/launch/PDAServicesInitSequence.java | 47 ++-- .../launch/PDAServicesShutdownSequence.java | 8 +- .../service/breakpoints/PDABreakpoints.java | 24 +- .../service/command/PDACommandControl.java | 27 +-- .../pda/service/command/PDACommandResult.java | 32 ++- ...mmandBase.java => AbstractPDACommand.java} | 10 +- .../commands/PDAClearBreakpointCommand.java | 13 +- .../commands/PDACommandBaseResult.java | 44 ---- .../command/commands/PDADataCommand.java | 11 +- .../commands/PDADataCommandResult.java | 4 +- .../command/commands/PDADropFrameCommand.java | 11 +- .../command/commands/PDAEvalCommand.java | 11 +- .../command/commands/PDAEventStopCommand.java | 11 +- .../command/commands/PDAExitCommand.java | 11 +- .../service/command/commands/PDAFrame.java | 38 +++ .../command/commands/PDAPopDataCommand.java | 11 +- .../command/commands/PDAPushDataCommand.java | 11 +- .../command/commands/PDAResumeCommand.java | 11 +- .../commands/PDASetBreakpointCommand.java | 13 +- .../command/commands/PDASetDataCommand.java | 11 +- .../command/commands/PDASetVarCommand.java | 11 +- .../command/commands/PDAStackCommand.java | 10 +- .../commands/PDAStackCommandResult.java | 33 +-- .../command/commands/PDAStepCommand.java | 11 +- .../commands/PDAStepReturnCommand.java | 11 +- .../command/commands/PDASuspendCommand.java | 11 +- .../command/commands/PDAVarCommand.java | 13 +- .../command/commands/PDAVarCommandResult.java | 4 +- .../command/commands/PDAWatchCommand.java | 11 +- .../expressions/ExpressionDMContext.java | 48 ++++ .../service/expressions/ExpressionDMData.java | 61 +++++ .../InvalidExpressionDMContext.java | 48 ++++ .../service/expressions/PDAExpressions.java | 224 ++++++++++++++++++ .../pda/service/runcontrol/PDARunControl.java | 10 +- .../pda/service/stack/FrameDMContext.java | 7 +- .../pda/service/stack/FrameDMData.java | 6 +- .../examples/pda/service/stack/PDAStack.java | 131 +++++----- .../tests/pda/service/command/BasicTests.java | 3 +- .../command/CommandControlTestsBase.java | 3 +- .../pda/service/command/PDATestCommand.java} | 11 +- .../sourcelookup/PDASourceLookupDirector.java | 14 +- .../PDASourceLookupParticipant.java | 29 --- 47 files changed, 780 insertions(+), 424 deletions(-) rename plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/{PDACommandBase.java => AbstractPDACommand.java} (79%) delete mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDACommandBaseResult.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAFrame.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/expressions/ExpressionDMContext.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/expressions/ExpressionDMData.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/expressions/InvalidExpressionDMContext.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/expressions/PDAExpressions.java rename plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/{examples/pda/service/command/PDACommand.java => tests/pda/service/command/PDATestCommand.java} (63%) delete mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourceLookupParticipant.java diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/PDAPlugin.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/PDAPlugin.java index d910c04dd5d..2df42155121 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/PDAPlugin.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/PDAPlugin.java @@ -169,7 +169,7 @@ public class PDAPlugin extends Plugin { Query launchShutdownQuery = new Query() { @Override protected void execute(DataRequestMonitor rm) { - pdaLaunch.shutdownSession(rm); + pdaLaunch.shutdownServices(rm); } }; diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/breakpoints/PDALineBreakpoint.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/breakpoints/PDALineBreakpoint.java index cf93ba6b6d4..bc518e16fe0 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/breakpoints/PDALineBreakpoint.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/breakpoints/PDALineBreakpoint.java @@ -48,7 +48,7 @@ public class PDALineBreakpoint extends LineBreakpoint { public PDALineBreakpoint(final IResource resource, final int lineNumber) throws CoreException { IWorkspaceRunnable runnable = new IWorkspaceRunnable() { public void run(IProgressMonitor monitor) throws CoreException { - IMarker marker = resource.createMarker("org.eclipse.debug.examples.core.pda.markerType.lineBreakpoint"); + IMarker marker = resource.createMarker("org.eclipse.dd.examples.pda.markerType.lineBreakpoint"); setMarker(marker); marker.setAttribute(IBreakpoint.ENABLED, Boolean.TRUE); marker.setAttribute(IMarker.LINE_NUMBER, lineNumber); diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/breakpoints/PDAWatchpoint.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/breakpoints/PDAWatchpoint.java index 809d149e6f4..ac3e9bcc80a 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/breakpoints/PDAWatchpoint.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/breakpoints/PDAWatchpoint.java @@ -59,7 +59,7 @@ public class PDAWatchpoint extends PDALineBreakpoint implements IWatchpoint { public PDAWatchpoint(final IResource resource, final int lineNumber, final String functionName, final String varName, final boolean access, final boolean modification) throws CoreException { IWorkspaceRunnable runnable = new IWorkspaceRunnable() { public void run(IProgressMonitor monitor) throws CoreException { - IMarker marker = resource.createMarker("org.eclipse.debug.examples.core.pda.markerType.watchpoint"); + IMarker marker = resource.createMarker("org.eclipse.dd.examples.pda.markerType.watchpoint"); setMarker(marker); setEnabled(true); ensureMarker().setAttribute(IMarker.LINE_NUMBER, lineNumber); diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunch.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunch.java index 8b5020cf440..587d8c993fc 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunch.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunch.java @@ -10,18 +10,12 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.launch; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor; import org.eclipse.dd.dsf.concurrent.DsfExecutor; -import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.concurrent.Sequence; @@ -29,7 +23,6 @@ import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.examples.pda.PDAPlugin; import org.eclipse.dd.examples.pda.service.command.PDATerminatedEvent; import org.eclipse.debug.core.DebugException; @@ -52,8 +45,9 @@ public class PDALaunch extends Launch @ConfinedToDsfExecutor("getSession().getExecutor()") private DsfServicesTracker fTracker; - private AtomicBoolean fInitialized = new AtomicBoolean(false); - private AtomicBoolean fShutDown = new AtomicBoolean(false); + private Sequence fInitializationSequence = null; + private boolean fInitialized = false; + private boolean fShutDown = false; public PDALaunch(ILaunchConfiguration launchConfiguration, String mode, ISourceLocator locator) { super(launchConfiguration, mode, locator); @@ -70,42 +64,53 @@ public class PDALaunch extends Launch public DsfSession getSession() { return fSession; } - @ConfinedToDsfExecutor("getExecutor") - public void initializeControl() - throws CoreException + @ConfinedToDsfExecutor("getSession().getExecutor()") + public void initializeServices(String program, int requestPort, int eventPort, final RequestMonitor rm) { + fTracker = new DsfServicesTracker(PDAPlugin.getBundleContext(), fSession.getId()); + fSession.addServiceEventListener(PDALaunch.this, null); - Runnable initRunnable = new DsfRunnable() { - public void run() { - fTracker = new DsfServicesTracker(PDAPlugin.getBundleContext(), fSession.getId()); - fSession.addServiceEventListener(PDALaunch.this, null); - fInitialized.set(true); - fireChanged(); - } - }; - - // Invoke the execution code and block waiting for the result. - try { - fExecutor.submit(initRunnable).get(); - } catch (InterruptedException e) { - throw new CoreException(new Status( - IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Error initializing launch", e)); //$NON-NLS-1$ - } catch (ExecutionException e) { - throw new CoreException(new Status( - IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Error initializing launch", e.getCause())); //$NON-NLS-1$ + synchronized(this) { + fInitializationSequence = new PDAServicesInitSequence( + getSession(), this, program, requestPort, eventPort, + new RequestMonitor(ImmediateExecutor.getInstance(), rm) { + @Override + protected void handleCompleted() { + boolean doShutdown = false; + synchronized (this) + { + fInitialized = true; + fInitializationSequence = null; + if (fShutDown) { + doShutdown = true; + } + } + if (doShutdown) { + doShutdown(rm); + } else { + if (getStatus().getSeverity() == IStatus.ERROR) { + rm.setStatus(getStatus()); + } + rm.done(); + } + fireChanged(); + } + }); } + getSession().getExecutor().execute(fInitializationSequence); } - @DsfServiceEventHandler public void eventDispatched(PDATerminatedEvent event) { - shutdownSession(new RequestMonitor(ImmediateExecutor.getInstance(), null)); + @DsfServiceEventHandler + public void eventDispatched(PDATerminatedEvent event) { + shutdownServices(new RequestMonitor(ImmediateExecutor.getInstance(), null)); } - public boolean isInitialized() { - return fInitialized.get(); + public synchronized boolean isInitialized() { + return fInitialized; } - public boolean isShutDown() { - return fShutDown.get(); + public synchronized boolean isShutDown() { + return fShutDown; } @Override @@ -138,13 +143,27 @@ public class PDALaunch extends Launch * @param rm The request monitor invoked when the shutdown is complete. */ @ConfinedToDsfExecutor("getSession().getExecutor()") - public void shutdownSession(final RequestMonitor rm) { - if (fShutDown.getAndSet(true)) { - rm.done(); - return; + public void shutdownServices(final RequestMonitor rm) { + boolean doShutdown = false; + synchronized (this) { + if (!fInitialized && fInitializationSequence != null) { + fInitializationSequence.cancel(false); + } else { + doShutdown = !fShutDown && fInitialized; + } + fShutDown = true; } - - Sequence shutdownSeq = new PDAServicesShutdownSequence( + + if (doShutdown) { + doShutdown(rm); + } else { + rm.done(); + } + } + + @ConfinedToDsfExecutor("getSession().getExecutor()") + private void doShutdown(final RequestMonitor rm) { + fExecutor.execute( new PDAServicesShutdownSequence( getDsfExecutor(), fSession.getId(), new RequestMonitor(fSession.getExecutor(), rm) { @Override @@ -166,8 +185,7 @@ public class PDALaunch extends Launch rm.setStatus(getStatus()); rm.done(); } - }); - fExecutor.execute(shutdownSeq); + }) ); } @SuppressWarnings("unchecked") diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunchDelegate.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunchDelegate.java index 8a6c57ee116..0f203cf26d4 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunchDelegate.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunchDelegate.java @@ -28,6 +28,8 @@ import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.core.variables.IValueVariable; import org.eclipse.core.variables.VariablesPlugin; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.Query; import org.eclipse.dd.examples.pda.PDAPlugin; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.DebugPlugin; @@ -99,12 +101,8 @@ public class PDALaunchDelegate extends LaunchConfigurationDelegate { } launchProcess(launch, program, requestPort, eventPort); - PDALaunch pdaLaunch = (PDALaunch)launch; - initServices(pdaLaunch, program, requestPort, eventPort); - - pdaLaunch.initializeControl(); } private void launchProcess(ILaunch launch, String program, int requestPort, int eventPort) throws CoreException { @@ -149,12 +147,19 @@ public class PDALaunchDelegate extends LaunchConfigurationDelegate { DebugPlugin.newProcess(launch, process, path); } - private void initServices(PDALaunch pdaLaunch, String program, int requestPort, int eventPort) throws CoreException { - final PDAServicesInitSequence initSequence = - new PDAServicesInitSequence(pdaLaunch.getSession(), pdaLaunch, program, requestPort, eventPort); - pdaLaunch.getSession().getExecutor().execute(initSequence); + private void initServices(final PDALaunch pdaLaunch, final String program, final int requestPort, final int eventPort) + throws CoreException + { + Query initQuery = new Query() { + @Override + protected void execute(DataRequestMonitor rm) { + pdaLaunch.initializeServices(program, requestPort, eventPort, rm); + } + }; + + pdaLaunch.getSession().getExecutor().execute(initQuery); try { - initSequence.get(); + initQuery.get(); } catch (InterruptedException e1) { throw new DebugException(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, "Interrupted Exception in dispatch thread", e1)); //$NON-NLS-1$ } catch (ExecutionException e1) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java index 60bed1a808c..38b17950fd7 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java @@ -18,6 +18,7 @@ import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.examples.pda.service.breakpoints.PDABreakpointAttributeTranslator; import org.eclipse.dd.examples.pda.service.breakpoints.PDABreakpoints; import org.eclipse.dd.examples.pda.service.command.PDACommandControl; +import org.eclipse.dd.examples.pda.service.expressions.PDAExpressions; import org.eclipse.dd.examples.pda.service.runcontrol.PDARunControl; import org.eclipse.dd.examples.pda.service.stack.PDAStack; import org.eclipse.debug.examples.core.pda.sourcelookup.PDASourceLookupDirector; @@ -37,7 +38,8 @@ public class PDAServicesInitSequence extends Sequence { new Step() { @Override public void execute(RequestMonitor requestMonitor) { - new PDARunControl(fSession).initialize(requestMonitor); + fRunControl = new PDARunControl(fSession); + fRunControl.initialize(requestMonitor); } }, new Step() { @@ -71,38 +73,16 @@ public class PDAServicesInitSequence extends Sequence { new PDAStack(fSession).initialize(requestMonitor); } }, - /*new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - new ExpressionService(fSession).initialize(requestMonitor); - }}, new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - fSourceLookup = new CSourceLookup(fSession); - fSourceLookup.initialize(requestMonitor); - }}, + public void execute(RequestMonitor requestMonitor) { + new PDAExpressions(fSession).initialize(requestMonitor); + } + }, new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - fSourceLookup.setSourceLookupDirector( - fCommandControl.getGDBDMContext(), - ((CSourceLookupDirector)fLaunch.getSourceLocator())); - requestMonitor.done(); - }}, - new Step() { @Override - public void execute(final RequestMonitor requestMonitor) { - // Create high-level breakpoint service and install breakpoints - // for the GDB debug context. - final MIBreakpointsManager bpmService = new MIBreakpointsManager(fSession, CDebugCorePlugin.PLUGIN_ID); - bpmService.initialize(new RequestMonitor(getExecutor(), requestMonitor) { - @Override - protected void handleOK() { - bpmService.startTrackingBreakpoints(fCommandControl.getGDBDMContext(), requestMonitor); - } - }); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - new MIRegisters(fSession).initialize(requestMonitor); - }},*/ + public void execute(RequestMonitor requestMonitor) { + fRunControl.resume(fCommandControl.getDMContext(), requestMonitor); + } + }, }; private DsfSession fSession; @@ -112,12 +92,13 @@ public class PDAServicesInitSequence extends Sequence { private int fEventPort; PDACommandControl fCommandControl; + PDARunControl fRunControl; PDASourceLookupDirector fSourceLookup; public PDAServicesInitSequence(DsfSession session, PDALaunch launch, String program, int requestPort, - int eventPort) + int eventPort, RequestMonitor rm) { - super(session.getExecutor()); + super(session.getExecutor(), rm); fSession = session; fLaunch = launch; fProgram = program; diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java index db75615afc4..583c11b3908 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java @@ -22,6 +22,7 @@ import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.examples.pda.PDAPlugin; import org.eclipse.dd.examples.pda.service.breakpoints.PDABreakpoints; import org.eclipse.dd.examples.pda.service.command.PDACommandControl; +import org.eclipse.dd.examples.pda.service.expressions.PDAExpressions; import org.eclipse.dd.examples.pda.service.runcontrol.PDARunControl; import org.eclipse.dd.examples.pda.service.stack.PDAStack; @@ -75,12 +76,13 @@ public class PDAServicesShutdownSequence extends Sequence { public void execute(RequestMonitor requestMonitor) { shutdownService(CSourceLookup.class, requestMonitor); } - }, new Step() { + },*/ + new Step() { @Override public void execute(RequestMonitor requestMonitor) { - shutdownService(ExpressionService.class, requestMonitor); + shutdownService(PDAExpressions.class, requestMonitor); } - },*/ + }, new Step() { @Override public void execute(RequestMonitor requestMonitor) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/breakpoints/PDABreakpoints.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/breakpoints/PDABreakpoints.java index 4f9625ba0f0..c943d8ae43c 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/breakpoints/PDABreakpoints.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/breakpoints/PDABreakpoints.java @@ -25,9 +25,11 @@ import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.examples.pda.PDAPlugin; import org.eclipse.dd.examples.pda.breakpoints.PDAWatchpoint; -import org.eclipse.dd.examples.pda.service.command.PDACommand; import org.eclipse.dd.examples.pda.service.command.PDACommandControl; import org.eclipse.dd.examples.pda.service.command.PDACommandResult; +import org.eclipse.dd.examples.pda.service.command.commands.PDAClearBreakpointCommand; +import org.eclipse.dd.examples.pda.service.command.commands.PDASetBreakpointCommand; +import org.eclipse.dd.examples.pda.service.command.commands.PDAWatchCommand; import org.osgi.framework.BundleContext; /** @@ -148,7 +150,7 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints fBreakpoints.add(breakpointCtx); fCommandControl.queueCommand( - new PDACommand(fCommandControl.getDMContext(), "set " + line), + new PDASetBreakpointCommand(fCommandControl.getDMContext(), line), new DataRequestMonitor(getExecutor(), rm) { @Override protected void handleOK() { @@ -191,20 +193,18 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints return; } - int watchOperation = 0; + PDAWatchCommand.WatchOperation watchOperation = PDAWatchCommand.WatchOperation.NONE; if (isAccess && isModification) { - watchOperation = 3; + watchOperation = PDAWatchCommand.WatchOperation.BOTH; } else if (isAccess) { - watchOperation = 1; + watchOperation = PDAWatchCommand.WatchOperation.READ; } else if (isModification) { - watchOperation = 2; + watchOperation = PDAWatchCommand.WatchOperation.WRITE; } - String watchCommand = "watch " + function + "::" + variable + " " + watchOperation; - fBreakpoints.add(watchpointCtx); fCommandControl.queueCommand( - new PDACommand(fCommandControl.getDMContext(), watchCommand), + new PDAWatchCommand(fCommandControl.getDMContext(), function, variable, watchOperation), new DataRequestMonitor(getExecutor(), rm) { @Override protected void handleOK() { @@ -244,7 +244,7 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints fBreakpoints.remove(bpCtx); fCommandControl.queueCommand( - new PDACommand(fCommandControl.getDMContext(), "clear " + bpCtx.fLine), + new PDAClearBreakpointCommand(fCommandControl.getDMContext(), bpCtx.fLine), new DataRequestMonitor(getExecutor(), rm)); } @@ -252,9 +252,9 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints fBreakpoints.remove(bpCtx); // Watchpoints are cleared using the same command, but with a "no watch" operation - String command = "watch " + bpCtx.fFunction + "::" + bpCtx.fVariable + " 0"; fCommandControl.queueCommand( - new PDACommand(fCommandControl.getDMContext(), command), + new PDAWatchCommand(fCommandControl.getDMContext(), bpCtx.fFunction, bpCtx.fVariable, + PDAWatchCommand.WatchOperation.NONE), new DataRequestMonitor(getExecutor(), rm)); } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommandControl.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommandControl.java index c2e6b5675f4..1c8013e1f7d 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommandControl.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommandControl.java @@ -32,8 +32,7 @@ import org.eclipse.dd.dsf.service.AbstractDsfService; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.examples.pda.PDAPlugin; -import org.eclipse.dd.examples.pda.service.command.commands.PDACommandBase; -import org.eclipse.dd.examples.pda.service.command.commands.PDACommandBaseResult; +import org.eclipse.dd.examples.pda.service.command.commands.AbstractPDACommand; import org.eclipse.dd.examples.pda.service.command.commands.PDAExitCommand; import org.osgi.framework.BundleContext; @@ -45,10 +44,10 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon // Structure used to store command information in services internal queues. private static class CommandHandle { - final private PDACommandBase fCommand; - final private DataRequestMonitor fRequestMonitor; + final private AbstractPDACommand fCommand; + final private DataRequestMonitor fRequestMonitor; - CommandHandle(PDACommandBase c, DataRequestMonitor rm) { + CommandHandle(AbstractPDACommand c, DataRequestMonitor rm) { fCommand = c; fRequestMonitor = rm; } @@ -300,16 +299,16 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon } public void queueCommand(ICommand command, DataRequestMonitor rm) { - if (command instanceof PDACommandBase) { + if (command instanceof AbstractPDACommand) { // Cast from command with "" to a more concrete // type to use internally in the command control. @SuppressWarnings("unchecked") - PDACommandBase pdaCommand = (PDACommandBase)command; + AbstractPDACommand pdaCommand = (AbstractPDACommand)command; // Similarly, cast the request monitor to a more concrete type. @SuppressWarnings("unchecked") - DataRequestMonitor pdaRM = (DataRequestMonitor)rm; - + DataRequestMonitor pdaRM = (DataRequestMonitor)rm; + fCommandQueue.add( new CommandHandle(pdaCommand, pdaRM) ); for (ICommandListener listener : fCommandListeners) { listener.commandQueued(command); @@ -362,9 +361,9 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon } private void processCommandDone(CommandHandle handle, String response) { - PDAPlugin.debug(response); + PDAPlugin.debug("R: " + response); - PDACommandBaseResult result = handle.fCommand.createResult(response); + PDACommandResult result = handle.fCommand.createResult(response); handle.fRequestMonitor.setData(result); handle.fRequestMonitor.done(); @@ -385,7 +384,7 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon } private void processEventReceived(String event) { - PDAPlugin.debug(event); + PDAPlugin.debug("E: " + event); for (IEventListener listener : fEventListeners) { listener.eventReceived(event); } @@ -408,7 +407,7 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon // - and there are commands waiting to be sent. CommandHandle handle = fCommandQueue.remove(0); fTxCommands.add(handle); - PDAPlugin.debug(handle.fCommand.getRequest()); + PDAPlugin.debug("C: " + handle.fCommand.getRequest()); for (ICommandListener listener : fCommandListeners) { listener.commandSent(handle.fCommand); } @@ -468,7 +467,7 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon if (!isTerminated()) { queueCommand( new PDAExitCommand(fDMContext), - new DataRequestMonitor(getExecutor(), rm)); + new DataRequestMonitor(getExecutor(), rm)); } else { // If already terminated, indicate success. rm.done(); diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommandResult.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommandResult.java index 1d81993739a..31f49a68b55 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommandResult.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommandResult.java @@ -10,14 +10,36 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.command; -import org.eclipse.dd.examples.pda.service.command.commands.PDACommandBaseResult; +import org.eclipse.dd.dsf.debug.service.command.ICommand; +import org.eclipse.dd.dsf.debug.service.command.ICommandResult; /** - * @see PDACommand + * */ -public class PDACommandResult extends PDACommandBaseResult { - PDACommandResult(String response) { - super(response); +public class PDACommandResult implements ICommandResult { + + final public String fResponseText; + + public PDACommandResult(String response) { + fResponseText = response; + } + + public V getSubsetResult(ICommand command) { + return null; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof PDACommandResult) { + PDACommandResult result = (PDACommandResult)obj; + return fResponseText.equals(result.fResponseText); + } + return false; + } + + @Override + public int hashCode() { + return fResponseText.hashCode(); } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDACommandBase.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/AbstractPDACommand.java similarity index 79% rename from plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDACommandBase.java rename to plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/AbstractPDACommand.java index 1c0c8e82c3c..719df9cd6ae 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDACommandBase.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/AbstractPDACommand.java @@ -13,16 +13,18 @@ package org.eclipse.dd.examples.pda.service.command.commands; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.debug.service.command.ICommand; import org.eclipse.dd.dsf.debug.service.command.ICommandResult; +import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandResult; /** * */ -abstract public class PDACommandBase implements ICommand { +abstract public class AbstractPDACommand implements ICommand { final private IDMContext fContext; final private String fRequest; - public PDACommandBase(IDMContext context, String request) { + public AbstractPDACommand(PDACommandControlDMContext context, String request) { fContext = context; fRequest = request; } @@ -43,8 +45,8 @@ abstract public class PDACommandBase implements @Override public boolean equals(Object obj) { - if (obj instanceof PDACommandBase) { - PDACommandBase cmd = (PDACommandBase)obj; + if (obj instanceof AbstractPDACommand) { + AbstractPDACommand cmd = (AbstractPDACommand)obj; return fContext.equals(cmd.fContext) && fRequest.equals(cmd.fRequest); } return false; diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAClearBreakpointCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAClearBreakpointCommand.java index c513d49362d..a394fb2e7f3 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAClearBreakpointCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAClearBreakpointCommand.java @@ -10,7 +10,8 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.command.commands; -import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandResult; /** * Clears any breakpoint set on given line @@ -21,14 +22,14 @@ import org.eclipse.dd.dsf.datamodel.IDMContext; * */ -public class PDAClearBreakpointCommand extends PDACommandBase { +public class PDAClearBreakpointCommand extends AbstractPDACommand { - public PDAClearBreakpointCommand(IDMContext context, int line) { - super(context, "clear " + line); + public PDAClearBreakpointCommand(PDACommandControlDMContext context, int line) { + super(context, "clear " + (line - 1)); } @Override - public PDACommandBaseResult createResult(String resultText) { - return new PDACommandBaseResult(resultText); + public PDACommandResult createResult(String resultText) { + return new PDACommandResult(resultText); } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDACommandBaseResult.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDACommandBaseResult.java deleted file mode 100644 index c700ea339a1..00000000000 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDACommandBaseResult.java +++ /dev/null @@ -1,44 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.command.commands; - -import org.eclipse.dd.dsf.debug.service.command.ICommand; -import org.eclipse.dd.dsf.debug.service.command.ICommandResult; - -/** - * - */ -public class PDACommandBaseResult implements ICommandResult { - - final public String fResponseText; - - protected PDACommandBaseResult(String response) { - fResponseText = response; - } - - public V getSubsetResult(ICommand command) { - return null; - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof PDACommandBaseResult) { - PDACommandBaseResult result = (PDACommandBaseResult)obj; - return fResponseText.equals(result.fResponseText); - } - return false; - } - - @Override - public int hashCode() { - return fResponseText.hashCode(); - } -} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDADataCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDADataCommand.java index 26614c26653..835f5a638a5 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDADataCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDADataCommand.java @@ -10,7 +10,8 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.command.commands; -import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandResult; /** * Retrieves data stack information @@ -20,14 +21,14 @@ import org.eclipse.dd.dsf.datamodel.IDMContext; * R: {value 1}|{value 2}|{value 3}|...| * */ -public class PDADataCommand extends PDACommandBase { +public class PDADataCommand extends AbstractPDACommand { - public PDADataCommand(IDMContext context) { + public PDADataCommand(PDACommandControlDMContext context) { super(context, "data"); } @Override - public PDACommandBaseResult createResult(String resultText) { - return new PDACommandBaseResult(resultText); + public PDACommandResult createResult(String resultText) { + return new PDACommandResult(resultText); } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDADataCommandResult.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDADataCommandResult.java index 322cb3fe1c6..20e895eeab8 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDADataCommandResult.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDADataCommandResult.java @@ -14,10 +14,12 @@ import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; +import org.eclipse.dd.examples.pda.service.command.PDACommandResult; + /** * @see PDADataCommand */ -public class PDADataCommandResult extends PDACommandBaseResult { +public class PDADataCommandResult extends PDACommandResult { final public int[] fValues; diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDADropFrameCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDADropFrameCommand.java index dbd705bb7d0..0c09a9b4f87 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDADropFrameCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDADropFrameCommand.java @@ -10,7 +10,8 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.command.commands; -import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandResult; /** * Returns from the current frame without executing the rest of instructions. @@ -23,14 +24,14 @@ import org.eclipse.dd.dsf.datamodel.IDMContext; * */ -public class PDADropFrameCommand extends PDACommandBase { +public class PDADropFrameCommand extends AbstractPDACommand { - public PDADropFrameCommand(IDMContext context) { + public PDADropFrameCommand(PDACommandControlDMContext context) { super(context, "drop"); } @Override - public PDACommandBaseResult createResult(String resultText) { - return new PDACommandBaseResult(resultText); + public PDACommandResult createResult(String resultText) { + return new PDACommandResult(resultText); } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAEvalCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAEvalCommand.java index 7978a3f8485..da38d1957cf 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAEvalCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAEvalCommand.java @@ -10,7 +10,8 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.command.commands; -import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandResult; /** * Sets what events cause the execution to stop. @@ -25,14 +26,14 @@ import org.eclipse.dd.dsf.datamodel.IDMContext; * * Where event_name could be unimpinstr or nosuchlabel. */ -public class PDAEvalCommand extends PDACommandBase { +public class PDAEvalCommand extends AbstractPDACommand { - public PDAEvalCommand(IDMContext context, String operation) { + public PDAEvalCommand(PDACommandControlDMContext context, String operation) { super(context, "eval " + operation); } @Override - public PDACommandBaseResult createResult(String resultText) { - return new PDACommandBaseResult(resultText); + public PDACommandResult createResult(String resultText) { + return new PDACommandResult(resultText); } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAEventStopCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAEventStopCommand.java index d6ed8d23f97..d19369f99d4 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAEventStopCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAEventStopCommand.java @@ -10,7 +10,8 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.command.commands; -import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandResult; /** * Sets what events cause the execution to stop. @@ -24,11 +25,11 @@ import org.eclipse.dd.dsf.datamodel.IDMContext; * * Where event_name could be unimpinstr or nosuchlabel. */ -public class PDAEventStopCommand extends PDACommandBase { +public class PDAEventStopCommand extends AbstractPDACommand { public enum Event { UNIMPINSTR, NOSUCHLABEL }; - public PDAEventStopCommand(IDMContext context, Event event, boolean enable) { + public PDAEventStopCommand(PDACommandControlDMContext context, Event event, boolean enable) { super(context, "eventstop " + (event == Event.UNIMPINSTR ? "unimpinstr " : "nosuchlabel ") + @@ -36,7 +37,7 @@ public class PDAEventStopCommand extends PDACommandBase { } @Override - public PDACommandBaseResult createResult(String resultText) { - return new PDACommandBaseResult(resultText); + public PDACommandResult createResult(String resultText) { + return new PDACommandResult(resultText); } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAExitCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAExitCommand.java index f1a78b77cf3..dd074c3ed1f 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAExitCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAExitCommand.java @@ -10,7 +10,8 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.command.commands; -import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandResult; /** * Instructs the debugger to exit. @@ -20,14 +21,14 @@ import org.eclipse.dd.dsf.datamodel.IDMContext; * R: ok * */ -public class PDAExitCommand extends PDACommandBase { +public class PDAExitCommand extends AbstractPDACommand { - public PDAExitCommand(IDMContext context) { + public PDAExitCommand(PDACommandControlDMContext context) { super(context, "exit"); } @Override - public PDACommandBaseResult createResult(String resultText) { - return new PDACommandBaseResult(resultText); + public PDACommandResult createResult(String resultText) { + return new PDACommandResult(resultText); } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAFrame.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAFrame.java new file mode 100644 index 00000000000..bc427e21fa4 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAFrame.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.command.commands; + +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + +public class PDAFrame { + PDAFrame(String frameString) { + StringTokenizer st = new StringTokenizer(frameString, "|"); + + fFilePath = new Path(st.nextToken()); + fLine = Integer.parseInt(st.nextToken()); + fFunction = st.nextToken(); + + List variablesList = new ArrayList(); + while (st.hasMoreTokens()) { + variablesList.add(st.nextToken()); + } + fVariables = variablesList.toArray(new String[variablesList.size()]); + } + final public IPath fFilePath; + final public int fLine; + final public String fFunction; + final public String[] fVariables; +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAPopDataCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAPopDataCommand.java index 3a27d46f5ed..1f35dba715f 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAPopDataCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAPopDataCommand.java @@ -10,7 +10,8 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.command.commands; -import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandResult; /** * Pops the top value from the data stack @@ -20,14 +21,14 @@ import org.eclipse.dd.dsf.datamodel.IDMContext; * R: ok * */ -public class PDAPopDataCommand extends PDACommandBase { +public class PDAPopDataCommand extends AbstractPDACommand { - public PDAPopDataCommand(IDMContext context) { + public PDAPopDataCommand(PDACommandControlDMContext context) { super(context, "popdata"); } @Override - public PDACommandBaseResult createResult(String resultText) { - return new PDACommandBaseResult(resultText); + public PDACommandResult createResult(String resultText) { + return new PDACommandResult(resultText); } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAPushDataCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAPushDataCommand.java index 73e902b5f65..a2b817e776c 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAPushDataCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAPushDataCommand.java @@ -10,7 +10,8 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.command.commands; -import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandResult; /** * Pushes the given value on top of the data stack. @@ -20,14 +21,14 @@ import org.eclipse.dd.dsf.datamodel.IDMContext; * R: ok * */ -public class PDAPushDataCommand extends PDACommandBase { +public class PDAPushDataCommand extends AbstractPDACommand { - public PDAPushDataCommand(IDMContext context, int value) { + public PDAPushDataCommand(PDACommandControlDMContext context, int value) { super(context, "pushdata " + value); } @Override - public PDACommandBaseResult createResult(String resultText) { - return new PDACommandBaseResult(resultText); + public PDACommandResult createResult(String resultText) { + return new PDACommandResult(resultText); } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAResumeCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAResumeCommand.java index c0a29a958e5..40582908460 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAResumeCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAResumeCommand.java @@ -10,7 +10,8 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.command.commands; -import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandResult; /** * Resumes the execution @@ -21,14 +22,14 @@ import org.eclipse.dd.dsf.datamodel.IDMContext; * E: resumed client * */ -public class PDAResumeCommand extends PDACommandBase { +public class PDAResumeCommand extends AbstractPDACommand { - public PDAResumeCommand(IDMContext context) { + public PDAResumeCommand(PDACommandControlDMContext context) { super(context, "resume"); } @Override - public PDACommandBaseResult createResult(String resultText) { - return new PDACommandBaseResult(resultText); + public PDACommandResult createResult(String resultText) { + return new PDACommandResult(resultText); } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASetBreakpointCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASetBreakpointCommand.java index 30844bac9be..a46ce388d2c 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASetBreakpointCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASetBreakpointCommand.java @@ -10,7 +10,8 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.command.commands; -import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandResult; /** * Sets a breakpoint at given line @@ -23,14 +24,14 @@ import org.eclipse.dd.dsf.datamodel.IDMContext; * E: suspended breakpoint line_number * */ -public class PDASetBreakpointCommand extends PDACommandBase { +public class PDASetBreakpointCommand extends AbstractPDACommand { - public PDASetBreakpointCommand(IDMContext context, int line) { - super(context, "set " + line); + public PDASetBreakpointCommand(PDACommandControlDMContext context, int line) { + super(context, "set " + (line - 1)); } @Override - public PDACommandBaseResult createResult(String resultText) { - return new PDACommandBaseResult(resultText); + public PDACommandResult createResult(String resultText) { + return new PDACommandResult(resultText); } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASetDataCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASetDataCommand.java index 7a7c1fa5b0e..fc4a94992da 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASetDataCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASetDataCommand.java @@ -10,7 +10,8 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.command.commands; -import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandResult; /** * Sets a data value in the data stack at the given location @@ -20,14 +21,14 @@ import org.eclipse.dd.dsf.datamodel.IDMContext; * R: ok * */ -public class PDASetDataCommand extends PDACommandBase { +public class PDASetDataCommand extends AbstractPDACommand { - public PDASetDataCommand(IDMContext context, int index, int value) { + public PDASetDataCommand(PDACommandControlDMContext context, int index, int value) { super(context, "setdata " + index + " " + value); } @Override - public PDACommandBaseResult createResult(String resultText) { - return new PDACommandBaseResult(resultText); + public PDACommandResult createResult(String resultText) { + return new PDACommandResult(resultText); } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASetVarCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASetVarCommand.java index 8a0cb9eaa99..cafbe6d1372 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASetVarCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASetVarCommand.java @@ -10,7 +10,8 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.command.commands; -import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandResult; /** * Sets a variable value @@ -20,14 +21,14 @@ import org.eclipse.dd.dsf.datamodel.IDMContext; * R: ok * */ -public class PDASetVarCommand extends PDACommandBase { +public class PDASetVarCommand extends AbstractPDACommand { - public PDASetVarCommand(IDMContext context, String variable, int value) { + public PDASetVarCommand(PDACommandControlDMContext context, String variable, String value) { super(context, "setvar " + variable + " " + value); } @Override - public PDACommandBaseResult createResult(String resultText) { - return new PDACommandBaseResult(resultText); + public PDACommandResult createResult(String resultText) { + return new PDACommandResult(resultText); } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStackCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStackCommand.java index 5ca5a30eb05..3db048e2c4e 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStackCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStackCommand.java @@ -10,7 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.command.commands; -import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; /** * Retrieves command stack information @@ -20,14 +20,14 @@ import org.eclipse.dd.dsf.datamodel.IDMContext; * R: {file}|{line}|{function}|{var_1}|{var_2}|...#{file}|{line}|{function}|{var_1}|{var_2}|...#... * */ -public class PDAStackCommand extends PDACommandBase { +public class PDAStackCommand extends AbstractPDACommand { - public PDAStackCommand(IDMContext context) { + public PDAStackCommand(PDACommandControlDMContext context) { super(context, "stack"); } @Override - public PDACommandBaseResult createResult(String resultText) { - return new PDACommandBaseResult(resultText); + public PDAStackCommandResult createResult(String resultText) { + return new PDAStackCommandResult(resultText); } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStackCommandResult.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStackCommandResult.java index 41cc81a9f29..1b4e07e5560 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStackCommandResult.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStackCommandResult.java @@ -14,44 +14,23 @@ import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.Path; +import org.eclipse.dd.examples.pda.service.command.PDACommandResult; /** * @see PDAStackCommand */ -public class PDAStackCommandResult extends PDACommandBaseResult { +public class PDAStackCommandResult extends PDACommandResult { - public static class Frame { - Frame(String frameString) { - StringTokenizer st = new StringTokenizer(frameString, "|"); - - fFilePath = new Path(st.nextToken()); - fLine = Integer.parseInt(st.nextToken()); - fFunction = st.nextToken(); - - List variablesList = new ArrayList(); - while (st.hasMoreTokens()) { - variablesList.add(st.nextToken()); - } - fVariables = variablesList.toArray(new String[variablesList.size()]); - } - final public IPath fFilePath; - final public int fLine; - final public String fFunction; - final public String[] fVariables; - } - - final public Frame[] fFrames; + final public PDAFrame[] fFrames; PDAStackCommandResult(String response) { super(response); StringTokenizer st = new StringTokenizer(response, "#"); - List framesList = new ArrayList(); + List framesList = new ArrayList(); while (st.hasMoreTokens()) { - framesList.add(new Frame(st.nextToken())); + framesList.add(new PDAFrame(st.nextToken())); } - fFrames = framesList.toArray(new Frame[framesList.size()]); + fFrames = framesList.toArray(new PDAFrame[framesList.size()]); } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStepCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStepCommand.java index 97d0311f831..9a3f536fbc5 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStepCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStepCommand.java @@ -10,7 +10,8 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.command.commands; -import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandResult; /** * Executes next instruciton @@ -22,14 +23,14 @@ import org.eclipse.dd.dsf.datamodel.IDMContext; * E: suspended step * */ -public class PDAStepCommand extends PDACommandBase { +public class PDAStepCommand extends AbstractPDACommand { - public PDAStepCommand(IDMContext context) { + public PDAStepCommand(PDACommandControlDMContext context) { super(context, "step"); } @Override - public PDACommandBaseResult createResult(String resultText) { - return new PDACommandBaseResult(resultText); + public PDACommandResult createResult(String resultText) { + return new PDACommandResult(resultText); } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStepReturnCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStepReturnCommand.java index e8be6d5ec06..4d1d6ec6996 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStepReturnCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStepReturnCommand.java @@ -10,7 +10,8 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.command.commands; -import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandResult; /** * Executes instructions until the current subroutine is finished @@ -22,14 +23,14 @@ import org.eclipse.dd.dsf.datamodel.IDMContext; * E: suspended step * */ -public class PDAStepReturnCommand extends PDACommandBase { +public class PDAStepReturnCommand extends AbstractPDACommand { - public PDAStepReturnCommand(IDMContext context) { + public PDAStepReturnCommand(PDACommandControlDMContext context) { super(context, "stepreturn"); } @Override - public PDACommandBaseResult createResult(String resultText) { - return new PDACommandBaseResult(resultText); + public PDACommandResult createResult(String resultText) { + return new PDACommandResult(resultText); } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASuspendCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASuspendCommand.java index 4b07d0a066b..8972c83f830 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASuspendCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASuspendCommand.java @@ -10,7 +10,8 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.command.commands; -import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandResult; /** * Suspends execution @@ -21,14 +22,14 @@ import org.eclipse.dd.dsf.datamodel.IDMContext; * E: suspended client * */ -public class PDASuspendCommand extends PDACommandBase { +public class PDASuspendCommand extends AbstractPDACommand { - public PDASuspendCommand(IDMContext context) { + public PDASuspendCommand(PDACommandControlDMContext context) { super(context, "suspend"); } @Override - public PDACommandBaseResult createResult(String resultText) { - return new PDACommandBaseResult(resultText); + public PDACommandResult createResult(String resultText) { + return new PDACommandResult(resultText); } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAVarCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAVarCommand.java index d4b52df8cd6..95280892e65 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAVarCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAVarCommand.java @@ -10,7 +10,8 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.command.commands; -import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandResult; /** * Retrieves variable value @@ -20,14 +21,14 @@ import org.eclipse.dd.dsf.datamodel.IDMContext; * R: {variable_value} * */ -public class PDAVarCommand extends PDACommandBase { +public class PDAVarCommand extends AbstractPDACommand { - public PDAVarCommand(IDMContext context, int frame, String name) { - super(context, "var " + frame + " " + name); + public PDAVarCommand(PDACommandControlDMContext context, int frameId, String name) { + super(context, "var " + frameId + " " + name); } @Override - public PDACommandBaseResult createResult(String resultText) { - return new PDACommandBaseResult(resultText); + public PDACommandResult createResult(String resultText) { + return new PDACommandResult(resultText); } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAVarCommandResult.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAVarCommandResult.java index 0b583335661..3275256f41a 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAVarCommandResult.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAVarCommandResult.java @@ -10,11 +10,13 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.command.commands; +import org.eclipse.dd.examples.pda.service.command.PDACommandResult; + /** * @see PDAVarCommand */ -public class PDAVarCommandResult extends PDACommandBaseResult { +public class PDAVarCommandResult extends PDACommandResult { final public int fValue; diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAWatchCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAWatchCommand.java index 48a959ed53d..7d23b37c087 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAWatchCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAWatchCommand.java @@ -10,7 +10,8 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.command.commands; -import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandResult; /** * Sets a watchpoint on a given variable @@ -23,7 +24,7 @@ import org.eclipse.dd.dsf.datamodel.IDMContext; * E: suspended watch {watch_operation} {function}::{variable_name} * */ -public class PDAWatchCommand extends PDACommandBase { +public class PDAWatchCommand extends AbstractPDACommand { public enum WatchOperation { READ, WRITE, BOTH, NONE }; @@ -40,12 +41,12 @@ public class PDAWatchCommand extends PDACommandBase { } } - public PDAWatchCommand(IDMContext context, String function, String variable, WatchOperation operation) { + public PDAWatchCommand(PDACommandControlDMContext context, String function, String variable, WatchOperation operation) { super(context, "watch " + function+ "::" + variable + " " + getWatchOperationCode(operation)); } @Override - public PDACommandBaseResult createResult(String resultText) { - return new PDACommandBaseResult(resultText); + public PDACommandResult createResult(String resultText) { + return new PDACommandResult(resultText); } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/expressions/ExpressionDMContext.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/expressions/ExpressionDMContext.java new file mode 100644 index 00000000000..477ee85f6de --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/expressions/ExpressionDMContext.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.expressions; + +import org.eclipse.dd.dsf.datamodel.AbstractDMContext; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; + +/** + * + */ +public class ExpressionDMContext extends AbstractDMContext implements IExpressionDMContext { + + private final String fExpression; + + ExpressionDMContext(String sessionId, IFrameDMContext frameDmc, String expressin) { + super(sessionId, new IDMContext[] { frameDmc }); + fExpression = expressin; + } + + public String getExpression() { + return fExpression; + } + + @Override + public boolean equals(Object other) { + return super.baseEquals(other) && ((ExpressionDMContext)other).fExpression.equals(fExpression); + } + + @Override + public int hashCode() { + return super.baseHashCode() + fExpression.hashCode(); + } + + @Override + public String toString() { + return baseToString() + ".expression(" + fExpression + ")"; //$NON-NLS-1$ //$NON-NLS-2$ + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/expressions/ExpressionDMData.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/expressions/ExpressionDMData.java new file mode 100644 index 00000000000..2929f61c020 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/expressions/ExpressionDMData.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.expressions; + +import java.util.Map; + +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMData; +import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext; + +/** + * + */ +public class ExpressionDMData implements IExpressionDMData { + + final private String fExpression; + + public ExpressionDMData(String expression) { + fExpression = expression; + } + + public BasicType getBasicType() { + return BasicType.basic; + } + + public String getEncoding() { + return null; + } + + public Map getEnumerations() { + return null; + } + + public String getName() { + return fExpression; + } + + public IRegisterDMContext getRegister() { + return null; + } + + public String getStringValue() { + return null; + } + + public String getTypeId() { + return null; + } + + public String getTypeName() { + return null; + } + +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/expressions/InvalidExpressionDMContext.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/expressions/InvalidExpressionDMContext.java new file mode 100644 index 00000000000..56124e06f87 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/expressions/InvalidExpressionDMContext.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.expressions; + +import org.eclipse.dd.dsf.datamodel.AbstractDMContext; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; + +class InvalidExpressionDMContext extends AbstractDMContext + implements IExpressionDMContext +{ + private final String expression; + + public InvalidExpressionDMContext(String sessionId, IDMContext parent, String expr) { + super(sessionId, new IDMContext[] { parent }); + expression = expr; + } + + @Override + public boolean equals(Object other) { + return super.baseEquals(other) && + expression == null + ? ((InvalidExpressionDMContext) other).getExpression() == null + : expression.equals(((InvalidExpressionDMContext) other).getExpression()); + } + + @Override + public int hashCode() { + return expression == null ? super.baseHashCode() : super.baseHashCode() ^ expression.hashCode(); + } + + @Override + public String toString() { + return baseToString() + ".invalid_expr[" + expression + "]"; //$NON-NLS-1$ //$NON-NLS-2$ + } + + public String getExpression() { + return expression; + } +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/expressions/PDAExpressions.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/expressions/PDAExpressions.java new file mode 100644 index 00000000000..550882bc74c --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/expressions/PDAExpressions.java @@ -0,0 +1,224 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.expressions; + +import java.util.Hashtable; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.IExpressions; +import org.eclipse.dd.dsf.debug.service.IStack; +import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent; +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.command.CommandCache; +import org.eclipse.dd.dsf.service.AbstractDsfService; +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.examples.pda.PDAPlugin; +import org.eclipse.dd.examples.pda.service.command.PDACommandControl; +import org.eclipse.dd.examples.pda.service.command.PDACommandResult; +import org.eclipse.dd.examples.pda.service.command.commands.PDASetVarCommand; +import org.eclipse.dd.examples.pda.service.command.commands.PDAVarCommand; +import org.osgi.framework.BundleContext; + +/** + * + */ +public class PDAExpressions extends AbstractDsfService implements IExpressions { + + private PDACommandControl fCommandControl; + private IStack fStack; + + private CommandCache fCommandCache; + + public PDAExpressions(DsfSession session) { + super(session); + } + + @Override + protected BundleContext getBundleContext() { + return PDAPlugin.getBundleContext(); + } + + @Override + public void initialize(final RequestMonitor rm) { + super.initialize( + new RequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + doInitialize(rm); + }}); + } + + private void doInitialize(final RequestMonitor rm) { + fCommandControl = getServicesTracker().getService(PDACommandControl.class); + fStack = getServicesTracker().getService(IStack.class); + fCommandCache = new CommandCache(fCommandControl); + + getSession().addServiceEventListener(this, null); + + register(new String[]{IExpressions.class.getName(), PDAExpressions.class.getName()}, new Hashtable()); + + rm.done(); + } + + @Override + public void shutdown(final RequestMonitor rm) { + getSession().removeServiceEventListener(this); + fCommandCache.reset(); + super.shutdown(rm); + } + + public void canWriteExpression(IExpressionDMContext expressionContext, DataRequestMonitor rm) { + rm.setData(true); + rm.done(); + } + + public IExpressionDMContext createExpression(IDMContext ctx, String expression) { + IFrameDMContext frameCtx = DMContexts.getAncestorOfType(ctx, IFrameDMContext.class); + if (frameCtx != null) { + return new ExpressionDMContext(getSession().getId(), frameCtx, expression); + } else { + return new InvalidExpressionDMContext(getSession().getId(), ctx, expression); + } + } + + public void getBaseExpressions(IExpressionDMContext exprContext, DataRequestMonitor rm) { + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$ + rm.done(); + } + + public void getExpressionAddressData(IExpressionDMContext dmc, DataRequestMonitor rm) { + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$ + rm.done(); + } + + public void getExpressionData(final IExpressionDMContext exprCtx, final DataRequestMonitor rm) { + if (exprCtx instanceof ExpressionDMContext) { + rm.setData(new ExpressionDMData(exprCtx.getExpression())); + rm.done(); + } else { + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid expression context " + exprCtx, null)); //$NON-NLS-1$ + rm.done(); + } + } + + public void getSubExpressionCount(IExpressionDMContext exprCtx, DataRequestMonitor rm) { + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$ + rm.done(); + } + + public void getSubExpressions(IExpressionDMContext exprCtx, DataRequestMonitor rm) { + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$ + rm.done(); + } + + public void getSubExpressions(IExpressionDMContext exprCtx, int startIndex, int length, + DataRequestMonitor rm) + { + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$ + rm.done(); + } + + + public void writeExpression(IExpressionDMContext exprCtx, String exprValue, String formatId, RequestMonitor rm) + { + if (exprCtx instanceof ExpressionDMContext) { + fCommandCache.execute( + new PDASetVarCommand(fCommandControl.getDMContext(), exprCtx.getExpression(), exprValue), + new DataRequestMonitor(getExecutor(), rm)); + } else { + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid expression context " + exprCtx, null)); //$NON-NLS-1$ + rm.done(); + } + } + + public void getAvailableFormats(IFormattedDataDMContext dmc, DataRequestMonitor rm) { + rm.setData(new String[] { NATURAL_FORMAT }); + rm.done(); + } + + public FormattedValueDMContext getFormattedValueContext(IFormattedDataDMContext dmc, String formatId) { + return new FormattedValueDMContext(this, dmc, formatId); + } + + public void getFormattedExpressionValue(FormattedValueDMContext formattedCtx, final DataRequestMonitor rm) { + final ExpressionDMContext exprCtx = DMContexts.getAncestorOfType(formattedCtx, ExpressionDMContext.class); + if (exprCtx != null) { + getExpressionValue( + exprCtx, + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + rm.setData(new FormattedValueDMData(getData())); + rm.done(); + } + }); + } else { + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid expression context " + formattedCtx, null)); //$NON-NLS-1$ + rm.done(); + } + } + + private void getExpressionValue(final ExpressionDMContext exprCtx, final DataRequestMonitor rm) { + final IFrameDMContext frameCtx = DMContexts.getAncestorOfType(exprCtx, IFrameDMContext.class); + fStack.getStackDepth( + frameCtx, 0, + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + int frameId = getData() - frameCtx.getLevel() - 1; + fCommandCache.execute( + new PDAVarCommand(fCommandControl.getDMContext(), frameId, exprCtx.getExpression()), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + rm.setData(getData().fResponseText); + rm.done(); + } + }); + } + }); + } + + @Deprecated + public void getModelData(IDMContext dmc, DataRequestMonitor rm) { + if (dmc instanceof IExpressionDMContext) { + getExpressionData((IExpressionDMContext) dmc, (DataRequestMonitor) rm); + } else if (dmc instanceof FormattedValueDMContext) { + getFormattedExpressionValue((FormattedValueDMContext) dmc, (DataRequestMonitor) rm); + } else { + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ + rm.done(); + } + } + + @DsfServiceEventHandler + public void eventDispatched(IResumedDMEvent e) { + fCommandCache.setTargetAvailable(false); + if (!e.getReason().equals(StateChangeReason.STEP)) { + fCommandCache.reset(); + } + } + + + @DsfServiceEventHandler + public void eventDispatched(ISuspendedDMEvent e) { + fCommandCache.setTargetAvailable(true); + fCommandCache.reset(); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/PDARunControl.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/PDARunControl.java index 48fb112f4aa..5bc8ec49f41 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/PDARunControl.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/PDARunControl.java @@ -27,9 +27,11 @@ import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.examples.pda.PDAPlugin; -import org.eclipse.dd.examples.pda.service.command.PDACommand; import org.eclipse.dd.examples.pda.service.command.PDACommandControl; import org.eclipse.dd.examples.pda.service.command.PDACommandResult; +import org.eclipse.dd.examples.pda.service.command.commands.PDAResumeCommand; +import org.eclipse.dd.examples.pda.service.command.commands.PDAStepCommand; +import org.eclipse.dd.examples.pda.service.command.commands.PDASuspendCommand; import org.osgi.framework.BundleContext; @@ -187,7 +189,7 @@ public class PDARunControl extends AbstractDsfService fCommandCache.setTargetAvailable(false); fCommandControl.queueCommand( - new PDACommand(fCommandControl.getDMContext(), "resume"), + new PDAResumeCommand(fCommandControl.getDMContext()), new DataRequestMonitor(getExecutor(), rm) { @Override protected void handleOK() { @@ -206,7 +208,7 @@ public class PDARunControl extends AbstractDsfService if (canSuspend(context)) { fCommandControl.queueCommand( - new PDACommand(fCommandControl.getDMContext(), "suspend"), + new PDASuspendCommand(fCommandControl.getDMContext()), new DataRequestMonitor(getExecutor(), rm)); } else { @@ -228,7 +230,7 @@ public class PDARunControl extends AbstractDsfService fCommandCache.setTargetAvailable(false); fCommandControl.queueCommand( - new PDACommand(fCommandControl.getDMContext(), "step"), + new PDAStepCommand(fCommandControl.getDMContext()), new DataRequestMonitor(getExecutor(), rm)); } else { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/FrameDMContext.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/FrameDMContext.java index 7947f0aea5d..48ac9084c67 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/FrameDMContext.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/FrameDMContext.java @@ -14,7 +14,6 @@ import org.eclipse.dd.dsf.datamodel.AbstractDMContext; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; -import org.eclipse.dd.examples.pda.service.stack.PDAStack.PDAFrame; /** * @@ -22,16 +21,12 @@ import org.eclipse.dd.examples.pda.service.stack.PDAStack.PDAFrame; class FrameDMContext extends AbstractDMContext implements IFrameDMContext { private final int fLevel; - private final PDAFrame fFrame; - FrameDMContext(String sessionId, IExecutionDMContext execDmc, int level, PDAFrame frame) { + FrameDMContext(String sessionId, IExecutionDMContext execDmc, int level) { super(sessionId, new IDMContext[] { execDmc }); fLevel = level; - fFrame = frame; } - PDAFrame getFrame() { return fFrame; } - public int getLevel() { return fLevel; } @Override diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/FrameDMData.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/FrameDMData.java index c3272d64564..304388503c9 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/FrameDMData.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/FrameDMData.java @@ -12,7 +12,7 @@ package org.eclipse.dd.examples.pda.service.stack; import org.eclipse.cdt.core.IAddress; import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMData; -import org.eclipse.dd.examples.pda.service.stack.PDAStack.PDAFrame; +import org.eclipse.dd.examples.pda.service.command.commands.PDAFrame; /** * @@ -26,7 +26,7 @@ public class FrameDMData implements IFrameDMData { } public String getFile() { - return fFrame.fFilePath; + return fFrame.fFilePath.lastSegment(); } public String getFunction() { @@ -34,7 +34,7 @@ public class FrameDMData implements IFrameDMData { } public int getLine() { - return fFrame.fLine; + return fFrame.fLine + 1; } public int getColumn() { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/PDAStack.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/PDAStack.java index e11c64dfa54..f533f191328 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/PDAStack.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/PDAStack.java @@ -10,10 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.stack; -import java.util.ArrayList; import java.util.Hashtable; -import java.util.List; -import java.util.StringTokenizer; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; @@ -33,9 +30,10 @@ import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.examples.pda.PDAPlugin; -import org.eclipse.dd.examples.pda.service.command.PDACommand; import org.eclipse.dd.examples.pda.service.command.PDACommandControl; -import org.eclipse.dd.examples.pda.service.command.PDACommandResult; +import org.eclipse.dd.examples.pda.service.command.commands.PDAFrame; +import org.eclipse.dd.examples.pda.service.command.commands.PDAStackCommand; +import org.eclipse.dd.examples.pda.service.command.commands.PDAStackCommandResult; import org.osgi.framework.BundleContext; /** @@ -91,16 +89,29 @@ public class PDAStack extends AbstractDsfService implements IStack { rm.done(); } - public void getFrameData(IFrameDMContext frameCtx, DataRequestMonitor rm) { + public void getFrameData(final IFrameDMContext frameCtx, final DataRequestMonitor rm) { if ( !(frameCtx instanceof FrameDMContext) ) { rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context " + frameCtx, null)); //$NON-NLS-1$ rm.done(); return; } - PDAFrame pdaFrame = ((FrameDMContext)frameCtx).getFrame(); - rm.setData(new FrameDMData(pdaFrame)); - rm.done(); + fCommandCache.execute( + new PDAStackCommand(fCommandControl.getDMContext()), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + int frameId = getData().fFrames.length - frameCtx.getLevel() - 1; + if (frameId < 0) { + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid frame level " + frameCtx, null)); //$NON-NLS-1$ + rm.done(); + return; + } + + rm.setData(new FrameDMData(getData().fFrames[frameId])); + rm.done(); + } + }); } public void getFrames(IDMContext context, final DataRequestMonitor rm) { @@ -111,15 +122,14 @@ public class PDAStack extends AbstractDsfService implements IStack { return; } - fCommandControl.queueCommand( - new PDACommand(execCtx, "stack"), - new DataRequestMonitor(getExecutor(), rm) { + fCommandCache.execute( + new PDAStackCommand(fCommandControl.getDMContext()), + new DataRequestMonitor(getExecutor(), rm) { @Override protected void handleOK() { - PDAFrame[] frames = parseStackResponse(getData().fResponseText); - IFrameDMContext[] frameCtxs = new IFrameDMContext[frames.length]; - for (int i = 0; i < frames.length; i++) { - frameCtxs[i] = new FrameDMContext(getSession().getId(), execCtx, i, frames[i]); + IFrameDMContext[] frameCtxs = new IFrameDMContext[getData().fFrames.length]; + for (int i = 0; i < getData().fFrames.length; i++) { + frameCtxs[i] = new FrameDMContext(getSession().getId(), execCtx, i); } rm.setData(frameCtxs); rm.done(); @@ -127,44 +137,59 @@ public class PDAStack extends AbstractDsfService implements IStack { }); } - public void getLocals(IFrameDMContext frameCtx, DataRequestMonitor rm) { + public void getLocals(final IFrameDMContext frameCtx, final DataRequestMonitor rm) { if ( !(frameCtx instanceof FrameDMContext) ) { rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context " + frameCtx, null)); //$NON-NLS-1$ rm.done(); return; } - PDAFrame pdaFrame = ((FrameDMContext)frameCtx).getFrame(); - IVariableDMContext[] variableCtxs = new IVariableDMContext[pdaFrame.fVariables.length]; - for (int i = 0; i < pdaFrame.fVariables.length; i++) { - variableCtxs[i] = new VariableDMContext(getSession().getId(), frameCtx, pdaFrame.fVariables[i]); - } - rm.setData(variableCtxs); - rm.done(); + fCommandCache.execute( + new PDAStackCommand(fCommandControl.getDMContext()), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + int frameId = getData().fFrames.length - frameCtx.getLevel() - 1; + if (frameId < 0) { + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid frame level " + frameCtx, null)); //$NON-NLS-1$ + rm.done(); + return; + } + + + PDAFrame pdaFrame = getData().fFrames[frameId]; + IVariableDMContext[] variableCtxs = new IVariableDMContext[pdaFrame.fVariables.length]; + for (int i = 0; i < pdaFrame.fVariables.length; i++) { + variableCtxs[i] = new VariableDMContext(getSession().getId(), frameCtx, pdaFrame.fVariables[i]); + } + rm.setData(variableCtxs); + rm.done(); + } + }); + } public void getStackDepth(IDMContext context, int maxDepth, final DataRequestMonitor rm) { - getFrames( - context, - new DataRequestMonitor(getExecutor(), rm) { + fCommandCache.execute( + new PDAStackCommand(fCommandControl.getDMContext()), + new DataRequestMonitor(getExecutor(), rm) { @Override protected void handleOK() { - rm.setData(getData().length); + rm.setData(getData().fFrames.length); rm.done(); } }); } public void getTopFrame(IDMContext context, final DataRequestMonitor rm) { - getFrames( - context, - new DataRequestMonitor(getExecutor(), rm) { - @Override - protected void handleOK() { - rm.setData(getData()[0]); - rm.done(); - } - }); + final IExecutionDMContext execCtx = DMContexts.getAncestorOfType(context, IExecutionDMContext.class); + if (execCtx == null) { + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context " + context, null)); //$NON-NLS-1$ + rm.done(); + return; + } + rm.setData(new FrameDMContext(getSession().getId(), execCtx, 0)); + rm.done(); } public void getVariableData(IVariableDMContext variableCtx, DataRequestMonitor rm) { @@ -213,36 +238,4 @@ public class PDAStack extends AbstractDsfService implements IStack { fCommandCache.setTargetAvailable(true); fCommandCache.reset(); } - - public static class PDAFrame { - PDAFrame(String frameString) { - StringTokenizer st = new StringTokenizer(frameString, "|"); - - fFilePath = st.nextToken(); - fLine = Integer.parseInt(st.nextToken()); - fFunction = st.nextToken(); - - List variablesList = new ArrayList(); - while (st.hasMoreTokens()) { - variablesList.add(st.nextToken()); - } - fVariables = variablesList.toArray(new String[variablesList.size()]); - } - - final public String fFilePath; - final public int fLine; - final public String fFunction; - final public String[] fVariables; - } - - private PDAFrame[] parseStackResponse(String response) { - StringTokenizer st = new StringTokenizer(response, "#"); - List framesList = new ArrayList(); - - while (st.hasMoreTokens()) { - framesList.add(new PDAFrame(st.nextToken())); - } - return framesList.toArray(new PDAFrame[framesList.size()]); - } - } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/BasicTests.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/BasicTests.java index 20127ad2d3c..abee9ba1650 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/BasicTests.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/BasicTests.java @@ -23,7 +23,6 @@ import org.eclipse.dd.dsf.concurrent.Query; import org.eclipse.dd.dsf.debug.service.command.ICommand; import org.eclipse.dd.dsf.debug.service.command.ICommandListener; import org.eclipse.dd.dsf.debug.service.command.ICommandResult; -import org.eclipse.dd.examples.pda.service.command.PDACommand; import org.eclipse.dd.examples.pda.service.command.PDACommandResult; import org.junit.BeforeClass; import org.junit.Test; @@ -82,7 +81,7 @@ public class BasicTests extends CommandControlTestsBase { } }); - final PDACommand testCommand = new PDACommand(fCommandControl.getDMContext(), "data"); + final PDATestCommand testCommand = new PDATestCommand(fCommandControl.getDMContext(), "data"); // Test sending the command and checking all listeners were called. Query sendCommandQuery = new Query() { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/CommandControlTestsBase.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/CommandControlTestsBase.java index 27b2429eba4..9d7a339177c 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/CommandControlTestsBase.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/CommandControlTestsBase.java @@ -27,7 +27,6 @@ import org.eclipse.dd.dsf.concurrent.Query; import org.eclipse.dd.dsf.debug.service.command.IEventListener; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.examples.pda.service.command.PDACommandControl; -import org.eclipse.dd.examples.pda.service.command.PDACommand; import org.eclipse.dd.examples.pda.service.command.PDACommandResult; import org.eclipse.dd.tests.pda.util.Launching; import org.junit.After; @@ -106,7 +105,7 @@ public class CommandControlTestsBase { protected void sendCommand(String command, String expectedResult) throws Throwable { - final PDACommand testCommand = new PDACommand(fCommandControl.getDMContext(), command); + final PDATestCommand testCommand = new PDATestCommand(fCommandControl.getDMContext(), command); // Test sending the command and checking all listeners were called. Query sendCommandQuery = new Query() { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/PDATestCommand.java similarity index 63% rename from plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommand.java rename to plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/PDATestCommand.java index cb6215a4136..0aba7c8441c 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/PDATestCommand.java @@ -8,16 +8,17 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.command; +package org.eclipse.dd.tests.pda.service.command; -import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.examples.pda.service.command.commands.PDACommandBase; +import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; +import org.eclipse.dd.examples.pda.service.command.PDACommandResult; +import org.eclipse.dd.examples.pda.service.command.commands.AbstractPDACommand; /** * */ -public class PDACommand extends PDACommandBase { - public PDACommand(IDMContext context, String command) { +class PDATestCommand extends AbstractPDACommand { + PDATestCommand(PDACommandControlDMContext context, String command) { super(context, command); } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourceLookupDirector.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourceLookupDirector.java index f975cf7c338..27e1cdd8ce1 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourceLookupDirector.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourceLookupDirector.java @@ -12,21 +12,13 @@ package org.eclipse.debug.examples.core.pda.sourcelookup; import org.eclipse.debug.core.sourcelookup.AbstractSourceLookupDirector; -import org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant; /** - * PDA source lookup director. For PDA source lookup there is one source - * lookup participant. + * PDA source lookup director. */ public class PDASourceLookupDirector extends AbstractSourceLookupDirector { - /* (non-Javadoc) - * @see org.eclipse.debug.internal.core.sourcelookup.ISourceLookupDirector#initializeParticipants() - */ public void initializeParticipants() { - //#ifdef ex4 -//# // TODO: Exercise 4 - add our participant to this director - //#else - addParticipants(new ISourceLookupParticipant[]{new PDASourceLookupParticipant()}); - //#endif + // No need to add participants here, the surce display adapter will + // add the participant with the correct session ID. } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourceLookupParticipant.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourceLookupParticipant.java deleted file mode 100644 index 66243d6518f..00000000000 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourceLookupParticipant.java +++ /dev/null @@ -1,29 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2007 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - * Bjorn Freeman-Benson - initial API and implementation - *******************************************************************************/ -package org.eclipse.debug.examples.core.pda.sourcelookup; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.debug.core.sourcelookup.AbstractSourceLookupParticipant; - - -/** - * The PDA source lookup participant knows how to translate a - * PDA stack frame into a source file name - */ -public class PDASourceLookupParticipant extends AbstractSourceLookupParticipant { - /* (non-Javadoc) - * @see org.eclipse.debug.internal.core.sourcelookup.ISourceLookupParticipant#getSourceName(java.lang.Object) - */ - public String getSourceName(Object object) throws CoreException { - return null; - } -} From fe730bbef710e726a04c58b14198b2d243e704d6 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Wed, 20 Feb 2008 16:11:32 +0000 Subject: [PATCH 258/834] Fix for bug 219193 If StopAtMain is not selected, -exec-run should still be done. --- .../dd/gdb/launching/LaunchSequence.java | 107 ++++++------------ 1 file changed, 34 insertions(+), 73 deletions(-) diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/LaunchSequence.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/LaunchSequence.java index 9f49b87e9a0..040e7d3a975 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/LaunchSequence.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/LaunchSequence.java @@ -10,8 +10,6 @@ *******************************************************************************/ package org.eclipse.dd.gdb.launching; -import java.util.concurrent.TimeUnit; - import org.eclipse.cdt.debug.core.CDebugCorePlugin; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector; @@ -27,7 +25,6 @@ import org.eclipse.dd.dsf.concurrent.Sequence; import org.eclipse.dd.dsf.debug.service.StepQueueManager; import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; -import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.gdb.internal.GdbPlugin; import org.eclipse.dd.gdb.service.GDBRunControl; @@ -42,33 +39,12 @@ import org.eclipse.dd.mi.service.MIRegisters; import org.eclipse.dd.mi.service.MIStack; import org.eclipse.dd.mi.service.command.commands.MIBreakInsert; import org.eclipse.dd.mi.service.command.commands.MIExecRun; -import org.eclipse.dd.mi.service.command.events.MIStoppedEvent; import org.eclipse.dd.mi.service.command.output.MIBreakInsertInfo; import org.eclipse.dd.mi.service.command.output.MIInfo; import org.eclipse.debug.core.DebugException; public class LaunchSequence extends Sequence { - public class EntryPointHitEventListener { - boolean fAborted = false; - boolean fFinished = false; - final RequestMonitor fRequestMonitor; - - EntryPointHitEventListener(RequestMonitor requestMonitor) { - fRequestMonitor = requestMonitor; - } - - @DsfServiceEventHandler - public void eventDispatched(MIStoppedEvent e) { - fFinished = true; - if (!fAborted) { - fSession.removeServiceEventListener(this); - fRequestMonitor.done(); - } - } - } - - Step[] fSteps = new Step[] { // Create and initialize the Connection service. new Step() { @@ -182,56 +158,41 @@ public class LaunchSequence extends Sequence { public void execute(final RequestMonitor requestMonitor) { if (!readStopAtMain(requestMonitor)) return; if (!fStopInMain) { - requestMonitor.done(); - return; - } + // Just start the program. + fCommandControl.queueCommand( + new MIExecRun((IContainerDMContext)fCommandControl.getControlDMContext(), new String[0]), + new DataRequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleOK() { + requestMonitor.done(); + } + } + ); + } else { + if (!readStopSymbol(requestMonitor)) return; - if (!readStopSymbol(requestMonitor)) return; - - // Create a listener to wait for the stopped event, and register as even handler. - // This handler will execute the requestMonitor. - final EntryPointHitEventListener entryPointHitListener = new EntryPointHitEventListener(requestMonitor); - fSession.addServiceEventListener(entryPointHitListener, null); - - // Create a time-out, to abort if breakpoint not hit. - fSession.getExecutor().schedule( - new Runnable() { public void run() { - // Only process the event if we have not finished yet (hit the breakpoint). - if (!entryPointHitListener.fFinished) { - // Mark the listener as aborted, and unregister it as event listener. - entryPointHitListener.fAborted = true; - fSession.removeServiceEventListener(entryPointHitListener); - - // Submit the error result for the step. - requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.TARGET_REQUEST_FAILED, "Timed out running to entry point.", null)); //$NON-NLS-1$ - requestMonitor.done(); - } - }}, - 60, TimeUnit.SECONDS); - - // Insert a breakpoint at the requested stop symbol. - fCommandControl.queueCommand( - new MIBreakInsert( - (IBreakpointsTargetDMContext)fCommandControl.getControlDMContext(), - true, false, null, 0, fStopSymbol, 0), - new DataRequestMonitor(getExecutor(), requestMonitor) { - @Override - protected void handleOK() { - - // After the break-insert is done, execute the -exec-run command. - fCommandControl.queueCommand( - new MIExecRun((IContainerDMContext)fCommandControl.getControlDMContext(), new String[0]), - new DataRequestMonitor(getExecutor(), requestMonitor) { - @Override - protected void handleOK() { - // Note : Do we not need to do something with the original requestMonitor? - // Do nothing. Execution was resumed and the EntryPointHitEventListener - // will resume execution - } - } - ); - } - }); + // Insert a breakpoint at the requested stop symbol. + fCommandControl.queueCommand( + new MIBreakInsert( + (IBreakpointsTargetDMContext)fCommandControl.getControlDMContext(), + true, false, null, 0, fStopSymbol, 0), + new DataRequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleOK() { + + // After the break-insert is done, execute the -exec-run command. + fCommandControl.queueCommand( + new MIExecRun((IContainerDMContext)fCommandControl.getControlDMContext(), new String[0]), + new DataRequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleOK() { + requestMonitor.done(); + } + } + ); + } + }); + } } }, }; From 2f616ee3bc7b96cad24f205845f0ed7b0f29f45b Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 20 Feb 2008 17:34:54 +0000 Subject: [PATCH 259/834] [219630] Fixed an NPE due to a null IStack service. --- .../dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java index 0a73e96939f..9ffd46cff9e 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java @@ -122,6 +122,8 @@ public class StackFramesVMNode extends AbstractDMVMNode try { getSession().getExecutor().execute(new DsfRunnable() { public void run() { + if (!checkService(IStack.class, null, update)) return; + getServicesTracker().getService(IStack.class).getTopFrame( execDmc, new DataRequestMonitor(getExecutor(), null) { From c58629c50879d95e58ef595e4241fee20fc4773a Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 21 Feb 2008 18:33:05 +0000 Subject: [PATCH 260/834] [219836] Fixed an exception and added some comments in modifyBreakpoints(). --- .../debug/service/BreakpointsMediator.java | 59 +++++++++++++++---- 1 file changed, 48 insertions(+), 11 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/BreakpointsMediator.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/BreakpointsMediator.java index c7982a28c8c..74ab060459c 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/BreakpointsMediator.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/BreakpointsMediator.java @@ -513,6 +513,15 @@ public class BreakpointsMediator extends AbstractDsfService implements IBreakpoi private void modifyBreakpoint(final IBreakpointsTargetDMContext context, final IBreakpoint breakpoint, final List> newAttrsList0, final IMarkerDelta oldValues, final RequestMonitor rm) { + // This method uses several lists to track the changed breakpoints: + // commonAttrsList - attributes which have not changed + // oldAttrsList - attributes for the breakpoint before the change + // newAttrsList - attributes for the breakpoint after the change + // oldBpContexts - target-side breakpoints from before the change + // newBpContexts - target-side breakpoints after the change + // attrDeltasList - changes in the attributes for each attribute map in + // oldAttrsList and newAttrsList + // Get the maps final Map>> platformBPs = fPlatformBPs.get(context); final Map> breakpointIDs = fBreakpointDMContexts.get(context); @@ -538,26 +547,43 @@ public class BreakpointsMediator extends AbstractDsfService implements IBreakpoi return; } - List> commonAttrsList = getCommonAttributeMaps(newAttrsList0, oldAttrsList0); + // Calculate the list of attributes maps that have not changed. + // Immediately add these to the list of new breakpoint contexts, + // and remove them from further breakpoint attribute comparisons. + final List> commonAttrsList = getCommonAttributeMaps(newAttrsList0, oldAttrsList0); final List newBpContexts = new ArrayList(commonAttrsList.size()); - List> newAttrsList = new ArrayList>(newAttrsList0); + final List> newAttrsList = new ArrayList>(newAttrsList0); newAttrsList.removeAll(commonAttrsList); List> oldAttrsList = new ArrayList>(oldAttrsList0); for (int i = 0; i < oldAttrsList.size(); i++) { if (commonAttrsList.contains(oldAttrsList.get(i))) { - newBpContexts.add(oldBpContexts.remove(i)); + if (oldBpContexts.size() > i) { + newBpContexts.add(oldBpContexts.remove(i)); + } } } + oldAttrsList.removeAll(commonAttrsList); - final List> attrDeltasArray = getAttributesDeltas(oldAttrsList, newAttrsList); + // Create a list of attribute changes. The lenghth of this list will + // always be max(oldAttrList.size(), newAttrsList.size()), padded with + // null's if oldAttrsList was longer. + final List> attrDeltasList = getAttributesDeltas(oldAttrsList, newAttrsList); + // Create the request monitor that will be called when all + // modifying/inserting/removing is complete. final CountingRequestMonitor countingRM = new CountingRequestMonitor(getExecutor(), rm) { @Override protected void handleCompleted() { + // Save the new list of breakpoint contexts and attributes breakpointIDs.put(breakpoint, newBpContexts); - // Update breakpoint status + newAttrsList.addAll(commonAttrsList); + platformBPs.put(breakpoint, newAttrsList); + + // Update breakpoint status. updateBreakpointStatus() cannot + // be called on the executor thread, so we need to + // use a Job. new Job("Breakpoint status update") { //$NON-NLS-1$ { setSystem(true); } @Override @@ -571,12 +597,18 @@ public class BreakpointsMediator extends AbstractDsfService implements IBreakpoi } }; - countingRM.setDoneCount(attrDeltasArray.size()); + // Set the count, if could be zero if no breakpoints have actually changed. + countingRM.setDoneCount(attrDeltasList.size()); - for (int i = 0; i < attrDeltasArray.size(); i++) { - if (attrDeltasArray.get(i) == null) { + // Process the changed breakpoints. + for (int i = 0; i < attrDeltasList.size(); i++) { + if (attrDeltasList.get(i) == null) { + // The list of new attribute maps was shorter than the old. + // Remove the corresponding target-side bp. fBreakpoints.removeBreakpoint(oldBpContexts.get(i), countingRM); } else if ( i >= oldBpContexts.size()) { + // The list of new attribute maps was longer, just insert + // the new breakpoint final Map attrs = newAttrsList.get(i); fBreakpoints.insertBreakpoint( context, attrs, @@ -587,7 +619,10 @@ public class BreakpointsMediator extends AbstractDsfService implements IBreakpoi countingRM.done(); } }); - } else if ( !fAttributeTranslator.canUpdateAttributes(oldBpContexts.get(i), attrDeltasArray.get(i)) ) { + } else if ( !fAttributeTranslator.canUpdateAttributes(oldBpContexts.get(i), attrDeltasList.get(i)) ) { + // The attribute translator tells us that the debugger cannot modify the + // breakpoint to change the given attributes. Remove the breakpoint + // and insert a new one. final Map attrs = newAttrsList.get(i); fBreakpoints.removeBreakpoint( oldBpContexts.get(i), @@ -606,9 +641,11 @@ public class BreakpointsMediator extends AbstractDsfService implements IBreakpoi } }); } else { + // The back end can modify the breakpoint. Update the breakpoint with the + // new attributes. final IBreakpointDMContext bpCtx = oldBpContexts.get(i); fBreakpoints.updateBreakpoint( - oldBpContexts.get(i), attrDeltasArray.get(i), + oldBpContexts.get(i), newAttrsList.get(i), new RequestMonitor(getExecutor(), countingRM) { @Override protected void handleOK() { @@ -623,7 +660,7 @@ public class BreakpointsMediator extends AbstractDsfService implements IBreakpoi private List> getCommonAttributeMaps(List> array1, List> array2) { List> intersection = new LinkedList>(); - List> list2 = new ArrayList>(array1); + List> list2 = new ArrayList>(array2); for (Map array1Map : array1) { if (list2.remove(array1Map)) { intersection.add(array1Map); From 6cd8e646a41035db50c50d2935e423e572260cd1 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 22 Feb 2008 00:27:02 +0000 Subject: [PATCH 261/834] Fixed a typo in a comment. --- .../src/org/eclipse/dd/dsf/datamodel/IDMService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMService.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMService.java index fc5d1f21be3..9ace7b66a43 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMService.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/datamodel/IDMService.java @@ -34,7 +34,7 @@ public interface IDMService extends IDsfService { * @param dmc Data Model Context for the data model data object to be retrieved. * @param rm Request completion monitor to be filled in with the Data Model Data. * - * @deprecated This method is not deprecated as there is no compile-time linking + * @deprecated This method is now deprecated as there is no compile-time linking * between IDMContext and IDMData objects (see bug 205132) */ @Deprecated From 0b291f4f12b61afa503a82d9dbfc9f438db7c824 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 22 Feb 2008 00:29:18 +0000 Subject: [PATCH 262/834] [219841] Added TODO comments regarding this bug. --- .../dd/dsf/debug/service/BreakpointsMediator.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/BreakpointsMediator.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/BreakpointsMediator.java index 74ab060459c..ee8b08bc760 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/BreakpointsMediator.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/BreakpointsMediator.java @@ -427,6 +427,9 @@ public class BreakpointsMediator extends AbstractDsfService implements IBreakpoi list = new LinkedList(); list.add(getData()); breakpointIDs.put(breakpoint, list); + } else { + // TODO (bug 219841): need to add breakpoint error status tracking + // in addition to fBreakpointDMContexts. } installRM.done(); } @@ -628,13 +631,18 @@ public class BreakpointsMediator extends AbstractDsfService implements IBreakpoi oldBpContexts.get(i), new RequestMonitor(getExecutor(), countingRM) { @Override - protected void handleOK() { + protected void handleCompleted() { fBreakpoints.insertBreakpoint( context, attrs, new DataRequestMonitor(getExecutor(), countingRM) { @Override - protected void handleOK() { - newBpContexts.add(getData()); + protected void handleCompleted() { + if (getStatus().isOK()) { + newBpContexts.add(getData()); + } else { + // TODO (bug 219841): need to add breakpoint error status tracking + // in addition to fBreakpointDMContexts. + } countingRM.done(); } }); From 2d3a869931035ad955a4cbfc80dd12e27a9c90ab Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 22 Feb 2008 00:31:41 +0000 Subject: [PATCH 263/834] [216854] Completed commenting and cleaning up the initial PDA debugger implementation. --- .../icons/full/dlcl16/pop.gif | Bin 159 -> 0 bytes .../icons/full/dlcl16/push.gif | Bin 361 -> 0 bytes .../icons/full/elcl16/pop.gif | Bin 163 -> 0 bytes .../icons/full/elcl16/push.gif | Bin 590 -> 0 bytes .../org.eclipse.dd.examples.pda.ui/plugin.xml | 24 -- .../dd/examples/pda/ui/PDAAdapterFactory.java | 68 +-- .../dd/examples/pda/ui/PDAUIPlugin.java | 74 +--- .../pda/ui/actions/DsfTerminateCommand.java | 95 ----- .../pda/ui/actions/PDATerminateCommand.java | 130 ++++++ .../ui/breakpoints/PDABreakpointAdapter.java | 7 +- .../breakpoints/PDAEditorAdapterFactory.java | 31 +- .../ui/breakpoints/PDARunToLineAdapter.java | 76 ---- .../pda/ui/editor/AnnotationHover.java | 9 +- .../ui/editor/PDAContentAssistProcessor.java | 7 +- .../pda/ui/editor/PDAContentAssistant.java | 3 +- .../dd/examples/pda/ui/editor/PDAEditor.java | 3 +- .../dd/examples/pda/ui/editor/PDAScanner.java | 3 +- .../editor/PDASourceViewerConfiguration.java | 3 +- .../pda/ui/editor/PopFrameActionDelegate.java | 4 +- .../dd/examples/pda/ui/editor/TextHover.java | 9 +- .../dd/examples/pda/ui/editor/WordFinder.java | 3 +- .../pda/ui/launcher/PDALaunchShortcut.java | 75 ---- .../examples/pda/ui/launcher/PDAMainTab.java | 7 +- .../examples/pda/ui/launcher/PDATabGroup.java | 7 +- .../ui/viewmodel/launch/LaunchVMProvider.java | 30 +- ...hreadVMNode.java => PDAProgramVMNode.java} | 182 ++++---- .../META-INF/MANIFEST.MF | 7 +- .../pdavm/docs/protocol.html | 2 +- .../org.eclipse.dd.examples.pda/plugin.xml | 4 +- .../eclipse/dd/examples/pda/PDAPlugin.java | 6 +- .../pda/breakpoints/PDALineBreakpoint.java | 7 +- .../breakpoints/PDARunToLineBreakpoint.java | 70 ---- .../pda/breakpoints/PDAWatchpoint.java | 7 +- .../dd/examples/pda/launch/PDALaunch.java | 99 ++++- .../pda/launch/PDALaunchDelegate.java | 42 +- .../pda/launch/PDAServicesInitSequence.java | 66 ++- .../launch/PDAServicesShutdownSequence.java | 182 ++++---- .../PDABreakpointAttributeTranslator.java | 32 +- .../examples/pda/service/PDABreakpoints.java | 395 ++++++++++++++++++ .../{command => }/PDACommandControl.java | 127 ++++-- .../examples/pda/service/PDAExpressions.java | 373 +++++++++++++++++ .../pda/service/PDAProgramDMContext.java | 87 ++++ .../examples/pda/service/PDARunControl.java | 317 ++++++++++++++ .../pda/service/{stack => }/PDAStack.java | 227 ++++++++-- .../{command => }/PDAStartedEvent.java | 8 +- .../{command => }/PDATerminatedEvent.java | 8 +- .../breakpoints/BreakpointDMContext.java | 48 --- .../service/breakpoints/PDABreakpoints.java | 264 ------------ .../breakpoints/WatchpointDMContext.java | 54 --- .../command/PDACommandControlDMContext.java | 45 -- .../command/commands/PDAVarCommandResult.java | 27 -- .../commands/AbstractPDACommand.java | 24 +- .../commands/PDAClearBreakpointCommand.java | 7 +- .../PDACommandResult.java | 6 +- .../commands/PDADataCommand.java | 7 +- .../commands/PDADataCommandResult.java | 12 +- .../commands/PDADropFrameCommand.java | 7 +- .../commands/PDAEvalCommand.java | 7 +- .../commands/PDAEventStopCommand.java | 7 +- .../commands/PDAExitCommand.java | 7 +- .../{command => }/commands/PDAFrame.java | 17 +- .../commands/PDAPopDataCommand.java | 7 +- .../commands/PDAPushDataCommand.java | 7 +- .../commands/PDAResumeCommand.java | 7 +- .../commands/PDASetBreakpointCommand.java | 7 +- .../commands/PDASetDataCommand.java | 7 +- .../commands/PDASetVarCommand.java | 11 +- .../commands/PDAStackCommand.java | 6 +- .../commands/PDAStackCommandResult.java | 7 +- .../commands/PDAStepCommand.java | 7 +- .../commands/PDAStepReturnCommand.java | 7 +- .../commands/PDASuspendCommand.java | 7 +- .../{command => }/commands/PDAVarCommand.java | 7 +- .../commands/PDAWatchCommand.java | 7 +- .../expressions/ExpressionDMContext.java | 48 --- .../service/expressions/ExpressionDMData.java | 61 --- .../InvalidExpressionDMContext.java | 48 --- .../service/expressions/PDAExpressions.java | 224 ---------- .../pda/service/runcontrol/ExecutionData.java | 24 -- .../pda/service/runcontrol/PDARunControl.java | 261 ------------ .../pda/service/runcontrol/ResumedEvent.java | 41 -- .../service/runcontrol/SuspendedEvent.java | 34 -- .../pda/service/stack/FrameDMContext.java | 46 -- .../pda/service/stack/FrameDMData.java | 47 --- .../pda/service/stack/VariableDMContext.java | 46 -- .../pda/service/stack/VariableDMData.java | 33 -- .../sourcelookup/PDASourceLookupDirector.java | 5 +- .../PDASourcePathComputerDelegate.java | 17 +- .../tests/pda/service/command/BasicTests.java | 4 +- .../command/CommandControlTestsBase.java | 8 +- .../pda/service/command/PDATestCommand.java | 8 +- 91 files changed, 2224 insertions(+), 2280 deletions(-) delete mode 100644 plugins/org.eclipse.dd.examples.pda.ui/icons/full/dlcl16/pop.gif delete mode 100644 plugins/org.eclipse.dd.examples.pda.ui/icons/full/dlcl16/push.gif delete mode 100644 plugins/org.eclipse.dd.examples.pda.ui/icons/full/elcl16/pop.gif delete mode 100644 plugins/org.eclipse.dd.examples.pda.ui/icons/full/elcl16/push.gif delete mode 100644 plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/actions/DsfTerminateCommand.java create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/actions/PDATerminateCommand.java delete mode 100644 plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/breakpoints/PDARunToLineAdapter.java delete mode 100644 plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/launcher/PDALaunchShortcut.java rename plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/{ThreadVMNode.java => PDAProgramVMNode.java} (53%) delete mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/breakpoints/PDARunToLineBreakpoint.java rename plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/{breakpoints => }/PDABreakpointAttributeTranslator.java (75%) create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpoints.java rename plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/{command => }/PDACommandControl.java (76%) create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAExpressions.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAProgramDMContext.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java rename plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/{stack => }/PDAStack.java (51%) rename plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/{command => }/PDAStartedEvent.java (74%) rename plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/{command => }/PDATerminatedEvent.java (74%) delete mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/breakpoints/BreakpointDMContext.java delete mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/breakpoints/PDABreakpoints.java delete mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/breakpoints/WatchpointDMContext.java delete mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommandControlDMContext.java delete mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAVarCommandResult.java rename plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/{command => }/commands/AbstractPDACommand.java (68%) rename plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/{command => }/commands/PDAClearBreakpointCommand.java (75%) rename plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/{command => commands}/PDACommandResult.java (84%) rename plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/{command => }/commands/PDADataCommand.java (77%) rename plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/{command => }/commands/PDADataCommandResult.java (77%) rename plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/{command => }/commands/PDADropFrameCommand.java (77%) rename plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/{command => }/commands/PDAEvalCommand.java (79%) rename plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/{command => }/commands/PDAEventStopCommand.java (80%) rename plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/{command => }/commands/PDAExitCommand.java (76%) rename plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/{command => }/commands/PDAFrame.java (89%) rename plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/{command => }/commands/PDAPopDataCommand.java (76%) rename plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/{command => }/commands/PDAPushDataCommand.java (76%) rename plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/{command => }/commands/PDAResumeCommand.java (76%) rename plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/{command => }/commands/PDASetBreakpointCommand.java (77%) rename plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/{command => }/commands/PDASetDataCommand.java (76%) rename plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/{command => }/commands/PDASetVarCommand.java (67%) rename plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/{command => }/commands/PDAStackCommand.java (82%) rename plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/{command => }/commands/PDAStackCommandResult.java (85%) rename plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/{command => }/commands/PDAStepCommand.java (77%) rename plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/{command => }/commands/PDAStepReturnCommand.java (77%) rename plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/{command => }/commands/PDASuspendCommand.java (76%) rename plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/{command => }/commands/PDAVarCommand.java (76%) rename plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/{command => }/commands/PDAWatchCommand.java (81%) delete mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/expressions/ExpressionDMContext.java delete mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/expressions/ExpressionDMData.java delete mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/expressions/InvalidExpressionDMContext.java delete mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/expressions/PDAExpressions.java delete mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/ExecutionData.java delete mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/PDARunControl.java delete mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/ResumedEvent.java delete mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/SuspendedEvent.java delete mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/FrameDMContext.java delete mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/FrameDMData.java delete mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/VariableDMContext.java delete mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/VariableDMData.java rename plugins/org.eclipse.dd.examples.pda/src/org/eclipse/{debug/examples/core => dd/examples}/pda/sourcelookup/PDASourceLookupDirector.java (85%) rename plugins/org.eclipse.dd.examples.pda/src/org/eclipse/{debug/examples/core => dd/examples}/pda/sourcelookup/PDASourcePathComputerDelegate.java (85%) diff --git a/plugins/org.eclipse.dd.examples.pda.ui/icons/full/dlcl16/pop.gif b/plugins/org.eclipse.dd.examples.pda.ui/icons/full/dlcl16/pop.gif deleted file mode 100644 index 559e462985f439553de36c89f65392eae3e9a44e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 159 zcmZ?wbhEHb6krfw*v!Ci=-|O)$BrF5cyQ02Jv(;n*t~i3x^?STu3Wif$&v*N7X1JJ zp8*vp{$ycfVBliV0SSZ5U|{hHIO(~1uSCNtU5#UEjBbj3ZUQY)yXJ8fa4;1Ld|~WA z@!)sI-4+*(HUmTFi3NKYgjzF96l>i0I}eMb=?0hv=!;iZy|UTOS9Ern3j>2S03Llh A4*&oF diff --git a/plugins/org.eclipse.dd.examples.pda.ui/icons/full/dlcl16/push.gif b/plugins/org.eclipse.dd.examples.pda.ui/icons/full/dlcl16/push.gif deleted file mode 100644 index f7e6cc089c226721a198a3ed515fd0626761db3a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 361 zcmZ?wbhEHb6krfwxXQrr`}dz;zkdJx`Rn`l9|sQ|UAJ-j*6q93uHU@>;L*=tzJ2=q z_0i*}*RJ2(wsYU9Gv^N+I=W{4=Jy{zU%h_w>$mUEp1(MJ9{K#~?WvPTH>{brY2AXgE9b0UKI_!+y^kMUdvNFCq5a#A9NhWh>D{-l zpDtTCb;aW8ySJ@AdSL6`9qYb-`*PvT(L)Ch{{8#+&!0d4|Nmzo1QdU=FfuThFzA33 zg8an5*5)v)z(Yr>ePhZSj~-7Io|BhWm{_diYu?0Zt*|eFBS)(zHSLATEa$#N2cyzi zv37g?K141)Fu!t|p_;O+vYNaRV`rzhr)FQjrXqI@E0a`%p00+jo)QD|f(6pShB_)b u+6=5!U(~$qz@e@b9PM>yUum%9b4zw!( diff --git a/plugins/org.eclipse.dd.examples.pda.ui/icons/full/elcl16/pop.gif b/plugins/org.eclipse.dd.examples.pda.ui/icons/full/elcl16/pop.gif deleted file mode 100644 index 2cd9c544436c47a57f20b348b3fb024bb50701a7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 163 zcmZ?wbhEHb6krfw*v!DNV#SID3l_|nF=N7n2^}3B4Gj$y6%_>q1sNF`2?+`R|Nmz| z1&Tje7#SG27<53wATtBYuHJj2L#xNM)vQ#JRl<>hDKU#-N&yE`p}?0M(Gw4T zcQCOfDoF5h^e6?|s2Q}nBw9^h7K$KQ28^82qz zvzLAT{^!PvAHV{+c)*@-qQ8==c6YNFZ_AC z^Y7>LoB9+t_A73mth#Hu+P2B6f1WM=`*!ENO0h+?5({f2mNiN(Ym#2mA$Mg*>hHVF zhgYTjc{t(nx`4yW;ttJnJT%wq!kUUJ8>)}aN<6o+?D(RhQ%g%Oud8}@|J1?RIY;K@ z@0*eR{8d*Rb6z9wC>*1tMmg_~C<+Ym>RXjlG!!%dz7u3SMkiFE} - - --> diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java index 46243cb2619..c519506f688 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java @@ -26,7 +26,7 @@ import org.eclipse.dd.dsf.debug.ui.sourcelookup.MISourceDisplayAdapter; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.examples.pda.PDAPlugin; import org.eclipse.dd.examples.pda.launch.PDALaunch; -import org.eclipse.dd.examples.pda.ui.actions.DsfTerminateCommand; +import org.eclipse.dd.examples.pda.ui.actions.PDATerminateCommand; import org.eclipse.dd.examples.pda.ui.viewmodel.PDAVMAdapter; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; @@ -45,47 +45,62 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactor import org.eclipse.debug.ui.sourcelookup.ISourceDisplay; /** - * This implementation of platform adapter factory only retrieves the adapters - * for the launch object. It also manages the creation and destruction - * of the session-based adapters which are returned by the - * IDMContext.getAdapter() methods. + * The adapter factory is the central point of control of view model and other + * UI adapters of a DSF-based debugger. As new launches are created and + * old ones removed, this factory manages the life cycle of the associated + * UI adapters. + *

    + * As a platform adapter factory, this factory only provides adapters for + * the launch object. Adapters for all other objects in the DSF model hierarchy + * are registered with the DSF session. + *

    */ @ThreadSafe @SuppressWarnings({"restriction"}) public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2 { + /** + * Contains the set of adapters that are created for eacy launch instance. + */ @Immutable - class LaunchAdapterSet { + private static class LaunchAdapterSet { + // View Model adapter final PDAVMAdapter fViewModelAdapter; + + // Source lookup and positioning adapter final MISourceDisplayAdapter fSourceDisplayAdapter; + + // Command adapters final DsfStepIntoCommand fStepIntoCommand; final DsfStepOverCommand fStepOverCommand; final DsfStepReturnCommand fStepReturnCommand; final DsfSuspendCommand fSuspendCommand; final DsfResumeCommand fResumeCommand; - final DsfTerminateCommand fTerminateCommand; + final PDATerminateCommand fTerminateCommand; + + // Adapters for integration with other UI actions final IDebugModelProvider fDebugModelProvider; final PDALaunch fLaunch; LaunchAdapterSet(PDALaunch launch) { + // Initialize launch and session. fLaunch = launch; DsfSession session = launch.getSession(); + // Initialize VM fViewModelAdapter = new PDAVMAdapter(session); - if (launch.getSourceLocator() instanceof ISourceLookupDirector) { - fSourceDisplayAdapter = new MISourceDisplayAdapter(session, (ISourceLookupDirector)launch.getSourceLocator()); - } else { - fSourceDisplayAdapter = null; - } + // Initialize source lookup + fSourceDisplayAdapter = new MISourceDisplayAdapter(session, (ISourceLookupDirector)launch.getSourceLocator()); session.registerModelAdapter(ISourceDisplay.class, fSourceDisplayAdapter); + // Initialize retargetable command handler. fStepIntoCommand = new DsfStepIntoCommand(session); fStepOverCommand = new DsfStepOverCommand(session); fStepReturnCommand = new DsfStepReturnCommand(session); fSuspendCommand = new DsfSuspendCommand(session); fResumeCommand = new DsfResumeCommand(session); - fTerminateCommand = new DsfTerminateCommand(session); + fTerminateCommand = new PDATerminateCommand(session); session.registerModelAdapter(IStepIntoHandler.class, fStepIntoCommand); session.registerModelAdapter(IStepOverHandler.class, fStepOverCommand); session.registerModelAdapter(IStepReturnHandler.class, fStepReturnCommand); @@ -93,19 +108,17 @@ public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2 session.registerModelAdapter(IResumeHandler.class, fResumeCommand); session.registerModelAdapter(ITerminateHandler.class, fTerminateCommand); + // Initialize debug model provider fDebugModelProvider = new IDebugModelProvider() { - // @see org.eclipse.debug.core.model.IDebugModelProvider#getModelIdentifiers() public String[] getModelIdentifiers() { return new String[] { PDAPlugin.ID_PDA_DEBUG_MODEL }; } }; session.registerModelAdapter(IDebugModelProvider.class, fDebugModelProvider); - /* - * Registering the launch as an adapter, ensures that this launch, - * and debug model ID will be associated with all DMContexts from this - * session. - */ + // Register the launch as an adapter This ensures that the launch, + // and debug model ID will be associated with all DMContexts from this + // session. session.registerModelAdapter(ILaunch.class, fLaunch); } @@ -139,10 +152,8 @@ public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2 DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this); } - /** - * This method only actually returns adapters for the launch object. - */ - @SuppressWarnings("unchecked") + // This IAdapterFactory method returns adapters for the PDA launch object only. + @SuppressWarnings("unchecked") // IAdapterFactory is Java 1.3 public Object getAdapter(Object adaptableObject, Class adapterType) { if (!(adaptableObject instanceof PDALaunch)) return null; @@ -167,20 +178,15 @@ public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2 else return null; } - /* (non-Javadoc) - * @see org.eclipse.core.runtime.IAdapterFactory#getAdapterList() - */ - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") // IAdapterFactory is Java 1.3 public Class[] getAdapterList() { return new Class[] { IElementContentProvider.class, IModelProxyFactory.class, IColumnPresentationFactory.class }; } - public void sessionEnded(DsfSession session) { - } - public void launchesRemoved(ILaunch[] launches) { // Dispose the set of adapters for a launch only after the launch is - // removed. + // removed from the view. If the launch is terminated, the adapters + // are still needed to populate the contents of the view. for (ILaunch launch : launches) { if (launch instanceof PDALaunch) { PDALaunch pdaLaunch = (PDALaunch)launch; diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAUIPlugin.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAUIPlugin.java index f44fc65f030..327d9a9a399 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAUIPlugin.java +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAUIPlugin.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 IBM Corporation and others. + * Copyright (c) 2005, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,16 +8,13 @@ * Contributors: * IBM Corporation - initial API and implementation * Bjorn Freeman-Benson - initial API and implementation + * Wind River Systems - adopted to use with DSF *******************************************************************************/ package org.eclipse.dd.examples.pda.ui; import java.net.URL; import java.util.HashMap; -import java.util.Iterator; import java.util.Map; -import java.util.MissingResourceException; -import java.util.ResourceBundle; -import java.util.Map.Entry; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.resource.ImageRegistry; @@ -32,29 +29,16 @@ import org.osgi.framework.BundleContext; * The main plugin class to be used in the desktop. */ public class PDAUIPlugin extends AbstractUIPlugin { + + public static String PLUGIN_ID = "org.eclipse.dd.examples.pda.ui "; + //The shared instance. private static PDAUIPlugin plugin; - //Resource bundle. - private ResourceBundle resourceBundle; private static BundleContext fContext; private final static String ICONS_PATH = "icons/full/";//$NON-NLS-1$ private final static String PATH_OBJECT = ICONS_PATH + "obj16/"; //Model object icons //$NON-NLS-1$ - private final static String PATH_ELOCALTOOL = ICONS_PATH + "elcl16/"; //Enabled local toolbar icons //$NON-NLS-1$ - private final static String PATH_DLOCALTOOL = ICONS_PATH + "dlcl16/"; //Disabled local toolbar icons //$NON-NLS-1$ - - /** - * Toolbar action to pop data stack - */ - public final static String IMG_ELCL_POP = "IMG_ELCL_POP"; - public final static String IMG_DLCL_POP = "IMG_DLCL_POP"; - - /** - * Toolbar action to push onto data stack - */ - public final static String IMG_ELCL_PUSH = "IMG_ELCL_PUSH"; - public final static String IMG_DLCL_PUSH = "IMG_DLCL_PUSH"; /** * PDA program image @@ -70,7 +54,7 @@ public class PDAUIPlugin extends AbstractUIPlugin { /** * Managed colors */ - private Map fColors = new HashMap(); + private Map fColors = new HashMap(); /** * The constructor. @@ -98,12 +82,9 @@ public class PDAUIPlugin extends AbstractUIPlugin { public void stop(BundleContext context) throws Exception { super.stop(context); plugin = null; - resourceBundle = null; fContext = null; - Iterator colors = fColors.entrySet().iterator(); - while (colors.hasNext()) { - Map.Entry entry = (Entry) colors.next(); - ((Color)entry.getValue()).dispose(); + for (Map.Entry entry : fColors.entrySet()) { + entry.getValue().dispose(); } } @@ -118,43 +99,8 @@ public class PDAUIPlugin extends AbstractUIPlugin { return fContext; } - - /** - * Returns the string from the plugin's resource bundle, - * or 'key' if not found. - */ - public static String getResourceString(String key) { - ResourceBundle bundle = PDAUIPlugin.getDefault().getResourceBundle(); - try { - return (bundle != null) ? bundle.getString(key) : key; - } catch (MissingResourceException e) { - return key; - } - } - - /** - * Returns the plugin's resource bundle, - */ - public ResourceBundle getResourceBundle() { - try { - if (resourceBundle == null) - resourceBundle = ResourceBundle.getBundle("org.eclipse.debug.examples.ui.pda.DebugUIPluginResources"); - } catch (MissingResourceException x) { - resourceBundle = null; - } - return resourceBundle; - } - - - /* (non-Javadoc) - * @see org.eclipse.ui.plugin.AbstractUIPlugin#initializeImageRegistry(org.eclipse.jface.resource.ImageRegistry) - */ protected void initializeImageRegistry(ImageRegistry reg) { declareImage(IMG_OBJ_PDA, PATH_OBJECT + "pda.gif"); - declareImage(IMG_ELCL_POP, PATH_ELOCALTOOL + "pop.gif"); - declareImage(IMG_DLCL_POP, PATH_DLOCALTOOL + "pop.gif"); - declareImage(IMG_ELCL_PUSH, PATH_ELOCALTOOL + "push.gif"); - declareImage(IMG_DLCL_PUSH, PATH_DLOCALTOOL + "push.gif"); } /** @@ -168,7 +114,7 @@ public class PDAUIPlugin extends AbstractUIPlugin { * false if this is not a shared image */ private void declareImage(String key, String path) { - URL url = BundleUtility.find("org.eclipse.debug.examples.ui", path); + URL url = BundleUtility.find("org.eclipse.dd.examples.pda.ui", path); ImageDescriptor desc = ImageDescriptor.createFromURL(url); getImageRegistry().put(key, desc); } @@ -180,7 +126,7 @@ public class PDAUIPlugin extends AbstractUIPlugin { * @return color */ public Color getColor(RGB rgb) { - Color color = (Color) fColors.get(rgb); + Color color = fColors.get(rgb); if (color == null) { color= new Color(Display.getCurrent(), rgb); fColors.put(rgb, color); diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/actions/DsfTerminateCommand.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/actions/DsfTerminateCommand.java deleted file mode 100644 index 720c4ec6fc4..00000000000 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/actions/DsfTerminateCommand.java +++ /dev/null @@ -1,95 +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.examples.pda.ui.actions; - -import org.eclipse.dd.dsf.concurrent.DsfExecutor; -import org.eclipse.dd.dsf.concurrent.DsfRunnable; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.datamodel.DMContexts; -import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; -import org.eclipse.dd.dsf.service.DsfServicesTracker; -import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext; -import org.eclipse.dd.examples.pda.service.command.PDACommandControl; -import org.eclipse.dd.examples.pda.ui.PDAUIPlugin; -import org.eclipse.debug.core.commands.IDebugCommandRequest; -import org.eclipse.debug.core.commands.IEnabledStateRequest; -import org.eclipse.debug.core.commands.ITerminateHandler; - -public class DsfTerminateCommand implements ITerminateHandler { - private final DsfExecutor fExecutor; - private final DsfServicesTracker fTracker; - - public DsfTerminateCommand(DsfSession session) { - fExecutor = session.getExecutor(); - fTracker = new DsfServicesTracker(PDAUIPlugin.getBundleContext(), session.getId()); - } - - public void dispose() { - fTracker.dispose(); - } - - // Run control may not be avilable after a connection is terminated and shut down. - public void canExecute(final IEnabledStateRequest request) { - if (request.getElements().length != 1 || - !(request.getElements()[0] instanceof IDMVMContext) ) - { - request.setEnabled(false); - request.done(); - return; - } - - // Javac doesn't like the cast to "(AbstractDMVMLayoutNode.DMVMContext)" need to use the - // construct below and suppress warnings. - IDMVMContext vmc = (IDMVMContext)request.getElements()[0]; - final IExecutionDMContext dmc = DMContexts.getAncestorOfType(vmc.getDMContext(), IExecutionDMContext.class); - if (dmc == null) { - request.setEnabled(false); - request.done(); - return; - } - - fExecutor.execute( - new DsfRunnable() { - public void run() { - // Get the processes service and the exec context. - PDACommandControl commandControl = fTracker.getService(PDACommandControl.class); - if (commandControl == null || dmc == null) { - // Context or service already invalid. - request.setEnabled(false); - request.done(); - } else { - // Check the terminate. - request.setEnabled(!commandControl.isTerminated()); - request.done(); - } - } - }); - } - - public boolean execute(final IDebugCommandRequest request) { - if (request.getElements().length != 1) { - request.done(); - return false; - } - - fExecutor.submit(new DsfRunnable() { - public void run() { - PDACommandControl commandControl = fTracker.getService(PDACommandControl.class); - if (commandControl != null) { - commandControl.shutdown(new RequestMonitor(fExecutor, null)); - } - } - }); - return false; - } - -} diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/actions/PDATerminateCommand.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/actions/PDATerminateCommand.java new file mode 100644 index 00000000000..cbfb60c4f75 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/actions/PDATerminateCommand.java @@ -0,0 +1,130 @@ +/******************************************************************************* + * Copyright (c) 2006, 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.ui.actions; + +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext; +import org.eclipse.dd.examples.pda.service.PDACommandControl; +import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; +import org.eclipse.dd.examples.pda.ui.PDAUIPlugin; +import org.eclipse.debug.core.commands.IDebugCommandRequest; +import org.eclipse.debug.core.commands.IEnabledStateRequest; +import org.eclipse.debug.core.commands.ITerminateHandler; + +/** + * The terminate command is specialized for the PDA debugger. Currently there + * is no standard interface for terminating a debug session in DSF, because the + * details of initiating and shutting down a debug session vary greatly in + * different debuggers. + */ +public class PDATerminateCommand implements ITerminateHandler { + // The executor and the services tracker, both initialized from a DSF session. + private final DsfSession fSession; + private final DsfServicesTracker fTracker; + + public PDATerminateCommand(DsfSession session) { + fSession = session; + fTracker = new DsfServicesTracker(PDAUIPlugin.getBundleContext(), session.getId()); + } + + public void dispose() { + // DSF services tracker always has to be disposed, because the OSGi services + // use reference counting. + fTracker.dispose(); + } + + // Run control may not be available after a connection is terminated and shut down. + public void canExecute(final IEnabledStateRequest request) { + // Terminate can only operate on a single element. + if (request.getElements().length != 1 || + !(request.getElements()[0] instanceof IDMVMContext) ) + { + request.setEnabled(false); + request.done(); + return; + } + + // Find the PDA program context in the selected element. If one is not found, + // the action should be disabled. + IDMVMContext vmc = (IDMVMContext)request.getElements()[0]; + final PDAProgramDMContext pdaProgramCtx = DMContexts.getAncestorOfType(vmc.getDMContext(), PDAProgramDMContext.class); + if (pdaProgramCtx == null) { + request.setEnabled(false); + request.done(); + return; + } + + try { + fSession.getExecutor().execute( + new DsfRunnable() { + public void run() { + // Get the processes service and the exec context. + PDACommandControl commandControl = fTracker.getService(PDACommandControl.class); + if (commandControl == null || pdaProgramCtx == null) { + // Context or service already invalid. + request.setEnabled(false); + request.done(); + } else { + // Check whether the control is terminated. + request.setEnabled(!commandControl.isTerminated()); + request.done(); + } + } + }); + } catch (RejectedExecutionException e) { + // The DSF session for this context is no longer active. It's possible to check + // for this condition before calling fSession.getExecutor().execute(), but + // since this method is executing in a different thread than the session control, + // there would still be a chance for a race condition leading to this exception. + request.setEnabled(false); + request.done(); + } + } + + public boolean execute(final IDebugCommandRequest request) { + // Skip the checks and assume that this method is called only if the action + // was enabled. + + try { + fSession.getExecutor().submit(new DsfRunnable() { + public void run() { + // If the command control service is available, attempt to terminate the program. + PDACommandControl commandControl = fTracker.getService(PDACommandControl.class); + if (commandControl != null) { + + commandControl.terminate( + new RequestMonitor(ImmediateExecutor.getInstance(), null) { + @Override + protected void handleCompleted() { + request.setStatus(getStatus()); + request.done(); + } + }); + } + } + }); + } catch (RejectedExecutionException e) { + request.setStatus(new Status(IStatus.ERROR, PDAUIPlugin.PLUGIN_ID, "PDA debug session is shut down.")); + request.done(); + } + return false; + } + +} diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/breakpoints/PDABreakpointAdapter.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/breakpoints/PDABreakpointAdapter.java index 006fbe1d6aa..f23551444b4 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/breakpoints/PDABreakpointAdapter.java +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/breakpoints/PDABreakpointAdapter.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 IBM Corporation and others. + * Copyright (c) 2005, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,6 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation * Bjorn Freeman-Benson - initial API and implementation + * Wind River Systems - adopted to use with DSF *******************************************************************************/ package org.eclipse.dd.examples.pda.ui.breakpoints; @@ -32,6 +33,10 @@ import org.eclipse.ui.texteditor.ITextEditor; /** * Adapter to create breakpoints in PDA files. + *

    + * This class is identical to the corresponding in PDA debugger implemented in + * org.eclipse.debug.examples.ui. + *

    */ public class PDABreakpointAdapter implements IToggleBreakpointsTargetExtension { /* (non-Javadoc) diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/breakpoints/PDAEditorAdapterFactory.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/breakpoints/PDAEditorAdapterFactory.java index 30d8c770a39..5065cadaa68 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/breakpoints/PDAEditorAdapterFactory.java +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/breakpoints/PDAEditorAdapterFactory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 IBM Corporation and others. + * Copyright (c) 2005, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,25 +8,28 @@ * Contributors: * IBM Corporation - initial API and implementation * Bjorn Freeman-Benson - initial API and implementation + * Wind River Systems - adopted to use with DSF *******************************************************************************/ package org.eclipse.dd.examples.pda.ui.breakpoints; - import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IAdapterFactory; import org.eclipse.dd.examples.pda.ui.editor.PDAEditor; -import org.eclipse.debug.ui.actions.IRunToLineTarget; import org.eclipse.debug.ui.actions.IToggleBreakpointsTarget; import org.eclipse.ui.texteditor.ITextEditor; + /** * Creates a toggle breakpoint adapter + *

    + * This class is identical to the corresponding in PDA debugger implemented in + * org.eclipse.debug.examples.ui. + *

    */ public class PDAEditorAdapterFactory implements IAdapterFactory { - /* (non-Javadoc) - * @see org.eclipse.core.runtime.IAdapterFactory#getAdapter(java.lang.Object, java.lang.Class) - */ - public Object getAdapter(Object adaptableObject, Class adapterType) { + + @SuppressWarnings("unchecked") // IAdapterFactory is Java 1.3 + public Object getAdapter(Object adaptableObject, Class adapterType) { if (adaptableObject instanceof PDAEditor) { ITextEditor editorPart = (ITextEditor) adaptableObject; IResource resource = (IResource) editorPart.getEditorInput().getAdapter(IResource.class); @@ -36,22 +39,14 @@ public class PDAEditorAdapterFactory implements IAdapterFactory { if (adapterType.equals(IToggleBreakpointsTarget.class)) { return new PDABreakpointAdapter(); } - //#ifdef ex7 -//# // TODO: Exercise 7 - create run to line adapter - //#else - if (adapterType.equals(IRunToLineTarget.class)) { - return new PDARunToLineAdapter(); - } - //#endif } } } return null; } - /* (non-Javadoc) - * @see org.eclipse.core.runtime.IAdapterFactory#getAdapterList() - */ - public Class[] getAdapterList() { + + @SuppressWarnings("unchecked") // IAdapterFactory is Java 1.3 + public Class[] getAdapterList() { return new Class[]{IToggleBreakpointsTarget.class}; } } diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/breakpoints/PDARunToLineAdapter.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/breakpoints/PDARunToLineAdapter.java deleted file mode 100644 index e73fbeeedab..00000000000 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/breakpoints/PDARunToLineAdapter.java +++ /dev/null @@ -1,76 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2007 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - * Bjorn Freeman-Benson - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.examples.pda.ui.breakpoints; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.dd.examples.pda.PDAPlugin; -import org.eclipse.dd.examples.pda.breakpoints.PDARunToLineBreakpoint; -import org.eclipse.debug.core.model.IBreakpoint; -import org.eclipse.debug.core.model.IDebugElement; -import org.eclipse.debug.core.model.IDebugTarget; -import org.eclipse.debug.core.model.ISuspendResume; -import org.eclipse.debug.ui.actions.IRunToLineTarget; -import org.eclipse.debug.ui.actions.RunToLineHandler; -import org.eclipse.jface.text.ITextSelection; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.texteditor.ITextEditor; - - -/** - * Run to line target for the Java debugger - */ -public class PDARunToLineAdapter implements IRunToLineTarget { - - /* (non-Javadoc) - * @see org.eclipse.debug.ui.actions.IRunToLineTarget#runToLine(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection, org.eclipse.debug.core.model.ISuspendResume) - */ - public void runToLine(IWorkbenchPart part, ISelection selection, ISuspendResume target) throws CoreException { - IEditorPart editorPart = (IEditorPart)part; - ITextEditor textEditor = (ITextEditor)editorPart; - ITextSelection textSelection = (ITextSelection) selection; - int lineNumber = textSelection.getStartLine() + 1; - if (lineNumber > 0) { - if (target instanceof IAdaptable) { - IDebugTarget debugTarget = (IDebugTarget) ((IAdaptable)target).getAdapter(IDebugTarget.class); - if (debugTarget != null) { - //#ifdef ex7 -//# // TODO: Exercise 7 - perform the run-to-line with a run-to-line breakpoint and handler - //#else - IFile resource = (IFile) textEditor.getEditorInput().getAdapter(IResource.class); - IBreakpoint breakpoint= new PDARunToLineBreakpoint(resource, lineNumber); - RunToLineHandler handler = new RunToLineHandler(debugTarget, target, breakpoint); - handler.run(new NullProgressMonitor()); - //#endif - } - } - } - } - - /* (non-Javadoc) - * @see org.eclipse.debug.ui.actions.IRunToLineTarget#canRunToLine(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection, org.eclipse.debug.core.model.ISuspendResume) - */ - public boolean canRunToLine(IWorkbenchPart part, ISelection selection, ISuspendResume target) { - //#ifdef ex7 -//# // TODO: Exercise 7 - ensure the target is a PDA target -//# return false; - //#else - return target instanceof IDebugElement && - ((IDebugElement)target).getModelIdentifier().equals(PDAPlugin.ID_PDA_DEBUG_MODEL); - //#endif - } -} diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/AnnotationHover.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/AnnotationHover.java index 0e76a9ca3f7..c06509aeac4 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/AnnotationHover.java +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/AnnotationHover.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 IBM Corporation and others. + * Copyright (c) 2005, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,6 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation * Bjorn Freeman-Benson - initial API and implementation + * Wind River Systems - adopted to use with DSF *******************************************************************************/ package org.eclipse.dd.examples.pda.ui.editor; @@ -22,12 +23,16 @@ import org.eclipse.jface.text.source.ISourceViewer; /** * Returns hover for breakpoints. + *

    + * This class is identical to the corresponding in PDA debugger implemented in + * org.eclipse.debug.examples.ui. + *

    */ public class AnnotationHover implements IAnnotationHover { public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) { IAnnotationModel annotationModel = sourceViewer.getAnnotationModel(); - Iterator iterator = annotationModel.getAnnotationIterator(); + Iterator iterator = annotationModel.getAnnotationIterator(); while (iterator.hasNext()) { Annotation annotation = (Annotation) iterator.next(); Position position = annotationModel.getPosition(annotation); diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAContentAssistProcessor.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAContentAssistProcessor.java index 93519ba4680..795b8dd05a0 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAContentAssistProcessor.java +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAContentAssistProcessor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 IBM Corporation and others. + * Copyright (c) 2005, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,6 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation * Bjorn Freeman-Benson - initial API and implementation + * Wind River Systems - adopted to use with DSF *******************************************************************************/ package org.eclipse.dd.examples.pda.ui.editor; @@ -41,7 +42,7 @@ public class PDAContentAssistProcessor implements IContentAssistProcessor { } } - List proposals = new ArrayList(); + List proposals = new ArrayList(); String[] keywords = PDAScanner.fgKeywords; if (prefix.length() > 0) { String word = prefix.toString(); @@ -59,7 +60,7 @@ public class PDAContentAssistProcessor implements IContentAssistProcessor { } } if (!proposals.isEmpty()) { - return (ICompletionProposal[]) proposals.toArray(new ICompletionProposal[proposals.size()]); + return proposals.toArray(new ICompletionProposal[proposals.size()]); } return null; } diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAContentAssistant.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAContentAssistant.java index 00d991204b5..287d302127c 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAContentAssistant.java +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAContentAssistant.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 IBM Corporation and others. + * Copyright (c) 2005, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,6 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation * Bjorn Freeman-Benson - initial API and implementation + * Wind River Systems - adopted to use with DSF *******************************************************************************/ package org.eclipse.dd.examples.pda.ui.editor; diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAEditor.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAEditor.java index c40a80b516c..3b8fe43d794 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAEditor.java +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAEditor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 IBM Corporation and others. + * Copyright (c) 2005, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,6 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation * Bjorn Freeman-Benson - initial API and implementation + * Wind River Systems - adopted to use with DSF *******************************************************************************/ package org.eclipse.dd.examples.pda.ui.editor; diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAScanner.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAScanner.java index b1b1e067893..87a149f0c10 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAScanner.java +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDAScanner.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 IBM Corporation and others. + * Copyright (c) 2005, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,6 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation * Bjorn Freeman-Benson - initial API and implementation + * Wind River Systems - adopted to use with DSF *******************************************************************************/ package org.eclipse.dd.examples.pda.ui.editor; diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDASourceViewerConfiguration.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDASourceViewerConfiguration.java index f0b873eac44..bf0185e26bd 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDASourceViewerConfiguration.java +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PDASourceViewerConfiguration.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 IBM Corporation and others. + * Copyright (c) 2005, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,6 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation * Bjorn Freeman-Benson - initial API and implementation + * Wind River Systems - adopted to use with DSF *******************************************************************************/ package org.eclipse.dd.examples.pda.ui.editor; diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PopFrameActionDelegate.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PopFrameActionDelegate.java index d9250db2bb4..1b9dee198a1 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PopFrameActionDelegate.java +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/PopFrameActionDelegate.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 IBM Corporation and others. + * Copyright (c) 2005, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,10 +8,10 @@ * Contributors: * IBM Corporation - initial API and implementation * Bjorn Freeman-Benson - initial API and implementation + * Wind River Systems - adopted to use with DSF *******************************************************************************/ package org.eclipse.dd.examples.pda.ui.editor; -import org.eclipse.debug.core.DebugException; import org.eclipse.jface.action.IAction; import org.eclipse.jface.viewers.ISelection; import org.eclipse.swt.widgets.Event; diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/TextHover.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/TextHover.java index 5874463e207..846a45d417f 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/TextHover.java +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/TextHover.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 IBM Corporation and others. + * Copyright (c) 2005, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,15 +8,10 @@ * Contributors: * IBM Corporation - initial API and implementation * Bjorn Freeman-Benson - initial API and implementation + * Wind River Systems - adopted to use with DSF *******************************************************************************/ package org.eclipse.dd.examples.pda.ui.editor; -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.debug.core.DebugException; -import org.eclipse.debug.core.model.IThread; -import org.eclipse.debug.core.model.IVariable; -import org.eclipse.debug.ui.DebugUITools; -import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.ITextHover; import org.eclipse.jface.text.ITextViewer; diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/WordFinder.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/WordFinder.java index 12cd611be11..e369e3be8c5 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/WordFinder.java +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/editor/WordFinder.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 IBM Corporation and others. + * Copyright (c) 2005, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,6 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation * Bjorn Freeman-Benson - initial API and implementation + * Wind River Systems - adopted to use with DSF *******************************************************************************/ package org.eclipse.dd.examples.pda.ui.editor; diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/launcher/PDALaunchShortcut.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/launcher/PDALaunchShortcut.java deleted file mode 100644 index 2e295858be8..00000000000 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/launcher/PDALaunchShortcut.java +++ /dev/null @@ -1,75 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2007 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - * Bjorn Freeman-Benson - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.examples.pda.ui.launcher; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.dd.examples.pda.PDAPlugin; -import org.eclipse.debug.core.DebugPlugin; -import org.eclipse.debug.core.ILaunchConfiguration; -import org.eclipse.debug.core.ILaunchConfigurationType; -import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; -import org.eclipse.debug.core.ILaunchManager; -import org.eclipse.debug.ui.DebugUITools; -import org.eclipse.debug.ui.ILaunchShortcut; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.ui.IEditorPart; - - -/** - * Launches a PDA file - */ -public class PDALaunchShortcut implements ILaunchShortcut { - - /* (non-Javadoc) - * @see org.eclipse.debug.ui.ILaunchShortcut#launch(org.eclipse.jface.viewers.ISelection, java.lang.String) - */ - public void launch(ISelection selection, String mode) { - // must be a structured selection with one file selected - IFile file = (IFile) ((IStructuredSelection)selection).getFirstElement(); - - // check for an existing launch config for the pda file - String path = file.getFullPath().toString(); - ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager(); - ILaunchConfigurationType type = launchManager.getLaunchConfigurationType(PDAPlugin.ID_PDA_LAUNCH_CONFIGURATION_TYPE); - try { - ILaunchConfiguration[] configurations = launchManager.getLaunchConfigurations(type); - for (int i = 0; i < configurations.length; i++) { - ILaunchConfiguration configuration = configurations[i]; - String attribute = configuration.getAttribute(PDAPlugin.ATTR_PDA_PROGRAM, (String)null); - if (path.equals(attribute)) { - DebugUITools.launch(configuration, mode); - return; - } - } - } catch (CoreException e) { - return; - } - - try { - // create a new configuration for the pda file - ILaunchConfigurationWorkingCopy workingCopy = type.newInstance(null, file.getName()); - workingCopy.setAttribute(PDAPlugin.ATTR_PDA_PROGRAM, path); - ILaunchConfiguration configuration = workingCopy.doSave(); - DebugUITools.launch(configuration, mode); - } catch (CoreException e1) { - } - } - - /* (non-Javadoc) - * @see org.eclipse.debug.ui.ILaunchShortcut#launch(org.eclipse.ui.IEditorPart, java.lang.String) - */ - public void launch(IEditorPart editor, String mode) { - } - -} diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/launcher/PDAMainTab.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/launcher/PDAMainTab.java index 2770df962da..7b9a894abd9 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/launcher/PDAMainTab.java +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/launcher/PDAMainTab.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 IBM Corporation and others. + * Copyright (c) 2005, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,6 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation * Bjorn Freeman-Benson - initial API and implementation + * Wind River Systems - adopted to use with DSF *******************************************************************************/ package org.eclipse.dd.examples.pda.ui.launcher; @@ -42,6 +43,10 @@ import org.eclipse.ui.dialogs.ResourceListSelectionDialog; /** * Tab to specify the PDA program to run/debug. + *

    + * This class is identical to the corresponding in PDA debugger implemented in + * org.eclipse.debug.examples.ui. + *

    */ public class PDAMainTab extends AbstractLaunchConfigurationTab { diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/launcher/PDATabGroup.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/launcher/PDATabGroup.java index 5df54b6f66d..af66ec6a5d4 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/launcher/PDATabGroup.java +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/launcher/PDATabGroup.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 IBM Corporation and others. + * Copyright (c) 2005, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,6 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation * Bjorn Freeman-Benson - initial API and implementation + * Wind River Systems - adopted to use with DSF *******************************************************************************/ package org.eclipse.dd.examples.pda.ui.launcher; @@ -19,6 +20,10 @@ import org.eclipse.debug.ui.sourcelookup.SourceLookupTab; /** * Tab group for a PDA application + *

    + * This class is identical to the corresponding in PDA debugger implemented in + * org.eclipse.debug.examples.ui. + *

    */ public class PDATabGroup extends AbstractLaunchConfigurationTabGroup { /* (non-Javadoc) diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/LaunchVMProvider.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/LaunchVMProvider.java index 2990aa9d968..3cbd4c36cef 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/LaunchVMProvider.java +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/LaunchVMProvider.java @@ -32,7 +32,15 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationCont /** - * + * View Model provider for the Launch (AKA Debug) view. The PDA debugger is + * single-threaded, so there is no need for a debug target element to be visible + * in the debug view. Therefore the launch VM provider is configured with three nodes: + *
      + *
    • LaunchRootVMNode - This is the root of the PDA view model.
    • + *
    • ThreadVMNode - Supplies the PDA program element.
    • + *
    • StackFramesVMNode - Supplies the stack frame elements.
    • + *
    • StandardProcessVMNode - Supplies elements representing the PDA debugger process.
    • + *
    */ @SuppressWarnings("restriction") public class LaunchVMProvider extends AbstractDMVMProvider @@ -46,15 +54,17 @@ public class LaunchVMProvider extends AbstractDMVMProvider IRootVMNode launchNode = new LaunchRootVMNode(this); setRootNode(launchNode); - // Container node to contain all processes and threads - IVMNode threadsNode = new ThreadVMNode(this, getSession()); + // Launch node is a parent to the processes and program nodes. + IVMNode threadsNode = new PDAProgramVMNode(this, getSession()); IVMNode processesNode = new StandardProcessVMNode(this); addChildNodes(launchNode, new IVMNode[] { threadsNode, processesNode}); + // Stack frames node is under the PDA program node. IVMNode stackFramesNode = new StackFramesVMNode(this, getSession()); addChildNodes(threadsNode, new IVMNode[] { stackFramesNode }); - + // Register the LaunchVM provider as a listener to debug and launch + // events. These events are used by the launch and processes nodes. DebugPlugin.getDefault().addDebugEventListener(this); DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this); } @@ -63,8 +73,8 @@ public class LaunchVMProvider extends AbstractDMVMProvider public void handleDebugEvents(final DebugEvent[] events) { if (isDisposed()) return; - // We're in session's executor thread. Re-dispach to VM Adapter - // executor thread and then call root layout node. + // This method may be called on any thread. Switch to the + // view model executor thread before processing. try { getExecutor().execute(new Runnable() { public void run() { @@ -75,7 +85,7 @@ public class LaunchVMProvider extends AbstractDMVMProvider } }}); } catch (RejectedExecutionException e) { - // Ignore. This exception could be thrown if the provider is being + // Ignore. This exception could be thrown if the view model is being // shut down. } } @@ -106,8 +116,8 @@ public class LaunchVMProvider extends AbstractDMVMProvider private void handleLaunchesEvent(final LaunchesEvent event) { if (isDisposed()) return; - // We're in session's executor thread. Re-dispach to VM Adapter - // executor thread and then call root layout node. + // This method also may be called on any thread. Switch to the + // view model executor thread before processing. try { getExecutor().execute(new Runnable() { public void run() { @@ -119,7 +129,7 @@ public class LaunchVMProvider extends AbstractDMVMProvider } }}); } catch (RejectedExecutionException e) { - // Ignore. This exception could be thrown if the provider is being + // Ignore. This exception could be thrown if the view model is being // shut down. } } diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/ThreadVMNode.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDAProgramVMNode.java similarity index 53% rename from plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/ThreadVMNode.java rename to plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDAProgramVMNode.java index a044c1e09a6..16b27393312 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/ThreadVMNode.java +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDAProgramVMNode.java @@ -17,12 +17,10 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMEvent; import org.eclipse.dd.dsf.debug.service.IRunControl; -import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerResumedDMEvent; -import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerSuspendedDMEvent; import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMData; import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent; @@ -36,8 +34,9 @@ import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMNode; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; import org.eclipse.dd.examples.pda.PDAPlugin; import org.eclipse.dd.examples.pda.launch.PDALaunch; -import org.eclipse.dd.examples.pda.service.command.PDACommandControl; -import org.eclipse.dd.examples.pda.service.command.PDAStartedEvent; +import org.eclipse.dd.examples.pda.service.PDACommandControl; +import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; +import org.eclipse.dd.examples.pda.service.PDAStartedEvent; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; @@ -50,20 +49,32 @@ import org.eclipse.debug.ui.DebugUITools; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.jface.viewers.TreePath; - +/** + * View Model node representing a PDA program. + */ @SuppressWarnings("restriction") -public class ThreadVMNode extends AbstractDMVMNode +public class PDAProgramVMNode extends AbstractDMVMNode implements IElementLabelProvider { - private class TerminatedThreadVMContext extends AbstractVMContext { - TerminatedThreadVMContext(IVMAdapter adapter, IVMNode node) { + // View model context representing a terminated PDA program. + // It's purpose is to show a terminated program in the debug view + // even after the DSF session is terminated. + // + // Note: this context does not implement the IDMVMContext + // interfaces, as it does not use an IDMContext as its root. + // + // To implement comparison methods, this contexts uses the + // VM node object, such that two terminated program contexts + // from the same instance of VM node will be equal. + private static class TerminatedProgramVMContext extends AbstractVMContext { + TerminatedProgramVMContext(IVMAdapter adapter, IVMNode node) { super(adapter, node); } @Override public boolean equals(Object obj) { - if (obj instanceof TerminatedThreadVMContext) { - TerminatedThreadVMContext context = (TerminatedThreadVMContext)obj; + if (obj instanceof TerminatedProgramVMContext) { + TerminatedProgramVMContext context = (TerminatedProgramVMContext)obj; return getVMNode().equals(context.getVMNode()); } return false; @@ -75,14 +86,17 @@ public class ThreadVMNode extends AbstractDMVMNode } } - public ThreadVMNode(AbstractDMVMProvider provider, DsfSession session) { + public PDAProgramVMNode(AbstractDMVMProvider provider, DsfSession session) { super(provider, session, IExecutionDMContext.class); } @Override public void update(IHasChildrenUpdate[] updates) { for (IHasChildrenUpdate update : updates) { - update.setHasChilren(true); + // Check if the launch is initialized. PDA program element should + // be shown only if the launch has completed initializing. + PDALaunch launch = findLaunchInPath(update.getElementPath()); + update.setHasChilren(launch != null && launch.isInitialized()); update.done(); } } @@ -90,7 +104,14 @@ public class ThreadVMNode extends AbstractDMVMNode @Override public void update(IChildrenCountUpdate[] updates) { for (IChildrenCountUpdate update : updates) { - update.setChildCount(1); + // Check if the launch is initialized. PDA program element should + // be shown only if the launch has completed initializing. + PDALaunch launch = findLaunchInPath(update.getElementPath()); + if (launch != null && launch.isInitialized()) { + update.setChildCount(1); + } else { + update.setChildCount(0); + } update.done(); } } @@ -100,10 +121,9 @@ public class ThreadVMNode extends AbstractDMVMNode for (IChildrenUpdate update : updates) { PDALaunch launch = findLaunchInPath(update.getElementPath()); if (launch != null && launch.isInitialized() && launch.isShutDown()) { - // If the debug session has been shut down. We cannot retrieve the - // DM context representing the thread. Instead add a dummy - // "terminated" PDA thread. - update.setChild(new TerminatedThreadVMContext(getVMProvider().getVMAdapter(), this), 0); + // If the debug session has been shut down, add a dummy + // VM context representing the PDA thread. + update.setChild(new TerminatedProgramVMContext(getVMProvider().getVMAdapter(), this), 0); update.done(); } else { super.update(new IChildrenUpdate[] { update }); @@ -113,24 +133,36 @@ public class ThreadVMNode extends AbstractDMVMNode @Override protected void updateElementsInSessionThread(final IChildrenUpdate update) { + // Check if service is still available. checkService() is a convenience + // method that marks the update as failed if the needed service is not + // available. if (!checkService(PDACommandControl.class, null, update)) return; + + // Get the instance of the service. Note that there is no race condition + // in getting the service since this method is called only in the + // service executor thred. final PDACommandControl commandControl = getServicesTracker().getService(PDACommandControl.class); - update.setChild(createVMContext(commandControl.getDMContext()), 0); + update.setChild(createVMContext(commandControl.getProgramDMContext()), 0); update.done(); } public void update(final ILabelUpdate[] updates) { for (final ILabelUpdate update : updates) { - if (update.getElement() instanceof TerminatedThreadVMContext) { + if (update.getElement() instanceof TerminatedProgramVMContext) { + // If the element is a terminated program, update the label + // in the View Model thread. updateTerminatedThreadLabel(update); } else { + // If the element is the PDA Program context, try to switch + // to the DSF session thread before updating the label. try { getSession().getExecutor().execute(new DsfRunnable() { public void run() { - updateActiveThreadLabelInSessionThread(update); + updateProgramLabelInSessionThread(update); }}); } catch (RejectedExecutionException e) { + // Acceptable race condition: DSF session terminated. handleFailedUpdate(update); } } @@ -138,53 +170,62 @@ public class ThreadVMNode extends AbstractDMVMNode } @ConfinedToDsfExecutor("getSession().getExecutor()") - private void updateActiveThreadLabelInSessionThread(final ILabelUpdate update) { + private void updateProgramLabelInSessionThread(final ILabelUpdate update) { + // Get a reference to the run control service. if (!checkService(IRunControl.class, null, update)) return; final IRunControl runControl = getServicesTracker().getService(IRunControl.class); - final IExecutionDMContext dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IExecutionDMContext.class); + // Find the PDA program context. + final PDAProgramDMContext programCtx = + findDmcInPath(update.getViewerInput(), update.getElementPath(), PDAProgramDMContext.class); + // Call service to get current program state + final boolean isSuspended = runControl.isSuspended(programCtx); + + // Set the program icon based on the running state of the program. String imageKey = null; - if (getServicesTracker().getService(IRunControl.class).isSuspended(dmc)) { + if (isSuspended) { imageKey = IDebugUIConstants.IMG_OBJS_THREAD_SUSPENDED; } else { imageKey = IDebugUIConstants.IMG_OBJS_THREAD_RUNNING; } update.setImageDescriptor(DebugUITools.getImageDescriptor(imageKey), 0); - final boolean isSuspended = runControl.isSuspended(dmc); - - // Find the Reason for the State - runControl.getExecutionData(dmc, - new DataRequestMonitor(getSession().getExecutor(), null) { - @Override - public void handleCompleted(){ - if (!getStatus().isOK()) { - handleFailedUpdate(update); - return; + // Retrieve the last state chagne reason + runControl.getExecutionData( + programCtx, + new DataRequestMonitor(ImmediateExecutor.getInstance(), null) + { + @Override + public void handleCompleted(){ + // If the request failed, fail the udpate. + if (!getStatus().isOK()) { + handleFailedUpdate(update); + return; + } + + // Compose the thread name string. + final StringBuilder builder = new StringBuilder(); + + builder.append("PDA ["); + builder.append(programCtx.getProgram()); + builder.append("]"); + + if(isSuspended) { + builder.append(" (Suspended"); + } else { + builder.append(" (Running"); + } + // Reason will be null before ContainerSuspendEvent is fired + if(getData().getStateChangeReason() != null) { + builder.append(" : "); + builder.append(getData().getStateChangeReason()); + } + builder.append(")"); + update.setLabel(builder.toString(), 0); + update.done(); } - - final StringBuilder builder = new StringBuilder(); - - builder.append("PDA ["); - builder.append(getProgramName(update)); - builder.append("]"); - - if(isSuspended) { - builder.append(" (Suspended"); - } else { - builder.append(" (Running"); - } - // Reason will be null before ContainerSuspendEvent is fired - if(getData().getStateChangeReason() != null) { - builder.append(" : "); - builder.append(getData().getStateChangeReason()); - } - builder.append(")"); - update.setLabel(builder.toString(), 0); - update.done(); - } - }); + }); } private void updateTerminatedThreadLabel(ILabelUpdate update) { @@ -194,6 +235,7 @@ public class ThreadVMNode extends AbstractDMVMNode } private String getProgramName(IViewerUpdate update) { + // Retrieve the program name from the launch object in the update path. String program = "unknown program"; ILaunch launch = findLaunchInPath(update.getElementPath()); if (launch != null) { @@ -214,33 +256,29 @@ public class ThreadVMNode extends AbstractDMVMNode } return null; } - + public int getDeltaFlags(Object e) { if(e instanceof IResumedDMEvent || e instanceof ISuspendedDMEvent) { - return IModelDelta.CONTENT; + return IModelDelta.STATE; } if (e instanceof PDAStartedEvent) { - return IModelDelta.EXPAND; + return IModelDelta.EXPAND | IModelDelta.SELECT; } return IModelDelta.NO_CHANGE; } public void buildDelta(Object e, VMDelta parentDelta, int nodeOffset, RequestMonitor rm) { - if(e instanceof IContainerResumedDMEvent) { - IDMContext triggeringContext = ((IContainerResumedDMEvent)e).getTriggeringContext(); - if (triggeringContext != null) { - parentDelta.addNode(createVMContext(triggeringContext), IModelDelta.CONTENT); - } - } else if (e instanceof IContainerSuspendedDMEvent) { - IDMContext triggeringContext = ((IContainerSuspendedDMEvent)e).getTriggeringContext(); - if (triggeringContext != null) { - parentDelta.addNode(createVMContext(triggeringContext), IModelDelta.CONTENT); - } - } else if(e instanceof IResumedDMEvent || e instanceof ISuspendedDMEvent) { - parentDelta.addNode(createVMContext(((IDMEvent)e).getDMContext()), IModelDelta.CONTENT); + if(e instanceof IResumedDMEvent || e instanceof ISuspendedDMEvent) { + // If a suspended/resumed event is received, just update the + // state of the program. StackFramesVMNode will take care of + // refreshing the stack frames. + parentDelta.addNode(createVMContext(((IDMEvent)e).getDMContext()), IModelDelta.STATE); } if (e instanceof PDAStartedEvent) { - parentDelta.addNode(createVMContext(((PDAStartedEvent)e).getDMContext()), IModelDelta.EXPAND); + // When debug session is started expand and select the program. + // If the program hits a breakpoint, the top stack frame will then + // be selected. + parentDelta.addNode(createVMContext(((PDAStartedEvent)e).getDMContext()), IModelDelta.EXPAND | IModelDelta.SELECT); } rm.done(); } diff --git a/plugins/org.eclipse.dd.examples.pda/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.examples.pda/META-INF/MANIFEST.MF index b3991100053..acf1d2ccb0e 100644 --- a/plugins/org.eclipse.dd.examples.pda/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.examples.pda/META-INF/MANIFEST.MF @@ -12,10 +12,11 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.dd.dsf.debug;bundle-version="1.0.0", org.junit4;bundle-version="4.3.1", org.eclipse.cdt.core;bundle-version="5.0.0" -Eclipse-LazyStart: true +Bundle-ActivationPolicy: lazy Export-Package: org.eclipse.dd.examples.pda, org.eclipse.dd.examples.pda.breakpoints, org.eclipse.dd.examples.pda.launch, - org.eclipse.dd.examples.pda.service.command, - org.eclipse.debug.examples.core.pda.sourcelookup + org.eclipse.dd.examples.pda.service, + org.eclipse.dd.examples.pda.service.commands, + org.eclipse.dd.examples.pda.sourcelookup Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/plugins/org.eclipse.dd.examples.pda/pdavm/docs/protocol.html b/plugins/org.eclipse.dd.examples.pda/pdavm/docs/protocol.html index 8717a8dbf61..9e2b92749f4 100644 --- a/plugins/org.eclipse.dd.examples.pda/pdavm/docs/protocol.html +++ b/plugins/org.eclipse.dd.examples.pda/pdavm/docs/protocol.html @@ -121,7 +121,7 @@ Sets a data value in the data stack at the given location Sets a variable value
    -   C: setvar {variable} {value}
    +   C: setvar {frame_number} {variable} {value}
        R: ok
     
    diff --git a/plugins/org.eclipse.dd.examples.pda/plugin.xml b/plugins/org.eclipse.dd.examples.pda/plugin.xml index 053f2625f91..1841f1cb7fc 100644 --- a/plugins/org.eclipse.dd.examples.pda/plugin.xml +++ b/plugins/org.eclipse.dd.examples.pda/plugin.xml @@ -21,14 +21,14 @@ perlExecutable). */ public static final String VARIALBE_PERL_EXECUTABLE = "dsfPerlExecutable"; + /** * Launch configuration attribute key. Value is a path to a perl * program. The path is a string representing a full path diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/breakpoints/PDALineBreakpoint.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/breakpoints/PDALineBreakpoint.java index bc518e16fe0..3913c517bb3 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/breakpoints/PDALineBreakpoint.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/breakpoints/PDALineBreakpoint.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 IBM Corporation and others. + * Copyright (c) 2005, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,6 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation * Bjorn Freeman-Benson - initial API and implementation + * Wind River Systems - adopted to use with DSF *******************************************************************************/ package org.eclipse.dd.examples.pda.breakpoints; @@ -23,6 +24,10 @@ import org.eclipse.debug.core.model.LineBreakpoint; /** * PDA line breakpoint + *

    + * This class is identical to the corresponding in PDA debugger implemented in + * org.eclipse.debug.examples. + *

    */ public class PDALineBreakpoint extends LineBreakpoint { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/breakpoints/PDARunToLineBreakpoint.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/breakpoints/PDARunToLineBreakpoint.java deleted file mode 100644 index eda5308d957..00000000000 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/breakpoints/PDARunToLineBreakpoint.java +++ /dev/null @@ -1,70 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2007 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - * Bjorn Freeman-Benson - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.examples.pda.breakpoints; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IMarker; -import org.eclipse.core.resources.IWorkspaceRunnable; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.debug.core.DebugException; -import org.eclipse.debug.core.model.IBreakpoint; - -/** - * A run to line breakpoint. - */ -public class PDARunToLineBreakpoint extends PDALineBreakpoint { - - private IFile fSourceFile; - - /** - * Constructs a run-to-line breakpoint in the given PDA program. - * - * @param resource PDA source file - * @param lineNumber line to run to - * @exception DebugException if unable to create the breakpoint - */ - public PDARunToLineBreakpoint(final IFile resource, final int lineNumber) throws DebugException { - IWorkspaceRunnable runnable = new IWorkspaceRunnable() { - public void run(IProgressMonitor monitor) throws CoreException { - // associate with workspace root to avoid drawing in editor ruler - IMarker marker = ResourcesPlugin.getWorkspace().getRoot().createMarker("org.eclipse.debug.examples.core.pda.markerType.lineBreakpoint"); - setMarker(marker); - marker.setAttribute(IBreakpoint.ENABLED, Boolean.TRUE); - marker.setAttribute(IMarker.LINE_NUMBER, lineNumber); - marker.setAttribute(IBreakpoint.ID, getModelIdentifier()); - setRegistered(false); - fSourceFile = resource; - } - }; - run(getMarkerRule(resource), runnable); - } - - /** - * Returns whether this breakpoint is a run-to-line breakpoint - * - * @return whether this breakpoint is a run-to-line breakpoint - */ - public boolean isRunToLineBreakpoint() { - return true; - } - - /** - * Returns the source file this breakpoint is contained in. - * - * @return the source file this breakpoint is contained in - */ - public IFile getSourceFile() { - return fSourceFile; - } -} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/breakpoints/PDAWatchpoint.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/breakpoints/PDAWatchpoint.java index ac3e9bcc80a..6a9b1353371 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/breakpoints/PDAWatchpoint.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/breakpoints/PDAWatchpoint.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 IBM Corporation and others. + * Copyright (c) 2005, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,6 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation * Bjorn Freeman-Benson - initial API and implementation + * Wind River Systems - adopted to use with DSF *******************************************************************************/ package org.eclipse.dd.examples.pda.breakpoints; @@ -22,6 +23,10 @@ import org.eclipse.debug.core.model.IWatchpoint; /** * A watchpoint. + *

    + * This class is identical to the corresponding in PDA debugger implemented in + * org.eclipse.debug.examples. + *

    */ public class PDAWatchpoint extends PDALineBreakpoint implements IWatchpoint { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunch.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunch.java index 587d8c993fc..6341c937efe 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunch.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunch.java @@ -15,16 +15,14 @@ import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor; -import org.eclipse.dd.dsf.concurrent.DsfExecutor; import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.concurrent.Sequence; import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; -import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.examples.pda.PDAPlugin; -import org.eclipse.dd.examples.pda.service.command.PDATerminatedEvent; +import org.eclipse.dd.examples.pda.service.PDATerminatedEvent; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.Launch; @@ -32,23 +30,38 @@ import org.eclipse.debug.core.model.ISourceLocator; import org.eclipse.debug.core.model.ITerminate; /** - * A DSF-based debugger has to override the base launch class in order to - * supply its own content providers for the debug view. + * The PDA launch object. In general, a DSF-based debugger has to override + * the base launch class in order to supply its own content providers for the + * debug view. Additionally, the PDA launch is used to monitor the state of the + * PDA debugger and to shutdown the DSF services and session belonging to the + * launch. + *

    + * The PDA launch class mostly contains methods and fields that can be accessed + * on any thread. However, some fields and methods used for managing the DSF + * session need to be synchronized using the DSF executor. + *

    */ @ThreadSafe public class PDALaunch extends Launch implements ITerminate -{ +{ + // DSF executor and session. Both are created and shutdown by the launch. private final DefaultDsfExecutor fExecutor; private final DsfSession fSession; - - @ConfinedToDsfExecutor("getSession().getExecutor()") - private DsfServicesTracker fTracker; - + + // Objects used to track the status of the DSF session. private Sequence fInitializationSequence = null; private boolean fInitialized = false; private boolean fShutDown = false; + /** + * Launch constructor creates the launch for given parameters. The + * constructor also creates a DSF session and an executor, so that + * {@link #getSession()} returns a valid value, however no services + * are initialized yet. + * + * @see Launch + */ public PDALaunch(ILaunchConfiguration launchConfiguration, String mode, ISourceLocator locator) { super(launchConfiguration, mode, locator); @@ -60,34 +73,68 @@ public class PDALaunch extends Launch fSession = DsfSession.startSession(fExecutor, PDAPlugin.ID_PDA_DEBUG_MODEL); } - public DsfExecutor getDsfExecutor() { return fExecutor; } - + /** + * Returns the DSF services session that belongs to this launch. This + * method will always return a DsfSession object, however if the debugger + * is shut down, the session will no longer active. + */ public DsfSession getSession() { return fSession; } + /** + * Initializes the DSF services using the specified parameters. This + * method has to be called on the executor thread in order to avoid + * synchronization issues. + */ @ConfinedToDsfExecutor("getSession().getExecutor()") public void initializeServices(String program, int requestPort, int eventPort, final RequestMonitor rm) { - fTracker = new DsfServicesTracker(PDAPlugin.getBundleContext(), fSession.getId()); + // Double-check that we're being called in the correct thread. + assert fExecutor.isInExecutorThread(); + + // Check if shutdownServices() was called already, which would be + // highly unusual, but if so we don't need to do anything except set + // the initialized flag. + synchronized(this) { + if (fShutDown) { + fInitialized = true; + return; + } + } + + // Register the launch as listener for services events. fSession.addServiceEventListener(PDALaunch.this, null); + // Initialize the fInitializationSequence attribute in a synchronized + // block, because it may be accessed in another thread by shutdown(). + // The initialization sequence is stored in a field to allow it to be + // canceled if shutdownServices() is called before the sequence + // completes. synchronized(this) { fInitializationSequence = new PDAServicesInitSequence( - getSession(), this, program, requestPort, eventPort, + getSession(), program, requestPort, eventPort, new RequestMonitor(ImmediateExecutor.getInstance(), rm) { @Override protected void handleCompleted() { + // Set the initialized flag and check whether the + // shutdown flag is set. Access the flags in a + // synchronized section as these flags can be accessed + // on any thread. boolean doShutdown = false; - synchronized (this) - { + synchronized (this) { fInitialized = true; fInitializationSequence = null; if (fShutDown) { doShutdown = true; } } + if (doShutdown) { + // If shutdownServices() was already called, start the + // shutdown sequence now. doShutdown(rm); } else { + // If there was an error in the startup sequence, + // report the error to the client. if (getStatus().getSeverity() == IStatus.ERROR) { rm.setStatus(getStatus()); } @@ -97,18 +144,30 @@ public class PDALaunch extends Launch } }); } + + // Finally, execute the sequence. getSession().getExecutor().execute(fInitializationSequence); } + /** + * Event handler for a debugger terminated event. + */ @DsfServiceEventHandler public void eventDispatched(PDATerminatedEvent event) { shutdownServices(new RequestMonitor(ImmediateExecutor.getInstance(), null)); } + /** + * Returns whether the DSF service initialization sequence has completed yet. + */ public synchronized boolean isInitialized() { return fInitialized; } + /** + * Returns whether the DSF services have been set to shut down. + * @return + */ public synchronized boolean isShutDown() { return fShutDown; } @@ -144,9 +203,13 @@ public class PDALaunch extends Launch */ @ConfinedToDsfExecutor("getSession().getExecutor()") public void shutdownServices(final RequestMonitor rm) { + // Check initialize and shutdown flags to determine if the shutdown + // sequence can be called yet. boolean doShutdown = false; synchronized (this) { if (!fInitialized && fInitializationSequence != null) { + // Launch has not yet initialized, try to cancel the + // shutdown sequence. fInitializationSequence.cancel(false); } else { doShutdown = !fShutDown && fInitialized; @@ -164,7 +227,7 @@ public class PDALaunch extends Launch @ConfinedToDsfExecutor("getSession().getExecutor()") private void doShutdown(final RequestMonitor rm) { fExecutor.execute( new PDAServicesShutdownSequence( - getDsfExecutor(), fSession.getId(), + fExecutor, fSession.getId(), new RequestMonitor(fSession.getExecutor(), rm) { @Override public void handleCompleted() { @@ -174,8 +237,6 @@ public class PDALaunch extends Launch PDAPlugin.PLUGIN_ID, -1, new IStatus[]{getStatus()}, "Session shutdown failed", null)); //$NON-NLS-1$ } // Last order of business, shutdown the dispatch queue. - fTracker.dispose(); - fTracker = null; DsfSession.endSession(fSession); // endSession takes a full dispatch to distribute the // session-ended event, finish step only after the dispatch. diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunchDelegate.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunchDelegate.java index 0f203cf26d4..9aa119d29bd 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunchDelegate.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunchDelegate.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 IBM Corporation and others. + * Copyright (c) 2005, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,6 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation * Bjorn Freeman-Benson - initial API and implementation + * Wind River Systems - adopted to use with DSF *******************************************************************************/ package org.eclipse.dd.examples.pda.launch; @@ -42,7 +43,7 @@ import org.eclipse.debug.core.sourcelookup.IPersistableSourceLocator2; /** - * Launches PDA program on a PDA interpretter written in Perl + * Launches PDA program on a PDA interpretter written in Perl */ public class PDALaunchDelegate extends LaunchConfigurationDelegate { @@ -59,9 +60,13 @@ public class PDALaunchDelegate extends LaunchConfigurationDelegate { @Override public boolean buildForLaunch(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException { + // PDA programs do not require building. return false; } + /** + * Returns a source locator created based on the attributes in the launch configuration. + */ private ISourceLocator getSourceLocator(ILaunchConfiguration configuration) throws CoreException { String type = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_ID, (String)null); if (type == null) { @@ -83,12 +88,7 @@ public class PDALaunchDelegate extends LaunchConfigurationDelegate { return null; } - - /* (non-Javadoc) - * @see org.eclipse.debug.core.model.ILaunchConfigurationDelegate#launch(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.debug.core.ILaunch, org.eclipse.core.runtime.IProgressMonitor) - */ public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException { - String program = configuration.getAttribute(PDAPlugin.ATTR_PDA_PROGRAM, (String)null); if (program == null) { abort("Perl program unspecified.", null); @@ -104,11 +104,21 @@ public class PDALaunchDelegate extends LaunchConfigurationDelegate { PDALaunch pdaLaunch = (PDALaunch)launch; initServices(pdaLaunch, program, requestPort, eventPort); } - + + /** + * Launches PDA interpreter with the given program. + * + * @param launch Launch that will contain the new process. + * @param program PDA program to use in the interpreter. + * @param requestPort The port number for connecting the request socket. + * @param eventPort The port number for connecting the events socket. + * + * @throws CoreException + */ private void launchProcess(ILaunch launch, String program, int requestPort, int eventPort) throws CoreException { List commandList = new ArrayList(); - // Perl executable + // Find Perl executable IValueVariable perl = VariablesPlugin.getDefault().getStringVariableManager().getValueVariable(PDAPlugin.VARIALBE_PERL_EXECUTABLE); if (perl == null) { abort("Perl executable location undefined. Check value of ${dsfPerlExecutable}.", null); @@ -130,6 +140,7 @@ public class PDALaunchDelegate extends LaunchConfigurationDelegate { } commandList.add(vm.getAbsolutePath()); + // Add PDA program IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(program)); if (!file.exists()) { abort(MessageFormat.format("Perl program {0} does not exist.", new Object[] {file.getFullPath().toString()}), null); @@ -137,19 +148,26 @@ public class PDALaunchDelegate extends LaunchConfigurationDelegate { commandList.add(file.getLocation().toOSString()); - // add debug arguments - i.e. '-debug requestPort eventPort' + // Add debug arguments - i.e. '-debug requestPort eventPort' commandList.add("-debug"); commandList.add("" + requestPort); commandList.add("" + eventPort); + // Launch the perl process. String[] commandLine = commandList.toArray(new String[commandList.size()]); Process process = DebugPlugin.exec(commandLine, null); + + // Create a debug platform process object and add it to the launch. DebugPlugin.newProcess(launch, process, path); } + /** + * Calls the launch to initialize DSF services for this launch. + */ private void initServices(final PDALaunch pdaLaunch, final String program, final int requestPort, final int eventPort) throws CoreException { + // Synchronization object to use when waiting for the services initialization. Query initQuery = new Query() { @Override protected void execute(DataRequestMonitor rm) { @@ -157,8 +175,10 @@ public class PDALaunchDelegate extends LaunchConfigurationDelegate { } }; + // Submit the query to the executor. pdaLaunch.getSession().getExecutor().execute(initQuery); try { + // Block waiting for query results. initQuery.get(); } catch (InterruptedException e1) { throw new DebugException(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, "Interrupted Exception in dispatch thread", e1)); //$NON-NLS-1$ @@ -181,8 +201,6 @@ public class PDALaunchDelegate extends LaunchConfigurationDelegate { /** * Returns a free port number on localhost, or -1 if unable to find a free port. - * - * @return a free port number on localhost, or -1 if unable to find a free port */ public static int findFreePort() { ServerSocket socket= null; diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java index 38b17950fd7..a92a61fc79d 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006 Wind River Systems and others. + * Copyright (c) 2008 Wind River Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -15,29 +15,46 @@ import org.eclipse.dd.dsf.concurrent.Sequence; import org.eclipse.dd.dsf.debug.service.BreakpointsMediator; import org.eclipse.dd.dsf.debug.service.StepQueueManager; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.examples.pda.service.breakpoints.PDABreakpointAttributeTranslator; -import org.eclipse.dd.examples.pda.service.breakpoints.PDABreakpoints; -import org.eclipse.dd.examples.pda.service.command.PDACommandControl; -import org.eclipse.dd.examples.pda.service.expressions.PDAExpressions; -import org.eclipse.dd.examples.pda.service.runcontrol.PDARunControl; -import org.eclipse.dd.examples.pda.service.stack.PDAStack; -import org.eclipse.debug.examples.core.pda.sourcelookup.PDASourceLookupDirector; +import org.eclipse.dd.examples.pda.service.PDABreakpointAttributeTranslator; +import org.eclipse.dd.examples.pda.service.PDABreakpoints; +import org.eclipse.dd.examples.pda.service.PDACommandControl; +import org.eclipse.dd.examples.pda.service.PDAExpressions; +import org.eclipse.dd.examples.pda.service.PDARunControl; +import org.eclipse.dd.examples.pda.service.PDAStack; +/** + * The initialization sequence for PDA debugger services. This sequence contains + * the series of steps that are executed to properly initialize the PDA-DSF debug + * session. If any of the individual steps fail, the initialization will abort. + *

    + * The order in which services are initialized is important. Some services depend + * on other services and they assume that they will be initialized only if those + * services are active. Also the service events are prioritized and their priority + * depends on the order in which the services were initialized. + *

    + */ public class PDAServicesInitSequence extends Sequence { Step[] fSteps = new Step[] { - // Create and initialize the Connection service. - new Step() { + new Step() + { @Override public void execute(RequestMonitor requestMonitor) { - // Create the connection. - fCommandControl = new PDACommandControl(fSession, fRequestPort, fEventPort); + // Create the connection to PDA debugger. + fCommandControl = new PDACommandControl(fSession, fProgram, fRequestPort, fEventPort); fCommandControl.initialize(requestMonitor); } + + @Override + public void rollBack(RequestMonitor rm) { + // TODO Auto-generated method stub + super.rollBack(rm); + } }, new Step() { @Override public void execute(RequestMonitor requestMonitor) { + // Start the run control service. fRunControl = new PDARunControl(fSession); fRunControl.initialize(requestMonitor); } @@ -45,62 +62,65 @@ public class PDAServicesInitSequence extends Sequence { new Step() { @Override public void execute(RequestMonitor requestMonitor) { + // Start the service to manage step actions. new StepQueueManager(fSession).initialize(requestMonitor); } }, new Step() { @Override public void execute(final RequestMonitor requestMonitor) { - // Create the low-level breakpoint service - new PDABreakpoints(fSession, fProgram).initialize(new RequestMonitor(getExecutor(), requestMonitor)); + // Start the low-level breakpoint service + new PDABreakpoints(fSession).initialize(new RequestMonitor(getExecutor(), requestMonitor)); } }, new Step() { @Override public void execute(final RequestMonitor requestMonitor) { + // Create the breakpoint mediator and start tracking PDA breakpoints. + final BreakpointsMediator bpmService = new BreakpointsMediator( fSession, new PDABreakpointAttributeTranslator()); bpmService.initialize(new RequestMonitor(getExecutor(), requestMonitor) { @Override protected void handleOK() { - bpmService.startTrackingBreakpoints(fCommandControl.getDMContext(), requestMonitor); + bpmService.startTrackingBreakpoints(fCommandControl.getProgramDMContext(), requestMonitor); } }); } }, new Step() { @Override public void execute(RequestMonitor requestMonitor) { + // Start the stack service. new PDAStack(fSession).initialize(requestMonitor); } }, new Step() { @Override public void execute(RequestMonitor requestMonitor) { + // Start the service to track expressions. new PDAExpressions(fSession).initialize(requestMonitor); } }, new Step() { @Override public void execute(RequestMonitor requestMonitor) { - fRunControl.resume(fCommandControl.getDMContext(), requestMonitor); + fRunControl.resume(fCommandControl.getProgramDMContext(), requestMonitor); } }, }; + // Sequence input parameters, used in initializing services. private DsfSession fSession; - private PDALaunch fLaunch; private String fProgram; private int fRequestPort; private int fEventPort; - PDACommandControl fCommandControl; - PDARunControl fRunControl; - PDASourceLookupDirector fSourceLookup; + // Service references, initialized when created and used in initializing other services. + private PDACommandControl fCommandControl; + private PDARunControl fRunControl; - public PDAServicesInitSequence(DsfSession session, PDALaunch launch, String program, int requestPort, - int eventPort, RequestMonitor rm) + public PDAServicesInitSequence(DsfSession session, String program, int requestPort, int eventPort, RequestMonitor rm) { super(session.getExecutor(), rm); fSession = session; - fLaunch = launch; fProgram = program; fRequestPort = requestPort; fEventPort = eventPort; diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java index 583c11b3908..7404dbad668 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006 Wind River Systems and others. + * Copyright (c) 2008 Wind River Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -20,17 +20,95 @@ import org.eclipse.dd.dsf.debug.service.StepQueueManager; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.examples.pda.PDAPlugin; -import org.eclipse.dd.examples.pda.service.breakpoints.PDABreakpoints; -import org.eclipse.dd.examples.pda.service.command.PDACommandControl; -import org.eclipse.dd.examples.pda.service.expressions.PDAExpressions; -import org.eclipse.dd.examples.pda.service.runcontrol.PDARunControl; -import org.eclipse.dd.examples.pda.service.stack.PDAStack; +import org.eclipse.dd.examples.pda.service.PDABreakpoints; +import org.eclipse.dd.examples.pda.service.PDACommandControl; +import org.eclipse.dd.examples.pda.service.PDAExpressions; +import org.eclipse.dd.examples.pda.service.PDARunControl; +import org.eclipse.dd.examples.pda.service.PDAStack; +/** + * The shutdown sequence for PDA debugger services. This sequence contains + * the series of steps that are executed to properly shutdown the PDA-DSF debug + * session. If any of the individual steps fail, the shutdown will abort. + *

    + * Services are shut down in the reverse order of initialization. + *

    + */ public class PDAServicesShutdownSequence extends Sequence { + + private final Step[] fSteps = new Step[] { + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + // Initialize services tracker. + assert PDAPlugin.getBundleContext() != null; + fTracker = new DsfServicesTracker(PDAPlugin.getBundleContext(), fSessionId); + requestMonitor.done(); + } + + @Override + public void rollBack(RequestMonitor requestMonitor) { + // In case the shutdown sequence aborts, ensure that the + // tracker is properly disposed. + fTracker.dispose(); + fTracker = null; + requestMonitor.done(); + } + }, + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(PDAExpressions.class, requestMonitor); + } + }, + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(PDAStack.class, requestMonitor); + } + }, + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(BreakpointsMediator.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(PDABreakpoints.class, requestMonitor); + } + }, + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(StepQueueManager.class, requestMonitor); + } + }, + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(PDARunControl.class, requestMonitor); + } + }, + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(PDACommandControl.class, requestMonitor); + } + }, + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + fTracker.dispose(); + fTracker = null; + requestMonitor.done(); + } + } + }; - String fSessionId; - DsfServicesTracker fTracker; - + private String fSessionId; + private DsfServicesTracker fTracker; + public PDAServicesShutdownSequence(DsfExecutor executor, String sessionId, RequestMonitor requestMonitor) { super(executor, requestMonitor); fSessionId = sessionId; @@ -41,92 +119,6 @@ public class PDAServicesShutdownSequence extends Sequence { return fSteps; } - private final Step[] fSteps = new Step[] { new Step() { - @Override - public void execute(RequestMonitor requestMonitor) { - assert PDAPlugin.getBundleContext() != null; - fTracker = new DsfServicesTracker(PDAPlugin.getBundleContext(), fSessionId); - requestMonitor.done(); - } - - @Override - public void rollBack(RequestMonitor requestMonitor) { - fTracker.dispose(); - fTracker = null; - requestMonitor.done(); - } - }, -/* new Step() { - @Override - public void execute(RequestMonitor requestMonitor) { - shutdownService(MIRegisters.class, requestMonitor); - } - }, new Step() { - @Override - public void execute(RequestMonitor requestMonitor) { - shutdownService(MIBreakpointsManager.class, requestMonitor); - } - }, new Step() { - @Override - public void execute(RequestMonitor requestMonitor) { - shutdownService(MIBreakpoints.class, requestMonitor); - } - }, new Step() { - @Override - public void execute(RequestMonitor requestMonitor) { - shutdownService(CSourceLookup.class, requestMonitor); - } - },*/ - new Step() { - @Override - public void execute(RequestMonitor requestMonitor) { - shutdownService(PDAExpressions.class, requestMonitor); - } - }, - new Step() { - @Override - public void execute(RequestMonitor requestMonitor) { - shutdownService(PDAStack.class, requestMonitor); - } - }, - new Step() { - @Override - public void execute(RequestMonitor requestMonitor) { - shutdownService(BreakpointsMediator.class, requestMonitor); - } - }, new Step() { - @Override - public void execute(RequestMonitor requestMonitor) { - shutdownService(PDABreakpoints.class, requestMonitor); - } - }, - new Step() { - @Override - public void execute(RequestMonitor requestMonitor) { - shutdownService(StepQueueManager.class, requestMonitor); - } - }, - new Step() { - @Override - public void execute(RequestMonitor requestMonitor) { - shutdownService(PDARunControl.class, requestMonitor); - } - }, - new Step() { - @Override - public void execute(RequestMonitor requestMonitor) { - shutdownService(PDACommandControl.class, requestMonitor); - } - }, - new Step() { - @Override - public void execute(RequestMonitor requestMonitor) { - fTracker.dispose(); - fTracker = null; - requestMonitor.done(); - } - } }; - @SuppressWarnings("unchecked") private void shutdownService(Class clazz, final RequestMonitor requestMonitor) { IDsfService service = fTracker.getService(clazz); diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/breakpoints/PDABreakpointAttributeTranslator.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpointAttributeTranslator.java similarity index 75% rename from plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/breakpoints/PDABreakpointAttributeTranslator.java rename to plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpointAttributeTranslator.java index 0e342716357..ccdf9aef3ca 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/breakpoints/PDABreakpointAttributeTranslator.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpointAttributeTranslator.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.breakpoints; +package org.eclipse.dd.examples.pda.service; import java.util.ArrayList; import java.util.HashMap; @@ -29,22 +29,33 @@ import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.model.IBreakpoint; /** - * + * Translator between {@link PDALineBreakpoint} object attributes and + * attributes used by the {@link PDABreakpoints} service. + *

    + * The attribute translator is used by the standard {@link BreakpointsMediator} + * service to map between platform breakpoint attributes and target-side DSF + * breakpoint attributes. Thus, this object encapsulates the model-specific + * functionality of synchronizing target side and IDE-side breakpoint objects. + *

    */ public class PDABreakpointAttributeTranslator implements IBreakpointAttributeTranslator { + // Arrays of common attributes between the two breakpoint types. These + // attributes can be copied directly without translation. private static final String[] fgPDALineBreakpointAttributes = { + IBreakpoint.ENABLED, IMarker.LINE_NUMBER, }; - private static final String[] fgPDAWatchpointAttributes = { + IBreakpoint.ENABLED, PDAWatchpoint.FUNCTION_NAME, PDAWatchpoint.VAR_NAME, PDAWatchpoint.ACCESS, PDAWatchpoint.MODIFICATION }; - + // PDA breakpoints translator doesn't keep any state and it doesn't + // need to initialize or clean up. public void initialize(BreakpointsMediator mediator) { } @@ -56,18 +67,22 @@ public class PDABreakpointAttributeTranslator implements IBreakpointAttributeTra { Map attrs = new HashMap(); + // Check that the marker exists and retrieve its attributes. + // Due to accepted race conditions, the breakpiont marker may become null + // while this method is being invoked. In this case throw an exception + // and let the caller handle it. IMarker marker = bp.getMarker(); if (marker == null || !marker.exists()) { throw new DebugException(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Breakpoint marker does not exist", null)); } - // Suppress cast warning: platform is still on Java 1.3 @SuppressWarnings("unchecked") Map platformBpAttrs = marker.getAttributes(); + // Copy breakpoint attributes. if (bp instanceof PDAWatchpoint) { attrs.put(PDABreakpoints.ATTR_BREAKPOINT_TYPE, PDABreakpoints.PDA_WATCHPOINT); - + copyAttributes(platformBpAttrs, attrs, fgPDAWatchpointAttributes); } else if (bp instanceof PDALineBreakpoint) { attrs.put(PDABreakpoints.ATTR_BREAKPOINT_TYPE, PDABreakpoints.PDA_LINE_BREAKPOINT); @@ -81,6 +96,9 @@ public class PDABreakpointAttributeTranslator implements IBreakpointAttributeTra attrs.put(IBreakpoint.ENABLED, false); } + // The breakpoint mediator allows for multiple target-side breakpoints + // to be created for each IDE breakpoint. Although in case of PDA this + // feature is never used, we still have to return a list of attributes. List> retVal = new ArrayList>(1); retVal.add(attrs); return retVal; @@ -96,7 +114,7 @@ public class PDABreakpointAttributeTranslator implements IBreakpointAttributeTra public boolean canUpdateAttributes(IBreakpointDMContext bp, Map delta) { // PDA debugger only allows updating of the action property of the watchpoint. - // All other breakpoint updates will require a reinstallation. + // All other breakpoint updates will require a re-installation. if (bp instanceof PDAWatchpoint) { Map deltaCopy = new HashMap(delta); deltaCopy.remove(PDAWatchpoint.ACCESS); diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpoints.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpoints.java new file mode 100644 index 00000000000..b0a4aa77e41 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpoints.java @@ -0,0 +1,395 @@ +/******************************************************************************* + * Copyright (c) 2007 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.examples.pda.service; + +import java.util.HashSet; +import java.util.Hashtable; +import java.util.Map; +import java.util.Set; + +import org.eclipse.core.resources.IMarker; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.AbstractDMContext; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.IBreakpoints; +import org.eclipse.dd.dsf.service.AbstractDsfService; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.examples.pda.PDAPlugin; +import org.eclipse.dd.examples.pda.breakpoints.PDAWatchpoint; +import org.eclipse.dd.examples.pda.service.commands.PDAClearBreakpointCommand; +import org.eclipse.dd.examples.pda.service.commands.PDACommandResult; +import org.eclipse.dd.examples.pda.service.commands.PDASetBreakpointCommand; +import org.eclipse.dd.examples.pda.service.commands.PDAWatchCommand; +import org.eclipse.debug.core.model.IBreakpoint; +import org.osgi.framework.BundleContext; + +/** + * Initial breakpoint service implementation. + * Implements the IBreakpoints interface. + */ +public class PDABreakpoints extends AbstractDsfService implements IBreakpoints +{ + /** + * Context representing a PDA line breakpoint. In PDA debugger, since there is only + * one file being debugged at a time, a breakpoint is uniquely identified using the + * line number only. + */ + @Immutable + private static class BreakpointDMContext extends AbstractDMContext implements IBreakpointDMContext { + + final Integer fLine; + + public BreakpointDMContext(String sessionId, PDAProgramDMContext commandControlCtx, Integer line) { + super(sessionId, new IDMContext[] { commandControlCtx }); + fLine = line; + } + + @Override + public boolean equals(Object obj) { + return baseEquals(obj) && (fLine.equals(((BreakpointDMContext) obj).fLine)); + } + + @Override + public int hashCode() { + return baseHashCode() + fLine.hashCode(); + } + + @Override + public String toString() { + return baseToString() + ".breakpoint(" + fLine + ")"; //$NON-NLS-1$//$NON-NLS-2$*/ + } + } + + /** + * Context representing a watch point. In PDA debugger, a watchpoint is + * uniquely identified using the function and variable. + */ + @Immutable + private static class WatchpointDMContext extends AbstractDMContext implements IBreakpointDMContext { + final String fFunction; + final String fVariable; + + public WatchpointDMContext(String sessionId, PDAProgramDMContext commandControlCtx, String function, + String variable) + { + super(sessionId, new IDMContext[] { commandControlCtx }); + fFunction = function; + fVariable = variable; + } + + @Override + public boolean equals(Object obj) { + if (baseEquals(obj)) { + WatchpointDMContext watchpointCtx = (WatchpointDMContext)obj; + return fFunction.equals(watchpointCtx.fFunction) && fVariable.equals(watchpointCtx.fVariable); + } + return false; + } + + @Override + public int hashCode() { + return baseHashCode() + fFunction.hashCode() + fVariable.hashCode(); + } + + @Override + public String toString() { + return baseToString() + ".watchpoint(" + fFunction + "::" + fVariable + ")"; + } + } + + // Attribute names + public static final String ATTR_BREAKPOINT_TYPE = PDAPlugin.PLUGIN_ID + ".pdaBreakpointType"; //$NON-NLS-1$ + public static final String PDA_LINE_BREAKPOINT = "breakpoint"; //$NON-NLS-1$ + public static final String PDA_WATCHPOINT = "watchpoint"; //$NON-NLS-1$ + public static final String ATTR_PROGRAM_PATH = PDAPlugin.PLUGIN_ID + ".pdaProgramPath"; //$NON-NLS-1$ + + // Services + private PDACommandControl fCommandControl; + + // Breakpoints currently installed + private Set fBreakpoints = new HashSet(); + + /** + * The service constructor + * + * @param session The debugging session this service belongs to. + */ + public PDABreakpoints(DsfSession session) { + super(session); + } + + @Override + public void initialize(final RequestMonitor rm) { + super.initialize(new RequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + doInitialize(rm); + } + }); + } + + private void doInitialize(final RequestMonitor rm) { + // Get the services references + fCommandControl = getServicesTracker().getService(PDACommandControl.class); + + // Register this service + register(new String[] { IBreakpoints.class.getName(), PDABreakpoints.class.getName() }, + new Hashtable()); + + rm.done(); + } + + @Override + public void shutdown(final RequestMonitor rm) { + unregister(); + rm.done(); + } + + @Override + protected BundleContext getBundleContext() { + return PDAPlugin.getBundleContext(); + } + + public void getBreakpoints(final IBreakpointsTargetDMContext context, final DataRequestMonitor rm) { + // Validate the context + if (!fCommandControl.getProgramDMContext().equals(context)) { + PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid breakpoints target context"); + return; + } + + rm.setData(fBreakpoints.toArray(new IBreakpointDMContext[fBreakpoints.size()])); + rm.done(); + } + + public void getBreakpointDMData(IBreakpointDMContext dmc, DataRequestMonitor rm) { + PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Retrieving breakpoint data is not supported"); + } + + public void insertBreakpoint(IBreakpointsTargetDMContext context, Map attributes, + DataRequestMonitor rm) + { + Boolean enabled = (Boolean)attributes.get(IBreakpoint.ENABLED); + if (enabled != null && !enabled.booleanValue()) { + // If the breakpoint is disabled, just fail the request. + PDAPlugin.failRequest(rm, REQUEST_FAILED, "Breakpoint is disabled"); + } else { + String type = (String) attributes.get(ATTR_BREAKPOINT_TYPE); + + if (PDA_LINE_BREAKPOINT.equals(type)) { + // Retrieve the PDA program context from the context given in the + // argument. This service is typically only called by the + // breakpoints mediator, which was called with the program context + // in the services initialization sequence. So checking if + // programCtx != null is mostly a formality. + PDAProgramDMContext programCtx = DMContexts.getAncestorOfType(context, PDAProgramDMContext.class); + if (programCtx != null) { + doInsertBreakpoint(programCtx, attributes, rm); + } else { + PDAPlugin.failRequest(rm, INVALID_HANDLE, "Unknown breakpoint type"); + } + } + else if (PDA_WATCHPOINT.equals(type)) { + doInsertWatchpoint(attributes, rm); + } + else { + PDAPlugin.failRequest(rm, REQUEST_FAILED, "Unknown breakpoint type"); + } + } + } + + private void doInsertBreakpoint(PDAProgramDMContext programCtx, final Map attributes, final DataRequestMonitor rm) + { + // Compare the program path in the breakpoint with the path in the PDA + // program context. Only insert the breakpoint if the program matches. + String program = (String)attributes.get(ATTR_PROGRAM_PATH); + if (!programCtx.getProgram().equals(program)) { + PDAPlugin.failRequest(rm, REQUEST_FAILED, "Invalid file name"); + return; + } + + // Retrieve the line. + Integer line = (Integer)attributes.get(IMarker.LINE_NUMBER); + if (line == null) { + PDAPlugin.failRequest(rm, REQUEST_FAILED, "No breakpoint line specified"); + return; + } + + // Create a new breakpoint context object and check that it's not + // installed already. PDA can only track a single breakpoint at a + // given line, attempting to set the second breakpoint should fail. + final BreakpointDMContext breakpointCtx = + new BreakpointDMContext(getSession().getId(), fCommandControl.getProgramDMContext(), line); + if (fBreakpoints.contains(breakpointCtx)) { + PDAPlugin.failRequest(rm, REQUEST_FAILED, "Breakpoint already set"); + return; + } + + // Add the new breakpoint context to the list of known breakpoints. + // Adding it here, before the set command is completed will prevent + // a possibility of a second breakpoint being installed in the same + // location while this breakpoint is being processed. It will also + // allow the breakpoint to be removed or updated even while it is + // still being processed here. + fBreakpoints.add(breakpointCtx); + fCommandControl.queueCommand( + new PDASetBreakpointCommand(fCommandControl.getProgramDMContext(), line), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + rm.setData(breakpointCtx); + rm.done(); + } + + @Override + protected void handleErrorOrCancel() { + // If inserting of the breakpoint failed, remove it from + // the set of installed breakpoints. + fBreakpoints.remove(breakpointCtx); + super.handleErrorOrCancel(); + } + }); + } + + private void doInsertWatchpoint(final Map attributes, final DataRequestMonitor rm) + { + String function = (String)attributes.get(PDAWatchpoint.FUNCTION_NAME); + if (function == null) { + PDAPlugin.failRequest(rm, REQUEST_FAILED, "No function specified"); + return; + } + + String variable = (String)attributes.get(PDAWatchpoint.VAR_NAME); + if (variable == null) { + PDAPlugin.failRequest(rm, REQUEST_FAILED, "No variable specified"); + return; + } + + Boolean isAccess = (Boolean)attributes.get(PDAWatchpoint.ACCESS); + isAccess = isAccess != null ? isAccess : Boolean.FALSE; + + Boolean isModification = (Boolean)attributes.get(PDAWatchpoint.MODIFICATION); + isModification = isModification != null ? isModification : Boolean.FALSE; + + // Create a new watchpoint context object and check that it's not + // installed already. PDA can only track a single watchpoint for a given + // function::variable, attempting to set the second breakpoint should fail. + final WatchpointDMContext watchpointCtx = + new WatchpointDMContext(getSession().getId(), fCommandControl.getProgramDMContext(), function, variable); + if (fBreakpoints.contains(watchpointCtx)) { + PDAPlugin.failRequest(rm, REQUEST_FAILED, "Watchpoint already set"); + return; + } + + // Determine the watch operation to perform. + PDAWatchCommand.WatchOperation watchOperation = PDAWatchCommand.WatchOperation.NONE; + if (isAccess && isModification) { + watchOperation = PDAWatchCommand.WatchOperation.BOTH; + } else if (isAccess) { + watchOperation = PDAWatchCommand.WatchOperation.READ; + } else if (isModification) { + watchOperation = PDAWatchCommand.WatchOperation.WRITE; + } + + // Add the new breakpoint context to the list of known breakpoints. + // Adding it here, before the set command is completed will prevent + // a possibility of a second breakpoint being installed in the same + // location while this breakpoint is being processed. It will also + // allow the breakpoint to be removed or updated even while it is + // still being processed here. + fBreakpoints.add(watchpointCtx); + fCommandControl.queueCommand( + new PDAWatchCommand(fCommandControl.getProgramDMContext(), function, variable, watchOperation), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + rm.setData(watchpointCtx); + rm.done(); + } + + @Override + protected void handleErrorOrCancel() { + // Since the command failed, we need to remove the breakpoint from + // the existing breakpoint set. + fBreakpoints.remove(watchpointCtx); + super.handleErrorOrCancel(); + } + }); + } + + public void removeBreakpoint(IBreakpointDMContext bpCtx, RequestMonitor rm) { + if (!fBreakpoints.contains(bpCtx)) { + PDAPlugin.failRequest(rm, REQUEST_FAILED, "Breakpoint already removed"); + return; + } + + if (bpCtx instanceof BreakpointDMContext) { + doRemoveBreakpoint((BreakpointDMContext)bpCtx, rm); + } else if (bpCtx instanceof WatchpointDMContext) { + doRemoveWatchpoint((WatchpointDMContext)bpCtx, rm); + } else { + PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid breakpoint"); + } + } + + private void doRemoveBreakpoint(BreakpointDMContext bpCtx, RequestMonitor rm) { + // Remove the breakpoint from the table right away, so that even when + // the remove is being processed, a new breakpoint can be created at the same + // location. + fBreakpoints.remove(bpCtx); + + fCommandControl.queueCommand( + new PDAClearBreakpointCommand(fCommandControl.getProgramDMContext(), bpCtx.fLine), + new DataRequestMonitor(getExecutor(), rm)); + } + + private void doRemoveWatchpoint(WatchpointDMContext bpCtx, RequestMonitor rm) { + fBreakpoints.remove(bpCtx); + + // Watchpoints are cleared using the same command, but with a "no watch" operation + fCommandControl.queueCommand( + new PDAWatchCommand( + fCommandControl.getProgramDMContext(), bpCtx.fFunction, bpCtx.fVariable, PDAWatchCommand.WatchOperation.NONE), + new DataRequestMonitor(getExecutor(), rm)); + } + + public void updateBreakpoint(final IBreakpointDMContext bpCtx, Map attributes, final RequestMonitor rm) { + if (!fBreakpoints.contains(bpCtx)) { + PDAPlugin.failRequest(rm, REQUEST_FAILED, "Breakpoint not installed"); + return; + } + + if (bpCtx instanceof BreakpointDMContext) { + PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Modifying PDA breakpoints is not supported"); + } else if (bpCtx instanceof WatchpointDMContext) { + // PDA debugger can only track one watchpoint in the same location, + // so we can simply remove the existing context from the set and + // call insert again. + fBreakpoints.remove(bpCtx); + doInsertWatchpoint( + attributes, + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + // The inserted watchpoint context will equal the + // current context. + assert bpCtx.equals(getData()); + rm.done(); + } + }); + } else { + PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid breakpoint"); + } + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommandControl.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java similarity index 76% rename from plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommandControl.java rename to plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java index 1c8013e1f7d..d835a549554 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommandControl.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java @@ -1,4 +1,4 @@ -package org.eclipse.dd.examples.pda.service.command; +package org.eclipse.dd.examples.pda.service; import java.io.BufferedReader; import java.io.IOException; @@ -30,10 +30,10 @@ import org.eclipse.dd.dsf.debug.service.command.ICommandResult; import org.eclipse.dd.dsf.debug.service.command.IEventListener; import org.eclipse.dd.dsf.service.AbstractDsfService; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.examples.pda.PDAPlugin; -import org.eclipse.dd.examples.pda.service.command.commands.AbstractPDACommand; -import org.eclipse.dd.examples.pda.service.command.commands.PDAExitCommand; +import org.eclipse.dd.examples.pda.service.commands.AbstractPDACommand; +import org.eclipse.dd.examples.pda.service.commands.PDACommandResult; +import org.eclipse.dd.examples.pda.service.commands.PDAExitCommand; import org.osgi.framework.BundleContext; @@ -53,6 +53,11 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon } } + // Parameters that the command control is created with. + final private String fProgram; + final private int fRequestPort; + final private int fEventPort; + // Queue of commands waiting to be sent to the debugger. As long as commands // are in this queue, they can still be removed by clients. private final List fCommandQueue = new LinkedList(); @@ -71,15 +76,13 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon private boolean fTerminated = false; // Data Model context of this command control. - private PDACommandControlDMContext fDMContext; + private PDAProgramDMContext fDMContext; // Synchronous listeners for commands and events. private final List fCommandListeners = new ArrayList(); private final List fEventListeners = new ArrayList(); // Sockets for communicating with PDA debugger - final private int fRequestPort; - final private int fEventPort; private Socket fRequestSocket; private PrintWriter fRequestWriter; private BufferedReader fRequestReader; @@ -96,14 +99,16 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon * @param requestPort Port number for sending PDA commands. * @param eventPort Port for listening to PDA events. */ - public PDACommandControl(DsfSession session, int requestPort, int eventPort) { + public PDACommandControl(DsfSession session, String program, int requestPort, int eventPort) { super(session); + fProgram = program; fRequestPort = requestPort; fEventPort = eventPort; } @Override public void initialize(final RequestMonitor rm) { + // Call the super-class to perform initialization first. super.initialize( new RequestMonitor(getExecutor(), rm) { @Override protected void handleOK() { @@ -112,10 +117,11 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon }); } - public void doInitialize(final RequestMonitor rm) { + private void doInitialize(final RequestMonitor rm) { // Create the control's data model context. - fDMContext = new PDACommandControlDMContext(getSession().getId()); + fDMContext = new PDAProgramDMContext(getSession().getId(), fProgram); + // Add a listener for PDA events to track the started/terminated state. addEventListener(new IEventListener() { public void eventReceived(Object output) { if ("started".equals(output)) { @@ -170,11 +176,11 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon socketsInitializeRm.done(); } catch (UnknownHostException e) { socketsInitializeRm.setStatus(new Status( - IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, "Unable to connect to PDA VM", e)); + IStatus.ERROR, PDAPlugin.PLUGIN_ID, REQUEST_FAILED, "Unable to connect to PDA VM", e)); socketsInitializeRm.done(); } catch (IOException e) { socketsInitializeRm.setStatus(new Status( - IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, "Unable to connect to PDA VM", e)); + IStatus.ERROR, PDAPlugin.PLUGIN_ID, REQUEST_FAILED, "Unable to connect to PDA VM", e)); socketsInitializeRm.done(); } return Status.OK_STATUS; @@ -211,8 +217,11 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon return PDAPlugin.getBundleContext(); } - class CommandSendJob extends Job { - public CommandSendJob() { + /** + * Job that services the send command queue. + */ + private class CommandSendJob extends Job { + CommandSendJob() { super("PDA Command Send"); setSystem(true); } @@ -222,26 +231,45 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon while (!isTerminated()) { synchronized(fTxCommands) { try { + // Remove comamnd from send queue. final CommandHandle commandHandle = fTxCommands.take(); + + // Send the request to PDA fRequestWriter.println(commandHandle.fCommand.getRequest()); fRequestWriter.flush(); try { // wait for reply final String response = fRequestReader.readLine(); - getExecutor().execute(new DsfRunnable() { - public void run() { - processCommandDone(commandHandle, response); - } - }); - + // Process the reply in the executor thread. + try { + getExecutor().execute(new DsfRunnable() { + public void run() { + processCommandDone(commandHandle, response); + } + }); + } catch (RejectedExecutionException e) { + // Acceptable race condition may see the session shut down + // while we're waiting for command response. Still complete + // the request monitor. + assert isTerminated(); + assert isTerminated(); + PDAPlugin.failRequest(commandHandle.fRequestMonitor, REQUEST_FAILED, "Command control shut down."); + } } catch (final IOException e) { - getExecutor().execute(new DsfRunnable() { - public void run() { - processCommandException(commandHandle, e); - } - }); + // Process error it in the executor thread + try { + getExecutor().execute(new DsfRunnable() { + public void run() { + processCommandException(commandHandle, e); + } + }); + } catch (RejectedExecutionException re) { + // Acceptable race condition... see above + assert isTerminated(); + PDAPlugin.failRequest(commandHandle.fRequestMonitor, REQUEST_FAILED, "Command control shut down."); + } } } catch (InterruptedException e) { break; // Shutting down. @@ -254,13 +282,12 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon } /** - * Listens to events from the PDA VM and fires corresponding - * debug events. + * Job that services the PDA event socket. */ class EventDispatchJob extends Job { public EventDispatchJob() { - super("PDA Event Dispatch"); + super("PDA Event Listner"); setSystem(true); } @@ -268,9 +295,11 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon protected IStatus run(IProgressMonitor monitor) { while (!isTerminated()) { try { + // Wait for an event. final String event = fEventReader.readLine(); if (event != null) { try { + // Process the event in executor thread. getExecutor().execute(new DsfRunnable() { public void run() { processEventReceived(event); @@ -285,6 +314,8 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon } } if (!isTerminated()) { + // Exception from the event socket is an indicator that the PDA debugger + // has exited. Call setTerminated() in executor thread. try { getExecutor().execute(new DsfRunnable() { public void run() { @@ -309,11 +340,14 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon @SuppressWarnings("unchecked") DataRequestMonitor pdaRM = (DataRequestMonitor)rm; + // Add the command to the queue and notify command listeners. fCommandQueue.add( new CommandHandle(pdaCommand, pdaRM) ); for (ICommandListener listener : fCommandListeners) { listener.commandQueued(command); } + // In a separate dispatch cycle. This allows command listeners to repond to the + // command queued event. getExecutor().execute(new DsfRunnable() { public void run() { processQueues(); @@ -321,9 +355,7 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon }); } else { - rm.setStatus(new Status( - IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Unrecognized command: " + command, null)); - rm.done(); + PDAPlugin.failRequest(rm, INTERNAL_ERROR, "Unrecognized command: " + command); } } @@ -333,6 +365,7 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon } public void removeCommand(ICommand command) { + // Removes given command from the queue and notify the listeners for (Iterator itr = fCommandQueue.iterator(); itr.hasNext();) { CommandHandle handle = itr.next(); if (command.equals(handle.fCommand)) { @@ -361,29 +394,44 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon } private void processCommandDone(CommandHandle handle, String response) { + // Trace to debug output. PDAPlugin.debug("R: " + response); + // Given the PDA response string, create the result using the command + // that was sent. PDACommandResult result = handle.fCommand.createResult(response); + + // Set the result to the request monitor and return to sender. + // Note: as long as PDA sends some response, a PDA command will never + // return an error. handle.fRequestMonitor.setData(result); handle.fRequestMonitor.done(); + // Notify listeners of the response for (ICommandListener listener : fCommandListeners) { listener.commandDone(handle.fCommand, result); } + + // Process next command in queue. processQueues(); } + private void processCommandException(CommandHandle handle, Throwable exception) { + + // If sending a command resulted in an exception, notify the client. handle.fRequestMonitor.setStatus(new Status( - IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, "Exception reading request response", exception)); + IStatus.ERROR, PDAPlugin.PLUGIN_ID, REQUEST_FAILED, "Exception reading request response", exception)); handle.fRequestMonitor.done(); + // Notify listeners also. for (ICommandListener listener : fCommandListeners) { listener.commandDone(handle.fCommand, null); } } private void processEventReceived(String event) { + // Notify the listeners only. PDAPlugin.debug("E: " + event); for (IEventListener listener : fEventListeners) { listener.eventReceived(event); @@ -396,7 +444,7 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon // with an error. for (CommandHandle handle : fCommandQueue) { handle.fRequestMonitor.setStatus(new Status( - IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Command control is terminated", null)); + IStatus.ERROR, PDAPlugin.PLUGIN_ID, INVALID_STATE, "Command control is terminated", null)); handle.fRequestMonitor.done(); } fCommandQueue.clear(); @@ -414,19 +462,24 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon } } + /** + * Return the PDA Debugger top-level Data Model context. + * @see PDAProgramDMContext + */ @ThreadSafe - public PDACommandControlDMContext getDMContext() { + public PDAProgramDMContext getProgramDMContext() { return fDMContext; } private void setStarted() { + // Mark the command control as started and ready to process commands. fStarted = true; - // Process any waiting commands. + // Process any commands which may have been queued before the processQueues(); // Issue a data model event. - getSession().dispatchEvent(new PDAStartedEvent(getDMContext()), getProperties()); + getSession().dispatchEvent(new PDAStartedEvent(getProgramDMContext()), getProperties()); } /** @@ -448,7 +501,7 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon processQueues(); // Issue a data model event. - getSession().dispatchEvent(new PDATerminatedEvent(getDMContext()), getProperties()); + getSession().dispatchEvent(new PDATerminatedEvent(getProgramDMContext()), getProperties()); } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAExpressions.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAExpressions.java new file mode 100644 index 00000000000..2995b3388d0 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAExpressions.java @@ -0,0 +1,373 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service; + +import java.util.Hashtable; +import java.util.Map; + +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.AbstractDMContext; +import org.eclipse.dd.dsf.datamodel.AbstractDMEvent; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.IExpressions; +import org.eclipse.dd.dsf.debug.service.IStack; +import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent; +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.command.CommandCache; +import org.eclipse.dd.dsf.service.AbstractDsfService; +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.examples.pda.PDAPlugin; +import org.eclipse.dd.examples.pda.service.commands.PDACommandResult; +import org.eclipse.dd.examples.pda.service.commands.PDASetVarCommand; +import org.eclipse.dd.examples.pda.service.commands.PDAVarCommand; +import org.osgi.framework.BundleContext; + +/** + * + */ +public class PDAExpressions extends AbstractDsfService implements IExpressions { + + @Immutable + private static class ExpressionDMContext extends AbstractDMContext implements IExpressionDMContext { + + final private String fExpression; + + ExpressionDMContext(String sessionId, IFrameDMContext frameDmc, String expressin) { + super(sessionId, new IDMContext[] { frameDmc }); + fExpression = expressin; + } + + public String getExpression() { + return fExpression; + } + + @Override + public boolean equals(Object other) { + return super.baseEquals(other) && ((ExpressionDMContext)other).fExpression.equals(fExpression); + } + + @Override + public int hashCode() { + return super.baseHashCode() + fExpression.hashCode(); + } + + @Override + public String toString() { + return baseToString() + ".expression(" + fExpression + ")"; + } + } + + /** + * PDA expressions are simply variables. Only the variable name + * is relevant for its data. + */ + @Immutable + private static class ExpressionDMData implements IExpressionDMData { + + final private String fExpression; + + public ExpressionDMData(String expression) { + fExpression = expression; + } + + public BasicType getBasicType() { + return BasicType.basic; + } + + public String getEncoding() { + return null; + } + + public Map getEnumerations() { + return null; + } + + public String getName() { + return fExpression; + } + + public IRegisterDMContext getRegister() { + return null; + } + + public String getStringValue() { + return null; + } + + public String getTypeId() { + return null; + } + + public String getTypeName() { + return null; + } + + } + + // @see #createExpression() + @Immutable + private static class InvalidExpressionDMContext extends AbstractDMContext implements IExpressionDMContext { + final private String fExpression; + + public InvalidExpressionDMContext(String sessionId, IDMContext parent, String expr) { + super(sessionId, new IDMContext[] { parent }); + fExpression = expr; + } + + @Override + public boolean equals(Object other) { + return super.baseEquals(other) && + fExpression == null + ? ((InvalidExpressionDMContext) other).getExpression() == null + : fExpression.equals(((InvalidExpressionDMContext) other).getExpression()); + } + + @Override + public int hashCode() { + return fExpression == null ? super.baseHashCode() : super.baseHashCode() ^ fExpression.hashCode(); + } + + @Override + public String toString() { + return baseToString() + ".invalid_expr[" + fExpression + "]"; + } + + public String getExpression() { + return fExpression; + } + } + + @Immutable + private static class ExpressionChangedDMEvent extends AbstractDMEvent + implements IExpressionChangedDMEvent + { + ExpressionChangedDMEvent(IExpressionDMContext expression) { + super(expression); + } + } + + + private PDACommandControl fCommandControl; + private IStack fStack; + + private CommandCache fCommandCache; + + public PDAExpressions(DsfSession session) { + super(session); + } + + @Override + protected BundleContext getBundleContext() { + return PDAPlugin.getBundleContext(); + } + + @Override + public void initialize(final RequestMonitor rm) { + super.initialize( + new RequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + doInitialize(rm); + }}); + } + + private void doInitialize(final RequestMonitor rm) { + fCommandControl = getServicesTracker().getService(PDACommandControl.class); + fStack = getServicesTracker().getService(IStack.class); + fCommandCache = new CommandCache(fCommandControl); + + getSession().addServiceEventListener(this, null); + + register(new String[]{IExpressions.class.getName(), PDAExpressions.class.getName()}, new Hashtable()); + + rm.done(); + } + + @Override + public void shutdown(final RequestMonitor rm) { + getSession().removeServiceEventListener(this); + fCommandCache.reset(); + super.shutdown(rm); + } + + public void canWriteExpression(IExpressionDMContext expressionContext, DataRequestMonitor rm) { + rm.setData(true); + rm.done(); + } + + public IExpressionDMContext createExpression(IDMContext ctx, String expression) { + // Create an expression based on the given context and string expression. + // The PDA debugger can only evaluate variables as expressions and only + // in context of a frame. + IFrameDMContext frameCtx = DMContexts.getAncestorOfType(ctx, IFrameDMContext.class); + if (frameCtx != null) { + return new ExpressionDMContext(getSession().getId(), frameCtx, expression); + } else { + // If a frame cannot be found in context, return an "invalid" + // expression context, because a null return value is not allowed. + // Evaluating an invalid expression context will always yield an + // error. + return new InvalidExpressionDMContext(getSession().getId(), ctx, expression); + } + } + + public void getBaseExpressions(IExpressionDMContext exprContext, DataRequestMonitor rm) { + PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Not supported"); + } + + public void getExpressionAddressData(IExpressionDMContext dmc, DataRequestMonitor rm) { + PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Not supported"); + } + + public void getExpressionData(final IExpressionDMContext exprCtx, final DataRequestMonitor rm) { + // Since expression data doesn't contain any more information than the + // context, it doesn't require any debugger commmands. + if (exprCtx instanceof ExpressionDMContext) { + rm.setData(new ExpressionDMData(exprCtx.getExpression())); + rm.done(); + } else { + PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid expression context " + exprCtx); + } + } + + public void getSubExpressionCount(IExpressionDMContext exprCtx, DataRequestMonitor rm) { + PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Not supported"); + } + + public void getSubExpressions(IExpressionDMContext exprCtx, DataRequestMonitor rm) { + PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Not supported"); + } + + public void getSubExpressions(IExpressionDMContext exprCtx, int startIndex, int length, + DataRequestMonitor rm) + { + PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Not supported"); + } + + public void getAvailableFormats(IFormattedDataDMContext dmc, DataRequestMonitor rm) { + // PDA debugger doesn't support formatting the expression. Natural + // formatting is the only available option. + rm.setData(new String[] { NATURAL_FORMAT }); + rm.done(); + } + + public FormattedValueDMContext getFormattedValueContext(IFormattedDataDMContext exprCtx, String formatId) { + // Creates a context that can be used to retrieve a formatted value. + return new FormattedValueDMContext(this, exprCtx, formatId); + } + + public void getFormattedExpressionValue(FormattedValueDMContext formattedCtx, + final DataRequestMonitor rm) + { + final ExpressionDMContext exprCtx = DMContexts.getAncestorOfType(formattedCtx, ExpressionDMContext.class); + if (exprCtx != null) { + final IFrameDMContext frameCtx = DMContexts.getAncestorOfType(exprCtx, IFrameDMContext.class); + + // First retrieve the stack depth, needed to properly calculate + // the frame index that is used by the PDAVarCommand. + fStack.getStackDepth( + frameCtx, 0, + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + // Calculate the frame index. + int frameId = getData() - frameCtx.getLevel() - 1; + + // Send the command to evaluate the variable. + fCommandCache.execute( + new PDAVarCommand(fCommandControl.getProgramDMContext(), frameId, exprCtx.getExpression()), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + rm.setData(new FormattedValueDMData(getData().fResponseText)); + rm.done(); + } + }); + } + }); + } else { + PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid expression context " + formattedCtx); + rm.done(); + } + } + + public void writeExpression(final IExpressionDMContext exprCtx, final String exprValue, String formatId, + final RequestMonitor rm) + { + if (exprCtx instanceof ExpressionDMContext) { + final IFrameDMContext frameCtx = DMContexts.getAncestorOfType(exprCtx, IFrameDMContext.class); + + // Similarly to retrieving the variable, retrieve the + // stack depth first. + fStack.getStackDepth( + frameCtx, 0, + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + // Calculate the frame index. + int frameId = getData() - frameCtx.getLevel() - 1; + + // Send the "write" command to PDA debugger + fCommandCache.execute( + new PDASetVarCommand(fCommandControl.getProgramDMContext(), frameId, exprCtx.getExpression(), exprValue), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + getSession().dispatchEvent(new ExpressionChangedDMEvent(exprCtx), getProperties()); + rm.done(); + } + }); + } + }); + } else { + PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid expression context " + exprCtx); + rm.done(); + } + } + + @SuppressWarnings("unchecked") + @Deprecated + public void getModelData(IDMContext dmc, DataRequestMonitor rm) { + if (dmc instanceof IExpressionDMContext) { + getExpressionData((IExpressionDMContext) dmc, (DataRequestMonitor) rm); + } else if (dmc instanceof FormattedValueDMContext) { + getFormattedExpressionValue((FormattedValueDMContext) dmc, (DataRequestMonitor) rm); + } else { + PDAPlugin.failRequest(rm, INVALID_HANDLE, "Unknown DMC type"); + rm.done(); + } + } + + @DsfServiceEventHandler + public void eventDispatched(IResumedDMEvent e) { + // Mark the cache as not available, so that data retrieval commands + // will fail. Also reset the cache unless it was a step command. + fCommandCache.setTargetAvailable(false); + if (!e.getReason().equals(StateChangeReason.STEP)) { + fCommandCache.reset(); + } + } + + + @DsfServiceEventHandler + public void eventDispatched(ISuspendedDMEvent e) { + // Enable sending commands to target and clear the cache. + fCommandCache.setTargetAvailable(true); + fCommandCache.reset(); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAProgramDMContext.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAProgramDMContext.java new file mode 100644 index 00000000000..4247483f78d --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAProgramDMContext.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service; + +import org.eclipse.core.runtime.PlatformObject; +import org.eclipse.dd.dsf.datamodel.AbstractDMContext; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.dsf.service.DsfSession; + +/** + * Top-level Data Model context for the PDA debugger representing the PDA + * program. + *

    + * The PDA debugger is a single-threaded application. Therefore this + * top level context implements IExecutionDMContext directly, hence this + * context can be used to call the IRunControl service to perform run + * control opreations. + *

    + *

    + * Also, the PDA debugger allows setting breakpoints in scope of the + * whole program only, so this context can be used with the breakpoints + * service to install/remove breakpoints. + *

    + *

    + * Note: There should only be one instance of PDACommandControlDMContext created + * by each PDA command control, so its equals method defaults to using + * instance comparison. + *

    + */ +public class PDAProgramDMContext extends PlatformObject + implements IExecutionDMContext, IBreakpointsTargetDMContext +{ + final static IDMContext[] EMPTY_PARENTS_ARRAY = new IDMContext[0]; + + final private String fSessionId; + final private String fProgram; + + public PDAProgramDMContext(String sessionId, String program) { + fSessionId = sessionId; + fProgram = program; + } + + public String getSessionId() { + return fSessionId; + } + + public String getProgram() { + return fProgram; + } + + public IDMContext[] getParents() { + return EMPTY_PARENTS_ARRAY; + } + + @Override + public String toString() { + return "PDA(" + getSessionId() + ")"; + } + + /** + * @see AbstractDMContext#getAdapter(Class) + */ + @Override + @SuppressWarnings("unchecked") + public Object getAdapter(Class adapterType) { + Object retVal = null; + DsfSession session = DsfSession.getSession(fSessionId); + if (session != null) { + retVal = session.getModelAdapter(adapterType); + } + if (retVal == null) { + retVal = super.getAdapter(adapterType); + } + return retVal; + } + +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java new file mode 100644 index 00000000000..62a59002dfa --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java @@ -0,0 +1,317 @@ +/******************************************************************************* + * 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 + * Ericsson AB - Modified for handling of multiple threads + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service; + +import java.util.Hashtable; + +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.AbstractDMEvent; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.datamodel.IDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.command.IEventListener; +import org.eclipse.dd.dsf.service.AbstractDsfService; +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.examples.pda.PDAPlugin; +import org.eclipse.dd.examples.pda.service.commands.PDACommandResult; +import org.eclipse.dd.examples.pda.service.commands.PDAResumeCommand; +import org.eclipse.dd.examples.pda.service.commands.PDAStepCommand; +import org.eclipse.dd.examples.pda.service.commands.PDASuspendCommand; +import org.osgi.framework.BundleContext; + + +/** + * Service for monitoring and controlling execution state of the DPA + * program. + *

    + * This service depends on the {@link PDACommandControl} service. + * It must be initialized before this service is initialized. + *

    + */ +public class PDARunControl extends AbstractDsfService + implements IRunControl, IEventListener +{ + // Implementation note about tracking execution state: + // This class implements event handlers for the events that are generated by + // this service itself. When the event is dispatched, these handlers will + // be called first, before any of the clients. These handlers update the + // service's internal state information to make them consistent with the + // events being issued. Doing this in the handlers as opposed to when + // the events are generated, guarantees that the state of the service will + // always be consistent with the events. + // The purpose of this pattern is to allow clients that listen to service + // events and track service state, to be perfectly in sync with the service + // state. + + @Immutable + private static class ExecutionDMData implements IExecutionDMData { + private final StateChangeReason fReason; + ExecutionDMData(StateChangeReason reason) { + fReason = reason; + } + public StateChangeReason getStateChangeReason() { return fReason; } + } + + @Immutable + private static class ResumedEvent extends AbstractDMEvent + implements IResumedDMEvent + { + private final String fPDAEvent; + + ResumedEvent(IExecutionDMContext ctx, String pdaEvent) { + super(ctx); + fPDAEvent = pdaEvent; + } + + public StateChangeReason getReason() { + if (fPDAEvent.startsWith("resumed breakpoint") || fPDAEvent.startsWith("suspended watch")) { + return StateChangeReason.BREAKPOINT; + } else if (fPDAEvent.equals("resumed step") || fPDAEvent.equals("resumed drop")) { + return StateChangeReason.STEP; + } else if (fPDAEvent.equals("resumed client")) { + return StateChangeReason.USER_REQUEST; + } else { + return StateChangeReason.UNKNOWN; + } + } + } + + @Immutable + private static class SuspendedEvent extends AbstractDMEvent + implements ISuspendedDMEvent + { + private final String fPDAEvent; + + SuspendedEvent(IExecutionDMContext ctx, String pdaEvent) { + super(ctx); + fPDAEvent = pdaEvent; + } + + public StateChangeReason getReason() { + if (fPDAEvent.startsWith("suspended breakpoint") || fPDAEvent.startsWith("suspended watch")) { + return StateChangeReason.BREAKPOINT; + } else if (fPDAEvent.equals("suspended step") || fPDAEvent.equals("suspended drop")) { + return StateChangeReason.STEP; + } else if (fPDAEvent.equals("suspended client")) { + return StateChangeReason.USER_REQUEST; + } else { + return StateChangeReason.UNKNOWN; + } + } + } + + // Services + private PDACommandControl fCommandControl; + + // State flags + private boolean fSuspended = true; + private boolean fResumePending = false; + private boolean fStepping = false; + private StateChangeReason fStateChangeReason; + + public PDARunControl(DsfSession session) { + super(session); + } + + @Override + protected BundleContext getBundleContext() { + return PDAPlugin.getBundleContext(); + } + + @Override + public void initialize(final RequestMonitor rm) { + super.initialize( + new RequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + doInitialize(rm); + }}); + } + + private void doInitialize(final RequestMonitor rm) { + fCommandControl = getServicesTracker().getService(PDACommandControl.class); + + // Add ourselves as a listener to PDA events, to catch suspended/resumed + // events. + fCommandControl.addEventListener(this); + + // Add ourselves as a listener to service events, in order to process + // our own suspended/resumed events. + getSession().addServiceEventListener(this, null); + + // Register the service with OSGi + register(new String[]{IRunControl.class.getName(), PDARunControl.class.getName()}, new Hashtable()); + + rm.done(); + } + + @Override + public void shutdown(final RequestMonitor rm) { + fCommandControl.removeEventListener(this); + getSession().removeServiceEventListener(this); + super.shutdown(rm); + } + + @Deprecated + @SuppressWarnings("unchecked") + public void getModelData(IDMContext dmc, DataRequestMonitor rm) { + // The getModelData() is deprecated and clients are expected to switch + // to getExecutionData() and other data retrieve methods directly. + // However the UI cache still uses it for now. + if (dmc instanceof IExecutionDMContext) { + getExecutionData((IExecutionDMContext)dmc, (DataRequestMonitor)rm); + } else { + PDAPlugin.failRequest(rm, INVALID_HANDLE, "Unknown DMC type"); + } + } + + public void eventReceived(Object output) { + if (!(output instanceof String)) return; + String event = (String)output; + + // Handle PDA debugger suspende/resumed events and issue the + // corresponding Data Model events. Do not update the state + // information until we start dispatching the service events. + if (event.startsWith("suspended")) { + IDMEvent dmEvent = new SuspendedEvent(fCommandControl.getProgramDMContext(), event); + getSession().dispatchEvent(dmEvent, getProperties()); + } else if (event.startsWith("resumed")) { + IDMEvent dmEvent = new ResumedEvent(fCommandControl.getProgramDMContext(), event); + getSession().dispatchEvent(dmEvent, getProperties()); + } + } + + + @DsfServiceEventHandler + public void eventDispatched(ResumedEvent e) { + // This service should be the first to receive the ResumedEvent, + // (before any other listeners are called). Here, update the + // service state information based on the the resumed event. + fSuspended = false; + fResumePending = false; + fStateChangeReason = e.getReason(); + fStepping = e.getReason().equals(StateChangeReason.STEP); + } + + + @DsfServiceEventHandler + public void eventDispatched(SuspendedEvent e) { + // This service should be the first to receive the SuspendedEvent also, + // (before any other listeners are called). Here, update the + // service state information based on the the suspended event. + fStateChangeReason = e.getReason(); + fResumePending = false; + fSuspended = true; + fStepping = false; + } + + + public boolean canResume(IExecutionDMContext context) { + return isSuspended(context) && !fResumePending; + } + + public boolean canSuspend(IExecutionDMContext context) { + return !isSuspended(context); + } + + public boolean isSuspended(IExecutionDMContext context) { + return fSuspended; + } + + public boolean isStepping(IExecutionDMContext context) { + return !isSuspended(context) && fStepping; + } + + public void resume(IExecutionDMContext context, final RequestMonitor rm) { + assert context != null; + + if (canResume(context)) { + fResumePending = true; + fCommandControl.queueCommand( + new PDAResumeCommand(fCommandControl.getProgramDMContext()), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleErrorOrCancel() { + // If the resume command failed, we no longer + // expect to receive a resumed event. + fResumePending = false; + } + } + ); + }else { + PDAPlugin.failRequest(rm, INVALID_STATE, "Given context: " + context + ", is already running."); + } + } + + public void suspend(IExecutionDMContext context, final RequestMonitor rm){ + assert context != null; + + if (canSuspend(context)) { + fCommandControl.queueCommand( + new PDASuspendCommand(fCommandControl.getProgramDMContext()), + new DataRequestMonitor(getExecutor(), rm)); + + } else { + PDAPlugin.failRequest(rm, IDsfService.INVALID_STATE, "Given context: " + context + ", is already suspended."); + } + } + + public boolean canStep(IExecutionDMContext context) { + return canResume(context); + } + + public void step(IExecutionDMContext context, StepType stepType, final RequestMonitor rm) { + assert context != null; + + if (canResume(context)) { + fResumePending = true; + fStepping = true; + + fCommandControl.queueCommand( + new PDAStepCommand(fCommandControl.getProgramDMContext()), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleErrorOrCancel() { + // If the step command failed, we no longer + // expect to receive a resumed event. + fResumePending = false; + fStepping = false; + } + }); + + } else { + PDAPlugin.failRequest(rm, INVALID_STATE, "Cannot resume context"); + return; + } + } + + public boolean canInstructionStep(IExecutionDMContext context) { + return false; + } + + public void instructionStep(IExecutionDMContext context, StepType stepType, RequestMonitor rm) { + PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Operation not implemented"); + } + + public void getExecutionContexts(final IContainerDMContext containerDmc, final DataRequestMonitor rm) { + PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Operation not implemented"); + } + + public void getExecutionData(IExecutionDMContext dmc, DataRequestMonitor rm){ + rm.setData( new ExecutionDMData(fStateChangeReason) ); + rm.done(); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/PDAStack.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java similarity index 51% rename from plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/PDAStack.java rename to plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java index f533f191328..f85e2f9e52f 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/PDAStack.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java @@ -8,14 +8,15 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.stack; +package org.eclipse.dd.examples.pda.service; import java.util.Hashtable; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; +import org.eclipse.cdt.core.IAddress; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.AbstractDMContext; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.debug.service.IRunControl; @@ -30,20 +31,143 @@ import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.examples.pda.PDAPlugin; -import org.eclipse.dd.examples.pda.service.command.PDACommandControl; -import org.eclipse.dd.examples.pda.service.command.commands.PDAFrame; -import org.eclipse.dd.examples.pda.service.command.commands.PDAStackCommand; -import org.eclipse.dd.examples.pda.service.command.commands.PDAStackCommandResult; +import org.eclipse.dd.examples.pda.service.commands.PDAFrame; +import org.eclipse.dd.examples.pda.service.commands.PDAStackCommand; +import org.eclipse.dd.examples.pda.service.commands.PDAStackCommandResult; import org.osgi.framework.BundleContext; /** - * + * Service for retrieving PDA debugger stack data. + *

    + * This service depends on the {@link PDACommandControl} service and the + * {@link IRunControl} service. These services must be initialized before + * this service is initialized. + *

    */ public class PDAStack extends AbstractDsfService implements IStack { + /** + * PDA stack frame contains only the stack frame level. It is only + * used as an index into the frame data returned by the PDA debugger. + */ + @Immutable + private static class FrameDMContext extends AbstractDMContext implements IFrameDMContext { + + final private int fLevel; + + FrameDMContext(String sessionId, IExecutionDMContext execDmc, int level) { + super(sessionId, new IDMContext[] { execDmc }); + fLevel = level; + } + + public int getLevel() { return fLevel; } + + @Override + public boolean equals(Object other) { + return super.baseEquals(other) && ((FrameDMContext)other).fLevel == fLevel; + } + + @Override + public int hashCode() { + return super.baseHashCode() ^ fLevel; + } + + @Override + public String toString() { + return baseToString() + ".frame[" + fLevel + "]"; //$NON-NLS-1$ //$NON-NLS-2$ + } + } + + /** + * Frame data based on the PDAFrame object returned by the PDA debugger. + */ + @Immutable + private static class FrameDMData implements IFrameDMData { + + final private PDAFrame fFrame; + + FrameDMData(PDAFrame frame) { + fFrame = frame; + } + + public String getFile() { + return fFrame.fFilePath.lastSegment(); + } + + public String getFunction() { + return fFrame.fFunction; + } + + public int getLine() { + return fFrame.fLine + 1; + } + + public int getColumn() { + return 0; + } + + public IAddress getAddress() { + return null; + } + } + + /** + * Context representing a variable in a given stack frame. + */ + @Immutable + private static class VariableDMContext extends AbstractDMContext implements IVariableDMContext { + + final private String fVariable; + + VariableDMContext(String sessionId, IFrameDMContext frameCtx, String variable) { + super(sessionId, new IDMContext[] { frameCtx }); + fVariable = variable; + } + + String getVariable() { return fVariable; } + + @Override + public boolean equals(Object other) { + return super.baseEquals(other) && ((VariableDMContext)other).fVariable.equals(fVariable); + } + + @Override + public int hashCode() { + return super.baseHashCode() + fVariable.hashCode(); + } + + @Override + public String toString() { + return baseToString() + ".variable(" + fVariable + ")"; //$NON-NLS-1$ //$NON-NLS-2$ + } + } + + /** + * PDA variable data, only supports returning the variable name. + */ + @Immutable + private static class VariableDMData implements IVariableDMData { + + final private String fVariable; + + VariableDMData(String variable) { + fVariable = variable; + } + + public String getName() { + return fVariable; + } + + public String getValue() { + return null; + } + } + + // Services that this service depends on. private PDACommandControl fCommandControl; private IRunControl fRunControl; + // Command cache private CommandCache fCommandCache; public PDAStack(DsfSession session) { @@ -66,12 +190,17 @@ public class PDAStack extends AbstractDsfService implements IStack { } private void doInitialize(final RequestMonitor rm) { + // Initialize service references that stack service depends on fCommandControl = getServicesTracker().getService(PDACommandControl.class); fRunControl = getServicesTracker().getService(IRunControl.class); + + // Create the commands cache fCommandCache = new CommandCache(fCommandControl); + // Register to listen for run control events, to clear cache accordingly. getSession().addServiceEventListener(this, null); + // Register stack service with OSGi register(new String[]{IStack.class.getName(), PDAStack.class.getName()}, new Hashtable()); rm.done(); @@ -84,46 +213,48 @@ public class PDAStack extends AbstractDsfService implements IStack { super.shutdown(rm); } + public void getArguments(IFrameDMContext frameCtx, DataRequestMonitor rm) { - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.NOT_SUPPORTED, "PDA debugger does not support function arguments.", null)); //$NON-NLS-1$ - rm.done(); + PDAPlugin.failRequest(rm, IDsfService.NOT_SUPPORTED, "PDA debugger does not support function arguments."); } public void getFrameData(final IFrameDMContext frameCtx, final DataRequestMonitor rm) { - if ( !(frameCtx instanceof FrameDMContext) ) { - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context " + frameCtx, null)); //$NON-NLS-1$ - rm.done(); - return; - } - + // Execute the PDA stack command, or retrieve the result from cache if already available. fCommandCache.execute( - new PDAStackCommand(fCommandControl.getDMContext()), + new PDAStackCommand(fCommandControl.getProgramDMContext()), new DataRequestMonitor(getExecutor(), rm) { @Override protected void handleOK() { + // PDAFrame array is ordered highest to lowest. We need to + // calculate the index based on frame level. int frameId = getData().fFrames.length - frameCtx.getLevel() - 1; if (frameId < 0) { - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid frame level " + frameCtx, null)); //$NON-NLS-1$ - rm.done(); + PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid frame level " + frameCtx); return; } - + + // Create the frame data object based on the corresponding PDAFrame rm.setData(new FrameDMData(getData().fFrames[frameId])); rm.done(); } }); } + public void getFrames(IDMContext context, final DataRequestMonitor rm) { + // Can only create stack frames for an execution context as a parent, + // however the argument context is a generic context type, so it could + // be an execution context, a frame, a variable, etc. Search the + // hierarchy of the argument context to find the execution one. final IExecutionDMContext execCtx = DMContexts.getAncestorOfType(context, IExecutionDMContext.class); if (execCtx == null) { - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context " + context, null)); //$NON-NLS-1$ - rm.done(); + PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid context " + context); return; } - + + // Execute the stack command and create the corresponding frame contexts. fCommandCache.execute( - new PDAStackCommand(fCommandControl.getDMContext()), + new PDAStackCommand(fCommandControl.getProgramDMContext()), new DataRequestMonitor(getExecutor(), rm) { @Override protected void handleOK() { @@ -138,26 +269,21 @@ public class PDAStack extends AbstractDsfService implements IStack { } public void getLocals(final IFrameDMContext frameCtx, final DataRequestMonitor rm) { - if ( !(frameCtx instanceof FrameDMContext) ) { - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context " + frameCtx, null)); //$NON-NLS-1$ - rm.done(); - return; - } - + // Execute the stack command again. fCommandCache.execute( - new PDAStackCommand(fCommandControl.getDMContext()), + new PDAStackCommand(fCommandControl.getProgramDMContext()), new DataRequestMonitor(getExecutor(), rm) { @Override protected void handleOK() { + // Find the correct PDAFrame int frameId = getData().fFrames.length - frameCtx.getLevel() - 1; if (frameId < 0) { - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid frame level " + frameCtx, null)); //$NON-NLS-1$ - rm.done(); + PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid frame level " + frameCtx); return; } - - PDAFrame pdaFrame = getData().fFrames[frameId]; + + // Create variable contexts for all variables in frame. IVariableDMContext[] variableCtxs = new IVariableDMContext[pdaFrame.fVariables.length]; for (int i = 0; i < pdaFrame.fVariables.length; i++) { variableCtxs[i] = new VariableDMContext(getSession().getId(), frameCtx, pdaFrame.fVariables[i]); @@ -170,8 +296,9 @@ public class PDAStack extends AbstractDsfService implements IStack { } public void getStackDepth(IDMContext context, int maxDepth, final DataRequestMonitor rm) { + // Execute stack command and return the data's size. fCommandCache.execute( - new PDAStackCommand(fCommandControl.getDMContext()), + new PDAStackCommand(fCommandControl.getProgramDMContext()), new DataRequestMonitor(getExecutor(), rm) { @Override protected void handleOK() { @@ -182,23 +309,30 @@ public class PDAStack extends AbstractDsfService implements IStack { } public void getTopFrame(IDMContext context, final DataRequestMonitor rm) { + // Can only create stack frames for an execution context as a parent, + // however the argument context is a generic context type, so it could + // be an execution context, a frame, a variable, etc. Search the + // hierarchy of the argument context to find the execution one. final IExecutionDMContext execCtx = DMContexts.getAncestorOfType(context, IExecutionDMContext.class); if (execCtx == null) { - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context " + context, null)); //$NON-NLS-1$ - rm.done(); + PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid context " + context); return; } + + // Since the frame context only contain the level, there's no need to + // call the PDA debugger. Simply create a context for level 0. rm.setData(new FrameDMContext(getSession().getId(), execCtx, 0)); rm.done(); } public void getVariableData(IVariableDMContext variableCtx, DataRequestMonitor rm) { if ( !(variableCtx instanceof VariableDMContext) ) { - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context " + variableCtx, null)); //$NON-NLS-1$ - rm.done(); + PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid context " + variableCtx); return; } + // The variable data doen't contain a value. So there's no need to + // go to the back end to retrieve it. String variable = ((VariableDMContext)variableCtx).getVariable(); rm.setData(new VariableDMData(variable)); @@ -206,26 +340,30 @@ public class PDAStack extends AbstractDsfService implements IStack { } public boolean isStackAvailable(IDMContext context) { + // Stack is available if the program is suspended or stepping. IExecutionDMContext execCtx = DMContexts.getAncestorOfType(context, IExecutionDMContext.class); return execCtx != null && (fRunControl.isSuspended(execCtx) || (fRunControl.isStepping(execCtx))); } + @SuppressWarnings("unchecked") @Deprecated public void getModelData(IDMContext dmc, DataRequestMonitor rm) { + // The getModelData() is deprecated and clients are expected to switch + // to getExecutionData() and other data retrieve methods directly. + // However the UI cache still uses it for now. if (dmc instanceof IFrameDMContext) { getFrameData((IFrameDMContext)dmc, (DataRequestMonitor)rm); - // getFrameData invokes rm } else if (dmc instanceof IVariableDMContext) { getVariableData((IVariableDMContext)dmc, (DataRequestMonitor)rm); - // getVariablesData invokes rm } else { - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Unknown context type", null)); //$NON-NLS-1$ - rm.done(); + PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Unknown context type"); } } @DsfServiceEventHandler public void eventDispatched(IResumedDMEvent e) { + // Mark the cache as not available, so that stack commands will + // fail. Also reset the cache unless it was a step command. fCommandCache.setTargetAvailable(false); if (!e.getReason().equals(StateChangeReason.STEP)) { fCommandCache.reset(); @@ -235,6 +373,7 @@ public class PDAStack extends AbstractDsfService implements IStack { @DsfServiceEventHandler public void eventDispatched(ISuspendedDMEvent e) { + // Enable sending commands to target and clear the cache. fCommandCache.setTargetAvailable(true); fCommandCache.reset(); } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDAStartedEvent.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStartedEvent.java similarity index 74% rename from plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDAStartedEvent.java rename to plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStartedEvent.java index 0c9f16ab8d1..801c561f5bd 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDAStartedEvent.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStartedEvent.java @@ -8,15 +8,15 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.command; +package org.eclipse.dd.examples.pda.service; import org.eclipse.dd.dsf.datamodel.AbstractDMEvent; /** - * + * Event issued when the PDA debugger is started. */ -public class PDAStartedEvent extends AbstractDMEvent { - PDAStartedEvent(PDACommandControlDMContext context) { +public class PDAStartedEvent extends AbstractDMEvent { + PDAStartedEvent(PDAProgramDMContext context) { super(context); } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDATerminatedEvent.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDATerminatedEvent.java similarity index 74% rename from plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDATerminatedEvent.java rename to plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDATerminatedEvent.java index ebc43b642c5..0117f90c155 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDATerminatedEvent.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDATerminatedEvent.java @@ -8,15 +8,15 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.command; +package org.eclipse.dd.examples.pda.service; import org.eclipse.dd.dsf.datamodel.AbstractDMEvent; /** - * + * Event issued when the PDA debugger exits. */ -public class PDATerminatedEvent extends AbstractDMEvent { - PDATerminatedEvent(PDACommandControlDMContext context) { +public class PDATerminatedEvent extends AbstractDMEvent { + PDATerminatedEvent(PDAProgramDMContext context) { super(context); } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/breakpoints/BreakpointDMContext.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/breakpoints/BreakpointDMContext.java deleted file mode 100644 index 0802693ccae..00000000000 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/breakpoints/BreakpointDMContext.java +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.breakpoints; - -import org.eclipse.dd.dsf.concurrent.Immutable; -import org.eclipse.dd.dsf.datamodel.AbstractDMContext; -import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointDMContext; -import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; - -/** - * Context representing a PDA line breakpoint. In PDA debugger, since there is only - * one file being debugged at a time, a breakpoint is uniquely identified using the - * line number only. - */ -@Immutable -class BreakpointDMContext extends AbstractDMContext implements IBreakpointDMContext { - - final Integer fLine; - - public BreakpointDMContext(String sessionId, PDACommandControlDMContext commandControlCtx, Integer line) { - super(sessionId, new IDMContext[] { commandControlCtx }); - fLine = line; - } - - @Override - public boolean equals(Object obj) { - return baseEquals(obj) && (fLine.equals(((BreakpointDMContext) obj).fLine)); - } - - @Override - public int hashCode() { - return baseHashCode() + fLine.hashCode(); - } - - @Override - public String toString() { - return baseToString() + ".breakpoint(" + fLine + ")"; //$NON-NLS-1$//$NON-NLS-2$*/ - } -} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/breakpoints/PDABreakpoints.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/breakpoints/PDABreakpoints.java deleted file mode 100644 index c943d8ae43c..00000000000 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/breakpoints/PDABreakpoints.java +++ /dev/null @@ -1,264 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Ericsson 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: - * Ericsson - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.dd.examples.pda.service.breakpoints; - -import java.util.HashSet; -import java.util.Hashtable; -import java.util.Map; -import java.util.Set; - -import org.eclipse.core.resources.IMarker; -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.debug.service.IBreakpoints; -import org.eclipse.dd.dsf.service.AbstractDsfService; -import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; -import org.eclipse.dd.examples.pda.PDAPlugin; -import org.eclipse.dd.examples.pda.breakpoints.PDAWatchpoint; -import org.eclipse.dd.examples.pda.service.command.PDACommandControl; -import org.eclipse.dd.examples.pda.service.command.PDACommandResult; -import org.eclipse.dd.examples.pda.service.command.commands.PDAClearBreakpointCommand; -import org.eclipse.dd.examples.pda.service.command.commands.PDASetBreakpointCommand; -import org.eclipse.dd.examples.pda.service.command.commands.PDAWatchCommand; -import org.osgi.framework.BundleContext; - -/** - * Initial breakpoint service implementation. - * Implements the IBreakpoints interface. - */ -public class PDABreakpoints extends AbstractDsfService implements IBreakpoints -{ - public static final String ATTR_BREAKPOINT_TYPE = PDAPlugin.PLUGIN_ID + ".pdaBreakpointType"; //$NON-NLS-1$ - public static final String PDA_LINE_BREAKPOINT = "breakpoint"; //$NON-NLS-1$ - public static final String PDA_WATCHPOINT = "watchpoint"; //$NON-NLS-1$ - public static final String ATTR_PROGRAM_PATH = PDAPlugin.PLUGIN_ID + ".pdaProgramPath"; //$NON-NLS-1$ - - private final String fProgram; - - // Services - private PDACommandControl fCommandControl; - - // Service breakpoints tracking - // The breakpoints are stored per context and keyed on the back-end breakpoint reference - private Set fBreakpoints = new HashSet(); - - /** - * The service constructor - * - * @param session The debugging session this service belongs to. - * @param program The name of the program of this PDA debugger. - */ - public PDABreakpoints(DsfSession session, String program) { - super(session); - fProgram = program; - } - - @Override - public void initialize(final RequestMonitor rm) { - super.initialize(new RequestMonitor(getExecutor(), rm) { - @Override - protected void handleOK() { - doInitialize(rm); - } - }); - } - - private void doInitialize(final RequestMonitor rm) { - - // Get the services references - fCommandControl = getServicesTracker().getService(PDACommandControl.class); - - // Register this service - register(new String[] { IBreakpoints.class.getName(), PDABreakpoints.class.getName() }, - new Hashtable()); - - rm.done(); - } - - @Override - public void shutdown(final RequestMonitor rm) { - unregister(); - rm.done(); - } - - @Override - protected BundleContext getBundleContext() { - return PDAPlugin.getBundleContext(); - } - - public void getBreakpoints(final IBreakpointsTargetDMContext context, final DataRequestMonitor rm) { - // Validate the context - if (!fCommandControl.getDMContext().equals(context)) { - PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid breakpoints target context"); - return; - } - - rm.setData(fBreakpoints.toArray(new IBreakpointDMContext[fBreakpoints.size()])); - rm.done(); - } - - public void getBreakpointDMData(IBreakpointDMContext dmc, DataRequestMonitor rm) { - PDAPlugin.failRequest(rm, IDsfService.NOT_SUPPORTED, "Retrieving breakpoint data is not supported"); - } - - public void insertBreakpoint(IBreakpointsTargetDMContext context, Map attributes, - DataRequestMonitor rm) - { - String type = (String) attributes.get(ATTR_BREAKPOINT_TYPE); - - if (PDA_LINE_BREAKPOINT.equals(type)) { - doInsertBreakpoint(attributes, rm); - } - else if (PDA_WATCHPOINT.equals(type)) { - doInsertWatchpoint(attributes, rm); - } - else { - PDAPlugin.failRequest(rm, IDsfService.REQUEST_FAILED, "Unknown breakpoint type"); - } - } - - private void doInsertBreakpoint(final Map attributes, final DataRequestMonitor rm) - { - String program = (String)attributes.get(ATTR_PROGRAM_PATH); - if (!fProgram.equals(program)) { - PDAPlugin.failRequest(rm, IDsfService.REQUEST_FAILED, "Invalid file name"); - return; - } - - Integer line = (Integer)attributes.get(IMarker.LINE_NUMBER); - if (line == null) { - PDAPlugin.failRequest(rm, IDsfService.REQUEST_FAILED, "No breakpoint line specified"); - return; - } - - final BreakpointDMContext breakpointCtx = - new BreakpointDMContext(getSession().getId(), fCommandControl.getDMContext(), line); - if (fBreakpoints.contains(breakpointCtx)) { - PDAPlugin.failRequest(rm, IDsfService.REQUEST_FAILED, "Breakpoint already set"); - return; - } - - fBreakpoints.add(breakpointCtx); - fCommandControl.queueCommand( - new PDASetBreakpointCommand(fCommandControl.getDMContext(), line), - new DataRequestMonitor(getExecutor(), rm) { - @Override - protected void handleOK() { - rm.setData(breakpointCtx); - rm.done(); - } - - @Override - protected void handleErrorOrCancel() { - fBreakpoints.remove(breakpointCtx); - super.handleErrorOrCancel(); - } - }); - } - - private void doInsertWatchpoint(final Map attributes, final DataRequestMonitor rm) - { - String function = (String)attributes.get(PDAWatchpoint.FUNCTION_NAME); - if (function == null) { - PDAPlugin.failRequest(rm, IDsfService.REQUEST_FAILED, "No function specified"); - return; - } - - String variable = (String)attributes.get(PDAWatchpoint.VAR_NAME); - if (variable == null) { - PDAPlugin.failRequest(rm, IDsfService.REQUEST_FAILED, "No variable specified"); - return; - } - - Boolean isAccess = (Boolean)attributes.get(PDAWatchpoint.ACCESS); - isAccess = isAccess != null ? isAccess : Boolean.FALSE; - - Boolean isModification = (Boolean)attributes.get(PDAWatchpoint.MODIFICATION); - isModification = isModification != null ? isModification : Boolean.FALSE; - - final WatchpointDMContext watchpointCtx = - new WatchpointDMContext(getSession().getId(), fCommandControl.getDMContext(), function, variable); - if (fBreakpoints.contains(watchpointCtx)) { - PDAPlugin.failRequest(rm, IDsfService.REQUEST_FAILED, "Watchpoint already set"); - return; - } - - PDAWatchCommand.WatchOperation watchOperation = PDAWatchCommand.WatchOperation.NONE; - if (isAccess && isModification) { - watchOperation = PDAWatchCommand.WatchOperation.BOTH; - } else if (isAccess) { - watchOperation = PDAWatchCommand.WatchOperation.READ; - } else if (isModification) { - watchOperation = PDAWatchCommand.WatchOperation.WRITE; - } - - fBreakpoints.add(watchpointCtx); - fCommandControl.queueCommand( - new PDAWatchCommand(fCommandControl.getDMContext(), function, variable, watchOperation), - new DataRequestMonitor(getExecutor(), rm) { - @Override - protected void handleOK() { - rm.setData(watchpointCtx); - rm.done(); - } - - @Override - protected void handleErrorOrCancel() { - // Since the command failed, we need to remove the breakpoint from - // the existing breakpoint set. - fBreakpoints.remove(watchpointCtx); - super.handleErrorOrCancel(); - } - }); - } - - public void removeBreakpoint(IBreakpointDMContext bpCtx, RequestMonitor rm) { - if (!fBreakpoints.contains(bpCtx)) { - PDAPlugin.failRequest(rm, IDsfService.REQUEST_FAILED, "Breakpoint already removed"); - return; - } - - if (bpCtx instanceof BreakpointDMContext) { - doRemoveBreakpoint((BreakpointDMContext)bpCtx, rm); - } else if (bpCtx instanceof WatchpointDMContext) { - doRemoveWatchpoint((WatchpointDMContext)bpCtx, rm); - } else { - PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid breakpoint"); - } - } - - private void doRemoveBreakpoint(BreakpointDMContext bpCtx, RequestMonitor rm) { - // Remove the breakpoint from the table right away, so that even when - // the remove is being processed, a new breakpoint can be created at the same - // location. - fBreakpoints.remove(bpCtx); - - fCommandControl.queueCommand( - new PDAClearBreakpointCommand(fCommandControl.getDMContext(), bpCtx.fLine), - new DataRequestMonitor(getExecutor(), rm)); - } - - private void doRemoveWatchpoint(WatchpointDMContext bpCtx, RequestMonitor rm) { - fBreakpoints.remove(bpCtx); - - // Watchpoints are cleared using the same command, but with a "no watch" operation - fCommandControl.queueCommand( - new PDAWatchCommand(fCommandControl.getDMContext(), bpCtx.fFunction, bpCtx.fVariable, - PDAWatchCommand.WatchOperation.NONE), - new DataRequestMonitor(getExecutor(), rm)); - } - - public void updateBreakpoint(IBreakpointDMContext dmc, Map properties, RequestMonitor rm) { - PDAPlugin.failRequest(rm, IDsfService.NOT_SUPPORTED, "Modifying PDA breakpoints is not supported"); - } -} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/breakpoints/WatchpointDMContext.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/breakpoints/WatchpointDMContext.java deleted file mode 100644 index 6e0e7252a87..00000000000 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/breakpoints/WatchpointDMContext.java +++ /dev/null @@ -1,54 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.breakpoints; - -import org.eclipse.dd.dsf.concurrent.Immutable; -import org.eclipse.dd.dsf.datamodel.AbstractDMContext; -import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointDMContext; -import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; - -/** - * Context representing a watch point. In PDA debugger, a watchpoint is - * uniquely identified using the function and variable. - */ -@Immutable -class WatchpointDMContext extends AbstractDMContext implements IBreakpointDMContext { - final String fFunction; - final String fVariable; - - public WatchpointDMContext(String sessionId, PDACommandControlDMContext commandControlCtx, String function, - String variable) - { - super(sessionId, new IDMContext[] { commandControlCtx }); - fFunction = function; - fVariable = variable; - } - - @Override - public boolean equals(Object obj) { - if (baseEquals(obj)) { - WatchpointDMContext watchpointCtx = (WatchpointDMContext)obj; - return fFunction.equals(watchpointCtx.fFunction) && fVariable.equals(watchpointCtx.fVariable); - } - return false; - } - - @Override - public int hashCode() { - return baseHashCode() + fFunction.hashCode() + fVariable.hashCode(); - } - - @Override - public String toString() { - return baseToString() + ".watchpoint(" + fFunction + "::" + fVariable + ")"; - } -} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommandControlDMContext.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommandControlDMContext.java deleted file mode 100644 index 2b34baf4477..00000000000 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommandControlDMContext.java +++ /dev/null @@ -1,45 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.command; - -import org.eclipse.dd.dsf.datamodel.AbstractDMContext; -import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; -import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; - -/** - * - */ -public class PDACommandControlDMContext extends AbstractDMContext - implements IExecutionDMContext, IBreakpointsTargetDMContext -{ - - private Object fHashObject = new Object(); - - public PDACommandControlDMContext(String sessionId) { - super(sessionId, new IDMContext[0]); - } - - @Override - public boolean equals(Object obj) { - return obj == this; - } - - @Override - public int hashCode() { - return fHashObject.hashCode(); - } - - @Override - public String toString() { - return "PDA(" + getSessionId() + ")"; - } -} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAVarCommandResult.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAVarCommandResult.java deleted file mode 100644 index 3275256f41a..00000000000 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAVarCommandResult.java +++ /dev/null @@ -1,27 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.command.commands; - -import org.eclipse.dd.examples.pda.service.command.PDACommandResult; - - -/** - * @see PDAVarCommand - */ -public class PDAVarCommandResult extends PDACommandResult { - - final public int fValue; - - PDAVarCommandResult(String response) { - super(response); - fValue = Integer.parseInt(response); - } -} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/AbstractPDACommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/AbstractPDACommand.java similarity index 68% rename from plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/AbstractPDACommand.java rename to plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/AbstractPDACommand.java index 719df9cd6ae..bd75d996c63 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/AbstractPDACommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/AbstractPDACommand.java @@ -8,23 +8,24 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.command.commands; +package org.eclipse.dd.examples.pda.service.commands; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.debug.service.command.ICommand; import org.eclipse.dd.dsf.debug.service.command.ICommandResult; -import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; -import org.eclipse.dd.examples.pda.service.command.PDACommandResult; +import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** - * + * Base class for PDA commands. The PDA commands consist of a text request and + * a context. Since the PDA debugger protocol is stateless, the context is only + * needed to satisfy the ICommand interface. */ abstract public class AbstractPDACommand implements ICommand { final private IDMContext fContext; final private String fRequest; - public AbstractPDACommand(PDACommandControlDMContext context, String request) { + public AbstractPDACommand(PDAProgramDMContext context, String request) { fContext = context; fRequest = request; } @@ -36,11 +37,20 @@ abstract public class AbstractPDACommand implements public ICommand coalesceWith(ICommand command) { return null; } - + + /** + * Returns the request to be sent to PDA. + */ public String getRequest() { return fRequest; } - + + /** + * Returns the command result based on the given PDA response. This command + * uses the class type parameter as the return type to allow the compiler to + * enforce the correct command result. This class must be implemented by + * each command to create the concrete result type. + */ abstract public V createResult(String resultText); @Override diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAClearBreakpointCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAClearBreakpointCommand.java similarity index 75% rename from plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAClearBreakpointCommand.java rename to plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAClearBreakpointCommand.java index a394fb2e7f3..b0873d3254d 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAClearBreakpointCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAClearBreakpointCommand.java @@ -8,10 +8,9 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.command.commands; +package org.eclipse.dd.examples.pda.service.commands; -import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; -import org.eclipse.dd.examples.pda.service.command.PDACommandResult; +import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** * Clears any breakpoint set on given line @@ -24,7 +23,7 @@ import org.eclipse.dd.examples.pda.service.command.PDACommandResult; */ public class PDAClearBreakpointCommand extends AbstractPDACommand { - public PDAClearBreakpointCommand(PDACommandControlDMContext context, int line) { + public PDAClearBreakpointCommand(PDAProgramDMContext context, int line) { super(context, "clear " + (line - 1)); } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommandResult.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDACommandResult.java similarity index 84% rename from plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommandResult.java rename to plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDACommandResult.java index 31f49a68b55..053f2e99796 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/PDACommandResult.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDACommandResult.java @@ -8,14 +8,16 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.command; +package org.eclipse.dd.examples.pda.service.commands; import org.eclipse.dd.dsf.debug.service.command.ICommand; import org.eclipse.dd.dsf.debug.service.command.ICommandResult; /** - * + * Basic command result object. This command result simply allows access to the + * PDA response. Sub-classes may override to optionally parse the response text + * and return higher-level objects. */ public class PDACommandResult implements ICommandResult { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDADataCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommand.java similarity index 77% rename from plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDADataCommand.java rename to plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommand.java index 835f5a638a5..fab0f679ba0 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDADataCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommand.java @@ -8,10 +8,9 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.command.commands; +package org.eclipse.dd.examples.pda.service.commands; -import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; -import org.eclipse.dd.examples.pda.service.command.PDACommandResult; +import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** * Retrieves data stack information @@ -23,7 +22,7 @@ import org.eclipse.dd.examples.pda.service.command.PDACommandResult; */ public class PDADataCommand extends AbstractPDACommand { - public PDADataCommand(PDACommandControlDMContext context) { + public PDADataCommand(PDAProgramDMContext context) { super(context, "data"); } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDADataCommandResult.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommandResult.java similarity index 77% rename from plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDADataCommandResult.java rename to plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommandResult.java index 20e895eeab8..e31b1c8ae58 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDADataCommandResult.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommandResult.java @@ -8,35 +8,33 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.command.commands; +package org.eclipse.dd.examples.pda.service.commands; import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; -import org.eclipse.dd.examples.pda.service.command.PDACommandResult; /** * @see PDADataCommand */ public class PDADataCommandResult extends PDACommandResult { - final public int[] fValues; + final public String[] fValues; PDADataCommandResult(String response) { super(response); StringTokenizer st = new StringTokenizer(response, "|"); - List valuesList = new ArrayList(); + List valuesList = new ArrayList(); while (st.hasMoreTokens()) { String token = st.nextToken(); if (token.length() != 0) { - valuesList.add(new Integer(st.nextToken())); + valuesList.add(st.nextToken()); } } - - fValues = new int[valuesList.size()]; + fValues = new String[valuesList.size()]; for (int i = 0; i < valuesList.size(); i++) { fValues[i] = valuesList.get(i); } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDADropFrameCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADropFrameCommand.java similarity index 77% rename from plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDADropFrameCommand.java rename to plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADropFrameCommand.java index 0c09a9b4f87..1a1f4cc8f92 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDADropFrameCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADropFrameCommand.java @@ -8,10 +8,9 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.command.commands; +package org.eclipse.dd.examples.pda.service.commands; -import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; -import org.eclipse.dd.examples.pda.service.command.PDACommandResult; +import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** * Returns from the current frame without executing the rest of instructions. @@ -26,7 +25,7 @@ import org.eclipse.dd.examples.pda.service.command.PDACommandResult; */ public class PDADropFrameCommand extends AbstractPDACommand { - public PDADropFrameCommand(PDACommandControlDMContext context) { + public PDADropFrameCommand(PDAProgramDMContext context) { super(context, "drop"); } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAEvalCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAEvalCommand.java similarity index 79% rename from plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAEvalCommand.java rename to plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAEvalCommand.java index da38d1957cf..082362e7415 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAEvalCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAEvalCommand.java @@ -8,10 +8,9 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.command.commands; +package org.eclipse.dd.examples.pda.service.commands; -import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; -import org.eclipse.dd.examples.pda.service.command.PDACommandResult; +import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** * Sets what events cause the execution to stop. @@ -28,7 +27,7 @@ import org.eclipse.dd.examples.pda.service.command.PDACommandResult; */ public class PDAEvalCommand extends AbstractPDACommand { - public PDAEvalCommand(PDACommandControlDMContext context, String operation) { + public PDAEvalCommand(PDAProgramDMContext context, String operation) { super(context, "eval " + operation); } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAEventStopCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAEventStopCommand.java similarity index 80% rename from plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAEventStopCommand.java rename to plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAEventStopCommand.java index d19369f99d4..653f2aa945a 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAEventStopCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAEventStopCommand.java @@ -8,10 +8,9 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.command.commands; +package org.eclipse.dd.examples.pda.service.commands; -import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; -import org.eclipse.dd.examples.pda.service.command.PDACommandResult; +import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** * Sets what events cause the execution to stop. @@ -29,7 +28,7 @@ public class PDAEventStopCommand extends AbstractPDACommand { public enum Event { UNIMPINSTR, NOSUCHLABEL }; - public PDAEventStopCommand(PDACommandControlDMContext context, Event event, boolean enable) { + public PDAEventStopCommand(PDAProgramDMContext context, Event event, boolean enable) { super(context, "eventstop " + (event == Event.UNIMPINSTR ? "unimpinstr " : "nosuchlabel ") + diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAExitCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAExitCommand.java similarity index 76% rename from plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAExitCommand.java rename to plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAExitCommand.java index dd074c3ed1f..0514aa675f5 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAExitCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAExitCommand.java @@ -8,10 +8,9 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.command.commands; +package org.eclipse.dd.examples.pda.service.commands; -import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; -import org.eclipse.dd.examples.pda.service.command.PDACommandResult; +import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** * Instructs the debugger to exit. @@ -23,7 +22,7 @@ import org.eclipse.dd.examples.pda.service.command.PDACommandResult; */ public class PDAExitCommand extends AbstractPDACommand { - public PDAExitCommand(PDACommandControlDMContext context) { + public PDAExitCommand(PDAProgramDMContext context) { super(context, "exit"); } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAFrame.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAFrame.java similarity index 89% rename from plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAFrame.java rename to plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAFrame.java index bc427e21fa4..ab2b2c5612a 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAFrame.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAFrame.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.command.commands; +package org.eclipse.dd.examples.pda.service.commands; import java.util.ArrayList; import java.util.List; @@ -17,7 +17,18 @@ import java.util.StringTokenizer; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; +/** + * Object representing a frame in the stack command results. + * + * @see PDAStackCommand + */ public class PDAFrame { + + final public IPath fFilePath; + final public int fLine; + final public String fFunction; + final public String[] fVariables; + PDAFrame(String frameString) { StringTokenizer st = new StringTokenizer(frameString, "|"); @@ -31,8 +42,4 @@ public class PDAFrame { } fVariables = variablesList.toArray(new String[variablesList.size()]); } - final public IPath fFilePath; - final public int fLine; - final public String fFunction; - final public String[] fVariables; } \ No newline at end of file diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAPopDataCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAPopDataCommand.java similarity index 76% rename from plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAPopDataCommand.java rename to plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAPopDataCommand.java index 1f35dba715f..952e53cd17c 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAPopDataCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAPopDataCommand.java @@ -8,10 +8,9 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.command.commands; +package org.eclipse.dd.examples.pda.service.commands; -import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; -import org.eclipse.dd.examples.pda.service.command.PDACommandResult; +import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** * Pops the top value from the data stack @@ -23,7 +22,7 @@ import org.eclipse.dd.examples.pda.service.command.PDACommandResult; */ public class PDAPopDataCommand extends AbstractPDACommand { - public PDAPopDataCommand(PDACommandControlDMContext context) { + public PDAPopDataCommand(PDAProgramDMContext context) { super(context, "popdata"); } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAPushDataCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAPushDataCommand.java similarity index 76% rename from plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAPushDataCommand.java rename to plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAPushDataCommand.java index a2b817e776c..7226c765518 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAPushDataCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAPushDataCommand.java @@ -8,10 +8,9 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.command.commands; +package org.eclipse.dd.examples.pda.service.commands; -import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; -import org.eclipse.dd.examples.pda.service.command.PDACommandResult; +import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** * Pushes the given value on top of the data stack. @@ -23,7 +22,7 @@ import org.eclipse.dd.examples.pda.service.command.PDACommandResult; */ public class PDAPushDataCommand extends AbstractPDACommand { - public PDAPushDataCommand(PDACommandControlDMContext context, int value) { + public PDAPushDataCommand(PDAProgramDMContext context, int value) { super(context, "pushdata " + value); } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAResumeCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAResumeCommand.java similarity index 76% rename from plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAResumeCommand.java rename to plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAResumeCommand.java index 40582908460..35b83c35a13 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAResumeCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAResumeCommand.java @@ -8,10 +8,9 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.command.commands; +package org.eclipse.dd.examples.pda.service.commands; -import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; -import org.eclipse.dd.examples.pda.service.command.PDACommandResult; +import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** * Resumes the execution @@ -24,7 +23,7 @@ import org.eclipse.dd.examples.pda.service.command.PDACommandResult; */ public class PDAResumeCommand extends AbstractPDACommand { - public PDAResumeCommand(PDACommandControlDMContext context) { + public PDAResumeCommand(PDAProgramDMContext context) { super(context, "resume"); } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASetBreakpointCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASetBreakpointCommand.java similarity index 77% rename from plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASetBreakpointCommand.java rename to plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASetBreakpointCommand.java index a46ce388d2c..7dd14c6456a 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASetBreakpointCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASetBreakpointCommand.java @@ -8,10 +8,9 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.command.commands; +package org.eclipse.dd.examples.pda.service.commands; -import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; -import org.eclipse.dd.examples.pda.service.command.PDACommandResult; +import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** * Sets a breakpoint at given line @@ -26,7 +25,7 @@ import org.eclipse.dd.examples.pda.service.command.PDACommandResult; */ public class PDASetBreakpointCommand extends AbstractPDACommand { - public PDASetBreakpointCommand(PDACommandControlDMContext context, int line) { + public PDASetBreakpointCommand(PDAProgramDMContext context, int line) { super(context, "set " + (line - 1)); } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASetDataCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASetDataCommand.java similarity index 76% rename from plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASetDataCommand.java rename to plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASetDataCommand.java index fc4a94992da..b66772f8688 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASetDataCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASetDataCommand.java @@ -8,10 +8,9 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.command.commands; +package org.eclipse.dd.examples.pda.service.commands; -import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; -import org.eclipse.dd.examples.pda.service.command.PDACommandResult; +import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** * Sets a data value in the data stack at the given location @@ -23,7 +22,7 @@ import org.eclipse.dd.examples.pda.service.command.PDACommandResult; */ public class PDASetDataCommand extends AbstractPDACommand { - public PDASetDataCommand(PDACommandControlDMContext context, int index, int value) { + public PDASetDataCommand(PDAProgramDMContext context, int index, String value) { super(context, "setdata " + index + " " + value); } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASetVarCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASetVarCommand.java similarity index 67% rename from plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASetVarCommand.java rename to plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASetVarCommand.java index cafbe6d1372..5fcf7d77b49 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASetVarCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASetVarCommand.java @@ -8,23 +8,22 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.command.commands; +package org.eclipse.dd.examples.pda.service.commands; -import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; -import org.eclipse.dd.examples.pda.service.command.PDACommandResult; +import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** * Sets a variable value * *
    - *    C: setvar {variable} {value}
    + *    C: setvar {frame_number} {variable} {value}
      *    R: ok
      * 
    */ public class PDASetVarCommand extends AbstractPDACommand { - public PDASetVarCommand(PDACommandControlDMContext context, String variable, String value) { - super(context, "setvar " + variable + " " + value); + public PDASetVarCommand(PDAProgramDMContext context, int frame, String variable, String value) { + super(context, "setvar " + frame + " " + variable + " " + value); } @Override diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStackCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStackCommand.java similarity index 82% rename from plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStackCommand.java rename to plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStackCommand.java index 3db048e2c4e..cd26fa07ff5 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStackCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStackCommand.java @@ -8,9 +8,9 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.command.commands; +package org.eclipse.dd.examples.pda.service.commands; -import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; +import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** * Retrieves command stack information @@ -22,7 +22,7 @@ import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; */ public class PDAStackCommand extends AbstractPDACommand { - public PDAStackCommand(PDACommandControlDMContext context) { + public PDAStackCommand(PDAProgramDMContext context) { super(context, "stack"); } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStackCommandResult.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStackCommandResult.java similarity index 85% rename from plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStackCommandResult.java rename to plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStackCommandResult.java index 1b4e07e5560..5cc1bf1fc71 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStackCommandResult.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStackCommandResult.java @@ -8,19 +8,22 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.command.commands; +package org.eclipse.dd.examples.pda.service.commands; import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; -import org.eclipse.dd.examples.pda.service.command.PDACommandResult; /** * @see PDAStackCommand */ public class PDAStackCommandResult extends PDACommandResult { + /** + * Array of frames return by the stack commands. The frames are ordered + * with the highest-level frame first. + */ final public PDAFrame[] fFrames; PDAStackCommandResult(String response) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStepCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStepCommand.java similarity index 77% rename from plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStepCommand.java rename to plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStepCommand.java index 9a3f536fbc5..a50713acc8b 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStepCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStepCommand.java @@ -8,10 +8,9 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.command.commands; +package org.eclipse.dd.examples.pda.service.commands; -import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; -import org.eclipse.dd.examples.pda.service.command.PDACommandResult; +import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** * Executes next instruciton @@ -25,7 +24,7 @@ import org.eclipse.dd.examples.pda.service.command.PDACommandResult; */ public class PDAStepCommand extends AbstractPDACommand { - public PDAStepCommand(PDACommandControlDMContext context) { + public PDAStepCommand(PDAProgramDMContext context) { super(context, "step"); } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStepReturnCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStepReturnCommand.java similarity index 77% rename from plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStepReturnCommand.java rename to plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStepReturnCommand.java index 4d1d6ec6996..8ba0dedfb3b 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAStepReturnCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStepReturnCommand.java @@ -8,10 +8,9 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.command.commands; +package org.eclipse.dd.examples.pda.service.commands; -import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; -import org.eclipse.dd.examples.pda.service.command.PDACommandResult; +import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** * Executes instructions until the current subroutine is finished @@ -25,7 +24,7 @@ import org.eclipse.dd.examples.pda.service.command.PDACommandResult; */ public class PDAStepReturnCommand extends AbstractPDACommand { - public PDAStepReturnCommand(PDACommandControlDMContext context) { + public PDAStepReturnCommand(PDAProgramDMContext context) { super(context, "stepreturn"); } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASuspendCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASuspendCommand.java similarity index 76% rename from plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASuspendCommand.java rename to plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASuspendCommand.java index 8972c83f830..f1c7e548b85 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDASuspendCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASuspendCommand.java @@ -8,10 +8,9 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.command.commands; +package org.eclipse.dd.examples.pda.service.commands; -import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; -import org.eclipse.dd.examples.pda.service.command.PDACommandResult; +import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** * Suspends execution @@ -24,7 +23,7 @@ import org.eclipse.dd.examples.pda.service.command.PDACommandResult; */ public class PDASuspendCommand extends AbstractPDACommand { - public PDASuspendCommand(PDACommandControlDMContext context) { + public PDASuspendCommand(PDAProgramDMContext context) { super(context, "suspend"); } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAVarCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAVarCommand.java similarity index 76% rename from plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAVarCommand.java rename to plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAVarCommand.java index 95280892e65..745fa86a491 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAVarCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAVarCommand.java @@ -8,10 +8,9 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.command.commands; +package org.eclipse.dd.examples.pda.service.commands; -import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; -import org.eclipse.dd.examples.pda.service.command.PDACommandResult; +import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** * Retrieves variable value @@ -23,7 +22,7 @@ import org.eclipse.dd.examples.pda.service.command.PDACommandResult; */ public class PDAVarCommand extends AbstractPDACommand { - public PDAVarCommand(PDACommandControlDMContext context, int frameId, String name) { + public PDAVarCommand(PDAProgramDMContext context, int frameId, String name) { super(context, "var " + frameId + " " + name); } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAWatchCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAWatchCommand.java similarity index 81% rename from plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAWatchCommand.java rename to plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAWatchCommand.java index 7d23b37c087..91d54e942a0 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/command/commands/PDAWatchCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAWatchCommand.java @@ -8,10 +8,9 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.command.commands; +package org.eclipse.dd.examples.pda.service.commands; -import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; -import org.eclipse.dd.examples.pda.service.command.PDACommandResult; +import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** * Sets a watchpoint on a given variable @@ -41,7 +40,7 @@ public class PDAWatchCommand extends AbstractPDACommand { } } - public PDAWatchCommand(PDACommandControlDMContext context, String function, String variable, WatchOperation operation) { + public PDAWatchCommand(PDAProgramDMContext context, String function, String variable, WatchOperation operation) { super(context, "watch " + function+ "::" + variable + " " + getWatchOperationCode(operation)); } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/expressions/ExpressionDMContext.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/expressions/ExpressionDMContext.java deleted file mode 100644 index 477ee85f6de..00000000000 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/expressions/ExpressionDMContext.java +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.expressions; - -import org.eclipse.dd.dsf.datamodel.AbstractDMContext; -import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; -import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; - -/** - * - */ -public class ExpressionDMContext extends AbstractDMContext implements IExpressionDMContext { - - private final String fExpression; - - ExpressionDMContext(String sessionId, IFrameDMContext frameDmc, String expressin) { - super(sessionId, new IDMContext[] { frameDmc }); - fExpression = expressin; - } - - public String getExpression() { - return fExpression; - } - - @Override - public boolean equals(Object other) { - return super.baseEquals(other) && ((ExpressionDMContext)other).fExpression.equals(fExpression); - } - - @Override - public int hashCode() { - return super.baseHashCode() + fExpression.hashCode(); - } - - @Override - public String toString() { - return baseToString() + ".expression(" + fExpression + ")"; //$NON-NLS-1$ //$NON-NLS-2$ - } -} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/expressions/ExpressionDMData.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/expressions/ExpressionDMData.java deleted file mode 100644 index 2929f61c020..00000000000 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/expressions/ExpressionDMData.java +++ /dev/null @@ -1,61 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.expressions; - -import java.util.Map; - -import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMData; -import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext; - -/** - * - */ -public class ExpressionDMData implements IExpressionDMData { - - final private String fExpression; - - public ExpressionDMData(String expression) { - fExpression = expression; - } - - public BasicType getBasicType() { - return BasicType.basic; - } - - public String getEncoding() { - return null; - } - - public Map getEnumerations() { - return null; - } - - public String getName() { - return fExpression; - } - - public IRegisterDMContext getRegister() { - return null; - } - - public String getStringValue() { - return null; - } - - public String getTypeId() { - return null; - } - - public String getTypeName() { - return null; - } - -} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/expressions/InvalidExpressionDMContext.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/expressions/InvalidExpressionDMContext.java deleted file mode 100644 index 56124e06f87..00000000000 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/expressions/InvalidExpressionDMContext.java +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.expressions; - -import org.eclipse.dd.dsf.datamodel.AbstractDMContext; -import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; - -class InvalidExpressionDMContext extends AbstractDMContext - implements IExpressionDMContext -{ - private final String expression; - - public InvalidExpressionDMContext(String sessionId, IDMContext parent, String expr) { - super(sessionId, new IDMContext[] { parent }); - expression = expr; - } - - @Override - public boolean equals(Object other) { - return super.baseEquals(other) && - expression == null - ? ((InvalidExpressionDMContext) other).getExpression() == null - : expression.equals(((InvalidExpressionDMContext) other).getExpression()); - } - - @Override - public int hashCode() { - return expression == null ? super.baseHashCode() : super.baseHashCode() ^ expression.hashCode(); - } - - @Override - public String toString() { - return baseToString() + ".invalid_expr[" + expression + "]"; //$NON-NLS-1$ //$NON-NLS-2$ - } - - public String getExpression() { - return expression; - } -} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/expressions/PDAExpressions.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/expressions/PDAExpressions.java deleted file mode 100644 index 550882bc74c..00000000000 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/expressions/PDAExpressions.java +++ /dev/null @@ -1,224 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.expressions; - -import java.util.Hashtable; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.datamodel.DMContexts; -import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.debug.service.IExpressions; -import org.eclipse.dd.dsf.debug.service.IStack; -import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent; -import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent; -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.command.CommandCache; -import org.eclipse.dd.dsf.service.AbstractDsfService; -import org.eclipse.dd.dsf.service.DsfServiceEventHandler; -import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.examples.pda.PDAPlugin; -import org.eclipse.dd.examples.pda.service.command.PDACommandControl; -import org.eclipse.dd.examples.pda.service.command.PDACommandResult; -import org.eclipse.dd.examples.pda.service.command.commands.PDASetVarCommand; -import org.eclipse.dd.examples.pda.service.command.commands.PDAVarCommand; -import org.osgi.framework.BundleContext; - -/** - * - */ -public class PDAExpressions extends AbstractDsfService implements IExpressions { - - private PDACommandControl fCommandControl; - private IStack fStack; - - private CommandCache fCommandCache; - - public PDAExpressions(DsfSession session) { - super(session); - } - - @Override - protected BundleContext getBundleContext() { - return PDAPlugin.getBundleContext(); - } - - @Override - public void initialize(final RequestMonitor rm) { - super.initialize( - new RequestMonitor(getExecutor(), rm) { - @Override - protected void handleOK() { - doInitialize(rm); - }}); - } - - private void doInitialize(final RequestMonitor rm) { - fCommandControl = getServicesTracker().getService(PDACommandControl.class); - fStack = getServicesTracker().getService(IStack.class); - fCommandCache = new CommandCache(fCommandControl); - - getSession().addServiceEventListener(this, null); - - register(new String[]{IExpressions.class.getName(), PDAExpressions.class.getName()}, new Hashtable()); - - rm.done(); - } - - @Override - public void shutdown(final RequestMonitor rm) { - getSession().removeServiceEventListener(this); - fCommandCache.reset(); - super.shutdown(rm); - } - - public void canWriteExpression(IExpressionDMContext expressionContext, DataRequestMonitor rm) { - rm.setData(true); - rm.done(); - } - - public IExpressionDMContext createExpression(IDMContext ctx, String expression) { - IFrameDMContext frameCtx = DMContexts.getAncestorOfType(ctx, IFrameDMContext.class); - if (frameCtx != null) { - return new ExpressionDMContext(getSession().getId(), frameCtx, expression); - } else { - return new InvalidExpressionDMContext(getSession().getId(), ctx, expression); - } - } - - public void getBaseExpressions(IExpressionDMContext exprContext, DataRequestMonitor rm) { - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$ - rm.done(); - } - - public void getExpressionAddressData(IExpressionDMContext dmc, DataRequestMonitor rm) { - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$ - rm.done(); - } - - public void getExpressionData(final IExpressionDMContext exprCtx, final DataRequestMonitor rm) { - if (exprCtx instanceof ExpressionDMContext) { - rm.setData(new ExpressionDMData(exprCtx.getExpression())); - rm.done(); - } else { - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid expression context " + exprCtx, null)); //$NON-NLS-1$ - rm.done(); - } - } - - public void getSubExpressionCount(IExpressionDMContext exprCtx, DataRequestMonitor rm) { - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$ - rm.done(); - } - - public void getSubExpressions(IExpressionDMContext exprCtx, DataRequestMonitor rm) { - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$ - rm.done(); - } - - public void getSubExpressions(IExpressionDMContext exprCtx, int startIndex, int length, - DataRequestMonitor rm) - { - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$ - rm.done(); - } - - - public void writeExpression(IExpressionDMContext exprCtx, String exprValue, String formatId, RequestMonitor rm) - { - if (exprCtx instanceof ExpressionDMContext) { - fCommandCache.execute( - new PDASetVarCommand(fCommandControl.getDMContext(), exprCtx.getExpression(), exprValue), - new DataRequestMonitor(getExecutor(), rm)); - } else { - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid expression context " + exprCtx, null)); //$NON-NLS-1$ - rm.done(); - } - } - - public void getAvailableFormats(IFormattedDataDMContext dmc, DataRequestMonitor rm) { - rm.setData(new String[] { NATURAL_FORMAT }); - rm.done(); - } - - public FormattedValueDMContext getFormattedValueContext(IFormattedDataDMContext dmc, String formatId) { - return new FormattedValueDMContext(this, dmc, formatId); - } - - public void getFormattedExpressionValue(FormattedValueDMContext formattedCtx, final DataRequestMonitor rm) { - final ExpressionDMContext exprCtx = DMContexts.getAncestorOfType(formattedCtx, ExpressionDMContext.class); - if (exprCtx != null) { - getExpressionValue( - exprCtx, - new DataRequestMonitor(getExecutor(), rm) { - @Override - protected void handleOK() { - rm.setData(new FormattedValueDMData(getData())); - rm.done(); - } - }); - } else { - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid expression context " + formattedCtx, null)); //$NON-NLS-1$ - rm.done(); - } - } - - private void getExpressionValue(final ExpressionDMContext exprCtx, final DataRequestMonitor rm) { - final IFrameDMContext frameCtx = DMContexts.getAncestorOfType(exprCtx, IFrameDMContext.class); - fStack.getStackDepth( - frameCtx, 0, - new DataRequestMonitor(getExecutor(), rm) { - @Override - protected void handleOK() { - int frameId = getData() - frameCtx.getLevel() - 1; - fCommandCache.execute( - new PDAVarCommand(fCommandControl.getDMContext(), frameId, exprCtx.getExpression()), - new DataRequestMonitor(getExecutor(), rm) { - @Override - protected void handleOK() { - rm.setData(getData().fResponseText); - rm.done(); - } - }); - } - }); - } - - @Deprecated - public void getModelData(IDMContext dmc, DataRequestMonitor rm) { - if (dmc instanceof IExpressionDMContext) { - getExpressionData((IExpressionDMContext) dmc, (DataRequestMonitor) rm); - } else if (dmc instanceof FormattedValueDMContext) { - getFormattedExpressionValue((FormattedValueDMContext) dmc, (DataRequestMonitor) rm); - } else { - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ - rm.done(); - } - } - - @DsfServiceEventHandler - public void eventDispatched(IResumedDMEvent e) { - fCommandCache.setTargetAvailable(false); - if (!e.getReason().equals(StateChangeReason.STEP)) { - fCommandCache.reset(); - } - } - - - @DsfServiceEventHandler - public void eventDispatched(ISuspendedDMEvent e) { - fCommandCache.setTargetAvailable(true); - fCommandCache.reset(); - } -} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/ExecutionData.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/ExecutionData.java deleted file mode 100644 index 8591e79c690..00000000000 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/ExecutionData.java +++ /dev/null @@ -1,24 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.runcontrol; - -import org.eclipse.dd.dsf.concurrent.Immutable; -import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMData; -import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason; - -@Immutable -class ExecutionData implements IExecutionDMData { - private final StateChangeReason fReason; - ExecutionData(StateChangeReason reason) { - fReason = reason; - } - public StateChangeReason getStateChangeReason() { return fReason; } -} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/PDARunControl.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/PDARunControl.java deleted file mode 100644 index 5bc8ec49f41..00000000000 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/PDARunControl.java +++ /dev/null @@ -1,261 +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 - * Ericsson AB - Modified for handling of multiple threads - *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.runcontrol; - -import java.util.Hashtable; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.datamodel.IDMEvent; -import org.eclipse.dd.dsf.debug.service.IRunControl; -import org.eclipse.dd.dsf.debug.service.command.CommandCache; -import org.eclipse.dd.dsf.debug.service.command.IEventListener; -import org.eclipse.dd.dsf.service.AbstractDsfService; -import org.eclipse.dd.dsf.service.DsfServiceEventHandler; -import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; -import org.eclipse.dd.examples.pda.PDAPlugin; -import org.eclipse.dd.examples.pda.service.command.PDACommandControl; -import org.eclipse.dd.examples.pda.service.command.PDACommandResult; -import org.eclipse.dd.examples.pda.service.command.commands.PDAResumeCommand; -import org.eclipse.dd.examples.pda.service.command.commands.PDAStepCommand; -import org.eclipse.dd.examples.pda.service.command.commands.PDASuspendCommand; -import org.osgi.framework.BundleContext; - - -/** - * - *

    - * Implementation note: - * This class implements event handlers for the events that are generated by - * this service itself. When the event is dispatched, these handlers will - * be called first, before any of the clients. These handlers update the - * service's internal state information to make them consistent with the - * events being issued. Doing this in the handlers as opposed to when - * the events are generated, guarantees that the state of the service will - * always be consistent with the events. - * The purpose of this pattern is to allow clients that listen to service - * events and track service state, to be perfectly in sync with the service - * state. - */ -public class PDARunControl extends AbstractDsfService - implements IRunControl, IEventListener -{ - private PDACommandControl fCommandControl; - private CommandCache fCommandCache; - - // state flags - private boolean fSuspended = true; - private boolean fResumePending = false; - private boolean fStepping = false; - - private StateChangeReason fStateChangeReason; - - public PDARunControl(DsfSession session) { - super(session); - } - - @Override - protected BundleContext getBundleContext() { - return PDAPlugin.getBundleContext(); - } - - @Override - public void initialize(final RequestMonitor rm) { - super.initialize( - new RequestMonitor(getExecutor(), rm) { - @Override - protected void handleOK() { - doInitialize(rm); - }}); - } - - private void doInitialize(final RequestMonitor rm) { - fCommandControl = getServicesTracker().getService(PDACommandControl.class); - fCommandCache = new CommandCache(fCommandControl); - - fCommandControl.addEventListener(this); - getSession().addServiceEventListener(this, null); - - register(new String[]{IRunControl.class.getName(), PDARunControl.class.getName()}, new Hashtable()); - - rm.done(); - } - - @Override - public void shutdown(final RequestMonitor rm) { - fCommandControl.removeEventListener(this); - - getSession().removeServiceEventListener(this); - fCommandCache.reset(); - super.shutdown(rm); - } - - @SuppressWarnings("unchecked") - public void getModelData(IDMContext dmc, DataRequestMonitor rm) { - if (dmc instanceof IExecutionDMContext) { - getExecutionData((IExecutionDMContext)dmc, (DataRequestMonitor)rm); - } else { - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ - rm.done(); - } - } - - public void eventReceived(Object output) { - if (!(output instanceof String)) return; - String event = (String)output; - - if (event.startsWith("suspended")) { - suspendedEventReceived(event); - } else if (event.startsWith("resumed")) { - resumedEventReceived(event); - } - } - - private void suspendedEventReceived(String event) { - IDMEvent dmEvent = new SuspendedEvent(fCommandControl.getDMContext(), event); - getSession().dispatchEvent(dmEvent, getProperties()); - } - - - @DsfServiceEventHandler - private void resumedEventReceived(String event) { - IDMEvent dmEvent = new ResumedEvent(fCommandControl.getDMContext(), event); - getSession().dispatchEvent(dmEvent, getProperties()); - } - - - @DsfServiceEventHandler - public void eventDispatched(ResumedEvent e) { - fSuspended = false; - fResumePending = false; - fStateChangeReason = e.getReason(); - fCommandCache.setTargetAvailable(false); - if (e.getReason().equals(StateChangeReason.STEP)) { - fStepping = true; - } else { - fCommandCache.reset(); - } - } - - - @DsfServiceEventHandler - public void eventDispatched(SuspendedEvent e) { - fCommandCache.setTargetAvailable(true); - fCommandCache.reset(); - fStateChangeReason = e.getReason(); - fResumePending = false; - fSuspended = true; - fStepping = false; - } - - - public boolean canResume(IExecutionDMContext context) { - return isSuspended(context) && !fResumePending; - } - - public boolean canSuspend(IExecutionDMContext context) { - return !isSuspended(context); - } - - public boolean isSuspended(IExecutionDMContext context) { - return fSuspended; - } - - public boolean isStepping(IExecutionDMContext context) { - return !isSuspended(context) && fStepping; - } - - public void resume(IExecutionDMContext context, final RequestMonitor rm) { - assert context != null; - - if (canResume(context)) { - fResumePending = true; - // Cygwin GDB will accept commands and execute them after the step - // which is not what we want, so mark the target as unavailable - // as soon as we send a resume command. - fCommandCache.setTargetAvailable(false); - - fCommandControl.queueCommand( - new PDAResumeCommand(fCommandControl.getDMContext()), - new DataRequestMonitor(getExecutor(), rm) { - @Override - protected void handleOK() { - rm.done(); - } - } - ); - }else { - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Given context: " + context + ", is already running.", null)); //$NON-NLS-1$ //$NON-NLS-2$ - rm.done(); - } - } - - public void suspend(IExecutionDMContext context, final RequestMonitor rm){ - assert context != null; - - if (canSuspend(context)) { - fCommandControl.queueCommand( - new PDASuspendCommand(fCommandControl.getDMContext()), - new DataRequestMonitor(getExecutor(), rm)); - - } else { - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Given context: " + context + ", is already suspended.", null)); //$NON-NLS-1$ //$NON-NLS-2$ - rm.done(); - } - } - - public boolean canStep(IExecutionDMContext context) { - return canResume(context); - } - - public void step(IExecutionDMContext context, StepType stepType, final RequestMonitor rm) { - assert context != null; - - if (canResume(context)) { - fResumePending = true; - fStepping = true; - fCommandCache.setTargetAvailable(false); - - fCommandControl.queueCommand( - new PDAStepCommand(fCommandControl.getDMContext()), - new DataRequestMonitor(getExecutor(), rm)); - - } else { - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, INVALID_STATE, "Cannot resume context", null)); //$NON-NLS-1$ - rm.done(); - return; - } - } - - public boolean canInstructionStep(IExecutionDMContext context) { - return false; - } - - public void instructionStep(IExecutionDMContext context, StepType stepType, RequestMonitor rm) { - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, NOT_SUPPORTED, "Operation not implemented", null)); //$NON-NLS-1$ - rm.done(); - } - - public void getExecutionContexts(final IContainerDMContext containerDmc, final DataRequestMonitor rm) { - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, NOT_SUPPORTED, "Operation not implemented", null)); //$NON-NLS-1$ - rm.done(); - } - - public void getExecutionData(IExecutionDMContext dmc, DataRequestMonitor rm){ - rm.setData( new ExecutionData(fStateChangeReason) ); - rm.done(); - } -} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/ResumedEvent.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/ResumedEvent.java deleted file mode 100644 index 68ee1d725d2..00000000000 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/ResumedEvent.java +++ /dev/null @@ -1,41 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.runcontrol; - -import org.eclipse.dd.dsf.concurrent.Immutable; -import org.eclipse.dd.dsf.datamodel.AbstractDMEvent; -import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; -import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent; -import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason; - -@Immutable -class ResumedEvent extends AbstractDMEvent - implements IResumedDMEvent -{ - private final String fPDAEvent; - - ResumedEvent(IExecutionDMContext ctx, String pdaEvent) { - super(ctx); - fPDAEvent = pdaEvent; - } - - public StateChangeReason getReason() { - if (fPDAEvent.startsWith("resumed breakpoint") || fPDAEvent.startsWith("suspended watch")) { - return StateChangeReason.BREAKPOINT; - } else if (fPDAEvent.equals("resumed step") || fPDAEvent.equals("resumed drop")) { - return StateChangeReason.STEP; - } else if (fPDAEvent.equals("resumed client")) { - return StateChangeReason.USER_REQUEST; - } else { - return StateChangeReason.UNKNOWN; - } - } -} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/SuspendedEvent.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/SuspendedEvent.java deleted file mode 100644 index 04bf54aebd8..00000000000 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/runcontrol/SuspendedEvent.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.eclipse.dd.examples.pda.service.runcontrol; - -import org.eclipse.dd.dsf.concurrent.Immutable; -import org.eclipse.dd.dsf.datamodel.AbstractDMEvent; -import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; -import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent; -import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason; - -/** - * Indicates that the given thread has been suspended. - */ -@Immutable -class SuspendedEvent extends AbstractDMEvent - implements ISuspendedDMEvent -{ - private final String fPDAEvent; - - SuspendedEvent(IExecutionDMContext ctx, String pdaEvent) { - super(ctx); - fPDAEvent = pdaEvent; - } - - public StateChangeReason getReason() { - if (fPDAEvent.startsWith("suspended breakpoint") || fPDAEvent.startsWith("suspended watch")) { - return StateChangeReason.BREAKPOINT; - } else if (fPDAEvent.equals("suspended step") || fPDAEvent.equals("suspended drop")) { - return StateChangeReason.STEP; - } else if (fPDAEvent.equals("suspended client")) { - return StateChangeReason.USER_REQUEST; - } else { - return StateChangeReason.UNKNOWN; - } - } -} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/FrameDMContext.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/FrameDMContext.java deleted file mode 100644 index 48ac9084c67..00000000000 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/FrameDMContext.java +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.stack; - -import org.eclipse.dd.dsf.datamodel.AbstractDMContext; -import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; -import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; - -/** - * - */ -class FrameDMContext extends AbstractDMContext implements IFrameDMContext { - - private final int fLevel; - - FrameDMContext(String sessionId, IExecutionDMContext execDmc, int level) { - super(sessionId, new IDMContext[] { execDmc }); - fLevel = level; - } - - public int getLevel() { return fLevel; } - - @Override - public boolean equals(Object other) { - return super.baseEquals(other) && ((FrameDMContext)other).fLevel == fLevel; - } - - @Override - public int hashCode() { - return super.baseHashCode() ^ fLevel; - } - - @Override - public String toString() { - return baseToString() + ".frame[" + fLevel + "]"; //$NON-NLS-1$ //$NON-NLS-2$ - } -} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/FrameDMData.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/FrameDMData.java deleted file mode 100644 index 304388503c9..00000000000 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/FrameDMData.java +++ /dev/null @@ -1,47 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.stack; - -import org.eclipse.cdt.core.IAddress; -import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMData; -import org.eclipse.dd.examples.pda.service.command.commands.PDAFrame; - -/** - * - */ -public class FrameDMData implements IFrameDMData { - - final private PDAFrame fFrame; - - FrameDMData(PDAFrame frame) { - fFrame = frame; - } - - public String getFile() { - return fFrame.fFilePath.lastSegment(); - } - - public String getFunction() { - return fFrame.fFunction; - } - - public int getLine() { - return fFrame.fLine + 1; - } - - public int getColumn() { - return 0; - } - - public IAddress getAddress() { - return null; - } -} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/VariableDMContext.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/VariableDMContext.java deleted file mode 100644 index 7ed5b51ff5d..00000000000 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/VariableDMContext.java +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.stack; - -import org.eclipse.dd.dsf.datamodel.AbstractDMContext; -import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; -import org.eclipse.dd.dsf.debug.service.IStack.IVariableDMContext; - -/** - * - */ -class VariableDMContext extends AbstractDMContext implements IVariableDMContext { - - private final String fVariable; - - VariableDMContext(String sessionId, IFrameDMContext frameCtx, String variable) { - super(sessionId, new IDMContext[] { frameCtx }); - fVariable = variable; - } - - String getVariable() { return fVariable; } - - @Override - public boolean equals(Object other) { - return super.baseEquals(other) && ((VariableDMContext)other).fVariable.equals(fVariable); - } - - @Override - public int hashCode() { - return super.baseHashCode() + fVariable.hashCode(); - } - - @Override - public String toString() { - return baseToString() + ".variable(" + fVariable + ")"; //$NON-NLS-1$ //$NON-NLS-2$ - } -} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/VariableDMData.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/VariableDMData.java deleted file mode 100644 index 03087fd6012..00000000000 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/stack/VariableDMData.java +++ /dev/null @@ -1,33 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.examples.pda.service.stack; - -import org.eclipse.dd.dsf.debug.service.IStack.IVariableDMData; - -/** - * - */ -public class VariableDMData implements IVariableDMData { - - final private String fVariable; - - VariableDMData(String variable) { - fVariable = variable; - } - - public String getName() { - return fVariable; - } - - public String getValue() { - return null; - } -} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourceLookupDirector.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/sourcelookup/PDASourceLookupDirector.java similarity index 85% rename from plugins/org.eclipse.dd.examples.pda/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourceLookupDirector.java rename to plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/sourcelookup/PDASourceLookupDirector.java index 27e1cdd8ce1..d22968d6be9 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourceLookupDirector.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/sourcelookup/PDASourceLookupDirector.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 IBM Corporation and others. + * Copyright (c) 2005, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,8 +8,9 @@ * Contributors: * IBM Corporation - initial API and implementation * Bjorn Freeman-Benson - initial API and implementation + * Wind River Systems - adopted to use with DSF *******************************************************************************/ -package org.eclipse.debug.examples.core.pda.sourcelookup; +package org.eclipse.dd.examples.pda.sourcelookup; import org.eclipse.debug.core.sourcelookup.AbstractSourceLookupDirector; diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourcePathComputerDelegate.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/sourcelookup/PDASourcePathComputerDelegate.java similarity index 85% rename from plugins/org.eclipse.dd.examples.pda/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourcePathComputerDelegate.java rename to plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/sourcelookup/PDASourcePathComputerDelegate.java index 6087abf01a5..64a8f06eaa7 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourcePathComputerDelegate.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/sourcelookup/PDASourcePathComputerDelegate.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 IBM Corporation and others. + * Copyright (c) 2005, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,8 +8,9 @@ * Contributors: * IBM Corporation - initial API and implementation * Bjorn Freeman-Benson - initial API and implementation + * Wind River Systems - adopted to use with DSF *******************************************************************************/ -package org.eclipse.debug.examples.core.pda.sourcelookup; +package org.eclipse.dd.examples.pda.sourcelookup; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IProject; @@ -32,29 +33,25 @@ import org.eclipse.debug.core.sourcelookup.containers.WorkspaceSourceContainer; * The default source lookup path is the folder or project containing * the PDA program being launched. If the program is not specified, the workspace * is searched by default. + *

    + * This class is identical to the corresponding in PDA debugger implemented in + * org.eclipse.debug.examples. + *

    */ public class PDASourcePathComputerDelegate implements ISourcePathComputerDelegate { - - /* (non-Javadoc) - * @see org.eclipse.debug.internal.core.sourcelookup.ISourcePathComputerDelegate#computeSourceContainers(org.eclipse.debug.core.ILaunchConfiguration, org.eclipse.core.runtime.IProgressMonitor) - */ public ISourceContainer[] computeSourceContainers(ILaunchConfiguration configuration, IProgressMonitor monitor) throws CoreException { String path = configuration.getAttribute(PDAPlugin.ATTR_PDA_PROGRAM, (String)null); ISourceContainer sourceContainer = null; if (path != null) { IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(new Path(path)); if (resource != null) { - //#ifdef ex4 -//# // TODO: Exercise 4 - seed the source lookup path - //#else IContainer container = resource.getParent(); if (container.getType() == IResource.PROJECT) { sourceContainer = new ProjectSourceContainer((IProject)container, false); } else if (container.getType() == IResource.FOLDER) { sourceContainer = new FolderSourceContainer(container, false); } - //#endif } } if (sourceContainer == null) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/BasicTests.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/BasicTests.java index abee9ba1650..f8124f277e8 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/BasicTests.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/BasicTests.java @@ -23,7 +23,7 @@ import org.eclipse.dd.dsf.concurrent.Query; import org.eclipse.dd.dsf.debug.service.command.ICommand; import org.eclipse.dd.dsf.debug.service.command.ICommandListener; import org.eclipse.dd.dsf.debug.service.command.ICommandResult; -import org.eclipse.dd.examples.pda.service.command.PDACommandResult; +import org.eclipse.dd.examples.pda.service.commands.PDACommandResult; import org.junit.BeforeClass; import org.junit.Test; @@ -81,7 +81,7 @@ public class BasicTests extends CommandControlTestsBase { } }); - final PDATestCommand testCommand = new PDATestCommand(fCommandControl.getDMContext(), "data"); + final PDATestCommand testCommand = new PDATestCommand(fCommandControl.getProgramDMContext(), "data"); // Test sending the command and checking all listeners were called. Query sendCommandQuery = new Query() { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/CommandControlTestsBase.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/CommandControlTestsBase.java index 9d7a339177c..81ff0fc6257 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/CommandControlTestsBase.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/CommandControlTestsBase.java @@ -26,8 +26,8 @@ import org.eclipse.dd.dsf.concurrent.DsfExecutor; import org.eclipse.dd.dsf.concurrent.Query; import org.eclipse.dd.dsf.debug.service.command.IEventListener; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.examples.pda.service.command.PDACommandControl; -import org.eclipse.dd.examples.pda.service.command.PDACommandResult; +import org.eclipse.dd.examples.pda.service.PDACommandControl; +import org.eclipse.dd.examples.pda.service.commands.PDACommandResult; import org.eclipse.dd.tests.pda.util.Launching; import org.junit.After; import org.junit.Before; @@ -66,7 +66,7 @@ public class CommandControlTestsBase { fExecutor = new DefaultDsfExecutor(); fSession = DsfSession.startSession(fExecutor, "PDA Test"); - fCommandControl = new PDACommandControl(fSession, requestPort, eventPort); + fCommandControl = new PDACommandControl(fSession, fProgram, requestPort, eventPort); fCommandControl.addEventListener(new IEventListener() { public void eventReceived(Object output) { @@ -105,7 +105,7 @@ public class CommandControlTestsBase { protected void sendCommand(String command, String expectedResult) throws Throwable { - final PDATestCommand testCommand = new PDATestCommand(fCommandControl.getDMContext(), command); + final PDATestCommand testCommand = new PDATestCommand(fCommandControl.getProgramDMContext(), command); // Test sending the command and checking all listeners were called. Query sendCommandQuery = new Query() { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/PDATestCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/PDATestCommand.java index 0aba7c8441c..36ba23c3527 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/PDATestCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/PDATestCommand.java @@ -10,15 +10,15 @@ *******************************************************************************/ package org.eclipse.dd.tests.pda.service.command; -import org.eclipse.dd.examples.pda.service.command.PDACommandControlDMContext; -import org.eclipse.dd.examples.pda.service.command.PDACommandResult; -import org.eclipse.dd.examples.pda.service.command.commands.AbstractPDACommand; +import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; +import org.eclipse.dd.examples.pda.service.commands.AbstractPDACommand; +import org.eclipse.dd.examples.pda.service.commands.PDACommandResult; /** * */ class PDATestCommand extends AbstractPDACommand { - PDATestCommand(PDACommandControlDMContext context, String command) { + PDATestCommand(PDAProgramDMContext context, String command) { super(context, command); } From 5f9445edbdad52fee306c00567ba68ec5019f39b Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 22 Feb 2008 16:15:09 +0000 Subject: [PATCH 264/834] Replaced tabs with white space. --- .../pda/launch/PDALaunchDelegate.java | 148 +++++++++--------- 1 file changed, 74 insertions(+), 74 deletions(-) diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunchDelegate.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunchDelegate.java index 9aa119d29bd..97fcc746af1 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunchDelegate.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunchDelegate.java @@ -46,7 +46,7 @@ import org.eclipse.debug.core.sourcelookup.IPersistableSourceLocator2; * Launches PDA program on a PDA interpretter written in Perl */ public class PDALaunchDelegate extends LaunchConfigurationDelegate { - + @Override public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) throws CoreException { // Need to configure the source locator before creating the launch @@ -54,10 +54,10 @@ public class PDALaunchDelegate extends LaunchConfigurationDelegate { // the adapters will be created for the whole session, including // the source lookup adapter. ISourceLocator locator = getSourceLocator(configuration); - + return new PDALaunch(configuration, mode, locator); } - + @Override public boolean buildForLaunch(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException { // PDA programs do not require building. @@ -88,9 +88,9 @@ public class PDALaunchDelegate extends LaunchConfigurationDelegate { return null; } - public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException { - String program = configuration.getAttribute(PDAPlugin.ATTR_PDA_PROGRAM, (String)null); - if (program == null) { + public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException { + String program = configuration.getAttribute(PDAPlugin.ATTR_PDA_PROGRAM, (String)null); + if (program == null) { abort("Perl program unspecified.", null); } @@ -103,21 +103,21 @@ public class PDALaunchDelegate extends LaunchConfigurationDelegate { launchProcess(launch, program, requestPort, eventPort); PDALaunch pdaLaunch = (PDALaunch)launch; initServices(pdaLaunch, program, requestPort, eventPort); - } + } - /** - * Launches PDA interpreter with the given program. - * - * @param launch Launch that will contain the new process. - * @param program PDA program to use in the interpreter. - * @param requestPort The port number for connecting the request socket. - * @param eventPort The port number for connecting the events socket. - * - * @throws CoreException - */ - private void launchProcess(ILaunch launch, String program, int requestPort, int eventPort) throws CoreException { + /** + * Launches PDA interpreter with the given program. + * + * @param launch Launch that will contain the new process. + * @param program PDA program to use in the interpreter. + * @param requestPort The port number for connecting the request socket. + * @param eventPort The port number for connecting the events socket. + * + * @throws CoreException + */ + private void launchProcess(ILaunch launch, String program, int requestPort, int eventPort) throws CoreException { List commandList = new ArrayList(); - + // Find Perl executable IValueVariable perl = VariablesPlugin.getDefault().getStringVariableManager().getValueVariable(PDAPlugin.VARIALBE_PERL_EXECUTABLE); if (perl == null) { @@ -132,50 +132,50 @@ public class PDALaunchDelegate extends LaunchConfigurationDelegate { abort(MessageFormat.format("Specified Perl executable {0} does not exist. Check value of $dsfPerlExecutable.", new Object[]{path}), null); } commandList.add(path); - + // Add PDA VM File vm = PDAPlugin.getFileInPlugin(new Path("pdavm/pda.pl")); if (vm == null) { abort("Missing PDA VM", null); } commandList.add(vm.getAbsolutePath()); - + // Add PDA program IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(program)); if (!file.exists()) { abort(MessageFormat.format("Perl program {0} does not exist.", new Object[] {file.getFullPath().toString()}), null); } - + commandList.add(file.getLocation().toOSString()); - + // Add debug arguments - i.e. '-debug requestPort eventPort' commandList.add("-debug"); commandList.add("" + requestPort); commandList.add("" + eventPort); - + // Launch the perl process. String[] commandLine = commandList.toArray(new String[commandList.size()]); Process process = DebugPlugin.exec(commandLine, null); - + // Create a debug platform process object and add it to the launch. DebugPlugin.newProcess(launch, process, path); - } - - /** - * Calls the launch to initialize DSF services for this launch. - */ - private void initServices(final PDALaunch pdaLaunch, final String program, final int requestPort, final int eventPort) - throws CoreException - { - // Synchronization object to use when waiting for the services initialization. - Query initQuery = new Query() { - @Override - protected void execute(DataRequestMonitor rm) { - pdaLaunch.initializeServices(program, requestPort, eventPort, rm); - } - }; + } - // Submit the query to the executor. + /** + * Calls the launch to initialize DSF services for this launch. + */ + private void initServices(final PDALaunch pdaLaunch, final String program, final int requestPort, final int eventPort) + throws CoreException + { + // Synchronization object to use when waiting for the services initialization. + Query initQuery = new Query() { + @Override + protected void execute(DataRequestMonitor rm) { + pdaLaunch.initializeServices(program, requestPort, eventPort, rm); + } + }; + + // Submit the query to the executor. pdaLaunch.getSession().getExecutor().execute(initQuery); try { // Block waiting for query results. @@ -185,37 +185,37 @@ public class PDALaunchDelegate extends LaunchConfigurationDelegate { } catch (ExecutionException e1) { throw new DebugException(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Error in launch sequence", e1.getCause())); //$NON-NLS-1$ } - } - - /** - * Throws an exception with a new status containing the given - * message and optional exception. - * - * @param message error message - * @param e underlying exception - * @throws CoreException - */ - private void abort(String message, Throwable e) throws CoreException { - throw new CoreException(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, 0, message, e)); - } - - /** - * Returns a free port number on localhost, or -1 if unable to find a free port. - */ - public static int findFreePort() { - ServerSocket socket= null; - try { - socket= new ServerSocket(0); - return socket.getLocalPort(); - } catch (IOException e) { - } finally { - if (socket != null) { - try { - socket.close(); - } catch (IOException e) { - } - } - } - return -1; - } + } + + /** + * Throws an exception with a new status containing the given + * message and optional exception. + * + * @param message error message + * @param e underlying exception + * @throws CoreException + */ + private void abort(String message, Throwable e) throws CoreException { + throw new CoreException(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, 0, message, e)); + } + + /** + * Returns a free port number on localhost, or -1 if unable to find a free port. + */ + public static int findFreePort() { + ServerSocket socket= null; + try { + socket= new ServerSocket(0); + return socket.getLocalPort(); + } catch (IOException e) { + } finally { + if (socket != null) { + try { + socket.close(); + } catch (IOException e) { + } + } + } + return -1; + } } From 8c6342dc6d1d220636bc68f4b9cd7516e829a124 Mon Sep 17 00:00:00 2001 From: Francois Chouinard Date: Fri, 22 Feb 2008 22:11:24 +0000 Subject: [PATCH 265/834] Fix for bug219162 --- .../dd/mi/service/MIBreakpointsManager.java | 162 ++++++++++++------ 1 file changed, 114 insertions(+), 48 deletions(-) diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointsManager.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointsManager.java index 723027b914a..2246915bdd4 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointsManager.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointsManager.java @@ -28,8 +28,10 @@ import org.eclipse.cdt.debug.core.model.ICBreakpoint; import org.eclipse.cdt.debug.core.model.ICBreakpointExtension; import org.eclipse.cdt.debug.core.model.ICLineBreakpoint; import org.eclipse.cdt.debug.core.model.ICWatchpoint; +import org.eclipse.cdt.debug.internal.core.breakpoints.BreakpointProblems; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IMarkerDelta; +import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; @@ -60,7 +62,11 @@ import org.eclipse.dd.dsf.service.AbstractDsfService; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.mi.internal.MIPlugin; +import org.eclipse.dd.mi.service.MIBreakpoints.BreakpointAddedEvent; +import org.eclipse.dd.mi.service.MIBreakpoints.BreakpointRemovedEvent; +import org.eclipse.dd.mi.service.MIBreakpoints.BreakpointUpdatedEvent; import org.eclipse.dd.mi.service.MIRunControl.MIExecutionDMC; +import org.eclipse.dd.mi.service.command.events.MIBreakpointHitEvent; import org.eclipse.dd.mi.service.command.events.MIGDBExitEvent; import org.eclipse.dd.mi.service.command.events.MIWatchpointScopeEvent; import org.eclipse.debug.core.DebugPlugin; @@ -148,6 +154,9 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo private Set fPendingRequests = new HashSet(); private Set fPendingBreakpoints = new HashSet(); + private Map fBreakpointMarkerProblems = + new HashMap(); + /////////////////////////////////////////////////////////////////////////// // String constants // FIXME: Extract to some centralized location @@ -216,10 +225,10 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo private void doInitialize(RequestMonitor rm) { // Get the required services references from central repository - fConnection = getServicesTracker().getService(ICommandControl.class); - fRunControl = getServicesTracker().getService(IRunControl.class); - fSourceLookup = getServicesTracker().getService(ISourceLookup.class); - fBreakpoints = getServicesTracker().getService(IBreakpoints.class); + fConnection = getServicesTracker().getService(ICommandControl.class); + fRunControl = getServicesTracker().getService(IRunControl.class); + fSourceLookup = getServicesTracker().getService(ISourceLookup.class); + fBreakpoints = getServicesTracker().getService(IBreakpoints.class); fBreakpointManager = DebugPlugin.getDefault().getBreakpointManager(); // FIXME: fBreakpointActionManager = new MIBreakpointsActionManager(); @@ -334,7 +343,6 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo fBreakpointThreads.put(dmc, new HashMap>()); // Install the platform breakpoints (stored in fPlatformBPs) on the target. - // FIXME: Why bother with a Job? new Job("DSF BreakpointsManager: Install initial breakpoints on target") { //$NON-NLS-1$ @Override protected IStatus run(IProgressMonitor monitor) { @@ -526,7 +534,6 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo protected void handleCompleted() { // Store the platform breakpoint platformBPs.put(breakpoint, attributes); - threadsIDs.put(breakpoint, threads); rm.done(); } }; @@ -537,33 +544,37 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo DataRequestMonitor drm = new DataRequestMonitor(getExecutor(), installRM) { @Override - protected void handleCompleted() { - if (getStatus().isOK()) { - // Add the new back-end breakpoint to the map - Vector list = breakpointIDs.get(breakpoint); - if (list == null) - list = new Vector(); - IBreakpointDMContext targetBP = getData(); - list.add(targetBP); - breakpointIDs.put(breakpoint, list); - - // Add the reverse mapping - targetBPs.put(targetBP, breakpoint); - - // And update the corresponding thread list - Set thrds = threadsIDs.get(breakpoint); - if (thrds == null) - thrds = new HashSet(); - thrds.add(thread); - threadsIDs.put(breakpoint, thrds); - - // Finally, update the platform breakpoint - attributes.remove(ATTR_THREAD_ID); - try { - breakpoint.incrementInstallCount(); - } catch (CoreException e) { - } - } + protected void handleOK() { + // Add the new back-end breakpoint to the map + Vector list = breakpointIDs.get(breakpoint); + if (list == null) + list = new Vector(); + IBreakpointDMContext targetBP = getData(); + list.add(targetBP); + breakpointIDs.put(breakpoint, list); + + // Add the reverse mapping + targetBPs.put(targetBP, breakpoint); + + // And update the corresponding thread list + Set thrds = threadsIDs.get(breakpoint); + if (thrds == null) + thrds = new HashSet(); + thrds.add(thread); + threadsIDs.put(breakpoint, thrds); + + // Finally, update the platform breakpoint + attributes.remove(ATTR_THREAD_ID); + try { + breakpoint.incrementInstallCount(); + } catch (CoreException e) { + } + installRM.done(); + } + + @Override + protected void handleError() { + AddBreakpointProblemMarker(breakpoint, "Breakpoint attribute problem: installation failed", IMarker.SEVERITY_WARNING); //$NON-NLS-1$ installRM.done(); } }; @@ -575,6 +586,56 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo } } + private void AddBreakpointProblemMarker(final ICBreakpoint breakpoint, final String description, final int severity) { + + new Job("Add Breakpoint Problem Marker") { //$NON-NLS-1$ + @Override + protected IStatus run(IProgressMonitor monitor) { + + if (breakpoint instanceof ICLineBreakpoint) { + ICLineBreakpoint lineBreakpoint = (ICLineBreakpoint) breakpoint; + try { + // Locate the workspace resource via the breakpoint marker + IMarker breakpoint_marker = lineBreakpoint.getMarker(); + IResource resource = breakpoint_marker.getResource(); + + // Add a problem marker to the resource + IMarker problem_marker = resource.createMarker(BreakpointProblems.BREAKPOINT_PROBLEM_MARKER_ID); + int line_number = lineBreakpoint.getLineNumber(); + problem_marker.setAttribute(IMarker.LOCATION, String.valueOf(line_number)); + problem_marker.setAttribute(IMarker.MESSAGE, description); + problem_marker.setAttribute(IMarker.SEVERITY, severity); + problem_marker.setAttribute(IMarker.LINE_NUMBER, line_number); + + // And save the baby + fBreakpointMarkerProblems.put(breakpoint, problem_marker); + } catch (CoreException e) { + } + } + return Status.OK_STATUS; + } + }.schedule(); + } + + private void RemoveBreakpointProblemMarker(final ICBreakpoint breakpoint) { + + new Job("Remove Breakpoint Problem Marker") { //$NON-NLS-1$ + @Override + protected IStatus run(IProgressMonitor monitor) { + + IMarker marker = fBreakpointMarkerProblems.remove(breakpoint); + if (marker != null) { + try { + marker.delete(); + } catch (CoreException e) { + } + } + + return Status.OK_STATUS; + } + }.schedule(); + } + //------------------------------------------------------------------------- // uninstallBreakpoint //------------------------------------------------------------------------- @@ -604,6 +665,9 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo final Map> threadsIDs = fBreakpointThreads.get(dmc); assert threadsIDs != null; + // Remove breakpoint problem marker (if any) + RemoveBreakpointProblemMarker(breakpoint); + // Minimal validation if (!platformBPs.containsKey(breakpoint) || !breakpointIDs.containsKey(breakpoint) || !targetBPs.containsValue(breakpoint)) { rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INTERNAL_ERROR, BREAKPOINT_ALREADY_REMOVED, null)); @@ -749,7 +813,7 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo // at the back-end. rollbackAttributes(breakpoint, oldValues); platformBPs.put(breakpoint, attributes); - + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, INVALID_PARAMETER, null)); rm.done(); } @@ -1057,8 +1121,6 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo for (IBreakpointsTargetDMContext dmc : fPlatformBPs.keySet()) { if (fPlatformBPs.get(dmc).containsKey(breakpoint)) { uninstallBreakpoint(dmc, (ICBreakpoint) breakpoint, countingRm); - } else { - // Breakpoint not installed for given context, do nothing. } } } @@ -1072,16 +1134,21 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo // IServiceEventListener /////////////////////////////////////////////////////////////////////////// -// /* -// * When a breakpoint is hit, handle associated actions (if any) -// */ -// @DsfServiceEventHandler -// public void eventDispatched(DsfMIBreakpointHitEvent e) { -// IExecutionDMContext context = e.getDMContext(); -// int breakpointNumber = e.getNumber(); -//// IBreakpoint breakpoint = -//// fBreakpointActionManager. -// } + @DsfServiceEventHandler + public void eventDispatched(BreakpointAddedEvent e) { + } + + @DsfServiceEventHandler + public void eventDispatched(BreakpointUpdatedEvent e) { + } + + @DsfServiceEventHandler + public void eventDispatched(BreakpointRemovedEvent e) { + } + + @DsfServiceEventHandler + public void eventDispatched(MIBreakpointHitEvent e) { + } /* * When a watchpoint goes out of scope, it is automatically removed from @@ -1091,7 +1158,6 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo */ @DsfServiceEventHandler public void eventDispatched(MIWatchpointScopeEvent e) { -// fBreakpoints.remove(e.getNumber()); } @DsfServiceEventHandler @@ -1411,7 +1477,7 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo properties.put(MIBreakpoints.CONDITION, attributes.get(ICBreakpoint.CONDITION)); properties.put(MIBreakpoints.IGNORE_COUNT, attributes.get(ICBreakpoint.IGNORE_COUNT)); properties.put(MIBreakpoints.IS_ENABLED, attributes.get(ICBreakpoint.ENABLED)); - properties.put(MIBreakpointDMData.THREAD_ID, attributes.get(ATTR_THREAD_ID)); + properties.put(MIBreakpointDMData.THREAD_ID, attributes.get(ATTR_THREAD_ID)); // Adjust for "skip-all" if (!fBreakpointManager.isEnabled()) { From 398f01e873b597835bac75a341c7d6f91de3fb0a Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Tue, 26 Feb 2008 14:37:12 +0000 Subject: [PATCH 266/834] Fix for bug 214550. All variable objects are marked out-of-date on a MemoryChangedEvent --- .../dd/mi/service/ExpressionService.java | 4 ++-- .../dd/mi/service/MIVariableManager.java | 23 +++++++++++++++---- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/ExpressionService.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/ExpressionService.java index 9fb5aec2dcc..75223e4474a 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/ExpressionService.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/ExpressionService.java @@ -892,7 +892,7 @@ public class ExpressionService extends AbstractDsfService implements IExpression @DsfServiceEventHandler public void eventDispatched(IMemoryChangedEvent e) { fExpressionCache.reset(); - // We must also deal with our MIVariableManager since it - // caches variable values, which may now have changed + // MIVariableManager separately traps this event } + } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java index 3227e81206f..a8cb20bf35d 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java @@ -33,6 +33,7 @@ import org.eclipse.dd.dsf.debug.service.IStack; import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext; import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData; +import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryChangedEvent; import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; import org.eclipse.dd.dsf.debug.service.command.ICommand; import org.eclipse.dd.dsf.debug.service.command.ICommandControl; @@ -1629,6 +1630,13 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon return MIPlugin.getBundleContext(); } + private void markAllOutOfDate() { + MIRootVariableObject root; + while ((root = updatedRootList.poll()) != null) { + root.markAsOutOfDate(); + } + } + @DsfServiceEventHandler public void eventDispatched(IRunControl.IResumedDMEvent e) { // Program has resumed, all variable objects need to be updated. @@ -1636,13 +1644,20 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon // to deal with those. Also, to optimize this operation, we have // a list of all roots that have been updated, so we only have to // set those to needing to be updated. - MIRootVariableObject root; - while ((root = updatedRootList.poll()) != null) { - root.markAsOutOfDate(); - } + markAllOutOfDate(); } @DsfServiceEventHandler public void eventDispatched(IRunControl.ISuspendedDMEvent e) { } + + @DsfServiceEventHandler + public void eventDispatched(IMemoryChangedEvent e) { + // Some memory has changed. We currently do not know the address + // of each of our variable objects, so there is no way to know + // which one is affected. Mark them all as out of date. + // The views will fully refresh on a MemoryChangedEvent + markAllOutOfDate(); + } + } From e8d462f047bec91dfdbdbac1e519a67107d52183 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 26 Feb 2008 20:02:06 +0000 Subject: [PATCH 267/834] [220446] Added and preprocessor for tutorial excercises. --- .../org.eclipse.dd.examples.dsf/.classpath | 1 + .../.settings/org.eclipse.jdt.core.prefs | 9 +- .../META-INF/MANIFEST.MF | 4 +- .../build_preprocess.xml | 51 +++ .../dsf/requestmonitor/Async2Plus2.java | 40 +++ .../dsf/requestmonitor/AsyncQuicksort.java | 134 ++++++++ .../dd/examples/ant/tasks/PreProcessor.java | 292 ++++++++++++++++++ .../dsf/requestmonitor/AsyncHelloWorld.java | 59 ++++ 8 files changed, 586 insertions(+), 4 deletions(-) create mode 100644 plugins/org.eclipse.dd.examples.dsf/build_preprocess.xml create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/requestmonitor/Async2Plus2.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/requestmonitor/AsyncQuicksort.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src_ant/org/eclipse/dd/examples/ant/tasks/PreProcessor.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/requestmonitor/AsyncHelloWorld.java diff --git a/plugins/org.eclipse.dd.examples.dsf/.classpath b/plugins/org.eclipse.dd.examples.dsf/.classpath index 304e86186aa..5f6c0064a2e 100644 --- a/plugins/org.eclipse.dd.examples.dsf/.classpath +++ b/plugins/org.eclipse.dd.examples.dsf/.classpath @@ -3,5 +3,6 @@ + diff --git a/plugins/org.eclipse.dd.examples.dsf/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.dd.examples.dsf/.settings/org.eclipse.jdt.core.prefs index 3d7e8d5439f..0460aae85c2 100644 --- a/plugins/org.eclipse.dd.examples.dsf/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.eclipse.dd.examples.dsf/.settings/org.eclipse.jdt.core.prefs @@ -1,4 +1,4 @@ -#Thu Jun 07 11:07:55 PDT 2007 +#Fri Feb 22 09:41:13 PST 2008 eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 @@ -33,7 +33,7 @@ org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning -org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore org.eclipse.jdt.core.compiler.problem.nullReference=ignore org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore @@ -41,6 +41,7 @@ org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warnin org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore +org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled @@ -53,13 +54,17 @@ org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeUncheckedExceptions=disabled org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled org.eclipse.jdt.core.compiler.problem.unusedImport=error org.eclipse.jdt.core.compiler.problem.unusedLabel=warning org.eclipse.jdt.core.compiler.problem.unusedLocal=warning org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning org.eclipse.jdt.core.compiler.source=1.5 diff --git a/plugins/org.eclipse.dd.examples.dsf/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.examples.dsf/META-INF/MANIFEST.MF index 68022d0409e..f7d7de86ec3 100644 --- a/plugins/org.eclipse.dd.examples.dsf/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.examples.dsf/META-INF/MANIFEST.MF @@ -12,7 +12,7 @@ Require-Bundle: org.eclipse.ui, org.eclipse.debug.ui, org.eclipse.dd.dsf, org.eclipse.ui, - org.eclipse.dd.dsf.ui - + org.eclipse.dd.dsf.ui, + org.apache.ant;bundle-version="1.7.0";resolution:=optional Eclipse-LazyStart: true Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/plugins/org.eclipse.dd.examples.dsf/build_preprocess.xml b/plugins/org.eclipse.dd.examples.dsf/build_preprocess.xml new file mode 100644 index 00000000000..eec661b4c5a --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/build_preprocess.xml @@ -0,0 +1,51 @@ + + + + + Debug Tutorial Exercises + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/requestmonitor/Async2Plus2.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/requestmonitor/Async2Plus2.java new file mode 100644 index 00000000000..6fa56cb19c4 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/requestmonitor/Async2Plus2.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.dsf.requestmonitor; + +import java.util.concurrent.Executor; + +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; + +/** + * Example of using a DataRequestMonitor to retrieve a result from an + * asynchronous method. + */ +public class Async2Plus2 { + + public static void main(String[] args) { + Executor executor = ImmediateExecutor.getInstance(); + DataRequestMonitor rm = + new DataRequestMonitor(executor, null) { + @Override + protected void handleCompleted() { + System.out.println("2 + 2 = " + getData()); + } + }; + asyncAdd(2, 2, rm); + } + + static void asyncAdd(int value1, int value2, DataRequestMonitor rm) { + rm.setData(value1 + value2); + rm.done(); + } +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/requestmonitor/AsyncQuicksort.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/requestmonitor/AsyncQuicksort.java new file mode 100644 index 00000000000..df18735f3ff --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/requestmonitor/AsyncQuicksort.java @@ -0,0 +1,134 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.dsf.requestmonitor; + +import java.util.Arrays; +import java.util.concurrent.Executor; + +import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; + +/** + * Example of using a CountingRequestMonitor to wait for multiple + * asynchronous calls to complete. + */ +public class AsyncQuicksort { + + static Executor fgExecutor = ImmediateExecutor.getInstance(); + + public static void main(String[] args) { + final int[] array = {5, 7, 8, 3, 2, 1, 9, 5, 4}; + + System.out.println("To sort: " + Arrays.toString(array)); + asyncQuicksort( + array, 0, array.length - 1, + new RequestMonitor(fgExecutor, null) { + @Override + protected void handleCompleted() { + System.out.println("Sorted: " + Arrays.toString(array)); + } + }); + } + + static void asyncQuicksort(final int[] array, final int left, + final int right, final RequestMonitor rm) + { + if (right > left) { + int pivot = left; + //#ifdef request_monitors_ex2 +//# // TODO: Request Monitors Exercise 2 - Convert partition to an async. method. +//# int newPivot = partition(array, left, right, pivot); +//# int newPivot = getData(); +//# printArray(array, left, right, newPivot); +//# +//# CountingRequestMonitor countingRm = new CountingRequestMonitor(fgExecutor, rm); +//# asyncQuicksort(array, left, newPivot - 1, countingRm); +//# asyncQuicksort(array, newPivot + 1, right, countingRm); +//# countingRm.setDoneCount(2); + //#else + asyncPartition( + array, left, right, pivot, + new DataRequestMonitor(fgExecutor, rm) { + @Override + protected void handleCompleted() { + int newPivot = getData(); + printArray(array, left, right, newPivot); + + CountingRequestMonitor countingRm = new CountingRequestMonitor(fgExecutor, rm); + asyncQuicksort(array, left, newPivot - 1, countingRm); + asyncQuicksort(array, newPivot + 1, right, countingRm); + countingRm.setDoneCount(2); + } + }); + //#endif + + } else { + rm.done(); + } + } + + //#ifdef request_monitors_ex2 +//# // TODO: Request Monitors Exercise 2 - Convert partition to an async. method. +//# static int partition(int[] array, int left, int right, int pivot) + //#else + static void asyncPartition(int[] array, int left, int right, int pivot, DataRequestMonitor rm) + //#endif + { + int pivotValue = array[pivot]; + array[pivot] = array[right]; + array[right] = pivotValue; + int store = left; + for (int i = left; i < right; i++) { + if (array[i] <= pivotValue) { + int tmp = array[store]; + array[store] = array[i]; + array[i] = tmp; + store++; + } + } + array[right] = array[store]; + array[store] = pivotValue; + + //#ifdef request_monitors_ex2 +//# // TODO: Request Monitors Exercise 2 - Convert partition to an async. method. +//# return store; + //#else + rm.setData(store); + rm.done(); + //#endif + } + + static void printArray(int[] array, int left, int right, int pivot) { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < array.length; i++ ) { + if (i == left) { + buffer.append('>'); + } else if (i == pivot) { + buffer.append('-'); + } else { + buffer.append(' '); + } + buffer.append(array[i]); + + if (i == right) { + buffer.append('<'); + } else if (i == pivot) { + buffer.append('-'); + } else { + buffer.append(' '); + } + } + + System.out.println(buffer); + } +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src_ant/org/eclipse/dd/examples/ant/tasks/PreProcessor.java b/plugins/org.eclipse.dd.examples.dsf/src_ant/org/eclipse/dd/examples/ant/tasks/PreProcessor.java new file mode 100644 index 00000000000..240054a57c1 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src_ant/org/eclipse/dd/examples/ant/tasks/PreProcessor.java @@ -0,0 +1,292 @@ +/******************************************************************************* + * Copyright (c) 2005, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Bjorn Freeman-Benson - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.ant.tasks; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import java.util.Vector; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.DirectoryScanner; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.FileSet; +import org.apache.tools.ant.util.FileUtils; + +/** + * Java preprocessor for code examples. Used to export source code for + * example plug-ins with parts of code missing/inserted etc., for + * various exercises. + *

    + * The preprocessor looks for #ifdef statements in java comments, and is + * run with a set of symbols. For example: + *

    + * //#ifdef ex1
    + * ... code to insert when 'ex1' symbol is on
    + * //#else
    + * ... code to insert when not 'ex1'
    + * //#endif
    + * 
    + *

    + */ +public class PreProcessor extends Task { + + private Vector fFileSets = new Vector(); + private File fDestDir = null; + private Set fSymbols = new HashSet(); + private FileUtils fUtils = FileUtils.getFileUtils(); + + // possible states + private static final int STATE_OUTSIDE_CONDITION = 0; + private static final int STATE_TRUE_CONDITION = 1; + private static final int STATE_FALSE_CONDITION = 2; + private static final int STATE_POST_TRUE_CONDITION = 3; + + // matchers + private Matcher IF_DEF_MATCHER = Pattern.compile("#ifdef\\s+\\w+").matcher(""); + private Matcher ELSE_IF_MATCHER = Pattern.compile("#elseif\\s+\\w+").matcher(""); + private Matcher ELSE_MATCHER = Pattern.compile("#else$|#else\\W+").matcher(""); + private Matcher END_MATCHER = Pattern.compile("#endif").matcher(""); + + + /** + * Constructs a new preprocessor task + */ + public PreProcessor() { + } + + /** + * Adds a set of files to process. + * + * @param set a set of files to process + */ + public void addFileset(FileSet set) { + fFileSets.addElement(set); + } + + /** + * Sets the destination directory for processed files. + * + * @param destDir destination directory for processed files + */ + public void setDestdir(File destDir) { + fDestDir = destDir; + } + + /** + * Sets the symbols that are "on" for the preprocessing. + * + * @param symbols symbols that are "on" for the preprocessing + */ + public void setSymbols(String symbols) { + String[] strings = symbols.split(","); + for (int i = 0; i < strings.length; i++) { + String string = strings[i].trim(); + if (string.length() > 0) { + fSymbols.add(string); + } + } + } + + public void execute() throws BuildException { + if (fSymbols.size() == 0) { + throw new BuildException("No symbols specified for preprocessor"); + } + if (fFileSets.isEmpty()) { + throw new BuildException("No filesets specified for processing"); + } + if (!fDestDir.exists()) { + throw new BuildException("destdir does not exist: " + fDestDir.getAbsolutePath()); + } + StringBuffer buf = new StringBuffer("Symbols: "); + String[] symbols = (String[]) fSymbols.toArray(new String[fSymbols.size()]); + for (int i = 0; i < symbols.length; i++) { + String symbol = symbols[i]; + buf.append(symbol); + if(i < (symbols.length -1)) { + buf.append(", "); + } + } + log(buf.toString()); + + Iterator fileSets = fFileSets.iterator(); + while (fileSets.hasNext()) { + FileSet fileSet = (FileSet) fileSets.next(); + DirectoryScanner scanner = fileSet.getDirectoryScanner(getProject()); + String[] includedFiles = scanner.getIncludedFiles(); + File baseDir = fileSet.getDir(getProject()); + for (int i = 0; i < includedFiles.length; i++) { + String fileName = includedFiles[i]; + processFile(baseDir, fileName, fDestDir); + } + } + + } + + /** + * Process the file + * @param baseDir base directory source file is relative to + * @param fileName source file name + * @param destDir root destination directory + */ + private void processFile(File baseDir, String fileName, File destDir) throws BuildException { + File destFile = new File(destDir, fileName); + File srcFile = new File(baseDir, fileName); + File dir = destFile.getParentFile(); + if (!dir.exists()) { + dir.mkdirs(); + } + String contents = null; + if (fileName.endsWith(".java")) { + contents = preProcessFile(srcFile, "//#"); + } else if (fileName.equals("plugin.xml")) { + contents = preProcessFile(srcFile, null); + } + if (contents == null) { + // no change, just copy file + try { + fUtils.copyFile(srcFile, destFile); + } catch (IOException e) { + throw new BuildException(e); + } + } else { + // write new file + FileWriter writer; + try { + writer = new FileWriter(destFile); + writer.write(contents); + writer.close(); + } catch (IOException e) { + throw new BuildException(e); + } + + } + } + + /** + * Preprocesses a file + * + * @param srcFile the file to process + * @param strip chars to stip off lines in a true condition, or null + * @return + */ + public String preProcessFile(File srcFile, String strip) { + try { + FileReader fileReader = new FileReader(srcFile); + BufferedReader reader = new BufferedReader(fileReader); + StringBuffer buffer = new StringBuffer(); + String line = reader.readLine(); + String activeSymbol = null; + int state = STATE_OUTSIDE_CONDITION; + boolean changed = false; + while (line != null) { + boolean ifdef = IF_DEF_MATCHER.reset(line).find(); + boolean elseif = ELSE_IF_MATCHER.reset(line).find(); + boolean elze = ELSE_MATCHER.reset(line).find(); + boolean endif = END_MATCHER.reset(line).find(); + boolean commandLine = ifdef || elseif || elze || endif; + boolean written = false; + switch (state) { + case STATE_OUTSIDE_CONDITION: + if (ifdef) { + String condition = line.substring(IF_DEF_MATCHER.start(), IF_DEF_MATCHER.end()); + String[] strings = condition.split("\\s+"); + activeSymbol = strings[1].trim(); + if (fSymbols.contains(activeSymbol)) { + state = STATE_TRUE_CONDITION; + } else { + state = STATE_FALSE_CONDITION; + } + } else if (elseif) { + throw new BuildException("#elseif encountered without corresponding #ifdef"); + } else if (elze) { + throw new BuildException("#else encountered without corresponding #ifdef (" + srcFile.getPath() + ")"); + } else if (endif) { + throw new BuildException("#endif encountered without corresponding #ifdef"); + } + break; + case STATE_TRUE_CONDITION: + if (elze || elseif) { + state = STATE_POST_TRUE_CONDITION; + break; + } else if (endif) { + state = STATE_OUTSIDE_CONDITION; + break; + } else if (ifdef) { + throw new BuildException("illegal nested #ifdef"); + } + case STATE_FALSE_CONDITION: + if (elseif) { + String condition = line.substring(ELSE_IF_MATCHER.start(), ELSE_IF_MATCHER.end()); + String[] strings = condition.split("\\s+"); + activeSymbol = strings[1].trim(); + if (fSymbols.contains(activeSymbol)) { + state = STATE_TRUE_CONDITION; + } else { + state = STATE_FALSE_CONDITION; + } + } else if (elze) { + state = STATE_TRUE_CONDITION; + break; + } else if (endif) { + state = STATE_OUTSIDE_CONDITION; + break; + } else if (ifdef) { + throw new BuildException("illegal nested #ifdef"); + } + case STATE_POST_TRUE_CONDITION: + if (endif) { + state = STATE_OUTSIDE_CONDITION; + break; + } else if (ifdef) { + throw new BuildException("illegal nested #ifdef"); + } + } + if (!commandLine) { + if (state == STATE_OUTSIDE_CONDITION || state == STATE_TRUE_CONDITION) { + if (state == STATE_TRUE_CONDITION && strip != null) { + if (line.startsWith(strip)) { + line = line.substring(strip.length()); + } + } + buffer.append(line); + buffer.append("\n"); + written = true; + } + } + changed = changed || !written; + line = reader.readLine(); + } + if (!changed) { + return null; + } + return buffer.toString(); + } catch (IOException e) { + throw new BuildException(e); + } + } + + public static void main(String[] args) { + PreProcessor processor = new PreProcessor(); + processor.setSymbols("ex2"); + String string = processor.preProcessFile(new File("c:\\eclipse3.1\\dev\\example.debug.core\\src\\example\\debug\\core\\launcher\\PDALaunchDelegate.java"), "//#"); + //String string = processor.preProcessFile(new File("c:\\eclipse3.1\\dev\\example.debug.core\\plugin.xml"), null); + System.out.println(string); + } +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/requestmonitor/AsyncHelloWorld.java b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/requestmonitor/AsyncHelloWorld.java new file mode 100644 index 00000000000..b7c10afb29e --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/requestmonitor/AsyncHelloWorld.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +//#ifdef request_monitors_ex1 +//#package org.eclipse.dd.examples.dsf.requestmonitor.excercise; +//#else +package org.eclipse.dd.examples.dsf.requestmonitor.answer; +//#endif + +import java.util.concurrent.Executor; + +import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; + +/** + * "Hello world" example which uses an asynchronous method to print out + * the result. + *

    + * The main method uses an immediate executor, which executes runnables + * as soon as they are submitted, in creating its request monitor. + * + */ +public class AsyncHelloWorld { + + public static void main(String[] args) { + Executor executor = ImmediateExecutor.getInstance(); + RequestMonitor rm = new RequestMonitor(executor, null); + asyncHelloWorld(rm); + } + + static void asyncHelloWorld(RequestMonitor rm) { + System.out.println("Hello world"); + //#ifdef request_monitors_ex1 +//# // TODO: Request Monitors Exercise 1 - Call a second async. +//# // "Hello world 2" method. +//# rm.done(); + //#else + RequestMonitor rm2 = new RequestMonitor(ImmediateExecutor.getInstance(), rm); + asyncHelloWorld2(rm2); + //#endif + } + + //#ifdef request_monitors_ex1 +//# // TODO: Request Monitors Exercise 1 - Add a second async. +//# // "Hello world 2" method. + //#else + static void asyncHelloWorld2(RequestMonitor rm) { + System.out.println("Hello world 2"); + rm.done(); + } + //#endif +} From 9150b06a8f745d78e202a2437475552506734b83 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Tue, 26 Feb 2008 20:04:41 +0000 Subject: [PATCH 268/834] Fix for Bug 213061 Expressions and Variables views do a full refresh on MemoryChangedEvent and ExpressionChangedEvent. MIVariableManager sets all varObjects to out-of-date when any varObject is modified by the user. --- .../ui/viewmodel/variable/VariableVMNode.java | 55 ++++++++----------- .../dd/mi/service/MIVariableManager.java | 33 +++++++++-- 2 files changed, 51 insertions(+), 37 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java index 8e3883c4e36..077ed6ff17e 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java @@ -26,9 +26,9 @@ import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.service.IExpressions; import org.eclipse.dd.dsf.debug.service.IFormattedValues; +import org.eclipse.dd.dsf.debug.service.IMemory; import org.eclipse.dd.dsf.debug.service.IRunControl; import org.eclipse.dd.dsf.debug.service.IStack; -import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionChangedDMEvent; import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMData; import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext; @@ -77,13 +77,13 @@ public class VariableVMNode extends AbstractExpressionVMNode * @see buildDelta() */ - if (e instanceof IRunControl.ISuspendedDMEvent) { + // When an expression changes or memory, we must do a full refresh + // see Bug 213061 and Bug 214550 + if (e instanceof IRunControl.ISuspendedDMEvent || + e instanceof IExpressions.IExpressionChangedDMEvent || + e instanceof IMemory.IMemoryChangedEvent) { return IModelDelta.CONTENT; } - - if ( e instanceof IExpressions.IExpressionChangedDMEvent) { - return IModelDelta.STATE; - } if (e instanceof PropertyChangeEvent && ((PropertyChangeEvent)e).getProperty() == IDebugVMConstants.CURRENT_FORMAT_STORAGE) @@ -95,20 +95,15 @@ public class VariableVMNode extends AbstractExpressionVMNode } public void buildDelta(final Object event, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) { - - if (event instanceof IRunControl.ISuspendedDMEvent) { + + // When an expression changes or memory, we must do a full refresh + // see Bug 213061 and Bug 214550 + if (event instanceof IRunControl.ISuspendedDMEvent || + event instanceof IExpressions.IExpressionChangedDMEvent || + event instanceof IMemory.IMemoryChangedEvent) { parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); } - if ( event instanceof IExpressions.IExpressionChangedDMEvent) { - /* - * Logically one would think that STATE should be specified here. But we specifiy CONTENT - * as well so that if there sub expressions which are affected in some way ( such as with - * an expanded union then they will show the changes also. - */ - parentDelta.addNode( createVMContext(((IExpressions.IExpressionChangedDMEvent)event).getDMContext()), IModelDelta.CONTENT | IModelDelta.STATE ); - } - if (event instanceof PropertyChangeEvent && ((PropertyChangeEvent)event).getProperty() == IDebugVMConstants.CURRENT_FORMAT_STORAGE) { @@ -492,14 +487,14 @@ public class VariableVMNode extends AbstractExpressionVMNode } public int getDeltaFlagsForExpression(IExpression expression, Object event) { - if (event instanceof IRunControl.ISuspendedDMEvent) { + // When an expression changes or memory, we must do a full refresh + // see Bug 213061 and Bug 214550 + if (event instanceof IRunControl.ISuspendedDMEvent || + event instanceof IExpressions.IExpressionChangedDMEvent || + event instanceof IMemory.IMemoryChangedEvent) { return IModelDelta.CONTENT; } - if (event instanceof IExpressionChangedDMEvent) { - return IModelDelta.CONTENT; - } - if (event instanceof PropertyChangeEvent && ((PropertyChangeEvent)event).getProperty() == IDebugVMConstants.CURRENT_FORMAT_STORAGE) { @@ -517,20 +512,14 @@ public class VariableVMNode extends AbstractExpressionVMNode public void buildDeltaForExpressionElement(Object element, int elementIdx, Object event, VMDelta parentDelta, RequestMonitor rm) { - if (event instanceof IRunControl.ISuspendedDMEvent) { + // When an expression changes or memory, we must do a full refresh + // see Bug 213061 and Bug 214550 + if (event instanceof IRunControl.ISuspendedDMEvent || + event instanceof IExpressions.IExpressionChangedDMEvent || + event instanceof IMemory.IMemoryChangedEvent) { parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); } - if ( event instanceof IExpressions.IExpressionChangedDMEvent) { - /* - * Logically one would think that STATE should be specified here. But we specify CONTENT - * as well so that if there sub expressions which are affected in some way ( such as with - * an expanded union then they will show the changes also. - */ - parentDelta.addNode(element, IModelDelta.CONTENT); - } - - if (event instanceof PropertyChangeEvent && ((PropertyChangeEvent)event).getProperty() == IDebugVMConstants.CURRENT_FORMAT_STORAGE) { diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java index a8cb20bf35d..b445a0619d4 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java @@ -818,7 +818,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon * @param rm * The request monitor to indicate the operation is finished */ - private void writeValue(String value, final String formatId, final RequestMonitor rm) { + private void writeValue(String value, String formatId, final RequestMonitor rm) { // If the variable is a complex structure (including an array), then we cannot write to it if (isComplex()) { @@ -830,8 +830,8 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon // First deal with the format. For GDB, the way to specify a format is to prefix the value with // 0x for hex, 0 for octal etc So we need to make sure that 'value' has this prefix. - // Note that there is no way to specify a binary format for GDB so we convert 'value' - // into a decimal format. + // Note that there is no way to specify a binary format for GDB up to and including + // GDB 6.7.1, so we convert 'value' into a decimal format. // If the formatId is NATURAL, we do nothing for now because it is more complicated. // For example for a bool, a value of "true" is correct and should be left as is, // but for a pointer a value of 16 should be sent to GDB as 0x16. To figure this out, @@ -854,6 +854,8 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon rm.done(); return; } + + formatId = IFormattedValues.DECIMAL_FORMAT; } else if (formatId.equals(IFormattedValues.DECIMAL_FORMAT)) { // nothing to do @@ -867,6 +869,16 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon rm.done(); return; } + + // If the value has not changed, no need to set it. + // Return a status info so that handleOK is not called and we don't send + // an ExpressionChanged event + if (value.equals(getValue(formatId))) { + rm.setStatus(new Status(IStatus.INFO, MIPlugin.PLUGIN_ID, IDsfService.NOT_SUPPORTED, + "Setting to the same value of: " + value, null)); //$NON-NLS-1$ + rm.done(); + return; + } // No need to be in ready state or to lock the object fCommandControl.queueCommand( @@ -874,7 +886,20 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon new DataRequestMonitor(getExecutor(), rm) { @Override protected void handleOK() { - resetValues(getData().getValue()); + // We must also mark all variable objects + // as out-of-date. This is because some variable objects may be affected + // by this one having changed. + // e.g., + // int i; + // int* pi = &i; + // Here, if 'i' is changed by the user, then 'pi' will also change + // Since there is no way to know this unless we keep track of all addresses, + // we must mark everything as out-of-date. See bug 213061 + markAllOutOfDate(); + + // Useless since we just marked everything as out-of-date + // resetValues(getData().getValue()); + rm.done(); } }); From 7456589c4faebc05e509ea81aed7ea9bf2654075 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Tue, 26 Feb 2008 20:34:20 +0000 Subject: [PATCH 269/834] Fix for bug 220449 ExpressionService parses strings when requesting an address and only keeps the address part. --- .../src/org/eclipse/dd/mi/service/ExpressionService.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/ExpressionService.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/ExpressionService.java index 75223e4474a..d7e751cebef 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/ExpressionService.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/ExpressionService.java @@ -631,7 +631,14 @@ public class ExpressionService extends AbstractDsfService implements IExpression new DataRequestMonitor(getExecutor(), rm) { @Override protected void handleOK() { - final String addrStr = getData().getValue(); + String tmpAddrStr = getData().getValue(); + + // Deal with adresses of contents of a char* which is in + // the form of "0x12345678 \"This is a string\"" + int split = tmpAddrStr.indexOf(' '); + if (split != -1) tmpAddrStr = tmpAddrStr.substring(0, split); + final String addrStr = tmpAddrStr; + fExpressionCache.execute( new MIDataEvaluateExpression(sizeDmc), new DataRequestMonitor(getExecutor(), rm) { From fd71e3600f689413e66ebc932a7b71fae52b9712 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 26 Feb 2008 21:19:09 +0000 Subject: [PATCH 270/834] [220446] Converted request monitor excercises to use the request monitor. --- .../build_preprocess.xml | 27 ++++--- .../dsf/requestmonitor/Async2Plus2.java | 4 + .../dsf/requestmonitor/AsyncHelloWorld.java | 30 ++++---- .../dsf/requestmonitor/AsyncQuicksort.java | 75 ++++++++++--------- 4 files changed, 73 insertions(+), 63 deletions(-) rename plugins/org.eclipse.dd.examples.dsf/{src => src_preprocess}/org/eclipse/dd/examples/dsf/requestmonitor/Async2Plus2.java (93%) rename plugins/org.eclipse.dd.examples.dsf/{src => src_preprocess}/org/eclipse/dd/examples/dsf/requestmonitor/AsyncQuicksort.java (62%) diff --git a/plugins/org.eclipse.dd.examples.dsf/build_preprocess.xml b/plugins/org.eclipse.dd.examples.dsf/build_preprocess.xml index eec661b4c5a..8805fb7203c 100644 --- a/plugins/org.eclipse.dd.examples.dsf/build_preprocess.xml +++ b/plugins/org.eclipse.dd.examples.dsf/build_preprocess.xml @@ -8,24 +8,25 @@ Contributors: IBM Corporation - initial API and implementation + Wind River Systems - adopted to use with DSF EclipseCon - Debug Tutorial Exercises + DSF Tutorial Exercises ====================================================================== --> - Debug Tutorial Exercises + DSF Tutorial Exercises - - + + - + - @@ -47,7 +46,8 @@ - + + diff --git a/plugins/org.eclipse.dd.examples.dsf/plugin.xml b/plugins/org.eclipse.dd.examples.dsf/plugin.xml index 798b7f3e230..67936f7f0eb 100644 --- a/plugins/org.eclipse.dd.examples.dsf/plugin.xml +++ b/plugins/org.eclipse.dd.examples.dsf/plugin.xml @@ -28,19 +28,19 @@ Date: Thu, 28 Feb 2008 18:42:09 +0000 Subject: [PATCH 275/834] [220446] Updated the "dataviewer" example and excercises for EclipseCon tutorial. --- .../org.eclipse.dd.examples.dsf/plugin.xml | 26 +- ...llableInputCoalescingSlowDataProvider.java | 440 ------------------ ...InputCoalescingSlowDataProviderAction.java | 54 --- ...ellingSlowDataProviderContentProvider.java | 292 ------------ .../examples/dsf/concurrent/DataProvider.java | 64 --- .../InputCoalescingSlowDataProvider.java | 408 ---------------- ...InputCoalescingSlowDataProviderAction.java | 54 --- .../dsf/concurrent/SlowDataProvider.java | 330 ------------- .../concurrent/SlowDataProviderAction.java | 53 --- .../SlowDataProviderContentProvider.java | 190 -------- .../concurrent/SlowDataProviderDialog.java | 50 -- .../dsf/dataviewer/AsyncDataViewer.java | 266 +++++++++++ .../dataviewer/DataGeneratorWithExecutor.java | 404 ++++++++++++++++ .../dataviewer/DataGeneratorWithThread.java | 238 ++++++++++ .../dsf/dataviewer/IDataGenerator.java | 59 +++ .../dsf/dataviewer/SyncDataViewer.java | 180 +++++++ .../doc-files/dsf_concurrency_model-1.png | Bin .../dd/examples/dsf/dataviewer}/package.html | 0 18 files changed, 1151 insertions(+), 1957 deletions(-) delete mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/CancellableInputCoalescingSlowDataProvider.java delete mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/CancellableInputCoalescingSlowDataProviderAction.java delete mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/CancellingSlowDataProviderContentProvider.java delete mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/DataProvider.java delete mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/InputCoalescingSlowDataProvider.java delete mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/InputCoalescingSlowDataProviderAction.java delete mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/SlowDataProvider.java delete mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/SlowDataProviderAction.java delete mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/SlowDataProviderContentProvider.java delete mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/SlowDataProviderDialog.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/AsyncDataViewer.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithExecutor.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithThread.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/IDataGenerator.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/SyncDataViewer.java rename plugins/org.eclipse.dd.examples.dsf/{src/org/eclipse/dd/examples/dsf/concurrent => src_preprocess/org/eclipse/dd/examples/dsf/dataviewer}/doc-files/dsf_concurrency_model-1.png (100%) rename plugins/org.eclipse.dd.examples.dsf/{src/org/eclipse/dd/examples/dsf/concurrent => src_preprocess/org/eclipse/dd/examples/dsf/dataviewer}/package.html (100%) diff --git a/plugins/org.eclipse.dd.examples.dsf/plugin.xml b/plugins/org.eclipse.dd.examples.dsf/plugin.xml index 67936f7f0eb..22ed17e9762 100644 --- a/plugins/org.eclipse.dd.examples.dsf/plugin.xml +++ b/plugins/org.eclipse.dd.examples.dsf/plugin.xml @@ -6,12 +6,12 @@ point="org.eclipse.ui.views"> + id="org.eclipse.dd.examples.dsf"> @@ -22,34 +22,16 @@ id="org.eclipse.dd.dsf.test.actionSet" label="DSF Examples">

    - - - diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/CancellableInputCoalescingSlowDataProvider.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/CancellableInputCoalescingSlowDataProvider.java deleted file mode 100644 index d9839e94334..00000000000 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/CancellableInputCoalescingSlowDataProvider.java +++ /dev/null @@ -1,440 +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.examples.dsf.concurrent; - -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Random; -import java.util.Set; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.DelayQueue; -import java.util.concurrent.Delayed; -import java.util.concurrent.TimeUnit; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.DsfExecutor; -import org.eclipse.dd.dsf.concurrent.DsfRunnable; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; - -/** - * Example data provider which has a built-in delay when fetching data. This - * data provider simulates a service which retrieves data from an external - * source such as a networked target, which incurs a considerable delay when - * retrieving data. The data items are simulated values which consist of the - * time when data is being retrieved followed by the item's index. - *

    - * This version of the data provider builds on the input-coalescing feature, - * it adds a test to check if the requests were cancelled by the user, before - * they are coalesced and queued to be processed by the provider thread. - */ -public class CancellableInputCoalescingSlowDataProvider implements DataProvider { - - /** Minimum count of data items */ - private final static int MIN_COUNT = 1000; - - /** Maximum count of data items */ - private final static int MAX_COUNT = 2000; - - /** Time interval how often random changes occur. */ - private final static int RANDOM_CHANGE_MILIS = 10000; - - /** Number of times random changes are made, before count is changed. */ - private final static int RANDOM_COUNT_CHANGE_INTERVALS = 3; - - /** Percentage of values that is changed upon random change (0-100). */ - private final static int RANDOM_CHANGE_SET_PERCENTAGE = 10; - - /** - * Amount of time (in miliseconds) how long the requests to provider, and - * events from provider are delayed by. - */ - private final static int TRANSMISSION_DELAY_TIME = 500; - - /** - * Amount of time (in milliseconds) how long the provider takes to process - * a request. - */ - private final static int PROCESSING_TIME = 100; - - /** - * Maximum number of item requests that can be coalesced into a single - * request. - */ - private final static int COALESCING_COUNT_LIMIT = 10; - - /** - * Delay in processing the buffer of getItem() calls. This delay helps - * to ensure that a meaningful number of items is present in the buffer - * before the buffer data is coalesced into a request. - */ - private final static int COALESCING_DELAY_TIME = 100; - - /** - * Maximum allowed number of requests in transmission to provider thread. - * This limit causes most of the client calls to be buffered at the input - * rather than in the request queue, which in truns allows the stale - * requests to be cancelled, before they are sent to the provider thread - * for processing. - */ - private final static int REQUEST_QUEUE_SIZE_LIMIT = 100; - - /** Delay before processing calls buffer, if the request queue is full */ - private final static int REQUEST_BUFFER_FULL_RETRY_DELAY = PROCESSING_TIME; - - /** Dispatch-thread executor that this provider uses. */ - private DsfExecutor fExecutor; - - /** List of listeners registered for events from provider. */ - private List fListeners = new LinkedList(); - - /** Thread that handles data requests. */ - private ProviderThread fProviderThread; - - /** Queue of currently pending data requests. */ - private final BlockingQueue fQueue = new DelayQueue(); - - /** - * Runnable to be submitted when the data provider thread is shut down. - * This variable acts like a flag: when client want to shut down the - * provider, it sets this runnable, and when the backgroun thread sees - * that it's set, it shuts itself down, and posts this runnable with - * the executor. - */ - private RequestMonitor fShutdownRequestMonitor = null; - - /** - * Buffers for coalescing getItem() calls into a single request. - */ - private List fGetItemIndexesBuffer = new LinkedList(); - private List> fGetItemRequestMonitorsBuffer = new LinkedList>(); - - /** - * Base class for requests that are queued by the data provider. It - * implements java.util.concurrent.Delayed to allow for use of DelayedQueue. - * Every request into the queue is delayed by the simulated transmission - * time. - */ - private static abstract class Request implements Delayed { - /** Sequence counter and number are used to ensure FIFO order **/ - private static int fSequenceCounter = 0; - private int fSequenceNumber = fSequenceCounter++; - - /** Time delay tracks how items will be delayed. **/ - private long fTime = System.currentTimeMillis() + TRANSMISSION_DELAY_TIME; - - // @see java.util.concurrent.Delayed - public long getDelay(TimeUnit unit) { - return unit.convert(fTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS); - } - - // @see java.lang.Comparable - public int compareTo(Delayed other) { - if (other == this) // compare zero ONLY if same object - return 0; - Request x = (Request)other; - long diff = fTime - x.fTime; - - if (diff < 0) return -1; - else if (diff > 0) return 1; - else if (fSequenceNumber < x.fSequenceNumber) return -1; - else return 1; - } - - /** All requests have an associated array of RequestMonitor tokens **/ - abstract RequestMonitor[] getRequestMonitors(); - } - - /** - * Object used to encapsulate the "getItemCount" requests. Instances of it - * are queued till processed. - */ - private static class CountRequest extends Request - { - DataRequestMonitor fRequestMonitor; - CountRequest(DataRequestMonitor rm) { fRequestMonitor = rm; } - @Override - DataRequestMonitor[] getRequestMonitors() { return new DataRequestMonitor[] { fRequestMonitor }; } - } - - /** - * Object used to encapsulate the "getItem" requests. Instances of it - * are queued till processed. - */ - private static class ItemRequest extends Request - { - DataRequestMonitor[] fRequestMonitors; - Integer[] fIndexes; - ItemRequest(Integer[] indexes, DataRequestMonitor[] rms) { fIndexes = indexes; fRequestMonitors = rms; } - @Override - DataRequestMonitor[] getRequestMonitors() { return fRequestMonitors; } - } - - /** - * The background thread of data provider. This thread retrieves the - * requests from the provider's queue and processes them. It also - * initiates random changes in the data set and issues corresponding - * events. - */ - private class ProviderThread extends Thread - { - /** - * Current count of items in the data set. It is changed - * periodically for simulation purposes. - */ - private int fCount = MIN_COUNT; - - /** - * Incremented with every data change, it causes the count to be reset - * every four random changes. - */ - private int fCountTrigger = 0; - - /** Time when the last change was performed. */ - private long fLastChangeTime = System.currentTimeMillis(); - - /** Random number generator */ - private Random fRandom = new java.util.Random(); - - @Override - public void run() { - try { - // Initialize the count. - randomCount(); - - // Perform the loop until the shutdown runnable is set. - while(fShutdownRequestMonitor == null) { - // Get the next request from the queue. The time-out - // ensures that that we get to process the random changes. - final Request request = fQueue.poll(RANDOM_CHANGE_MILIS / 10, TimeUnit.MILLISECONDS); - - // If a request was dequeued, process it. - if (request != null) { - // Simulate a processing delay. - Thread.sleep(PROCESSING_TIME); - - if (request instanceof CountRequest) { - processCountRequest((CountRequest)request); - } else if (request instanceof ItemRequest) { - processItemRequest((ItemRequest)request); - } - - // Whatever the results, post it to dispatch thread - // executor (with transmission delay). - fExecutor.schedule( - new DsfRunnable() { - public void run() { - for (RequestMonitor requestMonitor : request.getRequestMonitors()) { - requestMonitor.done(); - } - } - }, - TRANSMISSION_DELAY_TIME, TimeUnit.MILLISECONDS); - } - - // Simulate data changes. - randomChanges(); - } - } - catch (InterruptedException x) { - DsfExamplesPlugin.getDefault().getLog().log( new Status( - IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, 0, "Interrupted exception in slow data provider thread.", x )); //$NON-NLS-1$ - } - - // Notify the client that requested shutdown, that shutdown is complete. - fShutdownRequestMonitor.done(); - fShutdownRequestMonitor = null; - } - - private void processCountRequest(CountRequest request) { - // Calculate the simulated values. - request.fRequestMonitor.setData(fCount); - } - - private void processItemRequest(ItemRequest request) { - // Check to make sure that the number of indexes matches the number - // of return tokens. - assert request.fRequestMonitors.length == request.fIndexes.length; - - // Calculate the simulated values for each index in request. - for (int i = 0; i < request.fIndexes.length; i++) { - request.fRequestMonitors[i].setData(Long.toHexString(fLastChangeTime) + "." + request.fIndexes[i]); //$NON-NLS-1$ - } - } - - /** - * This method simulates changes in provider's data set. - */ - private void randomChanges() - { - if (System.currentTimeMillis() > fLastChangeTime + RANDOM_CHANGE_MILIS) { - fLastChangeTime = System.currentTimeMillis(); - // once in every 30 seconds broadcast item count change - if (++fCountTrigger % RANDOM_COUNT_CHANGE_INTERVALS == 0) randomCount(); - else randomDataChange(); - } - } - - - /** - * Calculates new size for provider's data set. - */ - private void randomCount() - { - fCount = MIN_COUNT + Math.abs(fRandom.nextInt()) % (MAX_COUNT - MIN_COUNT); - - // Generate the event that the count has changed, and post it to - // dispatch thread with transmission delay. - fExecutor.schedule( - new Runnable() { public void run() { - for (Listener listener : fListeners) { - listener.countChanged(); - } - }}, - TRANSMISSION_DELAY_TIME, TimeUnit.MILLISECONDS); - } - - - /** - * Invalidates a random range of indexes. - */ - private void randomDataChange() - { - final Set set = new HashSet(); - // Change one in ten values. - for (int i = 0; i < fCount * RANDOM_CHANGE_SET_PERCENTAGE / 100; i++) { - set.add( new Integer(Math.abs(fRandom.nextInt()) % fCount) ); - } - - // Generate the event that the data has changed. - // Post dispatch thread with transmission delay. - fExecutor.schedule( - new Runnable() { public void run() { - for (Listener listener : fListeners) { - listener.dataChanged(set); - } - }}, - TRANSMISSION_DELAY_TIME, TimeUnit.MILLISECONDS); - } - } - - - public CancellableInputCoalescingSlowDataProvider(DsfExecutor executor) { - fExecutor = executor; - fProviderThread = new ProviderThread(); - fProviderThread.start(); - } - - /** - * Requests shutdown of this data provider. - * @param requestMonitor Monitor to call when shutdown is complete. - */ - public void shutdown(RequestMonitor requestMonitor) { - fShutdownRequestMonitor = requestMonitor; - } - - /////////////////////////////////////////////////////////////////////////// - // DataProvider - public DsfExecutor getDsfExecutor() { - return fExecutor; - } - - public void getItemCount(final DataRequestMonitor rm) { - fQueue.add(new CountRequest(rm)); - } - - public void getItem(final int index, final DataRequestMonitor rm) { - // Schedule a buffer-servicing call, if one is needed. - if (fGetItemIndexesBuffer.isEmpty()) { - fExecutor.schedule( - new Runnable() { public void run() { - fileBufferedRequests(); - }}, - COALESCING_DELAY_TIME, - TimeUnit.MILLISECONDS); - } - - // Add the call data to the buffer. - // Note: it doesn't matter that the items were added to the buffer - // after the buffer-servicing request was scheduled. This is because - // the buffers are guaranteed not to be modified until this dispatch - // cycle is over. - fGetItemIndexesBuffer.add(index); - fGetItemRequestMonitorsBuffer.add(rm); - } - - @SuppressWarnings("unchecked") - public void fileBufferedRequests() { - // Check if there is room in the request queue. If not, re-schedule the - // buffer-servicing for later. - if (fQueue.size() >= REQUEST_QUEUE_SIZE_LIMIT) { - if (fGetItemIndexesBuffer.isEmpty()) { - fExecutor.schedule( - new Runnable() { public void run() { - fileBufferedRequests(); - }}, - REQUEST_BUFFER_FULL_RETRY_DELAY, - TimeUnit.MILLISECONDS); - } - return; - } - - // Remove a number of getItem() calls from the buffer, and combine them - // into a request. - List indexes = new LinkedList(); - List rms = new LinkedList(); - int numToCoalesce = 0; - while (!fGetItemIndexesBuffer.isEmpty() && numToCoalesce < COALESCING_COUNT_LIMIT) { - // Get the next call from buffer. - Integer index = fGetItemIndexesBuffer.remove(0); - DataRequestMonitor rm = fGetItemRequestMonitorsBuffer.remove(0); - - // If call is already cancelled, ignore it. - if (rm.getStatus().getSeverity() == IStatus.CANCEL) continue; - - // Otherwise add it to the request. - indexes.add(index); - rms.add(rm); - numToCoalesce++; - } - - // Queue the coalesced request. - fQueue.add( new ItemRequest( - indexes.toArray(new Integer[indexes.size()]), - rms.toArray(new DataRequestMonitor[rms.size()])) - ); - - // If there are still calls left in the buffer, execute another - // buffer-servicing call, but without any delay. - if (!fGetItemIndexesBuffer.isEmpty()) { - fExecutor.execute(new Runnable() { public void run() { - fileBufferedRequests(); - }}); - } - } - - public void addListener(Listener listener) { - assert fExecutor.isInExecutorThread(); - fListeners.add(listener); - } - - public void removeListener(Listener listener) { - assert fExecutor.isInExecutorThread(); - fListeners.remove(listener); - } - - // - /////////////////////////////////////////////////////////////////////////// - -} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/CancellableInputCoalescingSlowDataProviderAction.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/CancellableInputCoalescingSlowDataProviderAction.java deleted file mode 100644 index 32bee8ca4e4..00000000000 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/CancellableInputCoalescingSlowDataProviderAction.java +++ /dev/null @@ -1,54 +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.examples.dsf.concurrent; - -import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.IWorkbenchWindowActionDelegate; -import org.eclipse.ui.actions.ActionDelegate; - -public class CancellableInputCoalescingSlowDataProviderAction extends ActionDelegate - implements IWorkbenchWindowActionDelegate -{ - private IWorkbenchWindow fWindow; - - @Override - public void run(IAction action) { - if (fWindow != null) { - // Create the standard data provider. - final CancellableInputCoalescingSlowDataProvider dataProvider = - new CancellableInputCoalescingSlowDataProvider(new DefaultDsfExecutor()); - - // Create the dialog and open it. - Dialog dialog = new SlowDataProviderDialog( - fWindow.getShell(), new CancellingSlowDataProviderContentProvider(), dataProvider); - dialog.open(); - - // Shut down the data provider thread and the DSF executor thread. - // Note, since data provider is running in background thread, we have to - // wait until this background thread has completed shutdown before - // killing the executor thread itself. - dataProvider.shutdown(new RequestMonitor(dataProvider.getDsfExecutor(), null) { - @Override - public void handleCompleted() { - dataProvider.getDsfExecutor().shutdown(); - } - }); - } - } - - public void init(IWorkbenchWindow window) { - fWindow = window; - } -} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/CancellingSlowDataProviderContentProvider.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/CancellingSlowDataProviderContentProvider.java deleted file mode 100644 index dfb153fa6b1..00000000000 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/CancellingSlowDataProviderContentProvider.java +++ /dev/null @@ -1,292 +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.examples.dsf.concurrent; - -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; -import java.util.concurrent.atomic.AtomicInteger; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.DsfExecutor; -import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; -import org.eclipse.jface.viewers.ILazyContentProvider; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Table; - -public class CancellingSlowDataProviderContentProvider - implements ILazyContentProvider, DataProvider.Listener -{ - TableViewer fTableViewer; - DataProvider fDataProvider; - Display fDisplay; - List fItemDataRequestMonitors = new LinkedList(); - Set fCancelledIdxs = new HashSet(); - AtomicInteger fCancelCallsPending = new AtomicInteger(); - - /////////////////////////////////////////////////////////////////////////// - // ILazyContentProvider - public void dispose() { - if (fDataProvider != null) { - final DataProvider dataProvider = fDataProvider; - dataProvider.getDsfExecutor().execute( - new Runnable() { public void run() { - dataProvider.removeListener(CancellingSlowDataProviderContentProvider.this); - fTableViewer = null; - fDisplay = null; - fDataProvider = null; - }}); - } else { - fTableViewer = null; - fDisplay = null; - } - } - - public void inputChanged(final Viewer viewer, Object oldInput, final Object newInput) { - // If old data provider is not-null, unregister from it as listener. - if (fDataProvider != null) { - final DataProvider dataProvider = fDataProvider; - dataProvider.getDsfExecutor().execute( - new Runnable() { public void run() { - dataProvider.removeListener(CancellingSlowDataProviderContentProvider.this); - }}); - } - - - // Register as listener with new data provider. - // Note: if old data provider and new data provider use different executors, - // there is a chance of a race condition here. - if (newInput != null) { - ((DataProvider)newInput).getDsfExecutor().execute( - new Runnable() { public void run() { - if ( ((TableViewer)viewer).getTable().isDisposed() ) return; - fTableViewer = (TableViewer)viewer; - fDisplay = fTableViewer.getTable().getDisplay(); - fDataProvider = (DataProvider)newInput; - fDataProvider.addListener(CancellingSlowDataProviderContentProvider.this); - queryItemCount(); - }}); - } - } - - public void updateElement(final int index) { - assert fTableViewer != null; - if (fDataProvider == null) return; - - // Calculate the visible index range. - final int topIdx = fTableViewer.getTable().getTopIndex(); - final int botIdx = topIdx + getVisibleItemCount(topIdx); - - fCancelCallsPending.incrementAndGet(); - fDataProvider.getDsfExecutor().execute( - new Runnable() { public void run() { - // Must check again, in case disposed while re-dispatching. - if (fDataProvider == null || fTableViewer.getTable().isDisposed()) return; - if (index >= topIdx && index <= botIdx) { - queryItemData(index); - } - cancelStaleRequests(topIdx, botIdx); - }}); - } - - protected int getVisibleItemCount(int top) { - Table table = fTableViewer.getTable(); - int itemCount = table.getItemCount(); - return Math.min((table.getBounds().height / table.getItemHeight()) + 2, itemCount - top); - } - - /////////////////////////////////////////////////////////////////////////// - // DataProvider.Listener - public void countChanged() { - // Check for dispose. - if (fDataProvider == null) return; - - // Request new count. - queryItemCount(); - } - - public void dataChanged(final Set indexes) { - // Check for dispose. - if (fDataProvider == null) return; - - // Clear changed items in table viewer. - final TableViewer tableViewer = fTableViewer; - fDisplay.asyncExec( - new Runnable() { public void run() { - // Check again if table wasn't disposed when - // switching to the display thread. - if (fTableViewer == null || fTableViewer.getTable().isDisposed()) return; - for (Integer index : indexes) { - tableViewer.clear(index); - } - }}); - } - // - /////////////////////////////////////////////////////////////////////////// - - - /** - * Convenience extension to standard data return runnable. This extension - * automatically checks for errors and asynchronous dispose. - * @param - */ - private abstract class CPGetDataRequestMonitor extends DataRequestMonitor { - public CPGetDataRequestMonitor(DsfExecutor executor) { super(executor, null); } - abstract protected void doRun(); - @Override - public void handleCompleted() { - // If there is an error processing request, return. - if (!getStatus().isOK()) return; - - // If content provider was disposed, return. - if (fTableViewer == null || fTableViewer.getTable().isDisposed()) return; - - // Otherwise execute runnable. - doRun(); - } - } - - /** - * Executes the item count query with DataProvider. Must be called on - * data provider's dispatch thread. - */ - private void queryItemCount() { - assert fDataProvider.getDsfExecutor().isInExecutorThread(); - - // Request coumt from data provider. When the count is returned, we - // have to re-dispatch into the display thread to avoid calling - // the table widget on the DSF dispatch thread. - fCancelledIdxs.clear(); - fDataProvider.getItemCount( - new CPGetDataRequestMonitor(fDataProvider.getDsfExecutor()) { - @Override - protected void doRun() { - final TableViewer tableViewer = fTableViewer; - tableViewer.getTable().getDisplay().asyncExec( - new Runnable() { public void run() { - // Check again if table wasn't disposed when - // switching to the display thread. - if (tableViewer.getTable().isDisposed()) return; // disposed - tableViewer.setItemCount(getData()); - tableViewer.getTable().clearAll(); - }}); - }}); - - } - - - /** - * Dedicated class for data item requests. This class holds the index - * argument so it can be examined when cancelling stale requests. - */ - // Request data from data provider. Likewise, when the data is - // returned, we have to re-dispatch into the display thread to - // call the table widget. - class ItemGetDataRequestMonitor extends CPGetDataRequestMonitor { - - /** Index is used when cancelling stale requests. */ - int fIndex; - - ItemGetDataRequestMonitor(DsfExecutor executor, int index) { - super(executor); - fIndex = index; - } - - // Remove the request from list of outstanding requests. This has - // to be done in run() because doRun() is not always called. - @Override - public void handleCompleted() { - fItemDataRequestMonitors.remove(this); - super.handleCompleted(); - } - - // Process the result as usual. - @Override - protected void doRun() { - final TableViewer tableViewer = fTableViewer; - tableViewer.getTable().getDisplay().asyncExec( - new Runnable() { public void run() { - // Check again if table wasn't disposed when - // switching to the display thread. - if (tableViewer.getTable().isDisposed()) return; // disposed - tableViewer.replace(getData(), fIndex); - }}); - } - } - - /** - * Executes the data query with DataProvider. Must be called on dispatch - * thread. - * @param index Index of item to fetch. - */ - private void queryItemData(final int index) { - assert fDataProvider.getDsfExecutor().isInExecutorThread(); - - ItemGetDataRequestMonitor rm = new ItemGetDataRequestMonitor(fDataProvider.getDsfExecutor(), index); - fItemDataRequestMonitors.add(rm); - fDataProvider.getItem(index, rm); - } - - /** - * Iterates through the outstanding requests to data provider and - * cancells any that are nto visible any more. - * @param topIdx Top index of the visible items - * @param botIdx Bottom index of the visible items - */ - private void cancelStaleRequests(int topIdx, int botIdx) { - // Go through the outstanding requests and cencel any that - // are not visible anymore. - for (Iterator itr = fItemDataRequestMonitors.iterator(); itr.hasNext();) { - ItemGetDataRequestMonitor item = itr.next(); - if (item.fIndex < topIdx || item.fIndex > botIdx) { - // Set the item to cancelled status, so that the data provider - // will ignore it. - item.setStatus(new Status(IStatus.CANCEL, DsfExamplesPlugin.PLUGIN_ID, 0, "Cancelled", null)); //$NON-NLS-1$ - - // Add the item index to list of indexes that were cancelled, - // which will be sent to the table widget. - fCancelledIdxs.add(item.fIndex); - - // Remove the item from the outstanding cancel requests. - itr.remove(); - } - } - int cancelRequestsPending = fCancelCallsPending.decrementAndGet(); - if (!fCancelledIdxs.isEmpty() && cancelRequestsPending == 0) { - final Set cancelledIdxs = fCancelledIdxs; - fCancelledIdxs = new HashSet(); - final TableViewer tableViewer = fTableViewer; - tableViewer.getTable().getDisplay().asyncExec( - new Runnable() { public void run() { - // Check again if table wasn't disposed when - // switching to the display thread. - if (tableViewer.getTable().isDisposed()) return; - - // Clear the indexes of the cancelled request, so that the - // viewer knows to request them again when needed. - // Note: clearing using TableViewer.clear(int) seems very - // inefficient, it's better to use Table.clear(int[]). - int[] cancelledIdxsArray = new int[cancelledIdxs.size()]; - int i = 0; - for (Integer index : cancelledIdxs) { - cancelledIdxsArray[i++] = index; - } - tableViewer.getTable().clear(cancelledIdxsArray); - }}); - } - } -} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/DataProvider.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/DataProvider.java deleted file mode 100644 index b2990b1c2ca..00000000000 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/DataProvider.java +++ /dev/null @@ -1,64 +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.examples.dsf.concurrent; - -import java.util.Set; - -import org.eclipse.dd.dsf.concurrent.DsfExecutor; -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; - -public interface DataProvider { - - /** - * Interface for listeners for changes in Provider's data. - */ - public interface Listener { - /** - * Indicates that the count of data items has changed. - */ - void countChanged(); - - /** - * Indicates that some of the data values have changed. - * @param indexes Indexes of the changed items. - */ - void dataChanged(Set indexes); - } - - /** - * Returns the DSF executor that has to be used to call this data - * provider. - */ - DsfExecutor getDsfExecutor(); - - /** - * Retrieves the current item count. - * @param rm Request monitor, to be filled in with the Integer value. - */ - void getItemCount(DataRequestMonitor rm); - - /** - * Retrieves data value for given index. - * @param index Index of the item to retrieve - * @param rm Return data token, to be filled in with a String value - */ - void getItem(int index, DataRequestMonitor rm); - - /** - * Registers given listener with data provider. - */ - void addListener(Listener listener); - - /** - * Removes given listener from data provider. - */ - void removeListener(Listener listener); -} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/InputCoalescingSlowDataProvider.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/InputCoalescingSlowDataProvider.java deleted file mode 100644 index 62d2a910084..00000000000 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/InputCoalescingSlowDataProvider.java +++ /dev/null @@ -1,408 +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.examples.dsf.concurrent; - -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Random; -import java.util.Set; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.DelayQueue; -import java.util.concurrent.Delayed; -import java.util.concurrent.TimeUnit; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.concurrent.DsfRunnable; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.concurrent.DsfExecutor; -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; - -/** - * Example data provider which has a built-in delay when fetching data. This - * data provider simulates a service which retrieves data from an external - * source such as a networked target, which incurs a considerable delay when - * retrieving data. The data items are simulated values which consist of the - * time when data is being retrieved followed by the item's index. - *

    - * This version of the data provider features an optimization which causes - * item requests to be grouped together even before they are filed into the - * processing queue. This example demonstrates how the service can implement - * coalescing impelemntation in a situation where the provider has an - * interface which only accepts aggregate requests, so the requests have to be - * coalesed before they are sent to the provider. - */ -public class InputCoalescingSlowDataProvider implements DataProvider { - - /** Minimum count of data items */ - private final static int MIN_COUNT = 1000; - - /** Maximum count of data items */ - private final static int MAX_COUNT = 2000; - - /** Time interval how often random changes occur. */ - private final static int RANDOM_CHANGE_MILIS = 10000; - - /** Number of times random changes are made, before count is changed. */ - private final static int RANDOM_COUNT_CHANGE_INTERVALS = 3; - - /** Percentage of values that is changed upon random change (0-100). */ - private final static int RANDOM_CHANGE_SET_PERCENTAGE = 10; - - /** - * Amount of time (in miliseconds) how long the requests to provider, and - * events from provider are delayed by. - */ - private final static int TRANSMISSION_DELAY_TIME = 500; - - /** - * Amount of time (in milliseconds) how long the provider takes to process - * a request. - */ - private final static int PROCESSING_TIME = 100; - - /** - * Maximum number of item requests that can be coalesced into a single - * request. - */ - private final static int COALESCING_COUNT_LIMIT = 10; - - /** - * Delay in processing the buffer of getItem() calls. This delay helps - * to ensure that a meaningful number of items is present in the buffer - * before the buffer data is coalesced into a request. - */ - private final static int COALESCING_DELAY_TIME = 10; - - /** Dispatch-thread executor that this provider uses. */ - private DsfExecutor fExecutor; - - /** List of listeners registered for events from provider. */ - private List fListeners = new LinkedList(); - - /** Thread that handles data requests. */ - private ProviderThread fProviderThread; - - /** Queue of currently pending data requests. */ - private final BlockingQueue fQueue = new DelayQueue(); - - /** - * Runnable to be submitted when the data provider thread is shut down. - * This variable acts like a flag: when client want to shut down the - * provider, it sets this runnable, and when the backgroun thread sees - * that it's set, it shuts itself down, and posts this runnable with - * the executor. - */ - private RequestMonitor fShutdownRequestMonitor = null; - - /** - * Buffers for coalescing getItem() calls into a single request. - */ - private List fGetItemIndexesBuffer = new LinkedList(); - private List> fGetItemRequestMonitorsBuffer = new LinkedList>(); - - /** - * Base class for requests that are queued by the data provider. It - * implements java.util.concurrent.Delayed to allow for use of DelayedQueue. - * Every request into the queue is delayed by the simulated transmission - * time. - */ - private static abstract class Request implements Delayed { - /** Sequence counter and number are used to ensure FIFO order **/ - private static int fSequenceCounter = 0; - private int fSequenceNumber = fSequenceCounter++; - - /** Time delay tracks how items will be delayed. **/ - private long fTime = System.currentTimeMillis() + TRANSMISSION_DELAY_TIME; - - // @see java.util.concurrent.Delayed - public long getDelay(TimeUnit unit) { - return unit.convert(fTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS); - } - - // @see java.lang.Comparable - public int compareTo(Delayed other) { - if (other == this) // compare zero ONLY if same object - return 0; - Request x = (Request)other; - long diff = fTime - x.fTime; - - if (diff < 0) return -1; - else if (diff > 0) return 1; - else if (fSequenceNumber < x.fSequenceNumber) return -1; - else return 1; - } - - /** All requests have an associated array of RequestMonitor tokens **/ - abstract RequestMonitor[] getRequestMonitors(); - } - - /** - * Object used to encapsulate the "getItemCount" requests. Instances of it - * are queued till processed. - */ - private static class CountRequest extends Request - { - DataRequestMonitor fRequestMonitors; - CountRequest(DataRequestMonitor rms) { fRequestMonitors = rms; } - @Override - DataRequestMonitor[] getRequestMonitors() { return new DataRequestMonitor[] { fRequestMonitors }; } - } - - /** - * Object used to encapsulate the "getItem" requests. Instances of it - * are queued till processed. - */ - private static class ItemRequest extends Request - { - DataRequestMonitor[] fRequestMonitors; - Integer[] fIndexes; - ItemRequest(Integer[] indexes, DataRequestMonitor[] rms) { fIndexes = indexes; fRequestMonitors = rms; } - @Override - DataRequestMonitor[] getRequestMonitors() { return fRequestMonitors; } - } - - /** - * The background thread of data provider. This thread retrieves the - * requests from the provider's queue and processes them. It also - * initiates random changes in the data set and issues corresponding - * events. - */ - private class ProviderThread extends Thread - { - /** - * Current count of items in the data set. It is changed - * periodically for simulation purposes. - */ - private int fCount = MIN_COUNT; - - /** - * Incremented with every data change, it causes the count to be reset - * every four random changes. - */ - private int fCountTrigger = 0; - - /** Time when the last change was performed. */ - private long fLastChangeTime = System.currentTimeMillis(); - - /** Random number generator */ - private Random fRandom = new java.util.Random(); - - @Override - public void run() { - try { - // Initialize the count. - randomCount(); - - // Perform the loop until the shutdown runnable is set. - while(fShutdownRequestMonitor == null) { - // Get the next request from the queue. The time-out - // ensures that that we get to process the random changes. - final Request request = fQueue.poll(RANDOM_CHANGE_MILIS / 10, TimeUnit.MILLISECONDS); - - // If a request was dequeued, process it. - if (request != null) { - // Simulate a processing delay. - Thread.sleep(PROCESSING_TIME); - - if (request instanceof CountRequest) { - processCountRequest((CountRequest)request); - } else if (request instanceof ItemRequest) { - processItemRequest((ItemRequest)request); - } - // Whatever the results, post it to dispatch thread - // executor (with transmission delay). - fExecutor.schedule( - new DsfRunnable() { - public void run() { - for (RequestMonitor requestMonitor : request.getRequestMonitors()) { - requestMonitor.done(); - } - } - }, - TRANSMISSION_DELAY_TIME, TimeUnit.MILLISECONDS); - } - - // Simulate data changes. - randomChanges(); - } - } - catch (InterruptedException x) { - DsfExamplesPlugin.getDefault().getLog().log( new Status( - IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, 0, "Interrupted exception in slow data provider thread.", x )); //$NON-NLS-1$ - } - - // Notify the client that requested shutdown, that shutdown is complete. - fShutdownRequestMonitor.done(); - fShutdownRequestMonitor = null; - } - - private void processCountRequest(CountRequest request) { - // Calculate the simulated values. - request.fRequestMonitors.setData(fCount); - } - - private void processItemRequest(ItemRequest request) { - // Check to make sure that the number of indexes matches the number - // of return tokens. - assert request.fRequestMonitors.length == request.fIndexes.length; - - // Calculate the simulated values for each index in request. - for (int i = 0; i < request.fIndexes.length; i++) { - request.fRequestMonitors[i].setData(Long.toHexString(fLastChangeTime) + "." + request.fIndexes[i]); //$NON-NLS-1$ - } - } - - /** - * This method simulates changes in provider's data set. - */ - private void randomChanges() - { - if (System.currentTimeMillis() > fLastChangeTime + RANDOM_CHANGE_MILIS) { - fLastChangeTime = System.currentTimeMillis(); - // once in every 30 seconds broadcast item count change - if (++fCountTrigger % RANDOM_COUNT_CHANGE_INTERVALS == 0) randomCount(); - else randomDataChange(); - } - } - - - /** - * Calculates new size for provider's data set. - */ - private void randomCount() - { - fCount = MIN_COUNT + Math.abs(fRandom.nextInt()) % (MAX_COUNT - MIN_COUNT); - - // Generate the event that the count has changed, and post it to - // dispatch thread with transmission delay. - fExecutor.schedule( - new Runnable() { public void run() { - for (Listener listener : fListeners) { - listener.countChanged(); - } - }}, - TRANSMISSION_DELAY_TIME, TimeUnit.MILLISECONDS); - } - - - /** - * Invalidates a random range of indexes. - */ - private void randomDataChange() - { - final Set set = new HashSet(); - // Change one in ten values. - for (int i = 0; i < fCount * RANDOM_CHANGE_SET_PERCENTAGE / 100; i++) { - set.add( new Integer(Math.abs(fRandom.nextInt()) % fCount) ); - } - - // Generate the event that the data has changed. - // Post dispatch thread with transmission delay. - fExecutor.schedule( - new Runnable() { public void run() { - for (Listener listener : fListeners) { - listener.dataChanged(set); - } - }}, - TRANSMISSION_DELAY_TIME, TimeUnit.MILLISECONDS); - } - } - - - public InputCoalescingSlowDataProvider(DsfExecutor executor) { - fExecutor = executor; - fProviderThread = new ProviderThread(); - fProviderThread.start(); - } - - /** - * Requests shutdown of this data provider. - * @param requestMonitor Monitor to call when shutdown is complete. - */ - public void shutdown(RequestMonitor requestMonitor) { - fShutdownRequestMonitor = requestMonitor; - } - - /////////////////////////////////////////////////////////////////////////// - // DataProvider - public DsfExecutor getDsfExecutor() { - return fExecutor; - } - - public void getItemCount(final DataRequestMonitor rm) { - fExecutor.schedule( - new Runnable() { public void run() { - fQueue.add(new CountRequest(rm)); - }}, - TRANSMISSION_DELAY_TIME, - TimeUnit.MILLISECONDS); - } - - public void getItem(final int index, final DataRequestMonitor rm) { - // Schedule a buffer-servicing call, if one is needed. - if (fGetItemIndexesBuffer.isEmpty()) { - fExecutor.schedule( - new Runnable() { public void run() { - fileBufferedRequests(); - }}, - COALESCING_DELAY_TIME, - TimeUnit.MILLISECONDS); - } - - // Add the call data to the buffer. - // Note: it doesn't matter that the items were added to the buffer - // after the buffer-servicing request was scheduled. This is because - // the buffers are guaranteed not to be modified until this dispatch - // cycle is over. - fGetItemIndexesBuffer.add(index); - fGetItemRequestMonitorsBuffer.add(rm); - } - - @SuppressWarnings("unchecked") - public void fileBufferedRequests() { - // Remove a number of getItem() calls from the buffer, and combine them - // into a request. - int numToCoalesce = Math.min(fGetItemIndexesBuffer.size(), COALESCING_COUNT_LIMIT); - final ItemRequest request = new ItemRequest(new Integer[numToCoalesce], new DataRequestMonitor[numToCoalesce]); - for (int i = 0; i < numToCoalesce; i++) { - request.fIndexes[i] = fGetItemIndexesBuffer.remove(0); - request.fRequestMonitors[i] = fGetItemRequestMonitorsBuffer.remove(0); - } - - // Queue the coalesced request, with the appropriate transmission delay. - fQueue.add(request); - - // If there are still calls left in the buffer, execute another - // buffer-servicing call, but without any delay. - if (!fGetItemIndexesBuffer.isEmpty()) { - fExecutor.execute(new Runnable() { public void run() { - fileBufferedRequests(); - }}); - } - } - - public void addListener(Listener listener) { - assert fExecutor.isInExecutorThread(); - fListeners.add(listener); - } - - public void removeListener(Listener listener) { - assert fExecutor.isInExecutorThread(); - fListeners.remove(listener); - } - - // - /////////////////////////////////////////////////////////////////////////// - -} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/InputCoalescingSlowDataProviderAction.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/InputCoalescingSlowDataProviderAction.java deleted file mode 100644 index dccf8b8d92f..00000000000 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/InputCoalescingSlowDataProviderAction.java +++ /dev/null @@ -1,54 +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.examples.dsf.concurrent; - -import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.IWorkbenchWindowActionDelegate; -import org.eclipse.ui.actions.ActionDelegate; - -public class InputCoalescingSlowDataProviderAction extends ActionDelegate - implements IWorkbenchWindowActionDelegate -{ - private IWorkbenchWindow fWindow; - - @Override - public void run(IAction action) { - if (fWindow != null) { - // Create the standard data provider. - final InputCoalescingSlowDataProvider dataProvider = - new InputCoalescingSlowDataProvider(new DefaultDsfExecutor()); - - // Create the dialog and open it. - Dialog dialog = new SlowDataProviderDialog( - fWindow.getShell(), new SlowDataProviderContentProvider(), dataProvider); - dialog.open(); - - // Shut down the data provider thread and the DSF executor thread. - // Note, since data provider is running in background thread, we have to - // wait until this background thread has completed shutdown before - // killing the executor thread itself. - dataProvider.shutdown(new RequestMonitor(dataProvider.getDsfExecutor(), null) { - @Override - public void handleCompleted() { - dataProvider.getDsfExecutor().shutdown(); - } - }); - } - } - - public void init(IWorkbenchWindow window) { - fWindow = window; - } -} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/SlowDataProvider.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/SlowDataProvider.java deleted file mode 100644 index f0c350581d9..00000000000 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/SlowDataProvider.java +++ /dev/null @@ -1,330 +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.examples.dsf.concurrent; - -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Random; -import java.util.Set; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.DelayQueue; -import java.util.concurrent.Delayed; -import java.util.concurrent.TimeUnit; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.concurrent.DsfRunnable; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.concurrent.DsfExecutor; -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; - -/** - * Example data provider which has a built-in delay when fetching data. This - * data provider simulates a service which retrieves data from an external - * source such as a networked target, which incurs a considerable delay when - * retrieving data. The data items are simulated values which consist of the - * time when data is being retrieved followed by the item's index. - */ -public class SlowDataProvider implements DataProvider { - - /** Minimum count of data items */ - private final static int MIN_COUNT = 1000; - - /** Maximum count of data items */ - private final static int MAX_COUNT = 2000; - - /** Time interval how often random changes occur. */ - private final static int RANDOM_CHANGE_MILIS = 10000; - - /** Number of times random changes are made, before count is changed. */ - private final static int RANDOM_COUNT_CHANGE_INTERVALS = 3; - - /** Percentage of values that is changed upon random change (0-100). */ - private final static int RANDOM_CHANGE_SET_PERCENTAGE = 10; - - /** - * Amount of time (in miliseconds) how long the requests to provider, and - * events from provider are delayed by. - */ - private final static int TRANSMISSION_DELAY_TIME = 500; - - /** - * Amount of time (in milliseconds) how long the provider takes to process - * a request. - */ - private final static int PROCESSING_TIME = 100; - - /** Dispatch-thread executor that this provider uses. */ - private DsfExecutor fExecutor; - - /** List of listeners registered for events from provider. */ - private List fListeners = new LinkedList(); - - /** Thread that handles data requests. */ - private ProviderThread fProviderThread; - - /** Queue of currently pending data requests. */ - private final BlockingQueue fQueue = new DelayQueue(); - - /** - * Runnable to be submitted when the data provider thread is shut down. - * This variable acts like a flag: when client want to shut down the - * provider, it sets this runnable, and when the backgroun thread sees - * that it's set, it shuts itself down, and posts this runnable with - * the executor. - */ - private RequestMonitor fShutdownRequestMonitor = null; - - /** - * Base class for requests that are queued by the data provider. It - * implements java.util.concurrent.Delayed to allow for use of DelayedQueue. - * Every request into the queue is delayed by the simulated transmission - * time. - */ - private static abstract class Request implements Delayed { - /** Sequence counter and number are used to ensure FIFO order **/ - private static int fSequenceCounter = 0; - private int fSequenceNumber = fSequenceCounter++; - - /** Time delay tracks how items will be delayed. **/ - private long fTime = System.currentTimeMillis() + TRANSMISSION_DELAY_TIME; - - // @see java.util.concurrent.Delayed - public long getDelay(TimeUnit unit) { - return unit.convert(fTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS); - } - - // @see java.lang.Comparable - public int compareTo(Delayed other) { - if (other == this) // compare zero ONLY if same object - return 0; - Request x = (Request)other; - long diff = fTime - x.fTime; - - if (diff < 0) return -1; - else if (diff > 0) return 1; - else if (fSequenceNumber < x.fSequenceNumber) return -1; - else return 1; - } - - /** All requests have an associated RequestMonitor token **/ - abstract RequestMonitor getRequestMonitor(); - } - - /** - * Object used to encapsulate the "getItemCount" requests. Instances of it - * are queued till processed. - */ - private static class CountRequest extends Request - { - DataRequestMonitor fRequestMonitor; - CountRequest(DataRequestMonitor rm) { fRequestMonitor = rm; } - @Override - DataRequestMonitor getRequestMonitor() { return fRequestMonitor; } - } - - /** - * Object used to encapsulate the "getItem" requests. Instances of it - * are queued till processed. - */ - private static class ItemRequest extends Request - { - DataRequestMonitor fRequestMonitor; - int fIndex; - ItemRequest(int index, DataRequestMonitor rm) { fIndex = index; fRequestMonitor = rm; } - @Override - DataRequestMonitor getRequestMonitor() { return fRequestMonitor; } - } - - /** - * The background thread of data provider. This thread retrieves the - * requests from the provider's queue and processes them. It also - * initiates random changes in the data set and issues corresponding - * events. - */ - private class ProviderThread extends Thread - { - /** - * Current count of items in the data set. It is changed - * periodically for simulation purposes. - */ - private int fCount = MIN_COUNT; - - /** - * Incremented with every data change, it causes the count to be reset - * every four random changes. - */ - private int fCountTrigger = 0; - - /** Time when the last change was performed. */ - private long fLastChangeTime = System.currentTimeMillis(); - - /** Random number generator */ - private Random fRandom = new java.util.Random(); - - @Override - public void run() { - try { - // Initialize the count. - randomCount(); - - // Perform the loop until the shutdown runnable is set. - while(fShutdownRequestMonitor == null) { - // Get the next request from the queue. The time-out - // ensures that that we get to process the random changes. - final Request request = fQueue.poll(RANDOM_CHANGE_MILIS / 10, TimeUnit.MILLISECONDS); - - // If a request was dequeued, process it. - if (request != null) { - // Simulate a processing delay. - Thread.sleep(PROCESSING_TIME); - - if (request instanceof CountRequest) { - processCountRequest((CountRequest)request); - } else if (request instanceof ItemRequest) { - processItemRequest((ItemRequest)request); - } - // Whatever the result, post it to dispatch thread - // executor (with transmission delay). - fExecutor.schedule( - new DsfRunnable() { - public void run() { - request.getRequestMonitor().done(); - } - }, - TRANSMISSION_DELAY_TIME, TimeUnit.MILLISECONDS); - } - - // Simulate data changes. - randomChanges(); - } - } - catch (InterruptedException x) { - DsfExamplesPlugin.getDefault().getLog().log( new Status( - IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, 0, "Interrupted exception in slow data provider thread.", x )); //$NON-NLS-1$ - } - - // Notify the client that requested shutdown, that shutdown is complete. - fShutdownRequestMonitor.done(); - fShutdownRequestMonitor = null; - } - - private void processCountRequest(CountRequest request) { - // Calculate the simulated values. - request.fRequestMonitor.setData(fCount); - } - - private void processItemRequest(ItemRequest request) { - // Calculate the simulated values. - request.fRequestMonitor.setData(Long.toHexString(fLastChangeTime) + "." + request.fIndex); //$NON-NLS-1$ - } - - /** - * This method simulates changes in provider's data set. - */ - private void randomChanges() - { - if (System.currentTimeMillis() > fLastChangeTime + RANDOM_CHANGE_MILIS) { - fLastChangeTime = System.currentTimeMillis(); - // once in every 30 seconds broadcast item count change - if (++fCountTrigger % RANDOM_COUNT_CHANGE_INTERVALS == 0) randomCount(); - else randomDataChange(); - } - } - - - /** - * Calculates new size for provider's data set. - */ - private void randomCount() - { - fCount = MIN_COUNT + Math.abs(fRandom.nextInt()) % (MAX_COUNT - MIN_COUNT); - - // Generate the event that the count has changed, and post it to - // dispatch thread with transmission delay. - fExecutor.schedule( - new Runnable() { public void run() { - for (Listener listener : fListeners) { - listener.countChanged(); - } - }}, - TRANSMISSION_DELAY_TIME, TimeUnit.MILLISECONDS); - } - - - /** - * Invalidates a random range of indexes. - */ - private void randomDataChange() - { - final Set set = new HashSet(); - // Change one in ten values. - for (int i = 0; i < fCount * RANDOM_CHANGE_SET_PERCENTAGE / 100; i++) { - set.add( new Integer(Math.abs(fRandom.nextInt()) % fCount) ); - } - - // Generate the event that the data has changed. - // Post dispatch thread with transmission delay. - fExecutor.schedule( - new Runnable() { public void run() { - for (Listener listener : fListeners) { - listener.dataChanged(set); - } - }}, - TRANSMISSION_DELAY_TIME, TimeUnit.MILLISECONDS); - } - } - - - public SlowDataProvider(DsfExecutor executor) { - fExecutor = executor; - fProviderThread = new ProviderThread(); - fProviderThread.start(); - } - - /** - * Requests shutdown of this data provider. - * @param requestMonitor Request completion monitor. - */ - public void shutdown(RequestMonitor requestMonitor) { - fShutdownRequestMonitor = requestMonitor; - } - - /////////////////////////////////////////////////////////////////////////// - // DataProvider - public DsfExecutor getDsfExecutor() { - return fExecutor; - } - - public void getItemCount(final DataRequestMonitor rm) { - fQueue.add(new CountRequest(rm)); - } - - public void getItem(final int index, final DataRequestMonitor rm) { - fQueue.add(new ItemRequest(index, rm)); - } - - public void addListener(Listener listener) { - assert fExecutor.isInExecutorThread(); - fListeners.add(listener); - } - - public void removeListener(Listener listener) { - assert fExecutor.isInExecutorThread(); - fListeners.remove(listener); - } - - // - /////////////////////////////////////////////////////////////////////////// - -} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/SlowDataProviderAction.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/SlowDataProviderAction.java deleted file mode 100644 index 77c0c37e192..00000000000 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/SlowDataProviderAction.java +++ /dev/null @@ -1,53 +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.examples.dsf.concurrent; - -import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.IWorkbenchWindowActionDelegate; -import org.eclipse.ui.actions.ActionDelegate; - -public class SlowDataProviderAction extends ActionDelegate - implements IWorkbenchWindowActionDelegate -{ - private IWorkbenchWindow fWindow; - - @Override - public void run(IAction action) { - if (fWindow != null) { - // Create the standard data provider. - final SlowDataProvider dataProvider = new SlowDataProvider(new DefaultDsfExecutor()); - - // Create the dialog and open it. - Dialog dialog = new SlowDataProviderDialog( - fWindow.getShell(), new SlowDataProviderContentProvider(), dataProvider); - dialog.open(); - - // Shut down the data provider thread and the DSF executor thread. - // Note, since data provider is running in background thread, we have to - // wait until this background thread has completed shutdown before - // killing the executor thread itself. - dataProvider.shutdown(new RequestMonitor(dataProvider.getDsfExecutor(), null) { - @Override - public void handleCompleted() { - dataProvider.getDsfExecutor().shutdown(); - } - }); - } - } - - public void init(IWorkbenchWindow window) { - fWindow = window; - } -} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/SlowDataProviderContentProvider.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/SlowDataProviderContentProvider.java deleted file mode 100644 index a71d5019c8c..00000000000 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/SlowDataProviderContentProvider.java +++ /dev/null @@ -1,190 +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.examples.dsf.concurrent; - -import java.util.Set; - -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.DsfExecutor; -import org.eclipse.jface.viewers.ILazyContentProvider; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.jface.viewers.Viewer; - -public class SlowDataProviderContentProvider - implements ILazyContentProvider, DataProvider.Listener -{ - - TableViewer fTableViewer; - DataProvider fDataProvider; - - /////////////////////////////////////////////////////////////////////////// - // ILazyContentProvider - public void dispose() { - if (fDataProvider != null) { - final DataProvider dataProvider = fDataProvider; - dataProvider.getDsfExecutor().execute( - new Runnable() { public void run() { - dataProvider.removeListener(SlowDataProviderContentProvider.this); - fTableViewer = null; - fDataProvider = null; - }}); - } else { - fTableViewer = null; - } - } - - public void inputChanged(final Viewer viewer, Object oldInput, final Object newInput) { - // If old data provider is not-null, unregister from it as listener. - if (fDataProvider != null) { - final DataProvider dataProvider = fDataProvider; - dataProvider.getDsfExecutor().execute( - new Runnable() { public void run() { - dataProvider.removeListener(SlowDataProviderContentProvider.this); - }}); - } - - - // Register as listener with new data provider. - // Note: if old data provider and new data provider use different executors, - // there is a chance of a race condition here. - if (newInput != null) { - ((DataProvider)newInput).getDsfExecutor().execute( - new Runnable() { public void run() { - fTableViewer = (TableViewer)viewer; - fDataProvider = (DataProvider)newInput; - fDataProvider.addListener(SlowDataProviderContentProvider.this); - queryItemCount(); - }}); - } - } - - public void updateElement(final int index) { - assert fTableViewer != null; - if (fDataProvider == null) return; - - fDataProvider.getDsfExecutor().execute( - new Runnable() { public void run() { - // Must check again, in case disposed while re-dispatching. - if (fDataProvider == null) return; - - queryItemData(index); - }}); - } - - - /////////////////////////////////////////////////////////////////////////// - // DataProvider.Listener - public void countChanged() { - // Check for dispose. - if (fDataProvider == null) return; - - // Request new count. - queryItemCount(); - } - - public void dataChanged(final Set indexes) { - // Check for dispose. - if (fDataProvider == null) return; - - // Clear changed items in table viewer. - if (fTableViewer != null) { - final TableViewer tableViewer = fTableViewer; - tableViewer.getTable().getDisplay().asyncExec( - new Runnable() { public void run() { - // Check again if table wasn't disposed when - // switching to the display thread. - if (tableViewer.getTable().isDisposed()) return; // disposed - for (Integer index : indexes) { - tableViewer.clear(index); - } - }}); - } - } - // - /////////////////////////////////////////////////////////////////////////// - - - /** - * Convenience extension to standard data return runnable. This extension - * automatically checks for errors and asynchronous dipose. - * @param - */ - private abstract class CPGetDataRequestMonitor extends DataRequestMonitor { - CPGetDataRequestMonitor(DsfExecutor executor) { super(executor, null); } - abstract protected void doRun(); - @Override - final public void handleCompleted() { - // If there is an error processing request, return. - if (!getStatus().isOK()) return; - - // If content provider was disposed, return. - if (fTableViewer == null) return; - - // Otherwise execute runnable. - doRun(); - } - } - - /** - * Executes the item count query with DataProvider. Must be called on - * data provider's dispatch thread. - */ - private void queryItemCount() { - assert fDataProvider.getDsfExecutor().isInExecutorThread(); - - // Request coumt from data provider. When the count is returned, we - // have to re-dispatch into the display thread to avoid calling - // the table widget on the DSF dispatch thread. - fDataProvider.getItemCount( - new CPGetDataRequestMonitor(fDataProvider.getDsfExecutor()) { - @Override - protected void doRun() { - final TableViewer tableViewer = fTableViewer; - tableViewer.getTable().getDisplay().asyncExec( - new Runnable() { public void run() { - // Check again if table wasn't disposed when - // switching to the display thread. - if (tableViewer.getTable().isDisposed()) return; // disposed - tableViewer.setItemCount(getData()); - tableViewer.getTable().clearAll(); - }}); - }}); - - } - - /** - * Executes the data query with DataProvider. Must be called on dispatch - * thread. - * @param index Index of item to fetch. - */ - private void queryItemData(final int index) { - assert fDataProvider.getDsfExecutor().isInExecutorThread(); - - // Request data from data provider. Likewise, when the data is - // returned, we have to re-dispatch into the display thread to - // call the table widget. - fDataProvider.getItem( - index, - new CPGetDataRequestMonitor(fDataProvider.getDsfExecutor()) { - @Override - protected void doRun() { - final TableViewer tableViewer = fTableViewer; - tableViewer.getTable().getDisplay().asyncExec( - new Runnable() { public void run() { - // Check again if table wasn't disposed when - // switching to the display thread. - if (tableViewer.getTable().isDisposed()) return; // disposed - tableViewer.replace(getData(), index); - }}); - }}); - } - -} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/SlowDataProviderDialog.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/SlowDataProviderDialog.java deleted file mode 100644 index 4c763724658..00000000000 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/SlowDataProviderDialog.java +++ /dev/null @@ -1,50 +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.examples.dsf.concurrent; - -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.viewers.IContentProvider; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Shell; - -/** - * Dialog shared by all slow data provider examples. It accepts the data - * provider and the content provider as arguments to the constructor. So the - * only thing that the dialog does is to create the table viewer and - * initialize it with the providers. - */ -public class SlowDataProviderDialog extends Dialog { - - private TableViewer fDataViewer; - private DataProvider fDataProvider; - private IContentProvider fContentProvider; - - public SlowDataProviderDialog(Shell parent, IContentProvider contentProvider, DataProvider dataProvider) { - super(parent); - setShellStyle(getShellStyle() | SWT.RESIZE); - fContentProvider = contentProvider; - fDataProvider = dataProvider; - } - - @Override - protected Control createDialogArea(Composite parent) { - Composite area = (Composite) super.createDialogArea(parent); - fDataViewer = new TableViewer(area, SWT.VIRTUAL); - fDataViewer.getTable().setLayoutData(new GridData(GridData.FILL_BOTH)); - fDataViewer.setContentProvider(fContentProvider); - fDataViewer.setInput(fDataProvider); - return area; - } -} diff --git a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/AsyncDataViewer.java b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/AsyncDataViewer.java new file mode 100644 index 00000000000..e36a3bdaa56 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/AsyncDataViewer.java @@ -0,0 +1,266 @@ +/******************************************************************************* + * Copyright (c) 2006, 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.dsf.dataviewer; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; +import org.eclipse.dd.dsf.concurrent.Query; +import org.eclipse.dd.dsf.ui.concurrent.DisplayDsfExecutor; +import org.eclipse.jface.viewers.ILazyContentProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Table; + +/** + * Data viewer based on a table, which reads data using asynchronous methods. + *

    + * This viewer implements the {@link ILazyContentProvider} interface + * which is used by the JFace TableViewer class to populate a Table. This + * interface contains separate asynchronous methods for requesting the count + * and values for individual indexes, which neatly correspond to the methods + * in {@link IDataGenerator}. As an added optimization, this viewer + * implementation checks for the range of visible items in the view upon each + * request, and it cancels old requests which scroll out of view but have not + * been completed yet. However, it is up to the data generator implementation + * to check the canceled state of the requests and ignore them. + *

    + */ +public class AsyncDataViewer + implements ILazyContentProvider, IDataGenerator.Listener +{ + // Executor to use instead of Display.asyncExec(). + final private DsfExecutor fDisplayExecutor; + + // The viewer and generator that this content provider using. + final private TableViewer fViewer; + final private IDataGenerator fDataGenerator; + + // Fields used in request cancellation logic. + private List fItemDataRequestMonitors = new LinkedList(); + private Set fIndexesToCancel = new HashSet(); + private int fCancelCallsPending = 0; + + public AsyncDataViewer(TableViewer viewer, IDataGenerator generator) { + fViewer = viewer; + fDisplayExecutor = DisplayDsfExecutor.getDisplayDsfExecutor(fViewer.getTable().getDisplay()); + fDataGenerator = generator; + fDataGenerator.addListener(this); + } + + public void dispose() { + fDataGenerator.removeListener(this); + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + // Set the initial count to the viewer after the input is set. + queryItemCount(); + } + + public void updateElement(final int index) { + // Calculate the visible index range. + final int topIdx = fViewer.getTable().getTopIndex(); + final int botIdx = topIdx + getVisibleItemCount(topIdx); + + // Request the item for the given index. + queryValue(index); + + // Invoke a cancel task with a delay. The delay allows multiple cancel + // calls to be combined together improving performance of the viewer. + fCancelCallsPending++; + fDisplayExecutor.schedule( + new Runnable() { public void run() { + cancelStaleRequests(topIdx, botIdx); + }}, + 1, TimeUnit.MILLISECONDS); + } + + private int getVisibleItemCount(int top) { + Table table = fViewer.getTable(); + int itemCount = table.getItemCount(); + return Math.min((table.getBounds().height / table.getItemHeight()) + 2, itemCount - top); + } + + public void countChanged() { + queryItemCount(); + } + + public void valuesChanged(final Set indexes) { + // Mark the changed items in table viewer as dirty, this will + // trigger update requests for these indexes if they are + // visible in the viewer. + final TableViewer tableViewer = fViewer; + fDisplayExecutor.execute( new Runnable() { + public void run() { + if (!fViewer.getTable().isDisposed()) { + for (Integer index : indexes) { + tableViewer.clear(index); + } + } + }}); + } + + + private void queryItemCount() { + // Request count from data provider. When the count is returned, we + // have to re-dispatch into the display thread to avoid calling + // the table widget on the DSF dispatch thread. + fIndexesToCancel.clear(); + fDataGenerator.getCount( + // Use the display executor to construct the request monitor, this + // will cause the handleCompleted() method to be automatically + // called on the display thread. + new DataRequestMonitor(fDisplayExecutor, null) { + @Override + protected void handleCompleted() { + if (!fViewer.getTable().isDisposed()) { + fViewer.setItemCount(getData()); + fViewer.getTable().clearAll(); + } + } + }); + + } + + + // Dedicated class for data item requests. This class holds the index + // argument so it can be examined when canceling stale requests. + private class ValueDataRequestMonitor extends DataRequestMonitor { + + /** Index is used when canceling stale requests. */ + int fIndex; + + ValueDataRequestMonitor(int index) { + super(fDisplayExecutor, null); + fIndex = index; + } + + @Override + protected void handleCompleted() { + fItemDataRequestMonitors.remove(this); + + // Check if the request completed successfully, otherwise ignore it. + if (getStatus().isOK()) { + if (!fViewer.getTable().isDisposed()) { + fViewer.replace(getData(), fIndex); + } + } + } + } + + private void queryValue(final int index) { + ValueDataRequestMonitor rm = new ValueDataRequestMonitor(index); + fItemDataRequestMonitors.add(rm); + fDataGenerator.getValue(index, rm); + } + + private void cancelStaleRequests(int topIdx, int botIdx) { + // Decrement the count of outstanding cancel calls. + fCancelCallsPending--; + + // Must check again, in case disposed while re-dispatching. + if (fDataGenerator == null || fViewer.getTable().isDisposed()) return; + + // Go through the outstanding requests and cancel any that + // are not visible anymore. + for (Iterator itr = fItemDataRequestMonitors.iterator(); itr.hasNext();) { + ValueDataRequestMonitor item = itr.next(); + if (item.fIndex < topIdx || item.fIndex > botIdx) { + // Set the item to canceled status, so that the data provider + // will ignore it. + item.setCanceled(true); + + // Add the item index to list of indexes that were canceled, + // which will be sent to the table widget. + fIndexesToCancel.add(item.fIndex); + + // Remove the item from the outstanding cancel requests. + itr.remove(); + } + } + if (!fIndexesToCancel.isEmpty() && fCancelCallsPending == 0) { + Set canceledIdxs = fIndexesToCancel; + fIndexesToCancel = new HashSet(); + + // Clear the indexes of the canceled request, so that the + // viewer knows to request them again when needed. + // Note: clearing using TableViewer.clear(int) seems very + // inefficient, it's better to use Table.clear(int[]). + int[] canceledIdxsArray = new int[canceledIdxs.size()]; + int i = 0; + for (Integer index : canceledIdxs) { + canceledIdxsArray[i++] = index; + } + fViewer.getTable().clear(canceledIdxsArray); + } + } + + + public static void main(String[] args) { + // Create the shell to hold the viewer. + Display display = new Display(); + Shell shell = new Shell(display, SWT.SHELL_TRIM); + shell.setLayout(new GridLayout()); + GridData data = new GridData(GridData.FILL_BOTH); + shell.setLayoutData(data); + Font font = new Font(display, "Courier", 10, SWT.NORMAL); + + // Create the table viewer. + TableViewer tableViewer = new TableViewer(shell, SWT.BORDER | SWT.VIRTUAL); + tableViewer.getControl().setLayoutData(data); + + // Create the data generator. + final IDataGenerator generator = new DataGeneratorWithExecutor(); + + // Create the content provider which will populate the viewer. + AsyncDataViewer contentProvider = new AsyncDataViewer(tableViewer, generator); + tableViewer.setContentProvider(contentProvider); + tableViewer.setInput(new Object()); + + // Open the shell and service the display dispatch loop until user + // closes the shell. + shell.open(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) + display.sleep(); + } + + // The IDataGenerator.shutdown() method is asynchronous, this requires + // using a query again in order to wait for its completion. + Query shutdownQuery = new Query() { + @Override + protected void execute(DataRequestMonitor rm) { + generator.shutdown(rm); + } + }; + ImmediateExecutor.getInstance().execute(shutdownQuery); + try { + shutdownQuery.get(); + } catch (Exception e) {} + + // Shut down the display. + font.dispose(); + display.dispose(); + } +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithExecutor.java b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithExecutor.java new file mode 100644 index 00000000000..5fc0da81485 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithExecutor.java @@ -0,0 +1,404 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +//#ifdef excercises +package org.eclipse.dd.examples.dsf.dataviewer; +//#else +//#package org.eclipse.dd.examples.dsf.dataviewer.answers; +//#endif + +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Random; +import java.util.Set; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.TimeUnit; + +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.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; + +/** + * DSF Executor-based implementation of the data generator. + *

    + * This generator uses a queue of client requests and processes these + * requests periodically using a DSF executor. The main feature of this + * generator is that it uses the executor as its only synchronization object. + * This means that all the fields with the exception of the executor can only + * be accessed while running in the executor thread. + *

    + */ +//#ifdef excercises +// TODO Excercise 3 - Add an annotationindicating allowed concurrency access +//#else +//#@ThreadSafe +//#endif +public class DataGeneratorWithExecutor implements IDataGenerator { + + // Request objects are used to serialize the interface calls into objects + // which can then be pushed into a queue. + //#ifdef excercises + // TODO Excercise 3 - Add an annotationindicating allowed concurrency access + //#else +//# @Immutable + //#endif + abstract class Request { + final RequestMonitor fRequestMonitor; + + Request(RequestMonitor rm) { + fRequestMonitor = rm; + } + } + + //#ifdef excercises + // TODO Excercise 3 - Add an annotationindicating allowed concurrency access + //#else +//# @Immutable + //#endif + class CountRequest extends Request { + CountRequest(DataRequestMonitor rm) { + super(rm); + } + } + + //#ifdef excercises + // TODO Excercise 3 - Add an annotationindicating allowed concurrency access + //#else +//# @Immutable + //#endif + class ItemRequest extends Request { + final int fIndex; + ItemRequest(int index, DataRequestMonitor rm) { + super(rm); + fIndex = index; + } + } + + // The executor used to access all internal data of the generator. + //#ifdef excercises + // TODO Excercise 3 - Add an annotation indicating allowed concurrency access + //#endif + private DsfExecutor fExecutor; + + // Main request queue of the data generator. The getValue(), getCount(), + // and shutdown() methods write into the queue, while the serviceQueue() + // method reads from it. + // The executor used to access all internal data of the generator. + //#ifdef excercises + // TODO Excercise 3 - Add an annotationindicating allowed concurrency access + //#else +//# @ConfinedToDsfExecutor("fExecutor") + //#endif + private List fQueue = new LinkedList(); + + // List of listeners is not synchronized, it also has to be accessed + // using the executor. + //#ifdef excercises + // TODO Excercise 3 - Add an annotationindicating allowed concurrency access + //#else +//# @ConfinedToDsfExecutor("fExecutor") + //#endif + private List fListeners = new LinkedList(); + + // Current number of elements in this generator. + //#ifdef excercises + // TODO Excercise 3 - Add an annotationindicating allowed concurrency access + //#else +//# @ConfinedToDsfExecutor("fExecutor") + //#endif + private int fCount = MIN_COUNT; + + // Counter used to determine when to reset the element count. + //#ifdef excercises + // TODO Excercise 3 - Add an annotationindicating allowed concurrency access + //#else +//# @ConfinedToDsfExecutor("fExecutor") + //#endif + private int fCountResetTrigger = 0; + + // Elements which were modified since the last reset. + //#ifdef excercises + // TODO Excercise 3 - Add an annotationindicating allowed concurrency access + //#else +//# @ConfinedToDsfExecutor("fExecutor") + //#endif + private Set fChangedIndexes = new HashSet(); + + // Flag used to ensure that requests are processed sequentially. + //#ifdef excercises + // TODO Excercise 3 - Add an annotationindicating allowed concurrency access + //#else +//# @ConfinedToDsfExecutor("fExecutor") + //#endif + private boolean fServiceQueueInProgress = false; + + //#ifdef excercises + // TODO Excercise 3 - Add an annotation indicating allowed concurrency access + //#endif + public DataGeneratorWithExecutor() { + // Create the executor + fExecutor = new DefaultDsfExecutor("Supplier Executor"); + + // Schedule a runnable to make the random changes. + fExecutor.scheduleAtFixedRate( + new DsfRunnable() { + public void run() { + randomChanges(); + } + }, + RANDOM_CHANGE_INTERVAL, + RANDOM_CHANGE_INTERVAL, + TimeUnit.MILLISECONDS); + } + + //#ifdef excercises + // TODO Excercise 3 - Add an annotation indicating allowed concurrency access + //#endif + public void shutdown(final RequestMonitor rm) { + try { + fExecutor.execute( new DsfRunnable() { + public void run() { + // Empty the queue of requests and fail them. + for (Request request : fQueue) { + request.fRequestMonitor.setStatus( + new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, "Supplier shut down")); + request.fRequestMonitor.done(); + } + fQueue.clear(); + + // Kill executor. + fExecutor.shutdown(); + rm.done(); + } + }); + } catch (RejectedExecutionException e) { + rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, "Supplier shut down")); + rm.done(); + } + } + + //#ifdef excercises + // TODO Excercise 3 - Add an annotation indicating allowed concurrency access + //#endif + public void getCount(final DataRequestMonitor rm) { + try { + fExecutor.execute( new DsfRunnable() { + public void run() { + fQueue.add(new CountRequest(rm)); + serviceQueue(); + } + }); + } catch (RejectedExecutionException e) { + rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, "Supplier shut down")); + rm.done(); + } + } + + //#ifdef excercises + // TODO Excercise 3 - Add an annotation indicating allowed concurrency access + //#endif + public void getValue(final int index, final DataRequestMonitor rm) { + try { + fExecutor.execute( new DsfRunnable() { + public void run() { + fQueue.add(new ItemRequest(index, rm)); + serviceQueue(); + } + }); + } catch (RejectedExecutionException e) { + rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, "Supplier shut down")); + rm.done(); + } + } + + //#ifdef excercises + // TODO Excercise 3 - Add an annotation indicating allowed concurrency access + //#endif + public void addListener(final Listener listener) { + try { + fExecutor.execute( new DsfRunnable() { + public void run() { + fListeners.add(listener); + } + }); + } catch (RejectedExecutionException e) {} + } + + //#ifdef excercises + // TODO Excercise 3 - Add an annotation indicating allowed concurrency access + //#endif + public void removeListener(final Listener listener) { + try { + fExecutor.execute( new DsfRunnable() { + public void run() { + fListeners.remove(listener); + } + }); + } catch (RejectedExecutionException e) {} + } + + // Main processing function of this generator. + //#ifdef excercises + // TODO Excercise 3 - Add an annotationindicating allowed concurrency access + //#else +//# @ConfinedToDsfExecutor("fExecutor") + //#endif + private void serviceQueue() { + + //#ifdef excercises + // TODO Excercise 4 - Add logic to discard requests from queue. + //#else +//# for (Iterator requestItr = fQueue.iterator(); requestItr.hasNext();) { +//# Request request = requestItr.next(); +//# if (request.fRequestMonitor.isCanceled()) { +//# request.fRequestMonitor.setStatus( +//# new Status(IStatus.CANCEL, DsfExamplesPlugin.PLUGIN_ID, "Request canceled")); +//# request.fRequestMonitor.done(); +//# requestItr.remove(); +//# } +//# } + //#endif + + // If a queue servicing is already scheduled, do nothing. + if (fServiceQueueInProgress) { + return; + } + + if (fQueue.size() != 0) { + // If there are requests to service, remove one from the queue and + // schedule a runnable to process the request after a processing + // delay. + fServiceQueueInProgress = true; + final Request request = fQueue.remove(0); + fExecutor.schedule( + new DsfRunnable() { + public void run() { + if (request instanceof CountRequest) { + processCountRequest((CountRequest)request); + } else if (request instanceof ItemRequest) { + processItemRequest((ItemRequest)request); + } + + // Reset the processing flag and process next + // request. + fServiceQueueInProgress = false; + serviceQueue(); + } + }, + PROCESSING_DELAY, TimeUnit.MILLISECONDS); + } + } + + //#ifdef excercises + // TODO Excercise 3 - Add an annotationindicating allowed concurrency access + //#else +//# @ConfinedToDsfExecutor("fExecutor") + //#endif + private void processCountRequest(CountRequest request) { + @SuppressWarnings("unchecked") // Suppress warning about lost type info. + DataRequestMonitor rm = (DataRequestMonitor)request.fRequestMonitor; + + rm.setData(fCount); + rm.done(); + } + + //#ifdef excercises + // TODO Excercise 3 - Add an annotationindicating allowed concurrency access + //#else +//# @ConfinedToDsfExecutor("fExecutor") + //#endif + private void processItemRequest(ItemRequest request) { + @SuppressWarnings("unchecked") // Suppress warning about lost type info. + DataRequestMonitor rm = (DataRequestMonitor)request.fRequestMonitor; + + if (fChangedIndexes.contains(request.fIndex)) { + rm.setData("Changed: " + request.fIndex); + } else { + rm.setData(Integer.toString(request.fIndex)); + } + rm.done(); + } + + /** + * This method simulates changes in the supplier's data set. + */ + //#ifdef excercises + // TODO Excercise 3 - Add an annotationindicating allowed concurrency access + //#else +//# @ConfinedToDsfExecutor("fExecutor") + //#endif + private void randomChanges() { + // Once every number of changes, reset the count, the rest of the + // times just change certain values. + if (++fCountResetTrigger % RANDOM_COUNT_CHANGE_INTERVALS == 0){ + randomCountReset(); + } else { + randomDataChange(); + } + } + + /** + * Calculates new size for provider's data set. + */ + //#ifdef excercises + // TODO Excercise 3 - Add an annotationindicating allowed concurrency access + //#else +//# @ConfinedToDsfExecutor("fExecutor") + //#endif + private void randomCountReset() { + // Calculate the new count. + Random random = new java.util.Random(); + fCount = MIN_COUNT + Math.abs(random.nextInt()) % (MAX_COUNT - MIN_COUNT); + + // Reset the changed values. + fChangedIndexes.clear(); + + // Notify listeners + for (Listener listener : fListeners) { + listener.countChanged(); + } + } + + /** + * Invalidates a random range of indexes. + */ + //#ifdef excercises + // TODO Excercise 3 - Add an annotationindicating allowed concurrency access + //#else +//# @ConfinedToDsfExecutor("fExecutor") + //#endif + private void randomDataChange() { + // Calculate the indexes to change. + Random random = new java.util.Random(); + Set set = new HashSet(); + for (int i = 0; i < fCount * RANDOM_CHANGE_SET_PERCENTAGE / 100; i++) { + set.add( new Integer(Math.abs(random.nextInt()) % fCount) ); + } + + // Add the indexes to an overall set of changed indexes. + fChangedIndexes.addAll(set); + + // Notify listeners + for (Listener listener : fListeners) { + listener.valuesChanged(set); + } + } +} + diff --git a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithThread.java b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithThread.java new file mode 100644 index 00000000000..8aeab640e6b --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithThread.java @@ -0,0 +1,238 @@ +/******************************************************************************* + * 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.examples.dsf.dataviewer; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Random; +import java.util.Set; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.ListenerList; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; + +/** + * Thread-based implementation of the data generator. + *

    + * This generator is based around a queue of client requests and a thread which + * reads the requests from the queue and processes them. The distinguishing + * feature of this generator is that it uses a a blocking queue as the main + * synchronization object. However, fListeners, fShutdown, and fChangedIndexes + * fields also need to be thread-safe and so they implement their own + * synchronization. + *

    + */ +public class DataGeneratorWithThread extends Thread implements IDataGenerator { + + // Request objects are used to serialize the interface calls into objects + // which can then be pushed into a queue. + abstract class Request { + final RequestMonitor fRequestMonitor; + + Request(RequestMonitor rm) { + fRequestMonitor = rm; + } + } + + class CountRequest extends Request { + CountRequest(DataRequestMonitor rm) { + super(rm); + } + } + + class ItemRequest extends Request { + final int fIndex; + ItemRequest(int index, DataRequestMonitor rm) { + super(rm); + fIndex = index; + } + } + + class ShutdownRequest extends Request { + ShutdownRequest(RequestMonitor rm) { + super(rm); + } + } + + // Main request queue of the data generator. The getValue(), getCount(), + // and shutdown() methods write into the queue, while the run() method + // reads from it. + private final BlockingQueue fQueue = new LinkedBlockingQueue(); + + // ListenerList class provides thread safety. + private ListenerList fListeners = new ListenerList(); + + // Current number of elements in this generator. + private int fCount = MIN_COUNT; + + // Counter used to determine when to reset the element count. + private int fCountResetTrigger = 0; + + // Elements which were modified since the last reset. + private Set fChangedIndexes = Collections.synchronizedSet(new HashSet()); + + // Used to determine when to make changes in data. + private long fLastChangeTime = System.currentTimeMillis(); + + // Flag indicating when the generator has been shut down. + private AtomicBoolean fShutdown = new AtomicBoolean(false); + + public DataGeneratorWithThread() { + // Immediately kick off the request processing thread. + start(); + } + + public void shutdown(RequestMonitor rm) { + // Mark the generator as shut down. After the fShutdown flag is set, + // all new requests should be shut down. + if (!fShutdown.getAndSet(true)) { + fQueue.add(new ShutdownRequest(rm)); + } else { + // + rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, "Supplier shut down")); + rm.done(); + } + } + + public void getCount(DataRequestMonitor rm) { + if (!fShutdown.get()) { + fQueue.add(new CountRequest(rm)); + } else { + rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, "Supplier shut down")); + rm.done(); + } + } + + public void getValue(int index, DataRequestMonitor rm) { + if (!fShutdown.get()) { + fQueue.add(new ItemRequest(index, rm)); + } else { + rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, "Supplier shut down")); + rm.done(); + } + } + + public void addListener(Listener listener) { + fListeners.add(listener); + } + + public void removeListener(Listener listener) { + fListeners.remove(listener); + } + + @Override + public void run() { + try { + while(true) { + // Get the next request from the queue. The time-out + // ensures that that the random changes get processed. + final Request request = fQueue.poll(100, TimeUnit.MILLISECONDS); + + // If a request was dequeued, process it. + if (request != null) { + // Simulate a processing delay. + Thread.sleep(PROCESSING_DELAY); + + if (request instanceof CountRequest) { + processCountRequest((CountRequest)request); + } else if (request instanceof ItemRequest) { + processItemRequest((ItemRequest)request); + } else if (request instanceof ShutdownRequest) { + // If shutting down, just break out of the while(true) + // loop and thread will exit. + request.fRequestMonitor.done(); + break; + } + } + + // Simulate data changes. + randomChanges(); + } + } + catch (InterruptedException x) {} + } + + private void processCountRequest(CountRequest request) { + @SuppressWarnings("unchecked") // Suppress warning about lost type info. + DataRequestMonitor rm = (DataRequestMonitor)request.fRequestMonitor; + + rm.setData(fCount); + rm.done(); + } + + private void processItemRequest(ItemRequest request) { + @SuppressWarnings("unchecked") // Suppress warning about lost type info. + DataRequestMonitor rm = (DataRequestMonitor)request.fRequestMonitor; + + if (fChangedIndexes.contains(request.fIndex)) { + rm.setData("Changed: " + request.fIndex); + } else { + rm.setData(Integer.toString(request.fIndex)); + } + rm.done(); + } + + + private void randomChanges() { + // Check if enough time is elapsed. + if (System.currentTimeMillis() > fLastChangeTime + RANDOM_CHANGE_INTERVAL) { + fLastChangeTime = System.currentTimeMillis(); + + // Once every number of changes, reset the count, the rest of the + // times just change certain values. + if (++fCountResetTrigger % RANDOM_COUNT_CHANGE_INTERVALS == 0){ + randomCountReset(); + } else { + randomDataChange(); + } + } + } + + private void randomCountReset() { + // Calculate the new count. + Random random = new java.util.Random(); + fCount = MIN_COUNT + Math.abs(random.nextInt()) % (MAX_COUNT - MIN_COUNT); + + // Reset the changed values. + fChangedIndexes.clear(); + + // Notify listeners + for (Object listener : fListeners.getListeners()) { + ((Listener)listener).countChanged(); + } + } + + private void randomDataChange() { + // Calculate the indexes to change. + Random random = new java.util.Random(); + Set set = new HashSet(); + for (int i = 0; i < fCount * RANDOM_CHANGE_SET_PERCENTAGE / 100; i++) { + set.add( new Integer(Math.abs(random.nextInt()) % fCount) ); + } + + // Add the indexes to an overall set of changed indexes. + fChangedIndexes.addAll(set); + + // Notify listeners + for (Object listener : fListeners.getListeners()) { + ((Listener)listener).valuesChanged(set); + } + } +} + + diff --git a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/IDataGenerator.java b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/IDataGenerator.java new file mode 100644 index 00000000000..1a16605fb17 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/IDataGenerator.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * 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.examples.dsf.dataviewer; + +import java.util.Set; + +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.concurrent.ThreadSafe; + +/** + * Data generator is simple source of data used to populate the example table + * view. It contains two asynchronous methods for retrieving the data + * parameters: the count and the value for a given index. It also allows the + * view to receive events indicating when the data supplied by the generator + * is changed. + */ +@ThreadSafe +public interface IDataGenerator { + + // Constants which control the data generator behavior. + // Changing the count range can stress the scalability of the system, while + // changing of the process delay and random change interval can stress + // its performance. + final static int MIN_COUNT = 50; + final static int MAX_COUNT = 100; + final static int PROCESSING_DELAY = 10; + final static int RANDOM_CHANGE_INTERVAL = 10000; + final static int RANDOM_COUNT_CHANGE_INTERVALS = 3; + final static int RANDOM_CHANGE_SET_PERCENTAGE = 10; + + + // Listener interface that the view needs to implement to react + // to the changes in data. + public interface Listener { + void countChanged(); + void valuesChanged(Set indexes); + } + + // Data access methods. + void getCount(DataRequestMonitor rm); + void getValue(int index, DataRequestMonitor rm); + + // Method used to shutdown the data generator including any threads that + // it may use. + void shutdown(RequestMonitor rm); + + // Methods for registering change listeners. + void addListener(Listener listener); + void removeListener(Listener listener); +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/SyncDataViewer.java b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/SyncDataViewer.java new file mode 100644 index 00000000000..2f9f5913ed7 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/SyncDataViewer.java @@ -0,0 +1,180 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.dsf.dataviewer; + +import java.util.Set; + +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; +import org.eclipse.dd.dsf.concurrent.Query; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * Data viewer based on a table, which reads data using synchronous methods. + *

    + * This viewer implements the {@link IStructuredContentProvider} interface + * which is used by the JFace TableViewer class to populate a Table. This + * interface contains one principal methods for reading data {@link #getElements(Object)}, + * which synchronously returns an array of elements. In order to implement this + * method using the asynchronous data generator, this provider uses the + * {@link Query} object. + *

    + */ +public class SyncDataViewer + implements IStructuredContentProvider, IDataGenerator.Listener +{ + // The viewer and generator that this content provider using. + final private TableViewer fViewer; + final private IDataGenerator fDataGenerator; + + public SyncDataViewer(TableViewer viewer, IDataGenerator generator) { + fViewer = viewer; + fDataGenerator = generator; + fDataGenerator.addListener(this); + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + // Not used + } + + + public Object[] getElements(Object inputElement) { + + // Create the query object for reading data count. + Query countQuery = new Query() { + @Override + protected void execute(DataRequestMonitor rm) { + fDataGenerator.getCount(rm); + } + }; + + // Submit the query to be executed. A query implements a runnable + // interface and it has to be executed in order to do its work. + ImmediateExecutor.getInstance().execute(countQuery); + int count = 0; + + // Block until the query completes, which will happen when the request + // monitor of the execute() method is marked done. + try { + count = countQuery.get(); + } catch (Exception e) { + // InterruptedException and ExecutionException can be thrown here. + // ExecutionException containing a CoreException will be thrown + // if an error status is set to the Query's request monitor. + return new Object[0]; + } + + // Create the array that will be filled with elements. + // For each index in the array execute a query to get the element at + // that index. + final Object[] elements = new Object[count]; + + for (int i = 0; i < count; i++) { + final int index = i; + Query valueQuery = new Query() { + @Override + protected void execute(DataRequestMonitor rm) { + fDataGenerator.getValue(index, rm); + } + }; + ImmediateExecutor.getInstance().execute(valueQuery); + try { + elements[i] = valueQuery.get(); + } catch (Exception e) { + elements[i] = "error"; + } + } + return elements; + } + + public void dispose() { + fDataGenerator.removeListener(this); + } + + public void countChanged() { + // For any event from the generator, refresh the whole viewer. + refreshViewer(); + } + + public void valuesChanged(Set indexes) { + // For any event from the generator, refresh the whole viewer. + refreshViewer(); + } + + private void refreshViewer() { + // This method may be called on any thread, switch to the display + // thread before calling the viewer. + Display display = fViewer.getControl().getDisplay(); + display.asyncExec( new Runnable() { + public void run() { + if (!fViewer.getControl().isDisposed()) { + fViewer.refresh(); + } + } + }); + } + + public static void main(String[] args) { + // Create the shell to hold the viewer. + Display display = new Display(); + Shell shell = new Shell(display, SWT.SHELL_TRIM); + shell.setLayout(new GridLayout()); + GridData data = new GridData(GridData.FILL_BOTH); + shell.setLayoutData(data); + Font font = new Font(display, "Courier", 10, SWT.NORMAL); + + // Create the table viewer. + TableViewer tableViewer = new TableViewer(shell, SWT.BORDER); + tableViewer.getControl().setLayoutData(data); + + // Create the data generator. + final IDataGenerator generator = new DataGeneratorWithThread(); + + // Create the content provider which will populate the viewer. + SyncDataViewer contentProvider = new SyncDataViewer(tableViewer, generator); + tableViewer.setContentProvider(contentProvider); + tableViewer.setInput(new Object()); + + // Open the shell and service the display dispatch loop until user + // closes the shell. + shell.open(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) + display.sleep(); + } + + // The IDataGenerator.shutdown() method is asynchronous, this requires + // using a query again in order to wait for its completion. + Query shutdownQuery = new Query() { + @Override + protected void execute(DataRequestMonitor rm) { + generator.shutdown(rm); + } + }; + ImmediateExecutor.getInstance().execute(shutdownQuery); + try { + shutdownQuery.get(); + } catch (Exception e) {} + + // Shut down the display. + font.dispose(); + display.dispose(); + } + +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/doc-files/dsf_concurrency_model-1.png b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/doc-files/dsf_concurrency_model-1.png similarity index 100% rename from plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/doc-files/dsf_concurrency_model-1.png rename to plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/doc-files/dsf_concurrency_model-1.png diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/package.html b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/package.html similarity index 100% rename from plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/concurrent/package.html rename to plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/package.html From d7635bc04631cb65f36364086ea8507981904ca9 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 29 Feb 2008 16:26:34 +0000 Subject: [PATCH 276/834] [220446] Updated the "dataviewer" example and excercises for EclipseCon tutorial. --- .../examples/dsf/dataviewer/AsyncDataViewer.java | 4 ++++ .../dataviewer/DataGeneratorWithExecutor.java | 12 ++++++++---- .../dsf/dataviewer/DataGeneratorWithThread.java | 6 +++++- .../examples/dsf/dataviewer/IDataGenerator.java | 16 ++++++++++++---- .../examples/dsf/dataviewer/SyncDataViewer.java | 4 ++++ 5 files changed, 33 insertions(+), 9 deletions(-) diff --git a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/AsyncDataViewer.java b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/AsyncDataViewer.java index e36a3bdaa56..72feab635da 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/AsyncDataViewer.java +++ b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/AsyncDataViewer.java @@ -8,7 +8,11 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ +//#ifdef excercises package org.eclipse.dd.examples.dsf.dataviewer; +//#else +//#package org.eclipse.dd.examples.dsf.dataviewer.answers; +//#endif import java.util.HashSet; import java.util.Iterator; diff --git a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithExecutor.java b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithExecutor.java index 5fc0da81485..fb70c5e15a4 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithExecutor.java +++ b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithExecutor.java @@ -15,7 +15,9 @@ package org.eclipse.dd.examples.dsf.dataviewer; //#endif import java.util.HashSet; -import java.util.Iterator; +//#ifdef answers +//#import java.util.Iterator; +//#endif import java.util.LinkedList; import java.util.List; import java.util.Random; @@ -25,14 +27,16 @@ import java.util.concurrent.TimeUnit; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; +//#ifdef answers +//#import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; +//#import org.eclipse.dd.dsf.concurrent.Immutable; +//#import org.eclipse.dd.dsf.concurrent.ThreadSafe; +//#endif import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor; import org.eclipse.dd.dsf.concurrent.DsfExecutor; import org.eclipse.dd.dsf.concurrent.DsfRunnable; -import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; /** diff --git a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithThread.java b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithThread.java index 8aeab640e6b..6a4aa133dc4 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithThread.java +++ b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithThread.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006 Wind River Systems and others. + * Copyright (c) 2006, 2008 Wind River Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,7 +8,11 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ +//#ifdef excercises package org.eclipse.dd.examples.dsf.dataviewer; +//#else +//#package org.eclipse.dd.examples.dsf.dataviewer.answers; +//#endif import java.util.Collections; import java.util.HashSet; diff --git a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/IDataGenerator.java b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/IDataGenerator.java index 1a16605fb17..e31c0edb981 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/IDataGenerator.java +++ b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/IDataGenerator.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006 Wind River Systems and others. + * Copyright (c) 2006, 2008 Wind River Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,7 +8,11 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ +//#ifdef excercises package org.eclipse.dd.examples.dsf.dataviewer; +//#else +//#package org.eclipse.dd.examples.dsf.dataviewer.answers; +//#endif import java.util.Set; @@ -23,15 +27,19 @@ import org.eclipse.dd.dsf.concurrent.ThreadSafe; * view to receive events indicating when the data supplied by the generator * is changed. */ -@ThreadSafe +//#ifdef excercises +//TODO Excercise 3 - Add an annotationindicating allowed concurrency access +//#else +//#@ThreadSafe +//#endif public interface IDataGenerator { // Constants which control the data generator behavior. // Changing the count range can stress the scalability of the system, while // changing of the process delay and random change interval can stress // its performance. - final static int MIN_COUNT = 50; - final static int MAX_COUNT = 100; + final static int MIN_COUNT = 100; + final static int MAX_COUNT = 200; final static int PROCESSING_DELAY = 10; final static int RANDOM_CHANGE_INTERVAL = 10000; final static int RANDOM_COUNT_CHANGE_INTERVALS = 3; diff --git a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/SyncDataViewer.java b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/SyncDataViewer.java index 2f9f5913ed7..f0c4c20729e 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/SyncDataViewer.java +++ b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/SyncDataViewer.java @@ -8,7 +8,11 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ +//#ifdef excercises package org.eclipse.dd.examples.dsf.dataviewer; +//#else +//#package org.eclipse.dd.examples.dsf.dataviewer.answers; +//#endif import java.util.Set; From 14259c32e5fe3b53a475b4dcb85c7fd040e76f56 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Fri, 29 Feb 2008 16:46:33 +0000 Subject: [PATCH 277/834] Bug 220959 Do not sent target output generated by CLI commands to the target console. --- .../mi/service/command/MIInferiorProcess.java | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIInferiorProcess.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIInferiorProcess.java index 9cbe94eaa20..83bdc774da0 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIInferiorProcess.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIInferiorProcess.java @@ -38,6 +38,7 @@ import org.eclipse.dd.dsf.debug.service.command.IEventListener; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.mi.internal.MIPlugin; +import org.eclipse.dd.mi.service.command.commands.CLICommand; import org.eclipse.dd.mi.service.command.commands.CLIExecAbort; import org.eclipse.dd.mi.service.command.commands.MIGDBShowExitCode; import org.eclipse.dd.mi.service.command.output.MIConst; @@ -78,6 +79,20 @@ public class MIInferiorProcess extends Process @ConfinedToDsfExecutor("fSession#getExecutor") private boolean fDisposed = false; + + /** + * Counter for tracking console commands sent by services. + * + * The CLI 'monitor' command produces target output which should + * not be written to the target console, since it is in response to a CLI + * command. In fact, CLI commands should never have their output sent + * to the target console. + * + * This counter is incremented any time a CLI command is seen. It is + * decremented whenever a CLI command is finished. When counter + * value is 0, the inferior process writes the target output. + */ + private int fSuppressTargetOutputCounter = 0; Integer fExitCode = null; @@ -357,6 +372,7 @@ public class MIInferiorProcess extends Process } } } else if (oobr instanceof MITargetStreamOutput) { + if (fSuppressTargetOutputCounter > 0) return; MITargetStreamOutput tgtOut = (MITargetStreamOutput)oobr; if (fInputStreamPiped != null && tgtOut.getString() != null) { try { @@ -374,14 +390,20 @@ public class MIInferiorProcess extends Process } public void commandSent(ICommand command) { - // No action + if (command instanceof CLICommand) { + fSuppressTargetOutputCounter++; + } } public void commandRemoved(ICommand command) { // No action } - public void commandDone(ICommand cmd, ICommandResult result) { + public void commandDone(ICommand command, ICommandResult result) { + if (command instanceof CLICommand) { + fSuppressTargetOutputCounter--; + } + MIInfo cmdResult = (MIInfo) result ; MIOutput output = cmdResult.getMIOutput(); MIResultRecord rr = output.getMIResultRecord(); From 86e9c84f412764a7375621958377d25ae6e3a462 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Sat, 1 Mar 2008 00:43:50 +0000 Subject: [PATCH 278/834] [220446] Updated the "DSF Common Patterns" document. --- .../docs/common/dsf_common_patterns.html | 837 ++++++++++++++++++ .../docs/common/query_1.dia | Bin 0 -> 2247 bytes .../docs/common/query_1.png | Bin 0 -> 14759 bytes .../docs/common/synchronization_1.dia | Bin 0 -> 1487 bytes .../docs/common/synchronization_1.png | Bin 0 -> 4228 bytes .../docs/common/synchronization_2.dia | Bin 0 -> 1501 bytes .../docs/common/synchronization_2.png | Bin 0 -> 6076 bytes .../docs/pda/dsf_common_patterns.html | 159 ---- 8 files changed, 837 insertions(+), 159 deletions(-) create mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/common/dsf_common_patterns.html create mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/common/query_1.dia create mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/common/query_1.png create mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/common/synchronization_1.dia create mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/common/synchronization_1.png create mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/common/synchronization_2.dia create mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/common/synchronization_2.png delete mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/pda/dsf_common_patterns.html diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/common/dsf_common_patterns.html b/plugins/org.eclipse.dd.doc.dsf/docs/common/dsf_common_patterns.html new file mode 100644 index 00000000000..79f481f79fb --- /dev/null +++ b/plugins/org.eclipse.dd.doc.dsf/docs/common/dsf_common_patterns.html @@ -0,0 +1,837 @@ + + + + DSF Common Patterns + + +

    DSF Common Patterns
    +

    +

    Summary

    +

    Examples
    +

    +Running example code is and performing included excercises is very +helpful in following this tutorial.  In order to run the examples +in this tutorial the following is needed:
    +
      +
    1. Download and install Eclipse development environment, either the Eclipse Classic 3.4 or Eclipse IDE for C/C++ Developers
      +
    2. +
    3. Install the DSF SDK feature to build against, by performing +either:
      +
    4. +
        +
      1. Using update manager, install the Debugger Services Framework end-user and +extender SDK, found in the Ganymede +Discovery Site under Remote +Access and Device Development.
      2. +
      3. Check out org.eclipse.dd.dsf +and org.eclipse.dd.dsf.ui plugins, found in the /cvsroot/dsdp repository under org.eclipse.dd.dsf/plugins +directory.
      4. +
      +
    5. Check out the org.eclipse.dd.examples.dsf +plugin, found /cvsroot/dsdp +under org.eclipse.dd.dsf/plugins +directory.
    6. +
    7. Build the examples plugin:
    8. +
        +
      1. Execute the build the first time to build and run the +excercises preprocessor.
      2. +
      3. Refresh the resources in the plugin (right-click on project in Navigator and select Refresh), in order to recognize the +sources generated by the preprocessor.
      4. +
      5. Build the plugin again to compile the generated sources.
      6. +
      +
    9. Launch the examples
    10. +
        +
      1. Examples in data org.eclipse.dd.examples.dsf.requestmonitor and +org.eclipse.dd.examples.dsf.dataviewer packages each contain a public +main() function.  They can be launched using the Java Application +launch type.
      2. +
      3. TODO: Launching timers +example
      4. +
      +
    +

    Asynchronous Methods

    +One of the central features of DSF is that it relies very heavily on +the use of asynchronous methods.  Asynchronous methods here mean +simply methods that use a callback +object to indicate their completion. The use of asynchronous +methods can be very contageous in a system, where if a lower level API +is composed of asynchronous methods, a higher level system which uses +those methods also has to have asynchronous methods in its interface +(or risk blocking its calling thread).
    +
    +TODO? : +diagram of a layered system with asynchronous APIs
    +

    Request Monitor

    +There is a standard callback object used in DSF, the request +monitor.  A request monitor has the following features:
    +
      +
    • Executor - A +argument to the request monitor constructor allows the user to specify +what executor should be used to invoke the callback method. 
      +
    • +
    • Status - +Asynchronous methods that take a callback can always set the status +indicating the success or failure of the call.
    • +
    • Callback Methods +- The request monitor declares several protected methods which are +invoked when the callback is invoked: handleCompleted(), handleOK(), +handleError(), etc.  The users may override these methods as +needed to perform additional processing upon asynchronous method +completion.
    • +
    • Parent Request Monitor +- If the method calling an asynchronous method is itself asynchronous, +it may set its argument request monitor as the parent of the request +monitor it is creating.  The parent request monitor will be
      +automatically invoked when the lower level request monitor is completed.
    • +
    +Following is the snippet from a the +"hello world" example of using a +request monitor:
    +
    + + + + + + + + + + +
    org.eclipse.dd.examples.dsf.requestmonitor.AsyncHelloWorld
    +

    +
    +
     26: public class AsyncHelloWorld {

    28: public static void main(String[] args) {
    29: Executor executor = ImmediateExecutor.getInstance();
    30: RequestMonitor rm = new RequestMonitor(executor, null);
    31: asyncHelloWorld(rm);
    32: }

    34: static void asyncHelloWorld(RequestMonitor rm) {
    35: System.out.println("Hello world");
    36: rm.done();
    37: }
    +
    +
    +

    +

    + + + + + + + +
    Excercise 1: A common +problem in DSF is implementing nested asynchronous methods, this +excercise adds a second-level asynchronous method to +AsyncHelloWorld. 
    +

    Look +for comments preceeded with "// TODO Excercise 1" in the +org.eclipse.dd.examples.dsf.requestmonitor.AsyncHelloWorld +module.

    +
    +
    +

    Data Request Monitor

    +The base request monitor is useful for returning +status of the +asynchronous method, but they do not have an option of returning a +value to the caller.  DataRequestMonitor can be used for that +purpose. A simple example of using the data request monitor:
    +
    +
    + + + + + + + + + + +
    org.eclipse.dd.examples.dsf.requestmonitor.Async2Plus2
    +

    +
    +
     22: public class Async2Plus2 {
    23:
    24: public static void main(String[] args) {
    25: Executor executor = ImmediateExecutor.getInstance();
    26: DataRequestMonitor<Integer> rm =
    27: new DataRequestMonitor<Integer>(executor, null) {
    28: @Override
    29: protected void handleCompleted() {
    30: System.out.println("2 + 2 = " + getData());
    31: }
    32: };
    33: asyncAdd(2, 2, rm);
    34: }

    36: static void asyncAdd(int value1, int value2, DataRequestMonitor<Integer> rm) {
    37: rm.setData(value1 + value2);
    38: rm.done();
    39: }
    40: }
    +
    +
    +
      +
    • Lines 26-27 create the data request monitor using a local class +declaraion.  Note the type parameter to DataRequestMonitor allows +for compiler checking of the type when calling getData() and setData() +methods.
    • +
    • Lines 29-31 override the standard callback to print the result of +the calculation to the console.
      +
    • +
    +

    Multi-Request Monitor

    +A common problem when using asynchronous is that several asynchronous +methods need to be called in parallel, so the calling method needs to +somehow manage the completion of several request monitors.  +CountingRequestMonitor can be used for this purpose.  It is +configured such that it's done() method needs to be called a count number of times before the +callback method is invoked. 
    +The following snipped from the AsyncQuicksort example shows a simple +example of using the CountingRequestMonitor:
    +
    +
    + + + + + + + + + + +
    org.eclipse.dd.examples.dsf.requestmonitor.AsyncQuicksort.asyncQuickSort()
    +

    +
    +
     42:     static void asyncQuicksort(final int[] array, final int left, 
    43: final int right, final RequestMonitor rm)
    44: {
    45: if (right > left) {
    46: int pivot = left;
    48: int newPivot = partition(array, left, right, pivot);
    49: printArray(array, left, right, newPivot);

    51: CountingRequestMonitor countingRm = new CountingRequestMonitor(fgExecutor, rm);
    52: asyncQuicksort(array, left, newPivot - 1, countingRm);
    53: asyncQuicksort(array, newPivot + 1, right, countingRm);
    54: countingRm.setDoneCount(2);
    55: } else {
    56: rm.done();
    57: }
    58: }
    +
    +
    +
      +
    • Line 50 creates the CountingRequestMonitor.  Note that the +parent request monitor is set to the request monitor from the +asyncQuicksort() argument.  This parent request monitor is +automatically called when the counting request monitor is completed.
    • +
    • Lines 51 and 52, use the same instance of counting request +monitor when calling the sub-routine.  Each sub-routine will call +done() on the counting request monitor.
    • +
    • Line 53 sets the count to the number of sub-routines called with +the counting request monitor.  Note that the done count can be set +after calling the sub-routines, because the counting request monitor +will not be completed until the count is set.
      +
    • +
    • Line 55 Don't forget to complete the request monitor in all +execution paths!
    • +
    + + + + + + +
    Excercise 2: Converting a +synchronous method into an asynchronous one, is another common task in +DSF.  This excercise converts the AsyncQuicksort.partition() +method into asynchronous AsyncQuicksort.asyncPartition(). 
    +

    Look +for comments preceeded with "// TODO Excercise 2" in the +org.eclipse.dd.examples.dsf.requestmonitor.AsyncQuicksort +module.

    +
    +

    Concurrency

    +The simple examples in previous section used asynchronous method +signatures, however no real asynchronous work was performed since all +execution was performed in the main thread.  This section examines +a more typical example of a problem that DSF is intended to solve: a +viewer and an asynchronous data generator.
    +

    The IDataGenerator interface contains the following two asynchronous +data access methods:
    +

    +
    + + + + + + + + + + +
    org.eclipse.dd.examples.dsf.dataviewer.IDataGenerator
    +

    +
    +
     49:  void getCount(DataRequestMonitor<Integer> rm);
    50: void getValue(int index, DataRequestMonitor<String> rm);
    +
    +
    +

    The example is intended to simulate a realistic problem therefore, +it +can be assumed that these methods do not complete the request monitor +immediately, but rather that the requests are completed on a separate +thread and with some delay.  There are two implementations of this +service provided:

    +
      +
    1. DataGeneratorWithThread - Uses a java thread directly and various +synchronization mechanisms for data integrity.
      +
    2. +
    3. DataGeneratorWithExecutor - Uses a DSF executor for both +asynchronous execution and synchronization.
    4. +
    +There are also two viewers provided which display data from the data +generator:
    +
      +
    1. SyncDataViewer - Table-based viewer which implements a +synchronous IStructuredContentProvider interface.
      +
    2. +
    3. AsyncDataViewer - Table-based viewer which implements an +asynchronous ILazyContentProvider interface.
    4. +
    +

    Query

    +DSF is designed to facilitate use of asynchronous APIs.  However, +sometimes there are situations where a synchronous method has to be +implemented to call an asynchronous method.  One utility used to +accomplish this is a DSF Query object.  The Query object is meant +to be extended by clients in order to override the asynchronous +execute() method. The client code using a query can use the execute() +implementation in order to call other asynchronous methods.  The +following snippet +from SyncDataViewer.getElements()  shows the use of Query:
    +
    +
    + + + + + + + + + + +
    org.eclipse.dd.examples.dsf.dataviewer.SyncDataViewer.getElements() +

    +
    +
     59:         // Create the query object for reading data count. 
    60: Query<Integer> countQuery = new Query<Integer>() {
    61: @Override
    62: protected void execute(DataRequestMonitor<Integer> rm) {
    63: fDataGenerator.getCount(rm);
    64: }
    65: };
    66:
    67: // Submit the query to be executed. A query implements a runnable
    68: // interface and it has to be executed in order to do its work.
    69: ImmediateExecutor.getInstance().execute(countQuery);
    70: int count = 0;
    71:
    72: // Block until the query completes, which will happen when the request
    73: // monitor of the execute() method is marked done.
    74: try {
    75: count = countQuery.get();
    76: } catch (Exception e) {
    77: // InterruptedException and ExecutionException can be thrown here.
    78: // ExecutionException containing a CoreException will be thrown
    79: // if an error status is set to the Query's request monitor.
    80: return new Object[0];
    81: }
    +
    +
    +
      +
    • Line 60 creates the query object. 
      +
    • +
    • On line 63, inside the execute() method, the asynchronous +getCount() method is called
    • +
    • Line 69 submits the query to an executor.  This is very +important, because a Query object simply implements Runnable, it will +not perform the work in its exectute() method unless it is submitted to +an executor. 
      +
    • +
    • Line 75 blocks while calling the +java.util.concurrent.Future.get() method, implemented by Query, until +the request monitor from the execute() method is completed.
    • +
    + + + + + + + + + +

    +
    Image 1: Sequence diagram of Query use in +getElements().
    +
    +
    +
    +
    + + + + + + +
    Note: Using the query object +requires a great deal of care because calling +a blocking method can create performance problems and raises +possibility of deadlock. One common deadlock scenario occurs when +the get() method is being called by a thread which is itself required +for completion of the asynchronous methods called by execute().
    +
    +

    TODO +?: add a sequence diagram of the deadlock scenario
    +

    +

    +

    Synchronization

    +Managing race conditions and deadlocks is one of the most challanging +problems of large multi-threaded systems.  DSF uses a +single-threaded executor as the primary mechanism for safe-guarding +access to data.  Methods, which need to access data protected by +the DSF executor, have to access this data inside a runnable submitted +to the executor thread.  The following is an example of this from +the DataGeneratorWithExecutor:
    +
    +
    + + + + + + + + + + +
    org.eclipse.dd.examples.dsf.dataviewer.DataGeneratorWithExecutor.addListener()
    +

    +
    +
    174:     public void addListener(final Listener listener) {
    175: try {
    176: fExecutor.execute( new DsfRunnable() {
    177: public void run() {
    178: fListeners.add(listener);
    179: }
    180: });
    181: } catch (RejectedExecutionException e) {}
    182: }
    +
    +
    +
      +
    • Line 174 declares the addListener() method which can be called on +any thread.
    • +
    • Line 176 submits a local runnable to the DSF executor.
    • +
    • Line 178 accesses the protected data: fListeners.
    • +
    + + + + + + +
    Note: +It is immediately apparent that this synchronization mechanism +adds a lot of overhead and for such a simple example, it is much less +efficient than using a synchronized section or an atomic +variable.  It +is less obvious how this mechanism adds value, however this document is +just a tutorial so the discussion of the merits of the design will be +left out.
    +
    + + + + + + + + + + + +

    +
    Image 1: Synchronization using multiple +locks on data.
    +
    Image 2: Synchronization using a single +DSF executor thread.
    +
    +Comparing other parts of the two data generator implementation shows +that using the synchronization mechanism above is the principal +difference between the two implementations.  One notable exception +is the principal processing loop in each data generator.  In the +thread-based implementation this loop is implemented in the run method +of the generator's thread:
    +
    +
    + + + + + + + + + + +
    org.eclipse.dd.examples.dsf.dataviewer.DataGeneratorWithThread.run()
    +

    +
    +
    139:     public void run() {
    140: try {
    141: while(true) {
    142: // Get the next request from the queue. The time-out
    143: // ensures that that the random changes get processed.
    144: final Request request = fQueue.poll(100, TimeUnit.MILLISECONDS);
    145:
    146: // If a request was dequeued, process it.
    147: if (request != null) {
    148: // Simulate a processing delay.
    149: Thread.sleep(PROCESSING_DELAY);
    150:
    151: if (request instanceof CountRequest) {
    152: processCountRequest((CountRequest)request);
    153: } else if (request instanceof ItemRequest) {
    154: processItemRequest((ItemRequest)request);
    155: } else if (request instanceof ShutdownRequest) {
    156: // If shutting down, just break out of the while(true)
    157: // loop and thread will exit.
    158: request.fRequestMonitor.done();
    159: break;
    160: }
    161: }
    162:
    163: // Simulate data changes.
    164: randomChanges();
    165: }
    166: }
    167: catch (InterruptedException x) {}
    168: }
    +
    +
    +
      +
    • Line 141 creates the loop that runs continuously until the break +statement on line 159.
    • +
    • Line 149 implements the artcificial processing delay that is +executed for each request.
    • +
    +

    In contrast the executor-based generator uses a dedicated method for +servicing the queue, which is called by every method that adds a new +request to the queue:
    +

    +
    + + + + + + + + + + +
    org.eclipse.dd.examples.dsf.dataviewer.DataGeneratorWithExecutor.serviceQueue() +

    +
    +
    197:     private void serviceQueue() {
    ...
    201: // If a queue servicing is already scheduled, do nothing.
    202: if (fServiceQueueInProgress) {
    203: return;
    204: }
    205:
    206: if (fQueue.size() != 0) {
    207: // If there are requests to service, remove one from the queue and
    208: // schedule a runnable to process the request after a processing
    209: // delay.
    210: fServiceQueueInProgress = true;
    211: final Request request = fQueue.remove(0);
    212: fExecutor.schedule(
    213: new DsfRunnable() {
    214: public void run() {
    215: if (request instanceof CountRequest) {
    216: processCountRequest((CountRequest)request);
    217: } else if (request instanceof ItemRequest) {
    218: processItemRequest((ItemRequest)request);
    219: }
    220:
    221: // Reset the processing flag and process next
    222: // request.
    223: fServiceQueueInProgress = false;
    224: serviceQueue();
    225: }
    226: },
    227: PROCESSING_DELAY, TimeUnit.MILLISECONDS);
    228: }
    229: }
    +
    +
    +
      +
    • On line 202, the fServiceQueueInProgress flag is used to ensure +that the queue servicing runnable is not scheduled too often.
    • +
    • Line 211 removes the top request from the queue.
      +
    • +
    • Line 212 calls the ExecutorService.schedule() method to run the +queue servicing runnable, with a delay that simulates the request +processing time.
    • +
    • Line 224, after servicing runnableis finished, calls +serviceQueue() again to process the next item in the queue.
    • +
    + + + + + + +
    Note: When using a single-threaded +executor as the synchronization +method very few other synchronization mechanisms need to be used.  +For example the DataGeneratorWithExecutor.fQueue member is just a plain +un-synchronized list.  This is true even when using background +threads to perform long-running tasks, as long as these background +threads can call a request monitor when finished.
    +
    +
    + + + + + + +
    Excercise 3: One benefit of +the single-threaded executor concurrency model is that as long as a +method is guaranteed to run in the executor thread, this method may +access and modify any of the variables protected by this +executor.  This excercise demonstrates performing a somewhat more +complicated operation on protected state data.
    +

    Look +for comments preceeded with "// TODO Excercise 3" in the +org.eclipse.dd.examples.dsf.dataviewer.DataGeneratorWithExcecutor +module.

    +
    +

    Annotations

    +In any multi-threaded system it can become very difficult to determine +what are the rules governing access to the various data objects.  +In a DSF system, it is even more important to identify which data +objects can only be accessed using a designated DSF executor.  +Since there is no Java language mechanisms for this purpose, DSF +defines a number annotations that can be used for this purpose.  +The annotations are hierarchical, so that if a class has a given +annotation in its declaration, its members and fields are assumed to +have the same access restriction unless otherwise specified.
    +

    DSF synchronization annotations defined in +org.eclipse.dd.dsf.concurrent
    +

    +
      +
    • ThreadSafe - +Indicates that the given element can be accessed on any thread.  +Typically, if this annotation is used, the given member or class uses +syncrhonized or atomic objects to protect its data.
    • +
    • Immutable - +Immutable objects cannot be modified after they are created, thus they +are also thread-safe.  The easiest way to make an object +immutable, is to declare all its fields final and make sure that its +fields are also immutable.  Examples of immutable objects are Java +Strings, primitive object types, etc.
    • +
    • ConfinedToDsfExecutor(executor) +- Indicates that the given object can only be accessed using the given +executor.  The executor parameter is a string (since that's the +only allowable parameter type to annotations), but it should indicate +the executor, using classe's member and method names.
    • +
    • ThreadSafeAndProhibitedFromDsfExecutor(executor) +- Rarely used, it indicates that the given element can be accessed on +any thread except using the given executor.  An example of such a +method would be the SyncDataViewer.getElements() method, which should +never be called using the executor belonging to the data provider.
      +
    • +
    +
    + + + + + + +
    Note: The DSF synchronization +annotations are no more than a comment intended to help make the code +more understandable and maintainable.  Unfortunately, since there +is no compiler enforcment of their presence, it is easy to forget to +add them.
    +
    +
    +
    + + + + + + +
    +

    Excercise 4: +This excercise adds the appropriate synchronization annotations to the +methods and fields of DataProviderWithExecutor.
    +

    +

    Look +for comments preceeded with "// TODO Excercise 4" in the +org.eclipse.dd.examples.dsf.dataviewer.DataGeneratorWithExcecutor +module.

    +
    +
    +
    + + + + + + +
    Excercise 5: It is all too +easy to get into a deadlock situation.  This excercise +purposefully puts the data viewer system into a deadlock.  The +deadlock first renders the data viewer unusable, but the main thread +also gets deadlocked when attempting to exit the program.
    +

    Look +for comments preceeded with "// TODO Excercise 5" in the +org.eclipse.dd.examples.dsf.dataviewer.SyncDataViewer +module.

    +
    +

    Services

    +

    OSGi

    +

    Session

    +

    Tracker

    +

    Data Model

    +

    View Model

    +

    Adapter, Provider, Node

    +

    Timers

    +
    +
    + + + + + + + + + + +
    org.eclipse.dd.examples.dsf.requestmonitor.Async2Plus2
    +

    +

    +
    +
    +
    + + + + + + +

    +
    +
    +
    + + + + + + +
    Excercise abc: xyz
    +
    +
    + + diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/common/query_1.dia b/plugins/org.eclipse.dd.doc.dsf/docs/common/query_1.dia new file mode 100644 index 0000000000000000000000000000000000000000..68078a3d47b921de5a29d5f1f6bcc7afe7d74e90 GIT binary patch literal 2247 zcmV;&2srm2iwFP!000001MOX1kJ>mCeebV8^kphdP3$-yZaY(Tce~n^TCG;w?kfu5 zVX_Sgo0wsE+26iS3oVUg3(^+&FD>k9Msj&*J2T`q==s_I9heC;uBzZXse`eXrLV?Z41Ekpob zLjxG7p}}z!hC>=oG6zm_tEvbznzbaoAH#H%FA5+f50H$8Chq(oIKsp}ygSWA%%XYm z_B}m_8&*1sSaqcsG`;zg*jo`dC@jDNOA;%;4OPUn= zXge~SSDr)*d6j1^r=G-?x2jxR6!Ehvp#H@p)5MD>JgR=7k8CHR!gWN2Z6hj4!wLp6 zLuzKi1OyuxzlA1nU1Fyp)`Yg%%q&YgqXsnO%2XlYjBD+c%h9qaWgi1NqdbCNy{cen z2LMe~w2VSlW;MOuyYps#u;PvL!ld6z*eZSU@@J^{>Tfi7pv)h8yN`?0TX0YP>3wM% zc0s3W?7wh3qx)m=xbfJ;&OXLF@@dz^5a&_TFdZCa#%Q>htvm8aE2RkTw7Kz+H7P$k zwoNfRh)cCV548q*4v>uV9008i&~t#xv6TrNM>^8W`BhOOZHuL$UiYZ%Fxs<#274Op zeJ8Ldg6e0QB;K?vrkdT5XVQ4?9Lt}bYZqWk#8oRbXshARBrlPbMb_r-r+`v&U{w&i z%b@cH>W+CNWV96Ho@9a#=W6@`Tl9X-_{P9S{0=K2UbyvawB$1{VS`hzY&H@A?bM=6 z9P9jf*Em{)?9T;_SDJLmCS4_CQM0bgV_jC;n1qN_&V^iHZ#Wksz_hNBqkwbmdsX^* z+78XPDtQr4?U1~$UFX>hVd(B%m0zyIPf?{A+jX{-^R zY=oB|i5lLWDZH!Jf1GagA7}vS`VRr_M*ZRDh!XW@->)iNy|MGpU;UA+`(W9+4>aoG zWG6Js?MjGsq$e_Q8)%crL{uzqm3US;VTtBk2RN6}xOWb-E~FWkW?bKMh3i0MC9MgU zDObQkI|7!O3RwKvV@XdB-S?{WbJ&?0I)dXtC5e*|cLQ`JXLAdjg8|;|StAPM=Mvwl3K6YBA3!;hcC8`3 zYfa;vGZ3La#N)EqYIP7>T@}GqEazcNcyx8M+$AfOHWh?d_o(>lW-V$=YZvhY9Zvj& zdp)Mr(d4xOY)p1uuH`nf$eka0aU3n1%Zzn34+9!b+5Mp`3ahP&>~O9QETjX1k2yX$ zlEUL>^GWZX&!)AI&mtkg^tK=0^owJpLsVkTXJ%`A$pE{(ZvSH5c}ke zOh3j-Se{d}QLd@y&tGksQucGY#B>$Ye;1rDe2zk&Mezj-FlHve9FaTKjRwgi$ZTI9i3#D$KdAHj!>{kE>+8$yu*A3FzZ0I6tVw zxpMg9>h-321oY}+x00#r4ZCR$>tI? z(3;~rG~&^S=WG!Vf?ed-5TF3=xWF;C=`}?9e))o9ov-Hq5V8CRzg= z{+`n{Xh9`{IjT7nC=IZN-aJ*edFpbH1`->l_&qi|T*W#tGjT^V6UpAs$R}a8zAR4Z z;s^+xyKoE54(dy<`t|XBin+h9q1yItt8uydyOz~9m|w|-hAy^vWTu&3#@gE$$T*G zC)9yS6jJFh$daeNVt(IMOw{(NuIL(B(v#^(HV<}wFN)igpYTy|t!j!|I^p9mA9<4< zta8bR2dAV&4I}9&#T8-M`K`#@{sKDZ0G6WsR)mj9Zq<8?b$Y8NCC`18)N*6pgTx8LOd!w1Oh=Qf9r+{0)h4p{te@x!z*e* z(NEw%40~z$dpI~a17pgg2m}K{{)W^&m-wY2?|Y=`@32>?uf8z!ycLD%hrX{#&Y|Y@ zeR<&VNXbh40wWLG`_c(!6knA$z9-sF ziaJ0srS8X6iZDqYon*hgJggbpc$ zQRJK{2G5uF@OC1<2$rZ&g&NoR<34!s;Qsyl>obm9!|p4%GKAUb>FGPe?#e-qli2d2 z!IO(JpX>!ixijCtza$}{CptBkk~m!9SsG6LfhMKrWIE280IN3pVdMV({*^0N8p7$l z=fAUg=eJ%B*dg6hh*DL|Za7%zxj`>T6SmNsWj#=!l-7e1b61-#%XD*hC&a3qYJO8s z%B@#n$wL7z1P+)|;SR1jW~FSJc8%;Ye6`c&{mcYHI3C zTY~*#Wmi{M6_rTY0y@0}rMSJX*QmY3t?*R!@8VKhQ~7C$)j9HxBI)hrAQ4DQ{# zXJj;~WnEss;bCoUZDnP3XU2u~+~$~*J1^_Lw$K}LUn$Se z&lhbM5D-Ya_ZgOCLsU;o3truEo7GKHKK3qmLFrX^xXQ}P!eIL>Q3BRU1w@VU!IOO7!b;*FU7Bc42YqE%>hG)C-Qbg*0+(AfP^X+yNPCICN6 zx7<8iBSdz>k63)Rr0CP9PdPa`6%`fJ)6;{4+Nc>vVcH>rC)?Xj<+>~VmS+x^oh#$6 zS^Rj#u5LA0BqiW#U@$gVY~N~ZZ(*^J94=nsv1g~*HH2L0$3QYCzk64=Fwo!sxqD9Z z`1xW56}j8}93-(;@rMrqGkXmU4L^Ts^aoZREm@x&&PWhH9?}WY zyNlYv7J76^-3V$2At9lIp{HkgX)n*CY>ip1C*8Tr+p@i4C#fl@D{O483mJvFu2UD< zb4!(CF|dD5DZz5XwKmJX>jjj286`I=&ebvV+`Zhx@T zi9wUIk9<{>CgmbJs$CYhboar7m=`b3Ubt|9n)(1L*E-tuSk<(i>v64S&x>Z5bK}VC z2YpBrWbKV}T?dP7;ne27f;$CC9L*^c1u`)*RtKA?Tq+!mpjXIzHW|i=T8Oi**sJIE zvW3FY{V8&=dvY=K-h&5yo;yS2^z_Q%xuOCsX37z{?h4DC%QcToMMI|j1z#@mr#!gS ztX<*|RPm_avOxYN3+{>}-E~7{<@U*@mz-q5umJP(RIm-}4P*GtBEQgo8x;1R*@MOE z?bNokT#4l$Ii{Y(_1Xm)EVzm#A{H4 zxgR}IghJ8n7r|ciY7sl$ouK#HOjB> z9EyIa{UV5z)s3!IDPGWaWw=~NN9XA1NWgkHYEebVooQ>emiPqD`OgZ^gWPuU1y`qD zF)6zRLC#xt)^}N^3#>zd3kw81}77fADL#Q*HOHXJrxy|<#jD3 zB_$`P>j{i}d^wq!Z90FMj#^$ z;>5uPu5rIkk&AWLkpM6KD3a zDv#X`ch{hul)^Qk$(^>h^+|bR$C80>$mabiZtuMg8Dh`9sW-Zdgewj4P+<1w(>4cb zmUMfW!>9$8;SCCUdU_8ZG95KwtaN>_+m=PmoR+A%x*MfKR)qtqDk`7T(!^SpOIUAN z(WW%qTILiF6$-5F?CQ#ad)iJk#3-^5Crp38=llqnDDHW3w9_8VJF$>e>7?_?Nbm7b z$^En*sFg2f_FCfv!YQxH9`3&?c7zs67W}C5-OaJFF}HHB+NXq@-(S^^UFPEYn7Hua z{rjj_uR1AzWN67r_)I*Ck9(PJRHfroRb1!&d?44P9p&$j88-1zDNa_xZ((uq`KP}5RTf%Dk+z{)C<=e$6SBD7hW#`=ba<)7KL zzvfZcW>gaTt!4&`KaN(bPQr3QPInFwohSu8{m973O8xMvRf~M)EoDE-un87rRGIw@vWd&FP(V0F$bK5O-7E)e`b07Jg1|nV9n7YTiSHCm<@L_I zayWO>da(S)f>=>+^(Q86(^bW_#B~JF*naQv8sgrYQGx#4aS$j{oqP#qn zDY{DH>hqQF9VQHu7&W{mk1k@4CU9N6pWlKL_lft2-RUrdnXxH@@<; z+D50sV=qPG$js3(zgnLHDF)~1u&>=q?e5*Pq@)uW1!$Lpl24c~T~bUC&WBF4)=1x& zCEmy5x<0wRy=|cOP9^ob`4;r{7q%p2@x+>F2#Sd#_9z4b^L!l*f`^C~8xbPYf`*tN zu}4%1p1#y(%^QfnaeyQIL#yNEw>xhWd1EmU4UE$WAKPa_2z?quA_PTX^xt0Ms>4Kt z)SCYD7k__m(J+lgNA~a&)IF?B0c-@1_J4Q1Umsg&g;DYRKkuC>&`9NwUig;vmG9{% z2+03_&wt&bk?jkCGd+a@vN0eDQB~^URbE`}#fAmXKm4K2H0&!rw+A&T!UJvQe|k{E zuxq=zVgK)&{V_ipe)!w2_--ncc$-)Mn_>NRCVz}xG5h~BJ60O22^c)zwv0Bp5b9L(~Xc zaMSGwAhMmE9S0eH!ovDgb4*Ok$)@s&L$8jr7!*~&IS!XoR8nU#nkZ9{2_;YhPn&rp z;l?2c!sRAOV|?w{?tEGn9vg`V%J`h&CaXena&kC(KaBWdTBpB!`2t9-3!RdZ5^yHm48EW*>KPa?dXkU3qQoQO*CxUx zrd_?D60NPRahGp)sq1-8*$Dc}x_OZy%KUbC_Y^4axue{dg%XfERT#wSdX>iqE0y%$ zb4gi|=~-FMnhpvI_?|TM^m?kQGW3N71+sE-rCdXX*|QG9y65dN+IEk2MzXXDmwmD6 zI_4bO#dhLV15k-)e8xr(FJ#reS4)!%p)knTe0)7_0q5&R?#V&r$wB+cVLOtP5DUZ8 z=4gLwa?(f|3MRCXg!Z-^uzQ}oHI5RWz z`1m+Zz&es%Il&E;os+Yk->VzP_XtmnL(F#EzjiEQ?~f(<8FSS{EkpBFboAw!K4|>y zvDX&nd(xm0H^1hbSW!&dTIg+$xtfxcRBfCKi)3VC(mglP5PHz8cih$6+xzop^s84l zO@cx~($ms5cpe%Wj<0y_ltNv3{9k)f>3)0lr z*TXVVg|aX+e@IUcK}y(+R*CHl*4hpNOmSWwls9=$Xf*^BW$vN#RdgTkR2O=0vjEh) z$lUXL%+(mLzRe8q-+)7$Bq@QtAVV4dM5_lR&t_`SQ+ z(sU9e;zhunSXvPoAExLZaiLCP8yyi*JCiKr?1$qK!W`I=oiT%|Lr_Z7w6&fQD7%j! z_-c)v;o?a|dDM_xsZ}lRki&O=)+A*536`$oue+E&yY4eq%bM{=75uNlct~cy+ja$U z86#N;VdlcB_7wdnHSO zqRq|Cp;G6AcXmD^tKux)Y~S+ah)Rc!Ve`*9l&r35f|4@?tK68BTB@%EuV5@ru}5pkJ#V!1Q>T)qQpol-CAN~D~o?rR8(C< z!#U}9@80zf3&x<>tPe= zYH4>G@~5Mtqk+M8G&(vu^78U7lgZILI5>1Pk_7`*?5%+^U{#3k-M{3NueoHvc_~f_ z2bg3MDK$0q!-o&&G!M56D~~o3PdGBQflngDpGLo|vW?fwP)qA!k_};i-gE^u)BNq* za_LIN?(S}Xzb0|L3rhWzYbj|b#YewPS4!!QX*Es?v1lE?m(yn%*~A=Hj1~vnj9K?x zpCz4uReWF{bKKIsbpUX?-HFGOHiGBQotrhd)-ybu*}LG1ps$rm!}P1}fRa}@Kud)E zt7Q8}KufHtsky+eX4#+DB*QCQo}GPHo3YUrIK-x{iAl;~008G9Bfg+!!5$h~TF<@p zNBc$D*}THSn$zQhuCqyjz@q{ri0Q=-f!w%j;5#QUY=2|VvK%Ve`ktzKN?qKbpW=46 z#|yoTjO6rPq!Jnk5e$DFXLuBjj{z4WUH1EZq*#m{v^de4{ zKv-bsy;qi3WAC%|oXp8E_0FMeEh7e#J zceS+@C0;1X%d@ew$Nhn{bN@ivM!cF;=J{mj&xg>8z=A_1SrxVBi&0Tk6$%Ru4IRpU zh^^D=xbP#CPE1qdQB%LLh=`+bf(@!U-*}BRqqw-(A&SR1YOgVuA}gQKRWjWg8Tp`#^Pv(n>7l)rGr+qAFJxir+fgexqY zoLx}h1jLlD8Q-Mwsr7%x<8B7Gjg5^pHTz?)Sv=J%4tL3Bt;RUBPs!Uz#l6h`hFkA= zPT5;iM@Ot>g>|INb;CsB;K9wCHx(5_)Typxj?=q;U8JvzhvqWFP?XNH+YIe*U|=Bd zLD20FDrr41(>o6vgw9?hW+S^uVn3?oOT+xNlq9J`iXCw^B53$Sl@xmgVB?Tlc{Lnd zzVIuel{Bkt4{L&ofgmJZH)dJt> zhoRn$R99Yoh9bws6*eI_zTT?5pK|+y+f0Hpi&8AV-Q?H2yuA5&^ZiAj-P7%f+~?bx znuJ_d-#&SaZOk}b)qI7WU5Vx8kk!tekMG`%!(4(c21xaEUl_uE*VK%?W84rz2{LrW zV|M?i`eNZ2zVaVb^7Ha=b{rjrm!wbbrQV~ZrG+iQQcAgBM#oDn1_e$21Csf|EWo zGvm$`k3v;=pLmV6i@9&N#0j)F68cAs7TViaA8c{0R+;5`9V`_B3>|bH@igI~P|MWb zTRAyi*&K{tz!j1H8cHny%h8@7B3CK!CNk1)u8a9hn3k=yO<%_`Kxl zqIEy?NeOXpb>J%2lHUfxN6~tw5UqXa8|C}a_>xN=w;Kp5L#MxBuwfh#_;hN2B3UP5 zO){zx@jt~YvC0hc7V;!V;-(IB( z1!rT^*4TI&#OtF0IvlcHoF~_0W;GZm&|OVt=jU%LDyDz_%tt}s9|7$jkcDoE0~;S- zS9r#gvD#vxJJNT`qMboP*RMv8we^qqFYHrzpX5A=z2vh48TG*0Z1bKg<+>8)-#^92 z(*)Opdyvjuc^D~vP*1K0yF)pLf>S@Y?=`nxX7^m4=F+JoMb7AfxOjZ&MoxiDAW>@~ zm@3vtWE#!RS9xR8b)wHc_WQ$uoV)qI+TM+O=zL<+_)DbauXo ziZZ$$=h;pFOvq_;kjBN3haxsMcG0P{cI<7E3=SJ;?HnB1*@kCmzrg@g1g>9y&ORxa zSy=c+e0gy(s=B=x}dCNJt1E zT0%ks*e?%C9OeLF9t=5;$de`Ka_g4u!s3-VEonMCJ4;ESFUqHYjzn@ybYPU>}VRvj14|2h3#bOgrgSxk~ANi@6R=uC8VH2Ow_ zAR$#t=wHT8mxe<`lZn0oYEqXCM?1mbI?Ii*YXnIcr`2ULYErevfDN5UI&{R4h}G}> zQwP6@fKF|jmm5}$#}Q}-*uJuG&c&bLaBjY7Ikr0E^A3s=jyyIaaKCpv>3$u)(fDRK zBE%h6TO?c1blZOmRz$sVphg++V~7l`O5@dcVRQW5f=7IH)D+@t)B9RrS;gE^`FWN)5 z7$Swqi|ysKzd1K@I4uB@{xq?~;T>IFufttidQMa5q4;DRJQM`tpS?|oy-z#?YZ(vO z2FKj*Jl%NU3MPx2+y3%UX`r^us7#Bm^XB$87i=1UzH|~^hhQVkeW@9Qje}dWZl#trE9VG^1a|fNXmRREbh3%~^aBV{=uNt>R^McRk zp{Gaxf{GBAc-VC&0gh`ZIFp>5z&rZQ*!&~@C>)pdG&QNn$s29s1D(VV7ITpnlbL9d z*Jy<7jQaD;nB>CZ`OUh(+nedXB>lA|=IR_LB`za25zVdJx6h&MdNGg|SC&;$_J?{H zbe*Md{Vqb-rS*O|hD2o(p#sBDCC$yvKWAo&+m2%N_o3|l`>$p$5LoG!7jH4_+ICt- zRPIIfb&#?s7P+il^c?KykbDE`^Qof5S^$cYlcCcs1cFlaGz%anhp%+b_+DBM!1w%` zzjLOtW-FN+S@U6GMEgGtvu$W*G^2mHY*E%`W@k~6maL5LlahQ-Wh++a>1V1Kmn@zI z2eWf>KDM%Q;^aQI2RAa&W4(zr(F3Xm7uQ54wrF~)>d~?}NtQ_a#&4(2>s?h_P&%%f zFPZ ?&F*pud=0>k}C{dm=lFU<-hWOQ?}#WLNC&svsMQOt~7@8ac&0Adh3K!{kgD zk)D*3!^gzL1fKl$>)YKxIRy?nljT6j{-~S?oIEkO`RfXr^ASS|7HS5d?UtL^3M<}X zyrAism1kjLR_5mK!UM3e{D9Gd=qEx$gqk@xIM6ZifTd_|Zf0gL^Vs9_9Q^r{f|gbZ zXY5x2MgsSzxrYx5niXHnr9``4q%FoQ#_3?jsM*C`OnB<^W@r`e z9~_)I%V_TUcZ`16fbR_izFKXWQxsrB_4w&rfx99iEDU5GA0L0N?(p!itgH-N(*C7w z5CLW;Cp+eVHf{1mkmT4+eY>BgcC_PtQrKf&?l9K{4wXU*uxoNMvI6ji^Ybs9KM!&l zsdVJammt9pc6Zx@{&#rj(XMokJK)b+-W0jqzt^R}jZ64eb?};G&Qo}Z?cb$qT3BxYr04W|)Whb+d?Y;yQ) z-SF`6;Nal1UtjRe@USjwMu|n$-26(TZFY9Hh|?ki9kFJ@>#n}O)b6=iGq#lV$fZmE z91n8*GtVBO0t2yb{TkYzmd-Y$B8soe+m+&wGP_IKDFp-}x0+Lvii;nl^$Zu;*0w%< zR4vgaCE4-9+x!01N}Z;BLC(Uli+bh=ktIzB%9t zBBc0H^K0m=;F!ZQv8jHv?8~X|Rk(L9jdw<8JPQ*G={yEqT}fKH2DmlIrsvL{tv+nO zWFYyOey@}fplSw!2FgFtHSZ;VK$W^60x^9Sq zsi!kK-xuVr0FJy9rZ?_u>4e>&%%v2B?aPTfo?B> zvC33gPoo=(cuNrS7vw5wR-=^q`kc0NJqx1^`>do-^h2d*dT-fgm!G#D!*6}FtoV3IB)DQ9GY)50JE~g_ zj}$&pi#)7abK@V&iA~2{3!4&L20O<*KbGX;C7h!-BsCiz-rkkBKfK$ydtv83q)s5A zfK1uYHUL@!@dsxCnx;7<>6V+Pl2WK{R*JWig9C7A&{OCgWcAl3wld+#6>&>S4G(tI zIvCM;v48!L>kXqDt;ZOZTAO&+M>bAN4P!oiDEvw6u-;_cnQ0BbunPnmnLjHQg+P~DNuhz+~#vRU*4hYn)6=%Rr z7Ft=KFeM_FCsxy?2?Ggq$m{9)Wr@jkFQE|N!JwknuIpd>DT5&XLVT-6Dor`aSwU~- zDv>6d53F7gRm+)w!o!J!_y+zAnl)oo|w5wbA6p7G=JyPu#?Nq>_3MKq;1=)UN6v))?K#e-Kr+L8P;d zRh#^s_@^)Z2`ST`T%6XnZ=F+ae{{(HmTE$;n%d@kTdS}1Q+s@qRq{2nB7LD7jseja z0R;18ZKKYXm@r8g0c9u02i`{udW|8J8=%7-jvOzI91g|%p4q~87et?7-5GvzkcX94 zB>{EwS+-B|>XtqZu408-dGHvQbc@v2vx#==)(YsDwWo8#;J~QC8YMopD z@&@@cG{*%)?$^1s6he`V_F|S!P6Oc z#?-GmHQ$ngEBa$9o3t-u!$|!iNQJo_F=?g>qw%MZJ8TZ=@9!*-Va8L)+9P07602M= zWi%x6p{1ykmu^A(fk9jew*2AJrhIu~!W|XNozOmL8Vw&AhojMzB)bFLuL-!hk~w}jpU4=DIv~ZIy9B= zU$oGUr1(-p2e*e0lZ&K(h%$XSM?Rr(dm<*}jDNx>#9#>8;1& zjo+k6_YoFoTon>@)+kE<7`W0nmS&GY_lTGm*}Z`2a}qGhfRx9pkDuXWwbz(QiY^TE z4pbGF+-^gdVSPRCQ%d5FZphzAyrS9T8(}*xf$?4p<2Ck)bk$wFba%RII)j$-#V1(kV*jdC6s?`p56R#;$%zq>`|P>7jH8DaNgg6eLR`sjkd)r8 z!A|u$-@(gTC4LrSO}e04NcHU=c*qrkaj0)6oDPL&Zl)2{4d~ki>k z?w%#O`{0}=Z=>zt(f~ljYm9YPg%(bb}l~;WHD4W%bf8X)X zK0A_6c8HGFi0TkFg`nv_@o}s}=G8xZh7=$w;GotQww`%37I!fnFC*F=P`{qn-c(pv z7?7Nr8fjtPe+m)~Zbn8%o}OZ!e<+N$_uaP_V+5>Gk)hZlQdPWRr*8S(w_^XE?6K(? zvpEkeu(8pCKNjFKAb(Alp%TYrx$uul^S|;t(4aO`|J2n96AQ@Bzg=xcJG_|J)*1v0 z)0!Ys2(F2-YjUTCmR70rimvpne}OxXKFL*~_^0@18OiOzfo8vQB}X#@GPJ5675j1? z1uK&aD9X6dj;oW{F^r;Pdz~5c#Kpyh07C-bquY>`wK?Ltzs2M&aH(jFUmFLn7?grF z8uLicfX;Xkis~~gAZ!O15*>0y>HWkhl6>l?=3_wFro6mH)Jl-3r$%axs^uMJS32(V zA@P@@xl`oE!-Io{ZTPHsR7S6mQABow01Z2n#9j)6TeF?SM(Vb2D0DPam*Q`}J{avJ z_9S&Sq^1!d6|ujsVc46T@3{ zo>3oOidNqdhEYjM(3~(lBJgg5WYNX*41*VBz33-C7?qMOzUN46M&;o5oNyIdLn066 zpBP*e0|b$W+ufdn(a#Nbo5V2Bhk$NQVnbpI_QEwBK^#SRKRS#t2ECG2wx#+D!zjb* z*nBn5jq!F$7nEE>c4KfNDQL&(=^Up^cdB`o-_L+gQRG#7Ma*xS3%PBY0+)wKI6&`4 zFpTQeT+^;3+L@m!`H(8BS3S)>`#YXB#;x)K-rrwrZ(?S~#%S~}vsf($4K7EM;zPa2 zu)I0fUAfn4J?yd3dYUXOD+AkUV%X|!@8#Fzz?CX$$4HI`A?HVO1$VM@6AUgg4h{X& z!UT#K_`$Hn;BsEU#gfBU801BtEzHfi0@q)zI9P_Dv-NOU4ANPUCQU7)Yhf!{HuPIl zQ?>@jWaAf->7oCPe6ox4pX3uh^^`xo4Cm0(wBTuwF)wymlleg{*u;=~yAH|>bog?} z!ACB^X`UV~cb}X1?OWk07cY>d^pNl5{$}o_Rc4;p16a-pHnSZ`dmA(O3QfP=kCxWS z3ly!@Rocq6I7TAj_jc?&(6LL=On{#w9O2dO4n3S2wqLG zn80NOfyUI-^erjCou&k#@$Xlfdcyx_0YytRz2c8$khJrhDy-IFwV^S|*9`dZbIB=G zb|O>80}Vt=4_bTF2!6fUquf4I%CL#=kQvUP<2A(GTRXUOm~gOGWIF+AKdkgSe8q$1 zk<8tVjyJVaf=?VCi!$D@yEc@6+ir`Uo&72wAIziS!-o<_o2t&arz#|9JD?#ZdLI`T zg&bPh_6pgV+o(sAQGfsVVi7X|X>vU-pa!!4pl#=%i9hjEvtgO>`#w86`|%^ozJ?1N zh(ERMQP+yf$`QwgKzgsDvNG+Qn&vm$-Hi}BaNw!8)wZ_gPWai^CzRK7w(`7Kgk@Q^ zK1tzoahu*NO;mIqtJSbG^C0>T+56J~b>SxDT%rD_RaTz7kfS@R{ATgB6y-g_$OVy~ zRN5j2Fk+UM@|Pir`%7%e{QBi`OzP;(b%8`xd1Cvf5dl1We0Ww+Tp(S~$H!+n_8$^Q zHNU;;%{9n1Jm#S|RUg3?)q}>|6v^zc4_UO+OZ4}*7;nG2ObhlAChKai zlUtZjlhqoHJ#vd!!*4fxa{rsPUnz3-SHIr0)c;rBHvaJ>r&lQ{v(*zJ#myoWBt0H; zed6m9vIvjcVIX_MNylpxB&bD-82!r|2XhrpE?7}_?dF~p1N)99eP%+5tm4!vNdNTd zt9kzP)Ra;TA4oNvez9T{1}TIpyEqr~aI(6_PA*6V%c!c-63-uwdyH`}tm4 zJHvrig{#UdFiCx0P$v!bj7y!H=q;S}*jTEUP2Ye1beZ~gLD=?=0PpHIS^{mxQH1DP zLr*+f+iZx<|LE-%;ktS)Ug-4}~^2-CSuL1;R(2=YqYm_}*kQ zcjX}b^$9438XC7)r@_0Pn$jtA>9i_Ll<*d3Wer4zhlIQ@G-dLC5BPtiQcwHz53|6% zkXsfND1?avg1rVf0?hiFR{q@F+*AEk=PYDJXT>o8T|gy%OeTPV@Tj4e`zE>)M@lbK zA?3TPxpkQECXKuh@~eN%j&uaATN_HgNB$(-Cc+x;d(<{HLP$93te6l-O1(&k=MQTs zeP~y_Uk!N)eLr+PVxo#@`yCzcD-Kq7e4;U~kE)ZLC~q;f*W37^BW%viCJPZ4la1Gs zhD`eq;)P6mcs)=e7MdDcFR=4EoXiX<<$9PSni(`LvO6b!6@7WW+GPl&3%2w2eqsfY zq)vXGDTFW9Df|$ExJ8{b%w>0Yi!gi)@H(PN8CJ0HWrT3J@D{Uu>Fm)bX%PfU9d+@D zWC&?Qz1?%;K~!}xOe5Zp75M_(`@2uB;m18FX>(UU{N~?c*^t#>AT$w*@%^{#AtaKS zS^jg#qs!*?%l~kBJws_5h$A8pPZg35@(iD$A&#GPo(8{91fJ`tBuK+3 zncTWx?ti}K?)$r|cVQ&on!iaVXO6ie$?dmWcdGUL?QpnUElwY1mPSEbfjG+t=sByy&1-LVWFCt12kLbn{X9v7r>nmJE0zIER` z6d!lEHZ!c)*<*VyCu*E2`PgjQGan(&F+Eq=w%OS{%_B2JujV^L8tmBrFUG7#%v9(Xr5*|labzq9H(ilWKyE)Y@yD_$paaiCAQD47G69=TBir*{~+W17zfJBU$gDh z%$;OWxIb|#BO0tMqfk#r&mD!Uw7%-d`csrg<5<WQTlWvI8li2Uj6FksJ0Y5v z05Ze|&`>Vsbldw~?r4G;kGD}WLL%q7FbgiO{RJu7=?@w!YL92LdMRFp{ZKxkYgTz zUiAZ8fLVfA>^!h-Rq1)>K|Dlpd;~;Q6Q2f=Pt)b7MtC1q6(`3k*Q;1<1E^#%TR)f` zUaPHer@(6Utla}OWNS=Qml6_! zD73uwR~0`g9R>1bC{LfkPP*2n5#LH9(hjsr?zP;90V2pBKnhreX3v4E7W*S}_Z%Q2 zr6W4?7)RyuSStX9N|%YrE*rev{6eks3j<6GA?-20 z%k087k8lCxQEU~w?_*@sjUvc8Rq*XyJVw7m06C*C%CqQHzvBuPVv+K=^`ne4^Ca#p4=M4g4lrj!E zq7<-s@t5<`K1!wY>0whq+(&?V?M0VSyMafq0=WiVg~yW{q^) ztX;sxzFF(#Mc=Ib=*=3xz}A-`8dfk|w;Nv^S{P)Blmd?kZs`q+&R?W%>0aNa^*q|Q zX?>ga{k=skkPvo@ii-X%>b^}ou}u?~c*j#0sZZ_1dEE(Y_ZJEx#8(k-fXB{D$`K>R;;RhjeE{003$Z(`o!-U;0o=e_sO{oh|^_MClYuQO|}v(}#P`__)PFf(Fj5o7@X0PIj>h!u7I z1_022nP{nR7PIAn)ajg`9@LtNiD_cmd

    I(t<*Ctpi`J<(Ru&oEMEHKe=|##U*~E z#uLGer!Qc9%#{|oX2A8-#)GcJ^(((>W%RJzoD-|vs6Ly7u~>!&=NVV20Vh2=*g|o{ zZ0EgbFp!+|b$Q%Ing2W!5io|8NE`EgJ-Khs%euO=zi zGy#4tC4PE9NH{c{a~zv)M!CT9J-X$I2C?HT`ksVA${zE_YMQPmb;yttKRx3DrM{7u z$$6KfV6YQG7!8l%m`Js7ktKC`RheH;p#i672O=#KCt5@p-Lv zM*CGSAt5ZliBE^nd@Dyxldw z+45?@=o2djl1Hapx0H&ixdvZcZ(A1o7@)*iLTa_QEQ&P~3=-E*p z|n!G_D zo~E3oCE8|A8bKo?w8OX>bsJ$*UmA`eLm%{}l)Td1nLMCbuDeBSlpc;NbxZq}@KkD&|)v`J#dNT6h=MM1m3Y?1_6c@y8nW!Vklk^qwH zX$pRqNQrrq22AtE@BC!Z9RSb(Q77Qkxqk&mHR?u_FL%WS=e4$;pPaHdE@n}ZW^!oQ zl6U${3WuJ(9x&H%PD_s3mbq=afoujfGEt&yru;gj!WG>PSXiiTM)jE7gF0uEb#h_g z#l^*y$*~E{&q2ozP6Pr$GhkiIcdk=3>}1*~^~TN#AN9PY54W|o@i_)g_gy2iRl|6t z@RSYmueEA2$3^wc;hT!5XU7}PnQv)EG5JrEel=^j?ut`OSXqf7Toe+Ts6^O+fYO;g zk&%%TRgZsL#7JDNV1 z?}VMcv9I<*y?m)fneQ_8zaW&D%SP;Eif zxMEyoW#z|@3dj3N6LjG|UTdmI%g`m)j;{^}M=PbA7uB0GI7R;m znQ4umpP%=r3|{OPUbfcW^E}V;Wm$1`HV|?T?5cvDo}R{CLuQ!ZJ+I=r;G;+V{r$DI z*Q-KK4z>!7l6hI8P4L@`d10T0nyN{`D|21wo}Qj+B)R`#x&OLru^qv&@%icMSb43( zdN1~hr)#YPsm>o^Z$B|SJY2ugfH40uaOHH=Y0kesSt^+b|GYMZ!dpX zUEtPCuJ*InLw~Ik>j!c)JAkT}9T7NyQvYLHy88gFfF1gQrcGhg(|%u`x;I zYNVoB_On_c*fu@#0@jRzN)GGKV2yU)_Fi}7RA~koY+9tk3iX`FwRUy}2bGb(m)t5O z@v*0BLC{ z;`p9OJ9;<5-TK!)Op=`NohJ_3U}0{&Irvjq6{rNJ0u`8@NMiltUDOCW6@r+JWcJLc zV-)Ykp9SKL(I4)j`#Tu9C|^H}cGcyjqEjSX61{BtVC{t|V~xHpE&3#jy;G%@k+OTL z4@1RGf$6WH{A+F{j{7W$Gr#BN-e>-}`rY<;m#+FbYO_H|+ywSOIQZ4K4YWv3MELvW z&eR9havzp%>37-4q0_OoBQABu@2+uIS2qDCX%|dK1$jk%+@##570I!*dk_YRdL75IMdJuHn+Mhe@{0irC8}3wD zOy_AvWVd>MxVMfWJf&xh83ZfKo!(h@r&Ta^qLQYV+`maPt=9JfQwXYHotn23;y)Tqq%CDM`4pv6>o`0?BA~Jgw458F} zj!TgFtE;!fuc9l%zuU@2rYn~Wm0C~JH~^+d?3=p6Xi!eOodAzAl;r*aqsxu%y-{Rg zF$m&fVaWy&Pri9j#lyDQ0|Hw@7M-4vBpQ;deuw6XGPC*QiD7r~r6kXBeZ3po7w+Xw zjg)ZbP6Zo6(8huO%xEpiJ37p_r4(JTaIS9artV$_5f+z9ua{Gg&T;tk-*e>}0?qJ< zgveaJI1`-@R-VM+3~%;dQ*+XFL$fK>mK}6DrwJpypuwN4#NI;{Dk`J`EoLIo90y{5 z1p-qz{#Ppe8&Bp}LJv|wM!RZV+u}ikpzLfoFO!Oot`T~5Lr=G8VW=OJXqXbu7mS@d zcnF5iL>Pi=zf7@WvyJ%BS3}J&s;I^Df`42m0^lADd!`<4BP^YB0&S+-N{7tw?U-(G zP_90sO3;n5>hz13ymdzHNN+7oHJbUEky^!#};`|FN?I1(+#=d@`q2&l@ zI0`n{c}@lg(dwc@eJQAczR|_zr#?zw^O^9ersGhHKT_^$x}>gKxG>ZSveE~;wbFlu zNnFL|b1SMYU&fZHdI#syHBc21f6{#%pfA4!+PY7Fk($dYuW-$yc2E-^(UiqCW-k27 zo|>kl&pnt&$&2H>?8RaHO>J%MGTYU$M|r2q?@L$l+bKn}j%UJpIZ|H3MT>vpaibxj zC)+)W$i~xsBhk>^0i9nks=PdyP2O81N$rYf%unUZw9G5v%;$dC+&`s$DSWF+&cZ|% z)4lY)xW2A#e0*F5+e@qu7-Pr_-M*%4CCBe@#hgbM!%S+w4}d&e>?ES!EVHUP8gnGa;00 zsQ)K5s8=TV<;lP&Pj;7oygv+i?(eV0o0y~FpFp50hmEkKrQ(TdWaIugf+}WsxmQ}# znC!2ssbK~dWicj%51hgp>3t7x;;l-o$EozSxv3;RM*wtJg76B5d-g<5!4(*5x}x}rwNM;eg(N%5U@o37 zqb9I$$PEOHhe+60d5T9>R8&~tcw1HTm#y?DYWt9j(sYpa1{!8`M1 z4Gm`L?!;bsj=jcYcWZ`{!m?*uZG4x(;APnLRAV`L`P(uW6pG!%z0&S+)d&AuvMb+W zIrG$gT!MmX?Fgh=zgXcwiBww$2e=SVVw+J(&8R%b!ndamqFyB)kG&7K=cz193?LI5 z!x}B5*x1X)Z$**8lje{$Kwe0#I4 z>OznAkqw6nq_5A~T(&w>B|S4Kq-Pr#8%Jr3$@};3yWnZY<8@esSyZC)ca@OiwQ6cn zPeus#lyxFvvg3MoMOm4$hDP`Lr~M6b*mMiMoqj}WYARJs+F^s0x|9(nOKpjKl-05G zC_}0m4PBqSUUjq9L4=>*4S{$@t$!cI%U3JF4+&|}raNhg7Z25mk2*Cqp4Iz#@;zN9 z3#6wM4)evqmp()#E~r2~)6_Zc4&DMwn*wEcu*xR*0@yYdRHV-k!8f1-;-^p9x{AZx zeNB5USydU@Za4G}g%$%t6TFe8uTF^2G>=Li=}X@RLNpxOEkXTCQyb29RLASEcN$BvZt>;^45&a-r6LmCzW!9e{`abND^xQdM= z%%Cj>4Oy*RZ_aU`*x+jMOk(F%RU{EB51mG&K0RQ*bgMa)1Tu7*rs4RZ$Bm97pk|*t zJTF$%T+V9UENqyz(0=<6_>II!@y>Dp4l$~ks!aLX7w=2YM9+W)0xe9?SH7{{gV8>h f-0B2zC4|vvR(4dEMtl6eT>wB0%pf22oFe`KY~c{l literal 0 HcmV?d00001 diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/common/synchronization_2.dia b/plugins/org.eclipse.dd.doc.dsf/docs/common/synchronization_2.dia new file mode 100644 index 0000000000000000000000000000000000000000..8a725e36e02f3d70927cd23d55ecac769299f4ac GIT binary patch literal 1501 zcmV<31tR(%iwFP!000001MOSeZrer>efL)o@~gAr-pJiJc915$JQQt#B+tT%TuWP1 zq(D-Z)rWq2XGx{jjk=JcP^T1N113guc7`)&4`=Cj@1G};^Q6)}`C__dQsKw`Ua?tPWndJK z?yovBoU3opKQEwmCOpQvoXsJ%gO0*!^^@&mxW6& z3um&yG)ePRnS2{^m?V)_afzCzGhH7i3seLpwlAy(Q9PJDPY$gAK}Fdy0hE{j?Y2`p zca)lNf8(xMRCt-2Fdq+|TS`~yebJKlCzF|Bq<5{}#QE9WFV5qB^X?Sv{qpsO)lhn? z+#W)qx#p*D52Kk0b#|c4)@>?0jhANqLs{RnJ2o-prH#$HfQZyWr%U%gylm6X@&+#% zXC({C@J}7&%kVy$EJ&O;&aX-E*n80&pg2r;*ZbXFPtImI;0kzeD?8KVrGz;02_`o_ zl7v#Z8TdABRKW~~n`>f?<;2Ok%JM~|Hvx1!n=Eh47NPCj z+D^(}WTu00lA6DgI9Ji$;5M|z$uK}?xe3kyQeG^Hvx-SS0~v)X4S`HQq`?j@#f`a? zA(!7^im(v8O(vzlnLuYQ;Xb=11aV@Slp~-VS`Rl!;&`Cru!yEcj8%pb`Lu2>f?4{c z2cgLz_CQy&lRymO$F8856GnMmJP3cF(lnV@_ZuM%T@NB1kM>h-)72j)bAE|#B8|Jr zL)7E=29yG29%)yZ2=4|9x^r&F%HWjtOGwBn; zT}CMONY_-YH`UKNnP~V{0A2NU`sPzIkD~ zN?Btnm6m5bBwA+DB@FR}1l?~1wnyPPfcP%1$)mZ=$bnJehD}v-6lW`Ib{oeqKR)YV zmP03g8AG*(6=yPg2ANeQ1qHhc*IsuX)Wk#!Se}Zro>R0{v4@sl{Y6Jl+Lq#KKb^jU zEzaJ_rDB6iSu@b}l03dF>tLfrZqS4wq!8kCB1W>-gz%{IsJcJAQhF{Ny#} zC#b(0j1g;@p9&ZkNy|@|At{+fm9K)H{z#J?!qLtrl`E&?r`GvtXH9ne^q=FW-*i4t z(np}D&+vSqMtaA*%s<0CS`^1FKBcWv6yUfP#}l-eM!SraWhfgBmJUzLng@8yw2UB3 zr62;6a*Ty>tJ5-$eFh2SL^6zhzdI%Gre$ZCmR)k&?>73@H+uVO5R+CIdVG~+zlXgZ zUv97eZfD5H2n=zCSMiv4g9)Of-De=c!4`)U$K4<_m=wkFoZzzM7x9_~*a?hIU~~eb z6Bw^eV0Z}lLE3lp2;-f==mbU$fg#Uu21Gq>RW9>s%cnpTmq3Ja`>sFdc80+ap)Joa z&Jbd!F*=RWX^c)|yfTeJfb*ywVo*e7H^lgVYmD;m;$IK%uh#xI@&4)`P;Ajozd!&0 DR-NLU literal 0 HcmV?d00001 diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/common/synchronization_2.png b/plugins/org.eclipse.dd.doc.dsf/docs/common/synchronization_2.png new file mode 100644 index 0000000000000000000000000000000000000000..63124ecdf1bbaf7cb07030244c378ef5487d7c9b GIT binary patch literal 6076 zcmb`LcT^K$mxn`WAqEIV2t^Gvs`M&VdWRjqJ>Tx0{q~PNXZN0SCo_|oGxOei=f2PTi`3Q8poOwSK_CzgtW&uCsk5#Y+5C~*!`py&x#QFrQdegxB&04z4L*~}mZ;MN1IXSxM zFAhF}kON&N?N&`*0!>;*IfIK-?E~qo16OC-V7~b*DbnzR{;O9n)82fxdF<#PRgcU< z*aoYrsw#qC;RMQA^`LbsdLcO?brWY+!lGT{6Tc=V*1K2N_qRiY$Ldl?QV+ZPm3&ZG zUQm$St?6_SD0*tsdzfOqOq88RiMZRHEgt@DR-C0ImqwUc3Ei>=QR+5Ia2O^sH(tG< z*b;cQoxyZPr+w_k=}!Mj(N|H|J32ZtGBOK`iw+JB#zsal(a~@fet!P)N8@S9$+FIa zpPn7>#i#IFofT~r)r!l=80qULzW!@wW@ZX9GP#_!f#+wG7g)UOs@d1YzMgnYH-)pY zvGpk(uZCY>wITn0>#>!Um5EqNIM%lpU8(|=l8TFPC22NV@)d>MYAdv;p`xPl_4O6Cs^^4Jd2LL5=JZ+UPF3cC(?#r}%1TSO z=Q$5gm7Vz~3Gc;T!D?2;;=*U+^Q(wQIMAAhg6a&vrh_>Id z_36!{?z;pmrh5Tzq;!6=y*5@Mq`|_%^3>C_V@&qZuRn+W38OTSUTYoSU)t`Gi(TrkVbpWeJ9deh2aR2=5ba!`m z42W;3Lu^TDW+o2;hHswk=)htVc;gARr4<#%r)EV%3i9%Tu9MZC+LHbmeM3V-S6uh^ z_Ky6Ov~~D&(uO{pRk+W#ot>R&qCAfGTuk#rLcpF01HldOKk)SQ^omF0`T6-rQ=#;| z=?eRc8G)V0E6dAHPELj9Rg82IVwSZgrlwek>DPeM+}p2@j*lZEB2EKtAm3M3dT&hB z0hz0Nx^~aPBAs!yJ5_T2`vv5CAUpN-0S_KrWriM}o;`mKjp|jC?0NU@9Z+wkrlyU! z;_`AMrIL~okFHlDS_xdx@E=8F-viQ#X<-;Q1ulLjFxs__YH*JcBY94&g4yC3S!~(JC z1gx(w*-z&(T*$>d!zE3 zEM%DOMr+S5>%2rL8fD07p33R(bQFwibH`G8bU3z=;}MPFFWbWNgvl`p>K4YoUipbC zdLa@hL_cw-RSI(B2%?Aqn$q>}Hb$AEn-qAI`bTK);>(|2q7qllS0psxI0)@Z8aB#u zxO@IOsdxPrPSaf2=~Ai)RNV5Jhm!*s^M!biUbJFIg^|1=?!hN6)6Gsd8KQz~OZegd zx5_xQ#6P7&{KIw+TOJI@<4vX!9`TBK3eM|ClOImk)~txBi60VgdRN>&a<|~NsbMT(hgB?9_QKhg zvhc~M@&*gM8}~AZZC9{(sOQ{q}?pqR`EuDPx?VPZI{ z5Uon(iwZk6(LPaeuSce&7dX0}3r>rhqZrCL+$)hy3pK^X+|B|7QxhE-ivCy=dHI0; z{ugNVIhx2dT5L)liSK#O>&ZJ;X^vl7Sx0s3;p5~Ia7PTWLzaHA0idq2F9U>YNcRvV zir-AF%l{c`L`-P0NvZLp=FTm8tcH9_wlXBm|7?2nj zRmb1wch5Rk$LoEkhF{1v!cAdI)}WX>p-W+YMEOQIud)(2Zw8JD3Z3?gyo3iSljA`g z4MdJ$H*gB6RMHH*QQmvW|y~(kGkezdN@f!~CWXJzOb}~h|MRRZlBNgu| z-ZW%k>Ba=jryPLTjxUPrAP2KcJqU;J?39l-Fc>keq~u~xPfr;9&}uopPyg)bWZQn> z@-mr5EI&kM*FaiUHaSW7n%BCPhX4}|!sg<0E&-c(F8Pr!zm-pJ=$-8Zz0>GRd5I8h zfNK|*adkppN4^}}5t8g4^tUD)4ja(-DoMhawE(I1%&W(3wpZ+OxdxVEw))omN# zvr9u5C3Stqn8_=I+t*&-b7qybOPO%mK*3;zQuH$Rdp0Q-g*qXgB%9VC%hgN#}`mD;F3~g;^OYFOD-O(#ak&|AG z8ii99a2yQhSjN*<-RMk6{&0MB^h(Ui($v(^^Ai?{{c&(`u<`Z0-sxw)wDaJ}<~MHt zem*M+uOP0?I0FJFKL=M@MEBe4H6K6zZVJB;29Nz#`cFWaAQFjbX=%UyVZcOAB#LJr zNtM=$U%NIkJe-n|k&&KmVQP9!LP71eZ`+vt;~NS4-Z$4? z%eWjZ0n~DKVC&=XuWXYI9#Z6QJ&{<6VXWavrP$a;_hRtBYJEy`a^_PV-o~H%{gX$$ z)<&h#Xi|Uwb zwe-%at2^zulCk5hNKQ^pNl6(NSM_-Dt(?2f?;kl~aqH{rKse27p1x32T(YWkn~vwx zcpGr!sM0<)g>!e`e8C~R(3deeGQuWZfITSire;!UnszfX8fkE0yZ3Owq+(6#i-0_$- zgwkT){?NZ3u*=%7;3~d;e$SMwR>gsF0g#y{>uNdBJ27F|*_pCXbk+a-bicspb3z5c zEc+u48Ffd?1yxm5UhBU)dU{@5x9k&_XE?W&qAEU~y$vIIwif>jX!x813{q25Grv|{ zT@93wka1yH^K=xeSmy+E@z0jj?ln7AS-mk}f9jD^} zHvySG?G!4qb8z^2yk6s4x66W@Yo@>9zx*-pc~lg)-zrfpisko-Au|w2K0aHZjBWsM z3J|N7me$-UK%Tom=|1-GunahyPqy?Gkon{N4V1}ku0Nz^Is(;*DXE+s6FO6**taM9 z+fo1bzOhzDP0SG04NMz%DfV|%gfXypF1|OMY;-RYgf(2%Hh&V}GQJ#JQp1Vhy^8(m zr)hHuVb9k1i9M1m;b4jlW0CaobMa9QwUb#i+k*yK1tr^*83%YGB_7q5ZLH)><+rmG zsQ)`N;blub9<42@ZYq^6NUX}qrn?;pk%WE^Lb_XzycW7UywuDtN``;Xyn<;MCC_ra3W^Qwd z+?Rz^R0JC8m9#X__odhT_`YfOoVYE>+>Ht2f9eZAHkNH5_B1&a(YnRbfM+N$!&VrO z@U+5`X9yBx67d*zQ+7tPlC^*d*68tOcG{#x2dx_H=SSYH76$etAeYoRVUtb34wUzc zd;>FufYu@+Tec3uK7(E&6q@ zn0)s%q%!BNs+?p6Iw^{A0t7LL`9K#Y_XAF;*%ZaR3x_(e^XgofQ_H zgwMNSApEGo#B44bog2(=TnS(l5v;!hXER2Gh$)(enfgM;g5k*s6`n}S%A52vTo}Ti z%hqDu)r(pHB*h~sN}ncbTF^H-EIR$N2W}RRHuW8*9AXQh!3w5)h!By7&!}JskFc4# z!jJkx<&F!PpgSCT2NQ+a2JiOviVzwu0#64*D^HG*I})>c*$V*>9blfMcCSLJR-lq> zyKm!vGPpO^`@#__jM8IC8}4ZwWxs=?g2<~?5gr*~Yn)wT&*aI?ye>h}b7V)_1Ixf6 z$YJRwPLnxCz_?ycfWul-iVh+FxW%W68uP_nPpBQHaX*ct=;I2RY#u6#ZN;<-l=V)M9aPmN8*k1(K{85=7pgP_3I0C8ew)X;` zR{1B%9!GFD*K;)YNZSlTew>+t&Q0m})5FB6BMkW?(scwI;E6=f@e$ni!Y(Wq<3D2_lVHFa=&&F(ZsY@G5D?$ z_!fx{YbETba9w?eSQ^4k~wcJ{?rSG`74_ zG`}Q{2vVW|v7`T=-Ft}Uj-I~{{X|+TXa}iC%ofDZKW` zIzqq5A@5E`z((D^(&1d9g4gzU1egb|cJQ8R50qzW1_|XRX)XuXZnkku`ftCu z-+q@P0Ttdnovz@uFh6f^Z*OQ|aI)QZV~fnne^brc+8WSVu-Fb@ZOoK=SB zQ4Jgd^Sqp>beQIK2VruH)sB;l59i3K!6rdp)8oo?VU)w$eD92XV^?QUH zU;agLpPJR#z2$w&wo)aRW3HPfyPzoO~oyb>crX zo>{fOvccC$?!R)5?%lh0pFO*deE;#IBOn_fU~g{(o(&UikNW?>sXl?9FfQc(RKxN3 zSNROW1f4Jm@0*&M3JXPjj@w>vC}rGHnp)_2z115Z&rmcZbh-2S@Yl8rb~s!RqbKwK zpxL+x7Z69CC1^Hit)Fgd8c?g<@CJql=r)~QT~V~EXP--MLa=x47%zLF7&pBYx4!;p zPESE$?<&kva=G4l$dh)LNku0^sm}IW3_yMo61?YV#z;VV*xcOw@^3r{%b6JqXBT0|Vw& z9+x@ktZKc9B_$FQ@sbX`NfEO58N>kH<9l>;^rugsaA*@VGocM&?-zjcfO>Y7dF%L; z>YWr?f}B}u+bHapP70n+BZirk)xpkA*tA5|bcpxfc3ekC$KarmPpjidiG2j!r34%P zi(7$a_wE7fh8Z>X8Y{`Tu)Ep`PY(V}w??u0)lC4vb4k%#_pD=S>4Bl4p^=eMKtTO; znQ%Aemii);G5O)Q(`~9CB!40azRo6^7w0Fj3SL0oV#u=8IxoDvsYAFPgpAgu8sr6G zcgQg&JTV-1l@r1m;LZ&BE4qBYO~6zXc$4QTkFG-AD&B0k_bPQ5Xo=cpPe>6dv6q}V z+U{*CbAw4QNWgYI^pPqP0!;EF1tF)%meg&6kwNe$e4D{Y(BCskm8ROj-yqt5cdnpd zBS7Q)zcwjFkeF38<$thR&@qmXLjxlVqJoiyO`Y-s51%4K*tCK%AbB`Dy2WnQY>X8A z0F3EY9c;Et7#1o6TFQN!$@|0g0u}5C8;L#NU6I0I6fo%Ug9Ji`3PTWb;hj_mukp>x zE=$Twf7hhiWu@Bk*T9%hDswb6x!iz$#KN14BJl|*whI(6IJAiAXg#Djf_E|4&Cp$s zCc~ICSTHVGBce-&vj#&=%O6J$U>o3rXy@K(yg&n-PW46EEirIGv)4s*7>Ch-ZKbt5 zI!u!I*o*wKjTVnG6M`3-EBrW1>NYhV5 - - - DSF Common Patterns - - -

    DSF Common Patterns
    -

    -

    Summary

    -

    DSF

    -
      -
    • Customizing, componentization, performance.
    • -
    -

    Asynchronous Methods

    -One of the central features of DSF is that it relies very heavily on -the use of asynchronous methods.  Asynchronous methods here mean -simply methods that use a callback -object to indicate their completion. The use of asynchronous -methods can be very contageous in a system, where if a lower level API -is composed of asynchronous methods, a higher level system which uses -those methods also has to have asynchronous methods in its interface -(or risk blocking its calling thread).
    -
    -TODO? : diagram of a layered system with asynchronous APIs
    -

    Request Monitor

    -There is a standard callback object used in DSF, the request -monitor.  A request monitor has the following features:
    -
      -
    • Executor - A -argument to the request monitor constructor allows the user to specify -what executor should be used to invoke the callback method. 
      -
    • -
    • Status - -Asynchronous methods that take a callback can always set the status -indicating the success or failure of the call.
    • -
    • Callback Methods -- The request monitor declares several protected methods which are -invoked when the callback is invoked: handleCompleted(), handleOK(), -handleError(), etc.  The users may override these methods as -needed to perform additional processing upon asynchronous method -completion.
    • -
    • Parent Request Monitor -- If the method calling an asynchronous method is itself asynchronous, -it may set its argument request monitor as the parent of the request -monitor it is creating.  The parent request monitor will be
      -automatically invoked when the lower level request monitor is completed.
    • -
    -Following is the snippet from a the "hello world" example of using a -request monitor:
    -
     26: public class AsyncHelloWorld {

    28: public static void main(String[] args) {
    29: Executor executor = ImmediateExecutor.getInstance();
    30: RequestMonitor rm = new RequestMonitor(executor, null);
    31: asyncHelloWorld(rm);
    32: }

    34: static void asyncHelloWorld(RequestMonitor rm) {
    35: System.out.println("Hello world");
    36: rm.done();
    37: }
    -
      -
    • Line 29 creates an "immediate executor".  Unlike more -sophisticated executors, the immediate executor simply invokes the -runnable it receives immediately.  It does not use any threads and -it will never throw a RejectedExecutionException.
    • -
    • Line 30 creates the request monitor.  This program does not -perform any processing after the callback is invoked, so it does not -override RequestMonitor's completion methods.
    • -
    • Line 36 marks the callback as completed and implicilty invokes -the callback method.  As a contract with the caller, the -asynchronous method has to invoke done() when its finished.  As -there is no compiler support for ensuring that the asynchronous method -completes the request monitor,  failure to do so results in common -but often suble and difficult to track down bugs.
      -
    • -
    -

    Data Request Monitor

    -The base request monitor is useful for returning status of the -asynchronous method, but they do not have an option of returning a -value to the caller.  DataRequestMonitor can be used for that -purpose. A simple example of using the data request monitor:
    -
     22: public class Async2Plus2 {

    24: public static void main(String[] args) {
    25: Executor executor = ImmediateExecutor.getInstance();
    26: DataRequestMonitor<Integer> rm =
    27: new DataRequestMonitor<Integer>(executor, null) {
    28: @Override
    29: protected void handleCompleted() {
    30: System.out.println("2 + 2 = " + getData());
    31: }
    32: };
    33: asyncAdd(2, 2, rm);
    34: }

    36: static void asyncAdd(int value1, int value2, DataRequestMonitor<Integer> rm) {
    37: rm.setData(value1 + value2);
    38: rm.done();
    39: }
    40: }
    -
      -
    • Lines 26-27 create the data request monitor using a local class -declaraion.  Note the type parameter to DataRequestMonitor allows -for compiler checking of the type when calling getData() and setData() -methods.
    • -
    • Lines 29-31 override the standard callback to print the result of -the calculation to the console.
      -
    • -
    -

    Multi-Request Monitor

    -A common problem when using asynchronous is that several asynchronous -methods need to be called in parallel, so the calling method needs to -somehow manage the completion of several request monitors.  -CountingRequestMonitor can be used for this purpose.  It is -configured such that it's done() method needs to be called a count number of times before the -callback method is invoked. 
    -The following snipped from the AsyncQuicksort example shows a simple -example of using the CountingRequestMonitor:
    -
     42:     static void asyncQuicksort(final int[] array, final int left, 
    43: final int right, RequestMonitor rm)
    44: {
    45: if (right > left) {
    46: int pivot = left;
    47: int newPivot = partition(array, left, right, pivot);
    48: printArray(array, left, right, newPivot);
    49:
    50: CountingRequestMonitor countingRm = new CountingRequestMonitor(fgExecutor, rm);
    51: asyncQuicksort(array, left, newPivot - 1, countingRm);
    52: asyncQuicksort(array, newPivot + 1, right, countingRm);
    53: countingRm.setDoneCount(2);
    54: } else {
    55: rm.done();
    56: }
    57: }
    -
      -
    • Line 50 creates the CountingRequestMonitor.  Note that the -parent request monitor is set to the request monitor from the -asyncQuicksort() argument.  This parent request monitor is -automatically called when the counting request monitor is completed.
    • -
    • Lines 51 and 52, use the same instance of counting request -monitor when calling the sub-routine.  Each sub-routine will call -done() on the counting request monitor.
    • -
    • Line 53 sets the count to the number of sub-routines called with -the counting request monitor.  Note that the done count can be set -after calling the sub-routines, because the counting request monitor -will not be completed until the count is set.
      -
    • -
    • Line 55 Don't forget to complete the request monitor in all -execution paths!
      -
    • -
    -

    Non-Executor Thread

    -

    Future

    -

    Query

    -

    Concurrency Annotations
    -

    -

    Services

    -

    OSGi

    -

    Session

    -

    Tracker

    -

    Data Model

    -

    View Model

    -

    Adapter, Provider, Node

    -

    Timers

    - - From f4f4a354742c1d9deb585aca9c851a78ff43590f Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Sat, 1 Mar 2008 00:49:46 +0000 Subject: [PATCH 279/834] [221027] Added a listener to automatically shut down the executor thread when the display is disposed. --- .../dd/dsf/ui/concurrent/DisplayDsfExecutor.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/DisplayDsfExecutor.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/DisplayDsfExecutor.java index ddede1c2a5f..9a50763d173 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/DisplayDsfExecutor.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/DisplayDsfExecutor.java @@ -26,6 +26,8 @@ import org.eclipse.dd.dsf.concurrent.DsfExecutable; import org.eclipse.swt.SWT; import org.eclipse.swt.SWTException; import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; /** * DSF executor which uses the display thread to run the submitted runnables @@ -61,10 +63,16 @@ public class DisplayDsfExecutor extends DefaultDsfExecutor */ private final Display fDisplay; - private DisplayDsfExecutor(Display display) { super("Display DSF Executor"); //$NON-NLS-1$ fDisplay = display; + fDisplay.addListener(SWT.Dispose, new Listener() { + public void handleEvent(Event event) { + if (event.type == SWT.Dispose) { + DisplayDsfExecutor.super.shutdownNow(); + } + } + }); } /** @@ -151,7 +159,7 @@ public class DisplayDsfExecutor extends DefaultDsfExecutor }); } catch (SWTException swtException) { if (swtException.code == SWT.ERROR_DEVICE_DISPOSED) { - DisplayDsfExecutor.super.shutdown(); + DisplayDsfExecutor.super.shutdownNow(); } } } From 90f4dc4c71c3d819bff3d785635d47bed662ea52 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Sat, 1 Mar 2008 00:51:12 +0000 Subject: [PATCH 280/834] [220446] Updated the "DSF Common Patterns" document. --- .../.externalToolBuilders/PreProcessor.launch | 7 +- .../dsf/dataviewer/AsyncDataViewer.java | 6 + .../dataviewer/DataGeneratorWithExecutor.java | 56 ++-- .../dsf/dataviewer/IDataGenerator.java | 6 +- .../dsf/dataviewer/SyncDataViewer.java | 11 + .../doc-files/dsf_concurrency_model-1.png | Bin 6256 -> 0 bytes .../dd/examples/dsf/dataviewer/package.html | 289 ------------------ .../dsf/requestmonitor/AsyncHelloWorld.java | 7 +- .../dsf/requestmonitor/AsyncQuicksort.java | 45 +-- 9 files changed, 88 insertions(+), 339 deletions(-) delete mode 100644 plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/doc-files/dsf_concurrency_model-1.png delete mode 100644 plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/package.html diff --git a/plugins/org.eclipse.dd.examples.dsf/.externalToolBuilders/PreProcessor.launch b/plugins/org.eclipse.dd.examples.dsf/.externalToolBuilders/PreProcessor.launch index 948b857d441..ed027e9bf2d 100644 --- a/plugins/org.eclipse.dd.examples.dsf/.externalToolBuilders/PreProcessor.launch +++ b/plugins/org.eclipse.dd.examples.dsf/.externalToolBuilders/PreProcessor.launch @@ -3,16 +3,17 @@ - + - + + - + diff --git a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/AsyncDataViewer.java b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/AsyncDataViewer.java index 72feab635da..35f928b0b64 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/AsyncDataViewer.java +++ b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/AsyncDataViewer.java @@ -21,6 +21,8 @@ import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; +import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; +import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfExecutor; import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; @@ -51,10 +53,12 @@ import org.eclipse.swt.widgets.Table; * to check the canceled state of the requests and ignore them. *

    */ +@ConfinedToDsfExecutor("fDisplayExecutor") public class AsyncDataViewer implements ILazyContentProvider, IDataGenerator.Listener { // Executor to use instead of Display.asyncExec(). + @ThreadSafe final private DsfExecutor fDisplayExecutor; // The viewer and generator that this content provider using. @@ -106,10 +110,12 @@ public class AsyncDataViewer return Math.min((table.getBounds().height / table.getItemHeight()) + 2, itemCount - top); } + @ThreadSafe public void countChanged() { queryItemCount(); } + @ThreadSafe public void valuesChanged(final Set indexes) { // Mark the changed items in table viewer as dirty, this will // trigger update requests for these indexes if they are diff --git a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithExecutor.java b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithExecutor.java index fb70c5e15a4..d667b2810d4 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithExecutor.java +++ b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithExecutor.java @@ -50,7 +50,7 @@ import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; *

    */ //#ifdef excercises -// TODO Excercise 3 - Add an annotationindicating allowed concurrency access +// TODO Excercise 4 - Add an annotationindicating allowed concurrency access //#else //#@ThreadSafe //#endif @@ -59,7 +59,8 @@ public class DataGeneratorWithExecutor implements IDataGenerator { // Request objects are used to serialize the interface calls into objects // which can then be pushed into a queue. //#ifdef excercises - // TODO Excercise 3 - Add an annotationindicating allowed concurrency access + // TODO Excercise 4 - Add an annotationindicating allowed concurrency access + // Hint: Request and its subclasses have all their fields declared as final. //#else //# @Immutable //#endif @@ -72,7 +73,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { } //#ifdef excercises - // TODO Excercise 3 - Add an annotationindicating allowed concurrency access + // TODO Excercise 4 - Add an annotationindicating allowed concurrency access //#else //# @Immutable //#endif @@ -83,7 +84,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { } //#ifdef excercises - // TODO Excercise 3 - Add an annotationindicating allowed concurrency access + // TODO Excercise 4 - Add an annotationindicating allowed concurrency access //#else //# @Immutable //#endif @@ -97,7 +98,10 @@ public class DataGeneratorWithExecutor implements IDataGenerator { // The executor used to access all internal data of the generator. //#ifdef excercises - // TODO Excercise 3 - Add an annotation indicating allowed concurrency access + // TODO Excercise 4 - Add an annotation indicating allowed concurrency access + // Hint: If a member does not have an annotation, the programmer can assume + // that the concurrency rule that applies to the class also applies to this + // member. //#endif private DsfExecutor fExecutor; @@ -106,7 +110,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { // method reads from it. // The executor used to access all internal data of the generator. //#ifdef excercises - // TODO Excercise 3 - Add an annotationindicating allowed concurrency access + // TODO Excercise 4 - Add an annotationindicating allowed concurrency access //#else //# @ConfinedToDsfExecutor("fExecutor") //#endif @@ -115,7 +119,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { // List of listeners is not synchronized, it also has to be accessed // using the executor. //#ifdef excercises - // TODO Excercise 3 - Add an annotationindicating allowed concurrency access + // TODO Excercise 4 - Add an annotationindicating allowed concurrency access //#else //# @ConfinedToDsfExecutor("fExecutor") //#endif @@ -123,7 +127,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { // Current number of elements in this generator. //#ifdef excercises - // TODO Excercise 3 - Add an annotationindicating allowed concurrency access + // TODO Excercise 4 - Add an annotationindicating allowed concurrency access //#else //# @ConfinedToDsfExecutor("fExecutor") //#endif @@ -131,7 +135,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { // Counter used to determine when to reset the element count. //#ifdef excercises - // TODO Excercise 3 - Add an annotationindicating allowed concurrency access + // TODO Excercise 4 - Add an annotationindicating allowed concurrency access //#else //# @ConfinedToDsfExecutor("fExecutor") //#endif @@ -139,7 +143,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { // Elements which were modified since the last reset. //#ifdef excercises - // TODO Excercise 3 - Add an annotationindicating allowed concurrency access + // TODO Excercise 4 - Add an annotationindicating allowed concurrency access //#else //# @ConfinedToDsfExecutor("fExecutor") //#endif @@ -147,14 +151,14 @@ public class DataGeneratorWithExecutor implements IDataGenerator { // Flag used to ensure that requests are processed sequentially. //#ifdef excercises - // TODO Excercise 3 - Add an annotationindicating allowed concurrency access + // TODO Excercise 4 - Add an annotationindicating allowed concurrency access //#else //# @ConfinedToDsfExecutor("fExecutor") //#endif private boolean fServiceQueueInProgress = false; //#ifdef excercises - // TODO Excercise 3 - Add an annotation indicating allowed concurrency access + // TODO Excercise 4 - Add an annotation indicating allowed concurrency access //#endif public DataGeneratorWithExecutor() { // Create the executor @@ -173,7 +177,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { } //#ifdef excercises - // TODO Excercise 3 - Add an annotation indicating allowed concurrency access + // TODO Excercise 4 - Add an annotation indicating allowed concurrency access //#endif public void shutdown(final RequestMonitor rm) { try { @@ -199,7 +203,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { } //#ifdef excercises - // TODO Excercise 3 - Add an annotation indicating allowed concurrency access + // TODO Excercise 4 - Add an annotation indicating allowed concurrency access //#endif public void getCount(final DataRequestMonitor rm) { try { @@ -216,7 +220,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { } //#ifdef excercises - // TODO Excercise 3 - Add an annotation indicating allowed concurrency access + // TODO Excercise 4 - Add an annotation indicating allowed concurrency access //#endif public void getValue(final int index, final DataRequestMonitor rm) { try { @@ -233,7 +237,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { } //#ifdef excercises - // TODO Excercise 3 - Add an annotation indicating allowed concurrency access + // TODO Excercise 4 - Add an annotation indicating allowed concurrency access //#endif public void addListener(final Listener listener) { try { @@ -246,7 +250,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { } //#ifdef excercises - // TODO Excercise 3 - Add an annotation indicating allowed concurrency access + // TODO Excercise 4 - Add an annotation indicating allowed concurrency access //#endif public void removeListener(final Listener listener) { try { @@ -260,14 +264,18 @@ public class DataGeneratorWithExecutor implements IDataGenerator { // Main processing function of this generator. //#ifdef excercises - // TODO Excercise 3 - Add an annotationindicating allowed concurrency access + // TODO Excercise 4 - Add an annotationindicating allowed concurrency access //#else //# @ConfinedToDsfExecutor("fExecutor") //#endif private void serviceQueue() { //#ifdef excercises - // TODO Excercise 4 - Add logic to discard requests from queue. + // TODO Excercise 3 - Add logic to discard requests from queue. + // Hint: Since serviceQueue() is called using the executor, and the + // fQueue list can only be modified when running in the executor + // thread. This method can safely iterate and modify fQueue without + // risk of race conditions or concurrent modification exceptions. //#else //# for (Iterator requestItr = fQueue.iterator(); requestItr.hasNext();) { //# Request request = requestItr.next(); @@ -311,7 +319,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { } //#ifdef excercises - // TODO Excercise 3 - Add an annotationindicating allowed concurrency access + // TODO Excercise 4 - Add an annotationindicating allowed concurrency access //#else //# @ConfinedToDsfExecutor("fExecutor") //#endif @@ -324,7 +332,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { } //#ifdef excercises - // TODO Excercise 3 - Add an annotationindicating allowed concurrency access + // TODO Excercise 4 - Add an annotationindicating allowed concurrency access //#else //# @ConfinedToDsfExecutor("fExecutor") //#endif @@ -344,7 +352,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { * This method simulates changes in the supplier's data set. */ //#ifdef excercises - // TODO Excercise 3 - Add an annotationindicating allowed concurrency access + // TODO Excercise 4 - Add an annotationindicating allowed concurrency access //#else //# @ConfinedToDsfExecutor("fExecutor") //#endif @@ -362,7 +370,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { * Calculates new size for provider's data set. */ //#ifdef excercises - // TODO Excercise 3 - Add an annotationindicating allowed concurrency access + // TODO Excercise 4 - Add an annotationindicating allowed concurrency access //#else //# @ConfinedToDsfExecutor("fExecutor") //#endif @@ -384,7 +392,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { * Invalidates a random range of indexes. */ //#ifdef excercises - // TODO Excercise 3 - Add an annotationindicating allowed concurrency access + // TODO Excercise 4 - Add an annotationindicating allowed concurrency access //#else //# @ConfinedToDsfExecutor("fExecutor") //#endif diff --git a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/IDataGenerator.java b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/IDataGenerator.java index e31c0edb981..e3eb61bc6b1 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/IDataGenerator.java +++ b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/IDataGenerator.java @@ -18,7 +18,9 @@ import java.util.Set; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.concurrent.ThreadSafe; +//#ifdef answers +//#import org.eclipse.dd.dsf.concurrent.ThreadSafe; +//#endif /** * Data generator is simple source of data used to populate the example table @@ -28,7 +30,7 @@ import org.eclipse.dd.dsf.concurrent.ThreadSafe; * is changed. */ //#ifdef excercises -//TODO Excercise 3 - Add an annotationindicating allowed concurrency access +//TODO Excercise 4 - Add an annotationindicating allowed concurrency access //#else //#@ThreadSafe //#endif diff --git a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/SyncDataViewer.java b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/SyncDataViewer.java index f0c4c20729e..91e52cee3f9 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/SyncDataViewer.java +++ b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/SyncDataViewer.java @@ -122,6 +122,12 @@ public class SyncDataViewer } private void refreshViewer() { + //#ifdef excercises + // TODO Excercise 5 - Add a call to getElements() to force a deadlock. + //#else +//# getElements(null); + //#endif + // This method may be called on any thread, switch to the display // thread before calling the viewer. Display display = fViewer.getControl().getDisplay(); @@ -148,7 +154,12 @@ public class SyncDataViewer tableViewer.getControl().setLayoutData(data); // Create the data generator. + //#ifdef excercises + // TODO Excercise 5 - Use the DataGeneratorWithExecutor() instead. final IDataGenerator generator = new DataGeneratorWithThread(); + //#else +//# final IDataGenerator generator = new DataGeneratorWithExecutor(); + //#endif // Create the content provider which will populate the viewer. SyncDataViewer contentProvider = new SyncDataViewer(tableViewer, generator); diff --git a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/doc-files/dsf_concurrency_model-1.png b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/doc-files/dsf_concurrency_model-1.png deleted file mode 100644 index 1bb373447d7bd0f17cd54f8298fc6f65658c8420..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6256 zcmb7IXH-*Nvra<5D1dv zrDzaB2SJe=-}hVJk9&XJv(_nlpPAWn=FB{MX5x(vb)nZ-t^oi5s2=RL2><{JBR)q! zK*TG%I*&f_26odh&;S7HQ^J1TODB%6`ogRN0045@zb6p4_~kZU?c` z%=YG5e(+_`D3-r6fDIHE_W)^gCW$PQFC;a=@elm|^<$>?@g6w@0OSOKBLLKv5nWXH zuZ+|HkUHS+WE~*#F~iRY@_*kFXID-uUE1vI_LNpR85OSoOC&)Rc?+XF1{C3l?i$-z zDSAL7^jE-&0$3gUG1Jqri*qr4rAOxPTv3}H8NK?-nFfh3aYS4qG8ke%@iKNNI7E5M)_@JV>mW2sXncXP&W*nXvO^PVoj0 z+-Ks*L|JKDTDj2NVY?GM?wTIzQ7!D*nS`0@aDnFAB}Q(f|B#N#}f z{RaI?y}2?TknigAm8Q42&nfojJASl~d7;k45sY_`sai_+a48AbX4N`j-{B~olEKj% zx5{7JxgX+?Z`#)TiG?T)>8plI)WCj_5IwAsYnwESad$}*duu9867zDg$RTW!y=Y|Z zCc-J$B~99-EZpUnm)#0e)7y5%jp$fE!+lB~BsBnE(|raL--4{Ly}pqA+-+bXCfPK% zb0cHKYMLJQ=05ZJ!Jy;peY!7jTxMt)RwTsRU8mpbi^R$Ck!X`~D+|l}B>4f#CiXE9 z1J;o4&mc9+<}L7V3{s?HYp?joiH?7ff3iAG^u};Q`qDIoGQR(SLO2Vj;fcFC*^*(!7tR1a`o;)cS$F(@l`552e3Gj*|)pUeJ>#AGsSJPHqeYg3vLGa73 zjbM1t$GLayiDTQ_C-t3V-@*^trD;F(*MIr8CeEjpgao)6j!f!0#d zS=VKFEN3Cy02~w)6g98PV{cH(juXA*0-ssd?A@Z``F6a{61Lg@IKgElOut0uD;S?r zbn3Sls?+u2ZXTwxLupgD@!S3DqaNe3Kb^HhYuHx8ymx-5MWHS%5&Xe_SADZp()_t% z3<@fke~H}7ebGbnA@Y#Mg@u9^qYPQep4w#wBBe6z3R?O$O8ngU*4_(Ax027SNGm5^ z?2vrBK+3Rl!Gdn|j#94&QvR%+>=_#P6N$zVZaSWlWv zCD0%heIfOn&z%MBmY@{a*#X^%wTclFPb#$H**i5&`J`uvR-9%OCsQ&@N|*#D=iKV^ z2mfdW7^AAOw*3{HSIR5hB0;&(xpOq@)76p$SssVAgP1Zk=9bQ?cUPWbDbjZpLHI|t zrS8nK@^^F|qJD@LP9e%vFs3Hq<$S$25HM_FS->n?q4@f)Zf5QGD`%+;+0*T9E)G;v zuBizw1B8PdbfZvAkHQ!w#R(k|boic}$(kZCLowNsL+dA|Ut+hJZwo&5wT4zqTotRO zqlR@C%`S5J(Km+HCt} z00qwFSFEja>2on&IXMoe2Qhk2vB;D^mYx;n`dxn>_7FTU!oo0{avf|%)=h2Zo!0_- zGjf(4(6U|K9E3v1b*{(MM1YJ+Xi}QA!xqN?2^0K6 zMiMdtS0vyif}7rTfjvJzZO!Q0-kiH~W?PKVGUDB(jR@f?e?tNK4yRh%ZltPbBZfS| z_^E+YonAJLTY%}Si7am>m*IifrrPxc3;CzYMXcfEQohL_6+L=#yDF$nMe8U zm{m2W&$U|Xi&dGr%^ux|@#|b;Q1Npe$iMDoKHV}0#4nler-TvxTrd}>swY--&<_YL zuBZ#QsDPCTzTZ~ITE*9ex2yp~7)SJjgI9cKBLT1$lBzGaZz+N%8Dj)J{<}@un11nTO5e@UL@Lw&!u>2oI+p3pC-?#_h9%DmTl>*A9y&arSCc=Bw-b)MI z%!gQ$C^s%mt&!yRaUvLP3g-zWmgnaYCa_yyw3*}AtE?O3 zM?3aKHTQ!$iJIg>NK-_BxFi2yp+0s?*)G-Fn|$dnD#=W9b@9j8)H3)Iw6|}ciKh|{ z=d=C*%>KX{)&)8wj`Rlsj!88{d?kC>%UZay4?_lvGQ=moHgP`g)aT0dMuckvD-u~60Gedr}qAH z0TQZEHt8L}w9K_=Yy4d*&Ezd(GR)b(eoKExdj{c`LOwRym@TD&U6WP)+_S9)mvpGr z%a>H>ALM=BzM}WWP&B4y)`S}`b-;(G)O4a~5QF6G*~6QW)5|8adRVw8Ev3sc3-FMB zaiN%1`-m~6aJchw436S*%^Vzgs;E>_6#GH(HQGR6678jfqc3`d99c*bWZdKS4I=n4n;9w}*-|e0x@= ztrosDie|dPdFe^dlC7%!BlB@hHgOtsQjZk#k!^LQRVPz}t@w%ns{?bdFnK+T4frvE zCoiI&X5u;5)a)H@ZRDF5)tQAf)o&v`1n$j{ZEA~9qoIu!A*jd+iq7VD-isId;wng45%l9U*cAACz)7wq&(u)=I*n7O znU!wl(d-+^;xySGJzq;s7B~?MXurW(xU0ON=R9|9QiO$J4-rCENdJKlyKbvMp>I^J zag}#%TdU-Q7hekqo(y4rc)qm!*w-lc{;fiqB3#7w#oEEnVB?*K!U8>MvDaJlA79!N zIhD+^^Zj?T!GhUPvZi#@&c^N0uwz$yaOYK|gberPiPRTJsIv03n`HIUtXOvE6=!AB zlk->P45gLm49Vv@l-WvmokSNi{f9{#mx{sj#ToVb+7IaTABp~O{d_E6FmItV7Jxnf zb$R%TtgC8geBdf3apJ%XjD9dKJIj)L&JRmBhWbN)pjYX{9$3~3t3XJ;v4#LJp<0h?7HDK4k_cR{N9w0+$>4) z*e%pIhj;u)x6+J856qDBPaxf8YQcKHX7tl-XmRHHNc5CKiOVl0g?+!5ypSmxz^FXx z3T(z~Lz${q)k;~qNw1~tlMBbJn!eSvWg0WHseg62c{MZZ`z=sj4U&79#{XpX#)#KL0;D|-3mgI>EH!bA3Qw^28AAgJD zkCLC?DloJRY)0KO%zx>)yV)?dQ_Waocg8X*t89@jw#a0{@C4c#b`w*z$r|sFOdvYO z9{3-}NRl)V*F$XVc~Tm7uHhAUPW!gYl)eZaAH$TQJd1%iGtP?R`e?OEiV-C*USFf> zQ)d>W#6KI@oqj8|ZJ}6OerGs)$anuOx4unH6~c^Dca({~Ebkk)gD{`C#0~O6*@Tz( zV)_*+v4=80iV_VbcL!w16!zj*rz@xKU{PL06Zw?#uBI1T^@q2I)UxTn=R5a|&{%)X zu)~PG=EY~bik3Adjlh!Y0ov+cjkPlM831!y^HP7r;QNkD%<;G-j)md@HNkWEmBXrlHxU=oVx5f*#(hmb5OS zDsvE63(?+pGF+_Q;cQJbWGSABMWpe6Y0cjwwP=JZvbKhd3yI(ey!*SD*9_b2$9 zM2EDnsI}~%qMku1l~jVTE*@SsLgVY<7{?0nj8{MGo5S2;RLCRq2z^yAKByfWeJK!o zChwEUHkaTo-q*ZrokEr=C-0d`$kO$iDSE+UKhs6SNUcB%JnoxAa)cjRt=(+Sz3%Y} zo1p^l$%=+6bbQdmmF`E+XDdiBj#RmO7EEr_TdI60tvq*W|5RPyz&7_DqI4CQ>P?#} zK?1ggtn|INSF#mIM~&^|1n|^0-PhL<)S9m=_M? zj=|Pfc)Fr!og>s4Kni|VFoLIB9BL;p-772OZ2hQgyO`E4;H`5v?7$UVYLbB!96S$9 z6HBxuO)*hUsZ|s*Kf|c9ggv)s)() zH+D;3zj9U^8^aw4xA}3Q$DCIq^Y#C7D&Se}a4qgojHWuGR-F=>!ta&P83CF$a4Cat z)0BC3v3fA)$-GEw`s0zvGC@g@ihu?g#F;CCF8k^FDEcd=HNZShloXg0LC@p>hA7Z< z#Rq@_8<}9I-w#Hh>^$~j9d(r8KRN(@LQD#=J7m0JpTY#xSSca{YZ8@zYOj3vDkjvj z+dL+brjFL@Cx~bi`6B@AG)Cx3KpzAGx+2R-tqI^41AlSQ=UnW))+}Y46p{I$myx_+|SdY)$LjthE7D?%jw&8y?fW_p&*9!`(hL+Ye|bK!84^s?`jQZi{@VXhxh8v>2V6F=WL=l+t> zJu&`ceqOu}Go>;!&Uc~kxJl~3+}W3GUEW`HE}QhWSUT{yMW{`v6SsZswxRP)jK_I= zhG6JHUit>1$};ot{?|q5?%W)I3Lw+xdxrDjOQ@7wHnKIYVq;$uYO-{oA})0|ZOV@C zdoVXiIj|%~D6&GaX}=aY^zlk?C*qerR9&;IB51=fR7cc6`lmHN)3(~f6*{8@`}@_1{;i*QPQ zyHjVNec=`GxQThO(@}p{bWM^_p7&n(*H9gd34mN70Q8;)Wm@1nx!-a z;n~gWGFKhJRkv9?A^?U9P*nh~{ncRi4N1_GE)6Ioni$aJ-RK-z*lFF9Y6?akd*1my z(!XneCw~3kGAfRS8cgY-&KV6bw1qVHW~gIhuY0<@V*(0)juGdKpbOHXia`04`%CC1 zMR58WlYqF0+?sW4rC^+DmA!CpKg2R#E(}P-?*C?Lj$m+P6bm(kh-ZvXb|iRH2@a$- z%wjrS`i-mPM0{EtC*fRVt++8v!@~)=F&Uu_A#ziD#tPywzYgg;BLF&G4rR=%>?r`( zQC`Tn+Qr4?M8Eid+wk^4BHWO2_LBamQy;lZbc)Yc{_V#DzzoEHfdI=a0D%8;{N!*+ W(|ar%1~vi^4?S(e+clc@PyPove1psY diff --git a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/package.html b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/package.html deleted file mode 100644 index f0efe705346..00000000000 --- a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/package.html +++ /dev/null @@ -1,289 +0,0 @@ - - - - - DSF Slow Data Provider Example - - -

    Version -1.0
    -Pawel Piech
    -© 2006, Wind River Systems.  Release -under EPL version 1.0.

    -

    Slow Data Provider Example

    -The point of DSF concurrency can be most easily explained through -a practical example.  Suppose there is a viewer which needs to -show data that originates from a remote "provider".  There is a -considerable delay in transmitting the data to and from the provider, -and some delay in processing the data.  The viewer is a -lazy-loading table, which means that it request information only about -items that are visible on the screen, and as the table is scrolled, new -requests for data are generated.  The diagram below illustrates -the -logical relationship between components:
    -
    -.
    -

    In detail, these components look like this:

    -

    -Table Viewer
    -

    The table viewer is the standard -org.eclipse.jface.viewers.TableViewer, -created with SWT.VIRTUAL -flag.  It has an associated content -provider, SlowDataProviderContentProvider) which handles all the -interactions with the data provider.  The lazy content provider -operates in a very simple cycle:

    -
      -
    1. Table viewer tells content provider that the input has changed by -calling IContentProvider.inputChanged().  -This means that the content provider has to query initial state of the -data.
    2. -
    3. Next the content provider tells the viewer how many elements -there are, by calling TableViewer.setItemCount().
    4. -
    5. At this point, the table resizes, and it requests data values for -items that are visible.  So for each visible item it calls: ILazyContentProvider.updateElement().
    6. -
    7. After calculating the value, the content provider tells the table -what the value is, by calling TableViewer.replace().
    8. -
    9. If the data ever changes, the content provider tells the table to -rerequest the data, by calling TableViewer.clear().
    10. -
    -Table viewer operates in the -SWT display thread, which means that the content provider must switch -from the display thread to the DSF dispatch thread, whenever it is -called by the table viewer, as in the example below:
    -
        public void updateElement(final int index) {
    assert fTableViewer != null;
    if (fDataProvider == null) return;

    fDataProvider.getExecutor().execute(
    new Runnable() { public void run() {
    // Must check again, in case disposed while redispatching.
    if (fDataProvider == null) return;

    queryItemData(index);
    }});
    }
    -Likewise, when the content provider calls the table viewer, it also has -to switch back into the display thread as in following example, when -the content provider receives an event from the data provider, that an -item value has changed.
    -
        public void dataChanged(final Set<Integer> indexes) {
    // Check for dispose.
    if (fDataProvider == null) return;

    // Clear changed items in table viewer.
    if (fTableViewer != null) {
    final TableViewer tableViewer = fTableViewer;
    tableViewer.getTable().getDisplay().asyncExec(
    new Runnable() { public void run() {
    // Check again if table wasn't disposed when
    // switching to the display thread.
    if (tableViewer.getTable().isDisposed()) return; // disposed
    for (Integer index : indexes) {
    tableViewer.clear(index);
    }
    }});
    }
    }
    -All of this switching back and forth between threads makes the code -look a lot more complicated than it really is, and it takes some -getting used to, but this is the price to be paid for multi-threading. -Whether the participants use semaphores or the dispatch thread, the -logic is equally complicated, and we believe that using a single -dispatch thread, makes the synchronization very explicit and thus less -error-prone.
    -

    Data Provider Service

    -

    The data provider service interface, DataProvider, is very similar -to that of the lazy content provider.  It has methods to:

    -
      -
    • get item count
    • -
    • get a value for given item
    • -
    • register as listener for changes in data count and data values
    • -
    -But this is a DSF interface, and all methods must be called on the -service's dispatch thread.  For this reason, the DataProvider interface returns -an instance of DsfExecutor, -which must be used with the interface.
    -

    Slow Data Provider

    -

    The data provider is actually implemented as a thread which is an -inner class of SlowDataProvider -service.  The provider thread -communicates with the service by reading Request objects from a shared -queue, and by posting Runnable objects directly to the DsfExecutor but -with a simulated transmission delay.  Separately, an additional -flag is also used to control the shutdown of the provider thread.

    -To simulate a real back end, the data provider randomly invalidates a -set of items and notifies the listeners to update themselves.  It -also periodically invalidates the whole table and forces the clients to -requery all items.
    -

    Data and Control Flow
    -

    -This can be described in following steps:
    -
      -
    1. The table viewer requests data for an item at a given index (SlowDataProviderContentProvider.updateElement).
      -
    2. -
    3. The table viewer's content provider executes a Runnable in the DSF -dispatch thread and calls the data provider interface (SlowDataProviderContentProvider.queryItemData).
    4. -
    5. Data provider service creates a Request object, and files it in a -queue (SlowDataProvider.getItem).
    6. -
    7. Data provider thread de-queues the Request object and acts on it, -calculating the value (ProviderThread.processItemRequest).
    8. -
    9. Data provider thread schedules the calculation result to be -posted with DSF executor (SlowDataProvider.java:185).
    10. -
    11. The RequestMonitor callback sets the result data in the table -viewer (SlowDataProviderContentProvider.java:167).
      -
    12. -
    -

    Running the example and full sources

    -This example is implemented in the org.eclipse.dd.examples.dsf -plugin, in the org.eclipse.dd.examples.dsf.concurrent -package. 
    -
    -To run the example:
    -
      -
    1. Build the test plugin (along with the org.eclipse.dsdp.DSF plugin) -and launch the PDE. 
      -
    2. -
    3. Make sure to add the DSF -Tests action set to your current perspective.
    4. -
    5. From the main menu, select DSF -Tests -> Slow Data Provider.
    6. -
    7. A dialog will open and after a delay it will populate with data.
    8. -
    9. Scroll and resize dialog and observe the update behavior.
    10. -
    -

    Initial Notes
    -

    -This example is supposed to be representative of a typical embedded -debugger design problem.  Embedded debuggers are often slow in -retrieving and processing data, and can sometimes be accessed through a -relatively slow data channel, such as serial port or JTAG -connection.  But as such, this basic example presents a couple -of major usability problems
    -
      -
    1. The data provider service interface mirrors the table's content -provider interface, in that it has a method to retrieve a single piece -of data at a time.  The result of this is visible to the user as -lines of data are filled in one-by-one in the table.  However, -most debugger back ends are in fact capable of retrieving data in -batches and are much more efficient at it than retrieving data items -one-by-one.
    2. -
    3. When scrolling quickly through the table, the requests are -generated by the table viewer for items which are quickly scrolled out -of view, but the service still queues them up and calculates them in -the order they were received.  As a result, it takes a very long -time for the table to be populated with data at the location where the -user is looking. 
      -
    4. -
    -These two problems are very common in creating UI for embedded -debugging, and there are common patterns which can be used to solve -these problems in DSF services.
    -

    Coalescing

    -Coalescing many single-item requests into fewer multi-item requests is -the surest way to improve performance in communication with a remote -debugger, although it's not necessarily the simplest.  There are -two basic patterns in which coalescing is achieved:
    -
      -
    1. The back end provides an interface for retrieving data in large -chunks.  So when the service implementation receives a request for -a single item, it retrieves a whole chunk of data, returns the single -item, and stores the rest of the data in a local cache.
    2. -
    3. The back end providers an interface for retrieving data in -variable size chunks.  When the service implementation receives a -request for a single item, it buffers the request, and waits for other -requests to come in.  After a delay, the service clears the buffer -and submits a request for the combined items to the data provider.
    4. -
    -In practice, a combination of the two patterns is needed, but for -purpose of an example, we implemented the second pattern in the -"Input-Coalescing Slow Data Provider" (InputCoalescingSlowDataProvider.java).  -
    -

    Input Buffer

    -

    The main feature of this pattern is a buffer for holding the -requests before sending them to the data provider.  In this -example the user requests are buffered in two arrays: fGetItemIndexesBuffer and fGetItemRequestMonitorsBuffer.  The -DataProvider.getItem() -implementation is changed as follows:

    -
        public void getItem(final int index, final DataRequestMonitor<String> rm) {
    // Schedule a buffer-servicing call, if one is needed.
    if (fGetItemRequestMonitorsBuffer.isEmpty()) {
    fExecutor.schedule(
    new Runnable() { public void run() {
    fileBufferedRequests();
    }},
    COALESCING_DELAY_TIME,
    TimeUnit.MILLISECONDS);
    }

    // Add the call data to the buffer.
    // Note: it doesn't matter that the items were added to the buffer
    // after the buffer-servicing request was scheduled. This is because
    // the buffers are guaranteed not to be modified until this dispatch
    // cycle is over.
    fGetItemIndexesBuffer.add(index);
    fGetItemRequestMonitorsBuffer.add(rm);
    }

    -And method that services the buffer looks like this:
    -
        public void fileBufferedRequests() { 
    // Remove a number of getItem() calls from the buffer, and combine them
    // into a request.
    int numToCoalesce = Math.min(fGetItemIndexesBuffer.size(), COALESCING_COUNT_LIMIT);
    final ItemRequest request = new ItemRequest(new Integer[numToCoalesce], new DataRequestMonitor[numToCoalesce]);
    for (int i = 0; i < numToCoalesce; i++) {
    request.fIndexes[i] = fGetItemIndexesBuffer.remove(0);
    request.fDones[i] = fGetItemRequestMonitorsBuffer.remove(0);
    }

    // Queue the coalesced request, with the appropriate transmission delay.
    fQueue.add(request);

    // If there are still calls left in the buffer, execute another
    // buffer-servicing call, but without any delay.
    if (!fGetItemIndexesBuffer.isEmpty()) {
    fExecutor.execute(new Runnable() { public void run() {
    fileBufferedRequests();
    }});
    }
    }
    -The most interesting feature of this implementation is the fact that -there are no semaphores anywhere to control access to the input -buffers.  Even though the buffers are serviced with a delay and -multiple clients can call the getItem() -method, the use of a single -dispatch thread prevents any race conditions that could corrupt the -buffer data.  In real-world implementations, the buffers and -caches that need to be used are far more sophisticated with much more -complicated logic, and this is where managing access to them using the -dispatch thread is ever more important.
    -

    Cancellability

    -

    Table Viewer

    -

    -Unlike coalescing, which can be implemented entirely within the -service, cancellability requires that the client be modified as well -to take advantage of this capability.  For the table viewer -content provider, this means that additional features have to be -added.  In CancellingSlowDataProviderContentProvider.java -ILazyContentProvider.updateElement() -was changes as follows:
    -
        public void updateElement(final int index) {
    assert fTableViewer != null;
    if (fDataProvider == null) return;

    // Calculate the visible index range.
    final int topIdx = fTableViewer.getTable().getTopIndex();
    final int botIdx = topIdx + getVisibleItemCount(topIdx);

    fCancelCallsPending.incrementAndGet();
    fDataProvider.getExecutor().execute(
    new Runnable() { public void run() {
    // Must check again, in case disposed while redispatching.
    if (fDataProvider == null || fTableViewer.getTable().isDisposed()) return;
    if (index >= topIdx && index <= botIdx) {
    queryItemData(index);
    }
    cancelStaleRequests(topIdx, botIdx);
    }});
    }
    -Now the client keeps track of the requests it made to the service in fItemDataDones, and above, cancelStaleRequests() iterates -through all the outstanding requests and cancels the ones that are no -longer in the visible range.
    -

    Data Provider Service

    -

    -

    The data provider implementation -(CancellableInputCoalescingSlowDataProvider.java), -builds on top of the -coalescing data provider.  To make the canceling feature useful, -the data provider service has to limit the size of the request -queue.  This is because in this example which simulates -communication with a target and once requests are filed into the -request -queue, they cannot be canceled, just like a client can't cancel -request once it sends them over a socket.  So instead, if a flood -of getItem() -calls comes in, the service has to hold most of them in the coalescing -buffer in case the client decides to cancel them.  Therefore the -fileBufferedRequests() -method includes a simple check before servicing -the buffer, and if the request queue is full, the buffer servicing call -is delayed.

    -
            if (fQueue.size() >= REQUEST_QUEUE_SIZE_LIMIT) {
    if (fGetItemIndexesBuffer.isEmpty()) {
    fExecutor.schedule(
    new Runnable() { public void run() {
    fileBufferedRequests();
    }},
    REQUEST_BUFFER_FULL_RETRY_DELAY,
    TimeUnit.MILLISECONDS);
    }
    return;
    }
    -Beyond this change, the only other significant change is that before -the requests are queued, they are checked for cancellation.
    -

    Final Notes
    -

    -The example given here is fairly simplistic, and chances are that the -same example could be implemented using semaphores and free threading -with perhaps fewer lines of code.  But what we have found is that -as the problem gets bigger, the amount of -features in the data provider increases, the state of the -communication protocol gets more complicated, and the number of modules -needed in the service layer increases, using free threading and -semaphores does not safely scale.  Using a dispatch thread for -synchronization certainly doesn't make the inherent problems of the -system less complicated, but it does help eliminate the race conditions -and deadlocks from the overall system.
    -

    Coalescing and Cancellability are both optimizations.  Neither -of these optimizations affected the original interface of the service, -and one of them only needed a service-side modification.  But as -with all optimizations, it is often better to first make sure that the -whole system is working correctly and then add optimizations where they -can make the biggest difference in user experience. 

    -

    The above examples of optimizations can take many forms, and as -mentioned with coalescing, caching data that is retrieved from the data -provider is the most common form of data coalescing.  For -cancellation, many services in DSF build on top of other services, -which means that even a low-level service can cause a higher -level service to retrieve data, while another event might cause it to -cancel those requests.  The perfect example of this is a Variables -service, which is responsible for calculating the value of expressions -shown in the Variables view.  The Variables service reacts to the -Run Control service, which issues a suspended event and then requests a -set of variables to be evaluated by the debugger back end.  But as -soon as a resumed event is issued by Run Control, the Variables service -needs to cancel  the pending evaluation requests.
    -

    -
    -
    - - diff --git a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/requestmonitor/AsyncHelloWorld.java b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/requestmonitor/AsyncHelloWorld.java index b2272f97533..d7f08ea312e 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/requestmonitor/AsyncHelloWorld.java +++ b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/requestmonitor/AsyncHelloWorld.java @@ -38,7 +38,12 @@ public class AsyncHelloWorld { static void asyncHelloWorld(RequestMonitor rm) { System.out.println("Hello world"); //#ifdef excercises - // TODO Exercise 1: - Call the second async. "Hello world 2" method. + // TODO Exercise 1: - Call the second async. "Hello world 2" method. + // Hint: Calling an asynchronous method requires passing to it a + // request monitor. A new request monitor can be constructed with + // a parent RequestMonitor as an argument argument. The parent gets + // completed automatically when the lower level request monitor is + // completed. rm.done(); //#else //# RequestMonitor rm2 = new RequestMonitor(ImmediateExecutor.getInstance(), rm); diff --git a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/requestmonitor/AsyncQuicksort.java b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/requestmonitor/AsyncQuicksort.java index 21f861e6a87..f1ff70d406c 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/requestmonitor/AsyncQuicksort.java +++ b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/requestmonitor/AsyncQuicksort.java @@ -34,7 +34,7 @@ public class AsyncQuicksort { public static void main(String[] args) { final int[] array = {5, 7, 8, 3, 2, 1, 9, 5, 4}; - + System.out.println("To sort: " + Arrays.toString(array)); asyncQuicksort( array, 0, array.length - 1, @@ -51,16 +51,19 @@ public class AsyncQuicksort { { if (right > left) { int pivot = left; - //#ifdef excercises - // TODO: Request Monitors Exercise 2 - Convert partition to an async. method. - int newPivot = partition(array, left, right, pivot); - printArray(array, left, right, newPivot); - - CountingRequestMonitor countingRm = new CountingRequestMonitor(fgExecutor, rm); - asyncQuicksort(array, left, newPivot - 1, countingRm); - asyncQuicksort(array, newPivot + 1, right, countingRm); - countingRm.setDoneCount(2); - //#else + //#ifdef excercises + // TODO: Exercise 2 - Convert the call to partition into an + // asynchronous call to asyncPartition(). + // Hint: The rest of the code below should be executed inside + // the DataRequestMonitor.handleCompleted() overriding method. + int newPivot = partition(array, left, right, pivot); + printArray(array, left, right, newPivot); + + CountingRequestMonitor countingRm = new CountingRequestMonitor(fgExecutor, rm); + asyncQuicksort(array, left, newPivot - 1, countingRm); + asyncQuicksort(array, newPivot + 1, right, countingRm); + countingRm.setDoneCount(2); + //#else //# asyncPartition( //# array, left, right, pivot, //# new DataRequestMonitor(fgExecutor, rm) { @@ -75,15 +78,16 @@ public class AsyncQuicksort { //# countingRm.setDoneCount(2); //# } //# }); - //#endif - + //#endif } else { rm.done(); } } - + //#ifdef excercises // TODO Exercise 2 - Convert partition to an asynchronous method. + // Hint: a DataRequestMonitor should be used to carry the + // return value to the caller. static int partition(int[] array, int left, int right, int pivot) //#else //# static void asyncPartition(int[] array, int left, int right, int pivot, DataRequestMonitor rm) @@ -103,16 +107,17 @@ public class AsyncQuicksort { } array[right] = array[store]; array[store] = pivotValue; - + //#ifdef excercises - // TODO: Request Monitors Exercise 2 - Convert partition to an async. method. + // TODO: Request Monitors Exercise 2 - Return the data to caller using + // a request monitor. return store; //#else -//# rm.setData(store); -//# rm.done(); + //# rm.setData(store); + //# rm.done(); //#endif } - + static void printArray(int[] array, int left, int right, int pivot) { StringBuffer buffer = new StringBuffer(); for (int i = 0; i < array.length; i++ ) { @@ -133,7 +138,7 @@ public class AsyncQuicksort { buffer.append(' '); } } - + System.out.println(buffer); } } From 8868398cc994f54985dfc66faa011dbb010261c1 Mon Sep 17 00:00:00 2001 From: Francois Chouinard Date: Sat, 1 Mar 2008 20:21:08 +0000 Subject: [PATCH 281/834] Committing patches for bugs 159946 (disassembly) and 214546 (memory monitor persistence). --- .../dd/dsf/debug/model/DsfMemoryBlock.java | 15 +- .../debug/model/DsfMemoryBlockRetrieval.java | 242 ++++++- .../dd/dsf/debug/service/IDisassembly.java | 91 +++ .../dd/dsf/debug/service/IInstruction.java | 51 ++ .../dsf/debug/service/IMixedInstruction.java | 34 + .../dd/gdb/launching/GdbLaunchDelegate.java | 5 +- .../dd/gdb/launching/LaunchSequence.java | 5 + .../dd/gdb/launching/ShutdownSequence.java | 6 + .../service/command/GDBControlDMContext.java | 3 +- .../eclipse/dd/mi/service/MIDisassembly.java | 200 ++++++ .../command/commands/MIDataDisassemble.java | 93 +++ .../command/output/MIDataDisassembleInfo.java | 164 +++++ .../service/command/output/MIInstruction.java | 130 ++++ .../command/output/MIMixedInstruction.java | 97 +++ .../data/launch/bin/BreakpointTestApp.exe | Bin 0 -> 40081 bytes .../data/launch/bin/ExpressionTestApp.exe | Bin 0 -> 16978 bytes .../data/launch/bin/GDBMIGenericTestApp.exe | Bin 0 -> 9451 bytes .../data/launch/bin/MemoryTestApp.exe | Bin 0 -> 39820 bytes .../data/launch/bin/MultiThread.exe | Bin 0 -> 8979 bytes .../data/launch/bin/SpecialTestApp.exe | Bin 0 -> 9446 bytes .../dd/tests/gdb/MIDisassemblyTest.java | 592 ++++++++++++++++++ .../tests/gdb/launching/LaunchSequence.java | 5 + .../tests/gdb/launching/ShutdownSequence.java | 2 + .../gdb/launching/TestLaunchDelegate.java | 5 +- tests/.project | 11 + 25 files changed, 1708 insertions(+), 43 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IDisassembly.java create mode 100644 plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IInstruction.java create mode 100644 plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMixedInstruction.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIDisassembly.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIDataDisassemble.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIDataDisassembleInfo.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIInstruction.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIMixedInstruction.java create mode 100755 plugins/org.eclipse.dd.tests.gdb/data/launch/bin/BreakpointTestApp.exe create mode 100755 plugins/org.eclipse.dd.tests.gdb/data/launch/bin/ExpressionTestApp.exe create mode 100755 plugins/org.eclipse.dd.tests.gdb/data/launch/bin/GDBMIGenericTestApp.exe create mode 100755 plugins/org.eclipse.dd.tests.gdb/data/launch/bin/MemoryTestApp.exe create mode 100755 plugins/org.eclipse.dd.tests.gdb/data/launch/bin/MultiThread.exe create mode 100755 plugins/org.eclipse.dd.tests.gdb/data/launch/bin/SpecialTestApp.exe create mode 100644 plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIDisassemblyTest.java create mode 100644 tests/.project diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java index 9fabdab6f67..b114acad5ce 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java @@ -58,6 +58,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens private BigInteger fBlockAddress; private int fLength; + private int fWordSize; private MemoryByte[] fBlock; private ArrayList fConnections = new ArrayList(); @@ -72,9 +73,10 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens * @param modelId - * @param expression - the displayed expression in the UI * @param address - the actual memory block start address - * @param length - the memory block length (could be 0) + * @param word_size - the number of bytes per address + * @param length - the requested block length (could be 0) */ - DsfMemoryBlock(DsfMemoryBlockRetrieval retrieval, String modelId, String expression, BigInteger address, long length) { + DsfMemoryBlock(DsfMemoryBlockRetrieval retrieval, String modelId, String expression, BigInteger address, int word_size, long length) { fLaunch = retrieval.getLaunch(); fDebugTarget = retrieval.getDebugTarget(); @@ -85,6 +87,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens // Current block information fBlockAddress = address; + fWordSize = word_size; fLength = (int) length; fBlock = null; @@ -413,7 +416,6 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens // For the IAddress interface final Addr64 address = new Addr64(bigAddress); - final int word_size = 1; // Use a Query to synchronize the downstream calls Query query = new Query() { @@ -423,7 +425,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens if (memoryService != null) { // Go for it memoryService.getMemory( - fRetrieval.getContext(), address, 0, word_size, (int) length, + fRetrieval.getContext(), address, 0, fWordSize, (int) length, new DataRequestMonitor(fRetrieval.getExecutor(), drm) { @Override protected void handleOK() { @@ -460,9 +462,8 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens // For the IAddress interface final Addr64 address = new Addr64(fBaseAddress); - final int word_size = 1; - // Use a Query to synchronise the downstream calls + // Use a Query to synchronize the downstream calls Query query = new Query() { @Override protected void execute(final DataRequestMonitor drm) { @@ -470,7 +471,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens if (memoryService != null) { // Go for it memoryService.setMemory( - fRetrieval.getContext(), address, offset, word_size, bytes.length, bytes, + fRetrieval.getContext(), address, offset, fWordSize, bytes.length, bytes, new RequestMonitor(fRetrieval.getExecutor(), null)); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java index 5095a8c35ca..bd0c65652f2 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java @@ -15,8 +15,11 @@ package org.eclipse.dd.dsf.debug.model; import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.ExecutionException; +import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.PlatformObject; @@ -36,8 +39,12 @@ import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryDMContext; import org.eclipse.dd.dsf.service.DsfServices; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.dsf.service.DsfSession.SessionEndedListener; import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.debug.core.model.IDebugTarget; import org.eclipse.debug.core.model.IMemoryBlock; import org.eclipse.debug.core.model.IMemoryBlockExtension; @@ -45,6 +52,10 @@ import org.eclipse.debug.core.model.IMemoryBlockRetrievalExtension; import org.osgi.framework.BundleContext; import org.osgi.framework.InvalidSyntaxException; import org.osgi.util.tracker.ServiceTracker; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; /** * Implementation of memory access API of the Eclipse standard debug model. @@ -62,15 +73,24 @@ import org.osgi.util.tracker.ServiceTracker; * code will still be functional after some trivial adjustments. * */ -public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBlockRetrievalExtension +public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBlockRetrievalExtension, SessionEndedListener { - private final String fModelId; - private final DsfSession fSession; - private final DsfExecutor fExecutor; - private IMemoryDMContext fContext; - private final ServiceTracker fMemoryServiceTracker; - private final ServiceTracker fExpressionServiceTracker; + private final String fModelId; + private final DsfSession fSession; + private final DsfExecutor fExecutor; + private final IMemoryDMContext fContext; + private final String fContextString; + private final ServiceTracker fMemoryServiceTracker; + private final ServiceTracker fExpressionServiceTracker; + private final ILaunchConfiguration fLaunchConfig; + private final ILaunch fLaunch; + private final IDebugTarget fDebugTarget; + private final boolean fSupportsValueModification; + private final boolean fSupportBaseAddressModification; + private final int fAddressSize; + private final int fWordSize; // Number of bytes per address + /** * Constructor * @@ -78,11 +98,23 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl * @param dmc * @throws DebugException */ - public DsfMemoryBlockRetrieval(String modelId, IMemoryDMContext dmc) throws DebugException { + public DsfMemoryBlockRetrieval(String modelId, ILaunchConfiguration config, IMemoryDMContext dmc) throws DebugException { - fModelId = modelId; - fContext = dmc; - fSession = DsfSession.getSession(fContext.getSessionId()); + // DSF stuff + fModelId = modelId; + fContext = dmc; + + // FIXME: Currently memory contexts are differentiated by sessionID + // so there is no way to guarantee the memory blocks will be reinstated + // in the correct memory space. + // Need a way to create deterministically the context ID from a unique + // target, ideally from the launch configuration (or derived from it). + // For the time being, just put some constant. This will work until we + // support multiple targets in the same launch. + // fContextString = fContext.toString(); + fContextString = "Context string"; //$NON-NLS-1$ + + fSession = DsfSession.getSession(fContext.getSessionId()); if (fSession == null) { throw new IllegalArgumentException( "Session for context " + fContext + " is not active"); //$NON-NLS-1$ //$NON-NLS-2$ @@ -94,7 +126,7 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl // amalgamated one because it is less error prone (and we are lazy). // Create a tracker for the MemoryService - String memoryServiceFilter = DsfServices.createServiceFilter( IMemory.class, dmc.getSessionId() ); + String memoryServiceFilter = DsfServices.createServiceFilter(IMemory.class, dmc.getSessionId()); try { fMemoryServiceTracker = new ServiceTracker( @@ -124,11 +156,160 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl "Error creating service filter.", e)); //$NON-NLS-1$ } fExpressionServiceTracker.open(); + + // Launch configuration information + fLaunchConfig = config; + fLaunch = null; + fDebugTarget = null; + fAddressSize = 4; // Get this from the launch configuration + fWordSize = 1; // Get this from the launch configuration + fSupportsValueModification = true; // Get this from the launch configuration + fSupportBaseAddressModification = false; // Get this from the launch configuration + + // So we are notified on exit and can save the memory blocks + DsfSession.addSessionEndedListener(this); } - // //////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + // Memory monitors persistence + /////////////////////////////////////////////////////////////////////////// + + /* + * In the launch configuration file, the memory block entry is structured + * as follows (note: this differs from CDI): + * + * + * + * + * + * ... + * + * ... + * + * ... + * " + * /> + */ + + //------------------------------------------------------------------------- + // Memory blocks memento tags + //------------------------------------------------------------------------- + + // These 2 really belong in the DSF launch configuration class... + private static final String DSF_LAUNCH_ID = "org.eclipse.dsf.launch"; //$NON-NLS-1$ + private static final String ATTR_DEBUGGER_MEMORY_BLOCKS = DSF_LAUNCH_ID + ".MEMORY_BLOCKS"; //$NON-NLS-1$ + + private static final String MEMORY_BLOCK_EXPRESSION_LIST = "memoryBlockExpressionList"; //$NON-NLS-1$ + private static final String ATTR_EXPRESSION_LIST_CONTEXT = "context"; //$NON-NLS-1$ + private static final String MEMORY_BLOCK_EXPRESSION = "memoryBlockExpression"; //$NON-NLS-1$ + private static final String ATTR_MEMORY_BLOCK_EXPR_LABEL = "label"; //$NON-NLS-1$ + private static final String ATTR_MEMORY_BLOCK_EXPR_ADDRESS = "address"; //$NON-NLS-1$ + + //------------------------------------------------------------------------- + // Install persisted memory monitors + //------------------------------------------------------------------------- + + /** + * Restore the memory monitors from the memento in the launch configuration + */ + public void initialize() { + try { + final String memento = fLaunchConfig.getAttribute(ATTR_DEBUGGER_MEMORY_BLOCKS, ""); //$NON-NLS-1$ + if (memento != null && memento.trim().length() != 0) { + // Submit the runnable to install the monitors on dispatch thread. + getExecutor().submit(new Runnable() { + public void run() { + try { + createBlocksFromConfiguration(memento); + } catch (CoreException e) { + DsfDebugPlugin.getDefault().getLog().log(e.getStatus()); + } + } + }); + } + } catch (CoreException e) { + DsfDebugPlugin.getDefault().getLog().log(e.getStatus()); + } + } + + private void createBlocksFromConfiguration(String memento) throws CoreException { + + // Parse the memento and validate its type + Element root = DebugPlugin.parseDocument(memento); + if (!root.getNodeName().equalsIgnoreCase(MEMORY_BLOCK_EXPRESSION_LIST)) { + IStatus status = new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, DebugPlugin.INTERNAL_ERROR, + "Memory monitor initialization: invalid memento", null);//$NON-NLS-1$ + throw new CoreException(status); + } + + // Process the block list specific to this memory context + // FIXME: We only process the first entry... + if (root.getAttribute(ATTR_EXPRESSION_LIST_CONTEXT).equals(fContextString)) { + List blocks = new ArrayList(); + NodeList expressionList = root.getChildNodes(); + int length = expressionList.getLength(); + for (int i = 0; i < length; ++i) { + Node node = expressionList.item(i); + if (node.getNodeType() == Node.ELEMENT_NODE) { + Element entry = (Element) node; + if (entry.getNodeName().equalsIgnoreCase(MEMORY_BLOCK_EXPRESSION)) { + String label = entry.getAttribute(ATTR_MEMORY_BLOCK_EXPR_LABEL); + String address = entry.getAttribute(ATTR_MEMORY_BLOCK_EXPR_ADDRESS); + BigInteger blockAddress = new BigInteger(address); + DsfMemoryBlock block = new DsfMemoryBlock(this, fModelId, label, blockAddress, fWordSize, 0); + blocks.add(block); + } + } + } + DebugPlugin.getDefault().getMemoryBlockManager().addMemoryBlocks( blocks.toArray(new IMemoryBlock[blocks.size()])); + } + } + + /** + * On session exit, save the memory blocks in the launch configuration + */ + public void sessionEnded(DsfSession session) { + DsfSession.removeSessionEndedListener(this); + saveMemoryBlocks(); + } + + // FIXME: Each retrieval overwrites the previous one :-( + // FIXME: Racing condition :-( - synchronize on launch config enough? + // FIXME: Make it a Job? + public void saveMemoryBlocks() { + try { + ILaunchConfigurationWorkingCopy wc = fLaunchConfig.getWorkingCopy(); + wc.setAttribute(ATTR_DEBUGGER_MEMORY_BLOCKS, getMemento()); + wc.doSave(); + } + catch( CoreException e ) { + DsfDebugPlugin.getDefault().getLog().log(e.getStatus()); + } + } + + public String getMemento() throws CoreException { + IMemoryBlock[] blocks = DebugPlugin.getDefault().getMemoryBlockManager().getMemoryBlocks(this); + Document document = DebugPlugin.newDocument(); + Element expressionList = document.createElement(MEMORY_BLOCK_EXPRESSION_LIST); + expressionList.setAttribute(ATTR_EXPRESSION_LIST_CONTEXT, fContextString); + for (IMemoryBlock block : blocks) { + if (block instanceof IMemoryBlockExtension) { + IMemoryBlockExtension memoryBlock = (IMemoryBlockExtension) block; + Element expression = document.createElement(MEMORY_BLOCK_EXPRESSION); + expression.setAttribute(ATTR_MEMORY_BLOCK_EXPR_LABEL, memoryBlock.getExpression()); + expression.setAttribute(ATTR_MEMORY_BLOCK_EXPR_ADDRESS, memoryBlock.getBigBaseAddress().toString()); + expressionList.appendChild(expression); + } + } + document.appendChild(expressionList); + return DebugPlugin.serializeDocument(document); + } + + /////////////////////////////////////////////////////////////////////////// // Accessors - // //////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// public DsfSession getSession() { return fSession; @@ -146,38 +327,37 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl return fMemoryServiceTracker; } - // //////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// // Launch/Target specific information - // To be completed - // //////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// public ILaunch getLaunch() { - return null; + return fLaunch; } public IDebugTarget getDebugTarget() { - return null; + return fDebugTarget; } public int getAddressSize() { - return 4; + return fAddressSize; } public int getAddressableSize() { - return 1; + return fWordSize; } public boolean supportsValueModification() { - return true; + return fSupportsValueModification; } public boolean supportBaseAddressModification() { - return false; + return fSupportBaseAddressModification; } - // //////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// // IMemoryBlockRetrieval - obsoleted by IMemoryBlockRetrievalExtension - // //////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// /* * (non-Javadoc) @@ -198,12 +378,12 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl // The expression to display in the rendering tab (in hex by convention) // Put here for the sake of completeness (not used with IMemoryBlockExtension) String expression = "0x" + Long.toHexString(startAddress); //$NON-NLS-1$ - return new DsfMemoryBlock(this, fModelId, expression, BigInteger.valueOf(startAddress), length); + return new DsfMemoryBlock(this, fModelId, expression, BigInteger.valueOf(startAddress), fWordSize, length); } - // //////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// // IMemoryBlockRetrievalExtension - // //////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// /* * (non-Javadoc) @@ -277,12 +457,12 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl * the memory request cache should save the day. */ - return new DsfMemoryBlock(this, fModelId, expression, blockAddress, 0); + return new DsfMemoryBlock(this, fModelId, expression, blockAddress, fWordSize, 0); } - // //////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// // Helper functions - // //////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// private BigInteger resolveMemoryAddress(final IDMContext idmContext, final String expression) throws DebugException { diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IDisassembly.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IDisassembly.java new file mode 100644 index 00000000000..aa90f393975 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IDisassembly.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (c) 2008 Ericsson 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: + * Ericsson - initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.dsf.debug.service; + +import java.math.BigInteger; + +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.service.IDsfService; + +/** + * Disassembly service interface + */ +public interface IDisassembly extends IDsfService { + + public interface IDisassemblyDMContext extends IDMContext {} + + /** + * Gets the disassembled code from an address range. + * If [startAddress] == null, disassemble from the instruction pointer. + * + * @param context Context of the disassembly code + * @param startAddress Beginning address + * @param endAddress End address + * @param drm Disassembled code + */ + public void getInstructions( + IDisassemblyDMContext context, + BigInteger startAddress, + BigInteger endAddress, + DataRequestMonitor drm); + + /** + * Gets the disassembled code from a file location. + * If [lines] == -1, the whole function is disassembled. + * + * @param context Context of the disassembly code + * @param filename File to disassemble + * @param linenum Line number within the file + * @param lines Number of lines of disassembled code to produce + * @param drm Disassembled code + */ + public void getInstructions( + IDisassemblyDMContext context, + String filename, + int linenum, + int lines, + DataRequestMonitor drm); + + /** + * Gets the mixed disassembled code from an address range. + * If [startAddress] == null, disassemble from the instruction pointer. + * + * @param context Context of the disassembly code + * @param startAddress Beginning address + * @param endAddress End address + * @param drm Disassembled code + */ + public void getMixedInstructions( + IDisassemblyDMContext context, + BigInteger startAddress, + BigInteger endAddress, + DataRequestMonitor drm); + + /** + * Gets the mixed disassembled code from a file location. + * If [lines] == -1, the whole function is disassembled. + * + * @param context Context of the disassembly code + * @param filename File to disassemble + * @param linenum Line number within the file + * @param lines Number of lines of disassembled code to produce + * @param drm Disassembled code + */ + public void getMixedInstructions( + IDisassemblyDMContext context, + String filename, + int linenum, + int lines, + DataRequestMonitor drm); + +} diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IInstruction.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IInstruction.java new file mode 100644 index 00000000000..c51e8ae0542 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IInstruction.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2008 Ericsson 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: + * Ericsson - initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.dsf.debug.service; + +import java.math.BigInteger; + +/** + * Represents an assembly instruction + */ +public interface IInstruction { + + /** + * @return the instruction address. + */ + BigInteger getAdress(); + + /** + * @return the function name. + */ + String getFuntionName(); + + /** + * @return the offset of this machine instruction + */ + long getOffset(); + + /** + * @return the instruction. + */ + String getInstruction(); + + /** + * @return the opcode + */ + String getOpcode(); + + /** + * @return any arguments to the instruction + */ + String getArgs(); + +} diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMixedInstruction.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMixedInstruction.java new file mode 100644 index 00000000000..ab93679003b --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IMixedInstruction.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2008 Ericsson 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: + * Ericsson - initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.dsf.debug.service; + +/** + * Represents the assembly instruction(s) corresponding to a source line + */ +public interface IMixedInstruction { + + /** + * @return the file name + */ + String getFileName(); + + /** + * @return the line Number. + */ + int getLineNumber(); + + /** + * @return the array of instruction. + */ + IInstruction[] getInstructions(); + +} diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunchDelegate.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunchDelegate.java index ae3f5ff78ee..3824fecf5ec 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunchDelegate.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunchDelegate.java @@ -88,7 +88,7 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate } } - private void launchLocalDebugSession( ILaunchConfiguration config, ILaunch l, IProgressMonitor monitor ) throws CoreException { + private void launchLocalDebugSession( final ILaunchConfiguration config, ILaunch l, IProgressMonitor monitor ) throws CoreException { if ( monitor.isCanceled() ) { return; } @@ -154,8 +154,9 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate GDBControl gdbControl = tracker.getService(GDBControl.class); if (gdbControl != null) { IMemoryBlockRetrieval memRetrieval = new DsfMemoryBlockRetrieval( - GDB_DEBUG_MODEL_ID, (IMemoryDMContext)gdbControl.getControlDMContext()); + GDB_DEBUG_MODEL_ID, config, (IMemoryDMContext)gdbControl.getControlDMContext()); launch.getSession().registerModelAdapter(IMemoryBlockRetrieval.class, memRetrieval); + ((DsfMemoryBlockRetrieval) memRetrieval).initialize(); } tracker.dispose(); return null; diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/LaunchSequence.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/LaunchSequence.java index 040e7d3a975..240bc0ba787 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/LaunchSequence.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/LaunchSequence.java @@ -33,6 +33,7 @@ import org.eclipse.dd.mi.service.CSourceLookup; import org.eclipse.dd.mi.service.ExpressionService; import org.eclipse.dd.mi.service.MIBreakpoints; import org.eclipse.dd.mi.service.MIBreakpointsManager; +import org.eclipse.dd.mi.service.MIDisassembly; import org.eclipse.dd.mi.service.MIMemory; import org.eclipse.dd.mi.service.MIModules; import org.eclipse.dd.mi.service.MIRegisters; @@ -121,6 +122,10 @@ public class LaunchSequence extends Sequence { public void execute(RequestMonitor requestMonitor) { new MIRegisters(fSession).initialize(requestMonitor); }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new MIDisassembly(fSession).initialize(requestMonitor); + }}, /* * If needed, insert breakpoint at main and run to it. */ diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/ShutdownSequence.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/ShutdownSequence.java index b902a74bd80..e0dbd93c59a 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/ShutdownSequence.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/ShutdownSequence.java @@ -24,6 +24,7 @@ import org.eclipse.dd.mi.service.CSourceLookup; import org.eclipse.dd.mi.service.ExpressionService; import org.eclipse.dd.mi.service.MIBreakpoints; import org.eclipse.dd.mi.service.MIBreakpointsManager; +import org.eclipse.dd.mi.service.MIDisassembly; import org.eclipse.dd.mi.service.MIMemory; import org.eclipse.dd.mi.service.MIModules; import org.eclipse.dd.mi.service.MIRegisters; @@ -63,6 +64,11 @@ public class ShutdownSequence extends Sequence { fTracker = null; requestMonitor.done(); } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(MIDisassembly.class, requestMonitor); + } }, new Step() { @Override public void execute(RequestMonitor requestMonitor) { diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControlDMContext.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControlDMContext.java index 808536dfd15..ea3741e6e81 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControlDMContext.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControlDMContext.java @@ -11,6 +11,7 @@ package org.eclipse.dd.gdb.service.command; import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; +import org.eclipse.dd.dsf.debug.service.IDisassembly.IDisassemblyDMContext; import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryDMContext; import org.eclipse.dd.dsf.debug.service.IModules.ISymbolDMContext; import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; @@ -23,7 +24,7 @@ import org.eclipse.dd.mi.service.command.MIControlDMContext; */ public class GDBControlDMContext extends MIControlDMContext implements IContainerDMContext, ISymbolDMContext, IMemoryDMContext, IBreakpointsTargetDMContext, ISourceLookupDMContext, - ISignalsDMContext + ISignalsDMContext, IDisassemblyDMContext { public GDBControlDMContext(String sessionId, String commandControlId) { diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIDisassembly.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIDisassembly.java new file mode 100644 index 00000000000..b8cad253a70 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIDisassembly.java @@ -0,0 +1,200 @@ +/******************************************************************************* + * Copyright (c) 2008 Ericsson 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: + * Ericsson - initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service; + +import java.math.BigInteger; +import java.util.Hashtable; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.debug.service.IDisassembly; +import org.eclipse.dd.dsf.debug.service.IInstruction; +import org.eclipse.dd.dsf.debug.service.IMixedInstruction; +import org.eclipse.dd.dsf.debug.service.command.ICommandControl; +import org.eclipse.dd.dsf.service.AbstractDsfService; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.mi.internal.MIPlugin; +import org.eclipse.dd.mi.service.command.commands.MIDataDisassemble; +import org.eclipse.dd.mi.service.command.output.MIDataDisassembleInfo; +import org.osgi.framework.BundleContext; + +public class MIDisassembly extends AbstractDsfService implements IDisassembly { + + // Services + ICommandControl fConnection; + + /////////////////////////////////////////////////////////////////////////// + // AbstractDsfService + /////////////////////////////////////////////////////////////////////////// + + /** + * The service constructor + * + * @param session The debugging session + */ + public MIDisassembly(DsfSession session) { + super(session); + } + + /* (non-Javadoc) + * @see org.eclipse.dd.dsf.service.AbstractDsfService#initialize(org.eclipse.dd.dsf.concurrent.RequestMonitor) + */ + @Override + public void initialize(final RequestMonitor rm) { + super.initialize(new RequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + doInitialize(rm); + } + }); + } + + private void doInitialize(final RequestMonitor rm) { + fConnection = getServicesTracker().getService(ICommandControl.class); +// getSession().addServiceEventListener(this, null); + register(new String[] { IDisassembly.class.getName(), MIDisassembly.class.getName() }, + new Hashtable()); + rm.done(); + } + + /* (non-Javadoc) + * @see org.eclipse.dd.dsf.service.AbstractDsfService#shutdown(org.eclipse.dd.dsf.concurrent.RequestMonitor) + */ + @Override + public void shutdown(RequestMonitor rm) { + unregister(); +// getSession().removeServiceEventListener(this); + rm.done(); + } + + /* (non-Javadoc) + * @see org.eclipse.dd.dsf.service.AbstractDsfService#getBundleContext() + */ + @Override + protected BundleContext getBundleContext() { + return MIPlugin.getBundleContext(); + } + + /////////////////////////////////////////////////////////////////////////// + // IDisassembly + /////////////////////////////////////////////////////////////////////////// + + /* (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IDisassembly#getInstructions(org.eclipse.dd.dsf.debug.service.IDisassembly.IDisassemblyDMContext, java.math.BigInteger, java.math.BigInteger, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) + */ + public void getInstructions(IDisassemblyDMContext context, + BigInteger startAddress, BigInteger endAddress, + final DataRequestMonitor drm) + { + // Validate the context + if (context == null) { + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown context type", null)); //$NON-NLS-1$); + drm.done(); + return; + } + + // Go for it + String start = (startAddress != null) ? startAddress.toString() : "$pc"; //$NON-NLS-1$ + String end = (endAddress != null) ? endAddress.toString() : "$pc + 100"; //$NON-NLS-1$ + fConnection.queueCommand(new MIDataDisassemble(context, start, end, false), + new DataRequestMonitor(getExecutor(), drm) { + @Override + protected void handleOK() { + IInstruction[] result = getData().getMIAssemblyCode(); + drm.setData(result); + drm.done(); + } + }); + } + + /* (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IDisassembly#getInstructions(org.eclipse.dd.dsf.debug.service.IDisassembly.IDisassemblyDMContext, java.lang.String, int, int, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) + */ + public void getInstructions(IDisassemblyDMContext context, String filename, + int linenum, int lines, final DataRequestMonitor drm) + { + // Validate the context + if (context == null) { + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown context type", null)); //$NON-NLS-1$); + drm.done(); + return; + } + + // Go for it + fConnection.queueCommand(new MIDataDisassemble(context, filename, linenum, lines, false), + new DataRequestMonitor(getExecutor(), drm) { + @Override + protected void handleOK() { + IInstruction[] result = getData().getMIAssemblyCode(); + drm.setData(result); + drm.done(); + } + }); + } + + /* (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IDisassembly#getMixedInstructions(org.eclipse.dd.dsf.debug.service.IDisassembly.IDisassemblyDMContext, java.math.BigInteger, java.math.BigInteger, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) + */ + public void getMixedInstructions(IDisassemblyDMContext context, + BigInteger startAddress, BigInteger endAddress, + final DataRequestMonitor drm) + { + // Validate the context + if (context == null) { + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown context type", null)); //$NON-NLS-1$); + drm.done(); + return; + } + + // Go for it + String start = (startAddress != null) ? startAddress.toString() : "$pc"; //$NON-NLS-1$ + String end = (endAddress != null) ? endAddress.toString() : "$pc + 100"; //$NON-NLS-1$ + fConnection.queueCommand(new MIDataDisassemble(context, start, end, true), + new DataRequestMonitor(getExecutor(), drm) { + @Override + protected void handleOK() { + IMixedInstruction[] result = getData().getMIMixedCode(); + drm.setData(result); + drm.done(); + } + }); + } + + /* (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IDisassembly#getMixedInstructions(org.eclipse.dd.dsf.debug.service.IDisassembly.IDisassemblyDMContext, java.lang.String, int, int, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) + */ + public void getMixedInstructions(IDisassemblyDMContext context, + String filename, int linenum, int lines, + final DataRequestMonitor drm) + { + // Validate the context + if (context == null) { + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown context type", null)); //$NON-NLS-1$); + drm.done(); + return; + } + + // Go for it + fConnection.queueCommand(new MIDataDisassemble(context, filename, linenum, lines, true), + new DataRequestMonitor(getExecutor(), drm) { + @Override + protected void handleOK() { + IMixedInstruction[] result = getData().getMIMixedCode(); + drm.setData(result); + drm.done(); + } + }); + } + +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIDataDisassemble.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIDataDisassemble.java new file mode 100644 index 00000000000..df8fb0d88fb --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIDataDisassemble.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright (c) 2000, 2008 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Ericsson - Modified for DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.debug.service.IDisassembly.IDisassemblyDMContext; +import org.eclipse.dd.mi.service.command.output.MIDataDisassembleInfo; +import org.eclipse.dd.mi.service.command.output.MIOutput; + +/** + * -data-disassemble + * [ -s START-ADDR -e END-ADDR ] + * | [ -f FILENAME -l LINENUM [ -n LINES ] ] + * -- MODE + * + * Where: + * + * '-s START-ADDR' + * is the beginning address (or '$pc') + * + * '-e END-ADDR' + * is the end address + * + * '-f FILENAME' + * is the name of the file to disassemble + * + * '-l LINENUM' + * is the line number to disassemble around + * + * -n LINES' + * is the the number of disassembly lines to be produced. If it is + * -1, the whole function will be disassembled, in case no END-ADDR is + * specified. If END-ADDR is specified as a non-zero value, and + * LINES is lower than the number of disassembly lines between + * START-ADDR and END-ADDR, only LINES lines are displayed; if LINES + * is higher than the number of lines between START-ADDR and + * END-ADDR, only the lines up to END-ADDR are displayed. + * + * '-- MODE' + * is either 0 (meaning only disassembly) or 1 (meaning mixed source + * and disassembly). + */ + +public class MIDataDisassemble extends MICommand { + + public MIDataDisassemble(IDisassemblyDMContext ctx, String start, String end, boolean mode) { + super(ctx, "-data-disassemble"); //$NON-NLS-1$ + setOptions(new String[]{"-s", start, "-e", end}); //$NON-NLS-1$ //$NON-NLS-2$ + String mixed = "0"; //$NON-NLS-1$ + if (mode) { + mixed = "1"; //$NON-NLS-1$ + } + setParameters(new String[]{mixed}); + } + + public MIDataDisassemble(IDisassemblyDMContext ctx, String file, int linenum, int lines, boolean mode) { + super(ctx, "-data-disassemble"); //$NON-NLS-1$ + setOptions(new String[]{"-f", file, "-l", //$NON-NLS-1$ //$NON-NLS-2$ + Integer.toString(linenum), "-n", Integer.toString(lines)}); //$NON-NLS-1$ + String mixed = "0"; //$NON-NLS-1$ + if (mode) { + mixed = "1"; //$NON-NLS-1$ + } + setParameters(new String[]{mixed}); + } + + /* + * GDB the -data-disassemble uses "--" as a separator wit only the MODE + * So override the MICommand + */ + @Override + protected String parametersToString() { + String[] parameters = getParameters(); + if (parameters != null && parameters.length > 0) { + return "-- " + parameters[0]; //$NON-NLS-1$ + } + return new String(); + } + + @Override + public MIDataDisassembleInfo getResult(MIOutput output) { + return new MIDataDisassembleInfo(output); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIDataDisassembleInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIDataDisassembleInfo.java new file mode 100644 index 00000000000..14f28cb2b79 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIDataDisassembleInfo.java @@ -0,0 +1,164 @@ +/******************************************************************************* + * Copyright (c) 2000, 2008 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Ericsson - Modified for DSF Reference Implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + +import java.util.ArrayList; +import java.util.List; + +/** + * The parsed output of the data-disassemble command. The output format is + * determined by the mode field on the request. + * + * -data-disassemble -s $pc -e "$pc + 20" -- 0 + * ^done,asm_insns=[ + * {address="0x000107c0",func-name="main",offset="4",inst="mov 2, %o0"}, + * {address="0x000107c4",func-name="main",offset="8",inst="sethi %hi(0x11800), %o2"}, + * {address="0x000107c8",func-name="main",offset="12",inst="or %o2, 0x140, %o1\t! 0x11940 <_lib_version+8>"}, + * {address="0x000107cc",func-name="main",offset="16",inst="sethi %hi(0x11800), %o2"}, + * {address="0x000107d0",func-name="main",offset="20",inst="or %o2, 0x168, %o4\t! 0x11968 <_lib_version+48>"}] + * + * -data-disassemble -f basics.c -l 32 -- 0 + * ^done,asm_insns=[ + * {address="0x000107bc",func-name="main",offset="0",inst="save %sp, -112, %sp"}, + * {address="0x000107c0",func-name="main",offset="4",inst="mov 2, %o0"}, + * {address="0x000107c4",func-name="main",offset="8",inst="sethi %hi(0x11800), %o2"}, + * [...] + * {address="0x0001081c",func-name="main",offset="96",inst="ret "}, + * {address="0x00010820",func-name="main",offset="100",inst="restore "}] + * + * -data-disassemble -f basics.c -l 32 -n 3 -- 1 + * ^done,asm_insns=[ + * src_and_asm_line={line="31",file="/dir1/dir2/basics.c",line_asm_insn=[ + * {address="0x000107bc",func-name="main",offset="0",inst="save %sp, -112, %sp"}]}, + * src_and_asm_line={line="32",file="/dir1/dir2/basics.c",line_asm_insn=[ + * {address="0x000107c0",func-name="main",offset="4",inst="mov 2, %o0"}, + * {address="0x000107c4",func-name="main",offset="8",inst="sethi %hi(0x11800), %o2"}]}] + * + */ + +public class MIDataDisassembleInfo extends MIInfo { + + // The parsed information + private boolean mixed; + private MIMixedInstruction[] mixedCode; + private MIInstruction[] assemblyCode; + + public MIDataDisassembleInfo(MIOutput record) { + super(record); + mixed = false; + parse(); + } + + public boolean isMixed() { + return mixed; + } + + public MIInstruction[] getMIAssemblyCode() { + return assemblyCode; + } + + public MIMixedInstruction[] getMIMixedCode() { + return mixedCode; + } + + /** + * Find the relevant tag in the output record ("asm_insns") and then + * parse its value. + */ + private void parse() { + List asmList = new ArrayList(); + List srcList = new ArrayList(); + + if (isDone()) { + MIOutput out = getMIOutput(); + MIResultRecord rr = out.getMIResultRecord(); + if (rr != null) { + MIResult[] results = rr.getMIResults(); + // Technically, there should be only one field (asm_insns), but just in case... + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + if (var.equals("asm_insns")) { //$NON-NLS-1$ + MIValue value = results[i].getMIValue(); + if (value instanceof MIList) { + parseResult((MIList) value, srcList, asmList); + } + } + } + } + } + + assemblyCode = asmList.toArray(new MIInstruction[asmList.size()]); + mixedCode = srcList.toArray(new MIMixedInstruction[srcList.size()]); + } + + /** + * Parse the back-end result. Depending on the requested mode + * ("-- 0" or "-- 1" on the request), the result has one of the + * following forms: + * + * [1] Mode == 0 (assembly instructions only) + * {address="0x000107c0",func-name="main",offset="4",inst="mov 2, %o0"}, + * {address="0x000107c4",func-name="main",offset="8",inst="sethi %hi(0x11800), %o2"}, + * ..., + * {address="0x00010820",func-name="main",offset="100",inst="restore "} + * + * [2] Mode == 1 (Mixed source and assembly code) + * src_and_asm_line={ + * line="31",file="/dir1/dir2/basics.c", + * line_asm_insn=[ + * {address="0x000107c0",func-name="main",offset="4",inst="mov 2, %o0"}, + * {address="0x000107c4",func-name="main",offset="8",inst="sethi %hi(0x11800), %o2"}, + * ..., + * {address="0x00010820",func-name="main",offset="100",inst="restore "} + * ] + * }, + * ..., + * src_and_asm_line={ + * line="31",file="/dir1/dir2/basics.c", + * line_asm_insn=[ + * ..., + * ] + * } + */ + private void parseResult(MIList list, + List srcList, List asmList) { + + // Mixed mode (with source) + MIResult[] results = list.getMIResults(); + if (results != null && results.length > 0) { + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + if (var.equals("src_and_asm_line")) { //$NON-NLS-1$ + MIValue value = results[i].getMIValue(); + if (value instanceof MITuple) { + srcList.add(new MIMixedInstruction((MITuple) value)); + } + } + } + mixed = true; + } + + // Non-mixed mode + MIValue[] values = list.getMIValues(); + if (values != null && values.length > 0) { + for (int i = 0; i < values.length; i++) { + if (values[i] instanceof MITuple) { + asmList.add(new MIInstruction((MITuple) values[i])); + } + } + mixed = false; + } + + } + +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIInstruction.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIInstruction.java new file mode 100644 index 00000000000..50863384d7d --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIInstruction.java @@ -0,0 +1,130 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Ericsson - Adapted for DSF + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + +import java.math.BigInteger; + +import org.eclipse.dd.dsf.debug.service.IInstruction; + +public class MIInstruction implements IInstruction { + + // The parsed information + BigInteger address; + String function = ""; //$NON-NLS-1$ + long offset; + String opcode = ""; //$NON-NLS-1$ + String args = ""; //$NON-NLS-1$ + + public MIInstruction(MITuple tuple) { + parse(tuple); + } + + public BigInteger getAdress() { + return address; + } + + public String getFuntionName() { + return function; + } + + public long getOffset() { + return offset; + } + + public String getInstruction() { + return opcode + " " + args; //$NON-NLS-1$; + } + + public String getOpcode() { + return opcode; + } + + public String getArgs() { + return args; + } + + /** + * Parse the assembly instruction result. Each instruction has the following + * fields: + * - Address + * - Function name + * - Offset + * - Instruction + * + * {address="0x000107c0",func-name="main",offset="4",inst="mov 2, %o0"}, + * {address="0x000107c4",func-name="main",offset="8",inst="sethi %hi(0x11800), %o2"}, + * ..., + * {address="0x00010820",func-name="main",offset="100",inst="restore "} + * + * In addition, the opcode and arguments are extracted form the assembly instruction. + */ + private void parse(MITuple tuple) { + MIResult[] results = tuple.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + MIValue value = results[i].getMIValue(); + String str = ""; //$NON-NLS-1$ + + if (value != null && value instanceof MIConst) { + str = ((MIConst)value).getCString(); + } + + if (var.equals("address")) { //$NON-NLS-1$ + try { + address = new BigInteger(str.trim(), 16); + } catch (NumberFormatException e) { + } + continue; + } + + if (var.equals("func-name")) { //$NON-NLS-1$ + function = str; + continue; + } + + if (var.equals("offset")) { //$NON-NLS-1$ + try { + offset = Long.decode(str.trim()).longValue(); + } catch (NumberFormatException e) { + } + continue; + } + + if (var.equals("inst")) { //$NON-NLS-1$ + /* for the instruction, we do not want the C string but the + translated string since the only thing we are doing is + displaying it. */ + str = ((MIConst) value).getString(); + + char chars[] = str.toCharArray(); + int index = 0; + + // count the non-whitespace characters. + while( (index < chars.length) && (chars[index] > '\u0020')) + index++; + + opcode = str.substring( 0, index ); + + // skip any whitespace characters + while( index < chars.length && chars[index] >= '\u0000' && chars[index] <= '\u0020') + index++; + + // guard no argument + if( index < chars.length ) + args = str.substring( index ); + } + } + + } + +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIMixedInstruction.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIMixedInstruction.java new file mode 100644 index 00000000000..a430a0155cd --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIMixedInstruction.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Ericsson - Adapted for DSF + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.output; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.dd.dsf.debug.service.IInstruction; +import org.eclipse.dd.dsf.debug.service.IMixedInstruction; + +public class MIMixedInstruction implements IMixedInstruction { + + // The parsed information + private String fileName = ""; //$NON-NLS-1$ + private int lineNumber = 0; + private MIInstruction[] assemblyCode; + + public MIMixedInstruction(MITuple tuple) { + parse(tuple); + } + + public String getFileName() { + return fileName; + } + + public int getLineNumber() { + return lineNumber; + } + + public IInstruction[] getInstructions() { + return assemblyCode; + } + + /** + * Parse the mixed instruction result. It has the following 3 fields: + * + * line="31", + * file="/dir1/dir2/basics.c", + * line_asm_insn=[ + * {address="0x000107c0",func-name="main",offset="4",inst="mov 2, %o0"}, + * {address="0x000107c4",func-name="main",offset="8",inst="sethi %hi(0x11800), %o2"}, + * ..., + * {address="0x00010820",func-name="main",offset="100",inst="restore "} + * ] + */ + private void parse(MITuple tuple) { + List instructions = new ArrayList(); + MIResult[] results = tuple.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + MIValue value = results[i].getMIValue(); + String str = ""; //$NON-NLS-1$ + + if (value != null && value instanceof MIConst) { + str = ((MIConst) value).getCString(); + } + + if (var.equals("line")) { //$NON-NLS-1$ + try { + lineNumber = Integer.parseInt(str.trim()); + } catch (NumberFormatException e) { + } + continue; + } + + if (var.equals("file")) { //$NON-NLS-1$ + fileName = str; + continue; + } + + if (var.equals("line_asm_insn")) { //$NON-NLS-1$ + if (value instanceof MIList) { + MIList list = (MIList) value; + MIValue[] values = list.getMIValues(); + for (int j = 0; j < values.length; j++) { + if (values[j] instanceof MITuple) { + instructions.add(new MIInstruction((MITuple) values[j])); + } + } + } + } + } + assemblyCode = instructions.toArray(new MIInstruction[instructions.size()]); + + } + +} diff --git a/plugins/org.eclipse.dd.tests.gdb/data/launch/bin/BreakpointTestApp.exe b/plugins/org.eclipse.dd.tests.gdb/data/launch/bin/BreakpointTestApp.exe new file mode 100755 index 0000000000000000000000000000000000000000..001fd61c5ce05d3399f499d7ffa6b3bd334c24e5 GIT binary patch literal 40081 zcmd6Q3w&Hvo&UL$NjquMkThv%(@th;`bb|%^Jw~@Pm*Z~Eq$dtS}5aWW|B;s%%n4u zK3Kp)L0%##D2R&4>bkD7BDkm^$V%lUt1hC;;$y)@|8+q{DT>OH|M&Yl=ia$9NoeK2 z|IhzFpU<6h&+mPH=XuXL_uTh|HgB*jOW8kTQo0BleBHza<1^wPV)G0(I+LipjOgJnEOXs`h_-- zR?>=)aPkl*{%KIN7$^VXu6+;Ov*|w{#ckg2>n3(S!YR0Dm;DRkCSXSpGTv(9cSA7g zA2;#)pp@}VCjJeCj7M?Zit^!uv5fx%t_Jv#wpXgtl!AXU*;sVpLOQ2ig~NS=sbn~l zjij^TunM1jAiN{qm&jz}>5hR&CKJ!7@a`?$+2x5;CfpOr#M`=(iEKx6=)hR;PJxH} z4jl>)#nYKoGBS|J9u6N^LbZchBkua5(Qt;bX2OTE{poll#<6bVPN@k5C$BH)7zv3f9)NUDwtE?9qNSGc*cRc+kdbtaPNFvzDC8kDS5&>o3N4Z+cXtVgx(_Z zm6b?pq+g_DVA9`|G?P zA*-A1g;Cljf$6%?n{J|CKlRv+n`e9Bl#%^!LCbdJCCp_>JH8zrIsPF3F2kRs=IAl+ zu01zK-ZE*Ob{zzs`{vQh-m-?9uej_@x_h_*{Oj(7N7uhSGV(;{Y+nVeM94yxGiX!CZ>P)Ja%JtuDbCX^C%4Q^Uv!(z7@AuJhlg|$>Lk&zo8Isuj&kMe*16aPHoxq2i!yZH|{getCsJvW5P5O{A0`L6TM9=Y{?QXPHV zTJgu>pB+6`cHzb0J&)ZmbM|95Q(yN(FCypQlut|e=18{e=quil@83{#^v#js6Y$4{ zdzd@!I`CX2ocAcq*oE@W_E_rfjG{AwxM%$PP`D0Z4H6qe*og32ge=tjS(j{6)}_8; zX(-FQ-fQ8SAmF^-LRk$VR9^b4+;_Fd%cf#7s;1yO5uOPTpN?=m8rC-E0_y6RGz7z> z5z4Xe8S+Q1_I1eIUunXdO?Vf=GF)D?^JsLG&$RFT=uh8xdn9!iLfX6YO0+o$k0Cw@ zVKD@kB4lNsiio{5fCUOZb+6@0Hrti6GIo`cs4PrrvZU8BHZJP219`zI0@8Fp=zQ3PlGJLz#Hf z!Bl!*W+)PkXPP>@H#DWveT{LAYK+Aivyhc(?2Gj@#Uj~A(?Dc68SQV%q@&975=_Sk zI5`}S#e0VPR8eD5Q4@j6>jDGWtBMvD??hqs-Oe$?1m>l;cw#1TNj#iYz8_VinESp- zzKNa}(AHw$ib_yY+|Ecz@v@f~Ot@eUn%|NMyF(J}8ImA;lLS3qWKa_O3R?D(lKAat zq)STr{!W7aZ%dH)4+-|ZDZ#!fw9O?Y1B)dX+$cdZDM9MP5@ha`Ap7qU92k+{U_ILM zl9EGPCAcIZ!QWgd!KJrKaM?W)yziIdrqi;!Y)eKbml9KngNN~*-39dgZ!420- z@PW@raQ`t0zVfOB|1_pZKK&pRAlgzB^Y*@TsT-cik+( zr@th@-Ootywdz7kO+hzOGIjp~3DRdu zkWEW);3f$Uenx`B-<06epGt7qTM}GeKZoo`&XVAYK?$zBRDz?Ql;EoSCAj)|3Euyf z1lP=(OTOz?NpO8sg6~`=CjCnYZF0%f@9tyTrhflIiT&$GCHCx5p?vOc34S<1a6fuT zV*mD{1kcX_ur!&%V{qyqS`(`@GJtL@l1-&ov6EV(tg^?7mFgWxMY3p%lBx6{9(@lF z#FcmE7bY7(A{mS0p&jiao{`o2Y;dF}6GvO6>^R0U0AJo&hk$B86XB zR@GNQVpS7feK&6LD^14_V4ffzPQY|Yux@svhYqb=84fe0k%1gCno4G}K^nJUQBVvW zZNG+(PJo7wNhKDc-6ctHYRV21|IFs#7#0O&PUQtdxI{vg6CS_a$t`cK7?bK_05soKg>c|nV zDtp;>)7GJQaxfJ`O{m>RVl71M)5uIJ}o*roYsk9x*cz1G_@nAd^^S#On~H>Rm1r?Wz|-BPX8MWqHAkCW6a+* zH$zW4-WyHfu_>gkLjz*hLd17H^QC|7-~o zaRlY}Lj$HRb%p?u=)M? zo50pbSrY;r=UHf6qp5)bHF2M$wR#HMKmMrzn?m9b^`-~a#MA^h!nBV<#5m+qWPpQ2 zl4eu;)Wj!+QMaTbDagSi(eZRTmBysBw7ym~HLAe(i5!d%M*D&4kXZGzfC;) zd7lU9JrkU?=|uP@45X5M`6>2Jgm)zUCZWbH;*H{oaA`8z+Jc^}Y!MC65=0Cse8nz+ zqfIaq!MlGr5+mywi!cyIJk{IF=* zUY1rFxGx8nnpj$G5M_cmm_{F`i)!gqgQ;*~L`RK5RJ#zOPm$nqQbqRQ}KB)t#awJHr*y?6%k)Gw(F zqX?j7EuCcz2&4^uOblR*qDt$HBbOW3wy4s12DGX&oEnHRZ}F6_O6OaB$P-WfI*1!i zhf!UI2O)E@#X9Gy@2m_T$VPew;toTjHG;zGsozk^?kO#uPHB^s785pBhFK0&X{&Xm z0M3FoqiL0OrD)n*84eFcV$G^FWU)ec>UU}gjND)#7idVUD&1%x7imbFDm}|U-m4)? zRcV*SisY$}!A$=3N$y*ew|v{YaQI-fUzKm)3Yd=csPY}8Rt;DkVN+?yA~olA#2dq{s%-KMkPoFYYVu5-5frGqyvhCx4SSuJO%3eE z<8l_OJs?!#ph7{>WY9T9(se+|np2H$Sh%Pm%tn{l5;bi;}^80JL^gv67!-dkX z>$2l*5F<(-)@krTY`qAli{>*g9qXxbDgg8Ooa{j7sfoQv25S7I3z^vI-vri*V(N|! zqnh+%k5x?&nE99;;PbTAi&g`Jok>5UR)Y`n5!>oTf37C|)Z<3*p&JNkW+(lJ8x`P# zxYgS`Fr4X!DmN3K&8^19GbjhnG3WhR)K|aol01!>{xLSW| z(MbyMS>NjAC`L{Cvn1Tr)dV>OVD+*!QAgzPE1(Z zb&t4Rw@85OXeS-h@E~U`2!)e^E+?t!oX4;*7G>W!>9;5Zy3^#mhBY+ITsdw;yZp)N z4l5lWOdUYs__)qa;R|pE1ej!G5SUNqFk0+%&Wr$k5Km-k((QJUo6eaM3(Xx%{G?V( zr%(ED73A~@aR&ss+?7t<$%|RiQ7^W#gF|d#)ub;<)&w}&LLkghlOD{K4He}4i#43o z&I=p==TaEt#Eg|m4&mW13!C;CwG^RC1e4pSf}FXr4)kWCktE1I=eCX%)qg@&Q$bGb zSO*NzKN=zzo-;ncJL*znsx!hkF9c#E?S8kkoX9zxHX6V~;Q_V0a#;hOi4uHV)DJ6_ zE13>-;|ihRL&Loded*Nj5T1Kg<$4YBHNX+9Sx zkc{_5T<~)=e72a3$)j6L*Y|eB{S!M^-qN-~evY6Dt zQ+?I7tf5kF2g8`nQB~JzfR_{~%4t<~y@vP*8H_~^tEw9`q)Z?wFnvG+DhN1?{!dli zs3Fya92BMxYREL95y(v%GLw)*CWijK>ShfJ64W=C#Xw3`-NFXiQ$L%qOYjJ$s%~Yi zM4?j?&2Elx3eS<~h-d95KSvFEmxm1xHZkcFZ0F#C%Q(hcycj(;$8S|%TR=AkJ^(^1 zmgwyzg{u0d#H&{TCx2=}EH#Y5q4IeH_mXsQpC33Tl8I`9w{;#92!b~d_$eb;joD($&{#4ywyFsOQ7r<$h~nh41$T+X$Hgp76ySWc zE-V`PsvF5!YCgu9q&}_tX&RDikgLU_iG$e2!|4Q!`NABc`8b61P7HER+v>@t4n|e^ zT#I8x^B5TXE-@U15cQ--qX>lMd>jh?$sx$7@?Ux+TFrm`plC=(0GNQ0C}#-q92Vq! zxz&qqlwyBm#FD657=mXzcu4)V>4gZ?_&V=4-22H8?_ll5<-Gl2^b8qE>x#l0GW|bSLr7*ed99mFk94>k0}3POtD_0HP-7j$YHMl`k7&zH zzDYHfiXp`yz;zr@K@95f2VJ#|&Qt-e?+AKuNR@w7ml4O;D!_FgL33`Y{Jv3mE(i&J z=&&k(|0wBPC=zsL2u1rP-O%L32f2boyl#ogmltV@{4$}Nq5zkfNGrAE^_(ab;K~y* zNlD{}3#^dxs{&k?(nL(@#|lznh`4H{iI|@2$CMQOmLU?yqsH{PJx`>o#^C7#ZVqt$ zi*m&czsT8MEtwFU7|`f!Dh92V?s~*c#Gty;kl@u5-^FrmPyQ!q+Xkm823t^#iu z^iWS4`E%TbCy@$p@sj>b3;z#Xc+JmMP2$mmtMXS|XkicT7POg&EuUZ#=jhiZ-NPkO zXBAA9e7uPZi5AxJ)YLCxDu0E8YXvNHNO7Ljs^-6HdV-{}!~r$+zI;-^LWd41u2*VW z%}|<*9}E|)iD5NtjFmTZ8w>OzASO2pmJI*uCAYCvxEA;Rr`GnArGnpqKba|6%s8s@ z4_Oj-*G`$4He<*#Z;(sSh8|Vx?=0o5L0C#&BDk z^3_Be_7A7BswOsqoZ|Q%a|@~_u47&`hj|0ir6ApBNC)&d+mH_G7)bwKleVjhnuCV) z5Y2R?9@a6RTEdCJ!6A&*dXpHg)%?Zt2zcwf$ME0Gb#U0FPN!3g&a;;0y6x~#_zE?B3D#*2cDcd!HBJsW+l~R?O&J};oTE$h(g_v=nEEVMX zKZkm8Oc2!EYG#DQ*dX@=SOcsnHM5GCNmezzD}O4;tpXT%u|KQnFUloG*U%uh5O83| zp$f${?a|434KZ7}JRZ~`^EiX*^A`6?JVyfo% zx&;n$n*t`7q~5BUT^{W@XEskw=LQBVqnS=%ris(aD)6j8xr78+pUY)kH4(^Oj!y#I z?V#70kY5kdCuYD)B3>S^;`}mjxcHDMh!cSp!#=Ry$cc<;LZ(Ah1&3sy5DzbRDkTl|`uB5fZ3RjVuow#q`|1a1gWmS3ZYFSYO@R#Rx4yyhv zLu1x#o3@cC5{qF+Nk-LgLWi>{*Euz}=5cpLL(2?lXh&2r7phgl#!> zVVk0g9<`@Eh$!htF zlp%X#(!QMyt0O z`RwOyo!l<{1mb&GMBmd~K`^>4t3A%ba3PX4J7QIl0_F2^2NpFjy>aLa>vEH0n9!e{ zFgSZJL7kU-ky^cfkAFXJ{oIt`PeEgyw`77+OMkjiDekE9zGwNWBv&W=rPddVlp@@+ zR$~VfcZv>SB}e&Bv&aGyi%Riklvymr5DE9nTGPG|9EM)`r&!Fx?#wa+K}IpFi>#`j zQ?gpKH;=rA{Gl6A9)H{Xs*& z0`wXNmY77l+pe; zX7l__M)Go)A|O__sFY;e7+u>~oz>cV-Q3v3l*9z0@-H(&nwQ#A3@Wr&q~%Lu71Q&x zYhJa@P7GpX<6rACW`H2@k70_`(KQPfn@mn*_F~Hr*f-i{G{cOT0f(3z7B$BRosy_w zkEZZ|iXTa!s{%Bq{>N%mSJKUWKg}Ph9 zj(8TfYW}Hpw>shvzf19OmB??)$zO-zeKr5oy6-viFB?xj?8~uAGt57=uB^#U`4!`_ zQg?HXS-NqZ!JEho?+y;jF0s0AX%Td|2BB~Clq_{(yamXQgDUU>B zKki_U+gPUnYaP=cCCTOP$5iG2sb#25C(-c=iT)LBzW*26hmr2k4m91W_$(kyPD%1R zrZ(H8zjjDj)!md*5IR;nly5qe`E*jxI(tcHT4=BAuFEWysA+ADe${!ii|{lO!a|3V zh2HL2I{%53(t@9^1-9lIZ%5pZ9isObVTLMC)Pxp@N*nVQYH95{4*R}`;^YWyag(+g znK@eSFm^25CA4DVYAv)4E2`{Z@e-sMyQd8QX!`4Q0K}s&tQ`OB{ku zjw20??$A0eatI&MT7^y?cii@MUQIeonEHQUG9|5K(Tk* z<|_JOvJ7Eg6t)_2D0rUMv%&$vadr`v7IMW0$uZvpr~Oe^Ei-Z%$7fI5Lk1R4B@ zk5A&W5u3MeqMaVi`%XS-Y@bCO^1JfM$MxBU2g&kx?BpLdEQutlb2fC6 z5!f~vA-S3$8Gz+7qvJJ4@K5pu?;Yh_;nJO8%W~VC*T>*0aIwSZE}Mh4gt`IaXOkcf z-17^k@ViRr-8QR#hF2E{7whOkr#s^xJ4`JFOk+9S<)D@oc2Ya?8BfXcQF*+wOS3rN zbovyFw_LE-(0`#8yi}rm^cYofXpidrnu}*&9?vP+GRhRyIb~(eiue8X5;?MGn)1>o zqx+7nl>7t>>>XMz`k$cz>?K0_#x7Y-F;N}2JIr4mlX*NBRTs8^FW7?WKA=mP%Zjnf zSz%$TIm1rJk4KqOSi6PS5uiHGb9jG0ig(;nC;U=II==4kdyA!@JJz34ej|5Ad0I-K z{OO83Yn7e6ns=#UlpAv@Ty^%Sqi5l}*OON-^3|x0UpX4qy-N)RS&~!W%98HYw!dQU zQVX6M`QYfT;yF#ZXV8v^9ZjissR=pLjYs3LHA&v+rg7dHJ57h*r6!a#HU(pAa#E){ z?r=0+^)5AS>0T1aN#=x#qTf1Ru=xsAZg| z^J=M=Yc{OSmzjz5Vw`Qp&N3HeYa<3yojNjx+*~Euc$3KG6boK#l*!w=&q}>-hJSNV zJW-%tM=*(QCJ1%EO55}^Z|74KBoj<^k20xvPHZ#NOK3V>4>@|4$!WJ#=yh^t4n~Gl z-3i@dwlNmkfoEa6m1j1qPX9XU;LD=Q|7+$ZA4VmPCjutQej?}$k&;uW%Kt}0*v4of z-4W7ZfiAZMt^98rhUV5h1Xwwh>!^5$ti9Y~UH4r(!HjYet{}yZzx88C=kFX=f9(Y0 zD`92ZneQy8cTt^l*V_vH4S8IW)ou?v`c&sGhpFzRJS#EaakEHHGE-E?O=OwDr>PA_ z&C>Kqt?PK&=Bj($=rLR;bw|gD&Fb&TSNIMI>u5RCSXt-eaF8WITRDEh_LJoqB+-Aw z=xJ_c!tlOOI+Mj4I(o34=a-!SJO0ULubXZ(7P6l_sju5I{GS-dgm+4FQ-_^^FO9=J ze&Pqo%ac+358J#gl6ai4cJj2}Yjf8%*lEw_K6%oAZHw^#``8A&Q_34UZR=khn|b_% z?<4CLPC@?JW?kmWb-a^#(wx8F7E!m_PW>1nPVRy?Y&rhZC+afWJdT{aGMKB*9ZN$d zF?C(- z664!3t|K~!$(|X;77FwwX=6gW2Jms{;apSieuVrS*?z*pbd}**rgyi*^<>HjS{HlD zNso4aVRO`7X6$r0%u|V*$LSX3u|jn;VR}XM)!jHYH%uL$-);GO9Z7c|HO$x$>8Spe%idOK&f&mqRdGq!Qp;a*aZ)zlpjH0I zUA$aGC9jQjbFVyGr&!BomWHtj$stw#r*nc@xEwtWq0ByuMSA$vls1BK{D2-JK9>{J zyaa*_0><#+$WBhv1BMT$KlLd8^EoE2wiC!UfMaAnn7BA)glvY%|1B~wvc~Qy?BJ-Y z;9$v=locFt3tUfF$Z$JnxUS8z2(^3_3lFqnG}?5PNJZb?!{AVI6L?fS*2Ho`(`GIP{YTcg>- zLm=5(;>A%H0<*RzhX>TFn1j$5#rh#>^u;e5|3_EAmWCcC_t8~7Qr zd6VPzHUd#0M1IxF;)15PNsSks<>;Z+t5x859#4EfYed*I=E9?0)U<4?i*Xhhf0xIo ztI`;Zo%_gW7mVt>tZg@?LR40==g`V_;B`1t@MQOolcZ$^j#PlFO@61a&@F zvp}ky7Rn7@H%j0@W~^8S*5#>|Z5}x^1QuBZEK=%Jpd+7ed7fBZGReGVhzyR3T()e(ZZu>Mw5jSGAP2f7%4U9O52sf%a<8e3cZqM7Y>|egNDr@CCf11 zmf(g9DeB@z{U@?8p7{}*ttVk)o%g%=_p^N0dFk|4?|%@$+d8>D?>pO-VkPqi?$=EN z4%#}T0*}eNC2SkyoSneq`Ke08#y(?b-2lYt0{&DXhc4txxW}Z5TCM7T#lJfL{k%s# z4t$5%>cULF!^Zq8_BRMZNh?p{=O{i`0a_97i@t#R#wZfHg-v1ye95*z?4 zt?^&-@@#3i3;jehM?ZOVQh} zv{XL?v-OVh?gt%wX$~)=duF@p{-J{}%i#re{t2Qkmqe*Rxq~%rbN6XGZOs)9PBg1^ zA)=(&u9A_3T{X3b+yy&luUc~(xsYDj4j9g$B!qR_T{DJ|W@qDIjuMXHNZWRUTKi`s z(VmVqtxkePY}Ob;(fZ_OigU!6MZ~nTG$GpF$LU{bJ=R9g)kYVnK*KhB31z zX#=(RZJV}j+R`0H#SA$qs1`-{LYrE9tU!_OoB5a2c6Ch ziq)kZjTIwx-jCqle;u0X`K-ZIzDv!gA9?Kp!2={9yw&^9y!|*Ti1%agx~*Pz*% zcIJPfCzyzr4)F2>&ykt-~uCkA*fnU%lXpLW)@|O$CVS8#5^h<$pF;C6?=zGC00?WoWuaHVAk|)Fz|lwgsI+;XpNvkT zJKMY@caoYsF^?h*MR64GEz~GWBDp{Kh2Zm!Ux=slS#ZjnOFZlz^nn>!HRn=!@dh2G z=ghNdT{BwQIoEisDsour%$Nhb-Ue3x1}N3}C1UL1*#b33)?3`~7>uz2RklCGIMUPG zfc_*(I{)GpwRnx1^KllyQ;{{4g)IFzsbzJn-9<0J!*f1GA+C2G#)tqmhs&PXDVx0E6 zI3+lWhywyYpxNZB)ln@<@LGjbw$`a4eEz&Y^NtnltO-W^bPgO1-PK`Pb7*eF@A>4*0GJ%GoI zkU5T!uqEfmTk{Da-(PTDh5Pqjx`(gr@=OlAjO9E_A%^3DIB_O#$>8-I#+N9I- zzU7X8Bf7i_q!wPjbRUv$oz^H&75^9L!frhts?UW?nH(BXy*~%IxQO3Sna>mUnI;?c zhDPCwDt+N_ER({v_hbySlkz5`W%)meLEV_=b@o1qz6L_^{gZxk;L*$w=ef~`wV4Sd z988B7Ix<~@p>|DT&+h~i1L%8Z{$?Ed-cWN(e*_1$Cb1?1mxt6n3z%#xaV?s(nZF&M zt(9#1hZC4e-4fZ7K(FEdKRoFB&qtFmcsVL~t+M_b!;PnCp=Du`C#q_TtY;mN2h9S{ z+OC~oJqI35=S}j|?b;H{?|^)R@5Ok$w%qy}glejaq#VLsJH;wNi=bh_B#+~+ooY3M zT7%Xl^|{=&)2$ahHtToPo!PLuC*KFOBgRL9<4PkB8EGL!s4z2*c zcA0g$lcKXzLo|M+b)y6FT7I71oiyiW*KW4{7bL8TX|J0Tv}?Cozl2>H3dftXv}<=- zk05m#>`mI|aMzx1eFN^-VCCl->Pfu(SbM;_1VTP8qJ2r8`(1n3dIkn*P=%idd?)ds zqG~^AeHgZXTU)VT4lY-7TXny(L>}(sl-#9)38~+s7s4`zwSORWFrHR(+eT9g#-a4= z*N3;yT{@alFb<`6zjRt^Zu@9T!8nw@{f7+cvQeb%8s*Sd?AOQo&0Ric>r@`b)4xYqn`f09L*&t0Qr8vT+|!KC1>-CJn&nfTye zBN@bFOFn#>ws~33W*iyGIXjyEZg|E{?mOstH@1zDc=Ji6BWO3g)=OxCf*78@yH6@5 z8~;Z>sbp1JbIPkqi^^w|S6Wl73bdG>*{Za34M2FdGPh{ky!sa7;5JoMzOwX;(ypqt zWgaw16XvR}Dvre~RmFsJClvW+_~!Vk&;|kmfm5i$2Ni%r_zJ8U6#2*x@hcT?rh(hL zLfO#b8b<+y&jy_4V1f*AVWc*EqP3`8!%KXQlu2@1Oo63Upk9T!vofz}EG^YKCpQ2- zb25(duM#*(POGvgOcPYhL~@o-YJtYe$y#GE0hrWkwAPkM+Kb7BBz9G`;RdrZG-)a{ zmJ?9}aj+TU;DpnSyNa(_=cC73N=Y&eP^KjxI=vAlL4{yQRx28v=nTVEdd<3W$|A{3 z8`f3Ds9$GB-D$`}8WnJf1b`$#7YHdMXcozF4*y(aTD|s*ZU1bO8=%Cjhzke$xu@s3 zcAjyUC~n9_=)3tC-BeM;f?04@6POp;*@@5YHYz*S+MdM@z}Vb4jTOaZI9vdC()J}r zju_ZH)u?Hi3WnASWo|VDEO!H-m#`IXF2|OYPJYoo z(w&imFuE$2?@kV`c9$|1yEQI-x`60Hv$g=Pq3c|hkXl36iwBt|w}dm@w6v$g4RDgt zS)fQeI#d89|Aqp7!Zy0-bT(;|&dOCEM^hKlZWg|oz&&Z z!8wknb&6@qmQlPj;oq$}sL2FEw~f+G=yn5zOrh0D+2NGWoUU%SD>T{8JTeVCH_uEB zJI_@j(PW(Oa$vEhxWM>HS|XN_U9(WWcNZAPBwy%argPY;uS2VTQL%1uP@&jp?BUcgA z%Nz3ak%aA8o3v>ChC{oSOw5P`pt<5~L-*!r?W{!8zApzAx%A6`;nxL5n=+V_X>&tU zGRN(Lrbg2u4MU@80o`w)IbBR|Iw!%gYK%^^9vSOVe*9b3U&<%*u@KqBHFFE!i%eu2 zqlhVW6)um$!ue>jzkWc0eA6Fkq$XAD@#0I9MdjA4rdg|Z&+6-IYVzP~)fN!^_-0Xq zL3kzr*oaY#N4|iWp@$xSX3gFY#h+f{tA1$Lu3dLN==Bu&U-nu>QBQ-lx)-sTzF@DX z9JS;U6pR1an#*SaxRz$|>$XKD)~s2xJeVn9mF0JCi>h;w3efR8&_G}6GvA?}NoM?* zsCI;fpP{z#T<}=-4tTC>%pL>395DX4c7gZ)aVRbR@ZH4{ujNI~VvO!BR4MVRP_k{^ z_BXN%32nUneeCh@_P4PM@u$>Uj`dyIj+1-_dW^4jX%HT?3%@Nar-8~}-nXfo2xo)s z);~u}K@JHcu6JB;Qf6N1SMm&P_QjelM4U=U#KKbILz-Z@U6I>3c^J|X&Fex+liNFH zxpJpJcqXD9&ShpkFO;imO7^?x55M7C$ofDz6<*J?^1}T%c|C1p%MROoajlpt3nA@1 zhM>U470$Q*LdtB6$x9~Qx{z(WNSkZNK4fJFRBjPOv$!`SVABsjb|@{4y=wuf(I;EE zzFg>bsXnwyZ#TropF(#oGjpQwD34_}e#?ChPmItn56Bii+eu|iR?*@~&BLfBH7>@`q#nweyoRtm}Y?XnSUnv|F83Vhz&?E0Q!$aDqRvjTS8W>=xn zZx<{SHQtg74>Ci7Oa^0U#DIBj*ttb*j1lI74KpPvjVdxdQ$EU1JevsfbBEwCy3cENlnPv*)6 zi;L5eHZRFF7NNY66O&!gK;_AAV?!EJ<~=p#w3EtJdGi=d*7D@NTx&Bbtyp#ftndrD zV+mrbR9K`#(&*X?-D7d_r3R?i#=EOdzIl1=LC#&v%+gGu*-K>!Erf9f9#U|5R8|H7 z7+mn)$B?5Qj~d1drT#I_kq&7YuF&^BhJ$jSqfH{7(s(b!{rcX=@WXPSqh<%xzCAs67i=r-plYi`rgNIGScTxMmgfA2`uYnSgG$ZD}c#7 zxzEX+i}*Z^_cENX?|lqc%6*O&syK#3p!lpf7Z)E5XW$}?KO4^xX&Ww%Lub42su7>N z!Uq-+;&f;U`|UfaGefEoRVd!L{>-k$*+`#i#A9J2dWnA37(1KWNSG+IGeZ;m2Z$=!ETJjdxrbMcohyGMWYmn4h{F{P3R_$ zYLT*Wk)9rWqS}rPB=BC7p%Uxt2)t$AVjN}P8Z|l-PT_wBXpp-oHW>e3fxJQl^R&*7 zIR5H!;rU7E&H~+8Km-xDe;m^D$MHR$Plc`@bp4>?_@6NTNXM%g*B?ekQq+4F=aKa&4}~40k%H&-LH=~$P2$ZY%BiX@c9-wn7(M-i;gvq9%ndcbVDTU>ODK(`2VvjMYzHr=NI zu;pz7-8RsDz$QXy(|y6v!ENd%w|RX(0UiBj|7^PZ0H8e59S7aN?ZQVGF8*G`MS1p*bo*QY`}S8Luj$DSx zFgncqY`Vq*x)-lds=`Ks)@C`QfbO*`mHMwS^lm7id*OPeHo4^4x7!Qo8c>+m*~THX z{a1;5=9&HL2VK|}0-$}%&{bX4i>O#PBY)=t&M8KwgLN3$nI~`PV@h$GjQz9a*>QKs zcAxPgqm}Kuj%&?q$8}r_WP7dS+Kb1WxGs2Xe>I*p2MZNw?{r){mhGvIOQ6_p>Nr!O z6x&A~N1?)x?VygM@ZiVxPRDhPV7sQ{nEl6(?U#;Y5gR{y+)<=XlQ`QW-V}-Fu=eA` znJc<|VOS(RgKkH3T=$G@FLb<`fwT)cK2_qZ|2keHan^GkKV9Oi&pJL$;;gqiK3(GW zUlI0)xqn59y>;$al-EMjUalMDenqM-7r|YT3KYbH1@T!0@%I$OaX^9#;#I#J5yK6P zarfAPaazFknj{wdxd1r$Dw*Qo8 zih6HBJcBsF_CzyFB%5Yoq*I|ce5 zLENrSjDOqk1FeF%o-2qSN1XMGEkPyf*KZNG>)#YruHG>8ccbc4f30cE?gO0hWhVX& z+%tX=;tei&`w+L&Q-SmxLY&*XQ8>i@D-o|S<)hLwP2Gg}5u|6g$eXM_g}6Ph&GdW; z@o9#>0{Qn4;`Y2X@y8Ii=eZew7V%Ex7sR2p_}$3A74ZKI@moXb4g7^!jyiD;- zRyAlc?Rjs?<0)Hqdp3n5TeGOgfKMY>-@{^DCOh2Qi`#IxW9QZ#;muv$JHuhbI`d*@ zcQ`0M>JQ+nL$SuCE0(vYAqGpp5KEaC|HJb1A_vpyXPnsZ;NW3fL1;^7PQD%4uw(r> zp|BmJGW$L!RUVB*>X>U~W4<+j_aK^2`K^US0y71e6v68XDf$Q&>lX}c(OWlc=nm}+ z?_7W8<`7*(B0O!SBZtF0_d5@OHzhcW+_`JZ`g6KE6ra}k_5@+!=%ENEkoXO%b?Y{6 z?mDw0+|t{Ra^UTi!fRTNh03Xbv4PiZ8ez+}hX%lSG%;hso7MGG`ZZcC>`f(Gt40 z!X~^y5gyK96ER9dF2T7sE%IK5a3zqAgr5ADXu@GU+}f$O-)G5xEk?UNE|0?aZrq_m zVH|dlNhNU#0KOG)V9C059T!}Hr}{9xi|lD%-rmS#_lBb3Z2xd_Ut`Z9ED~VO^=tMxV!Xz020tyDgfDtM|kP;Nf$;>b_%VZ|bp9t2j zx`9@TRHJtLM?YQH?zUg8*0$SL3$)zJfroepGTe!ch}*O4p>Xa=|{17(Is=|bKAxrJ+|x*yMY!3+SkDgvguSPnaFJp_B2vWm(l<%77hoqq?(xCor`Cpp$KUy7q%_6t$>+GA{ESM zqY=@a&rvnxkyl#p3MEpab?w@Pi`s%szL{d_^0q~-K|hq(!G#)S%T|A~8Ob{N&38AV zTHWGbY&r6~f$O@gNhB)yHXgP4d%td4WvH+HfaQR%6XL}kBt%8MO$d$GZ2RM?-oxeq zvt4`pp7@zUY`^!|(9qD_A8B8Gb-V@dGTx5I$~Ezx zFPPTAHz9cR?xFy{dksI zJQw%~vVS$63w$Vc1YX`2*uNvNcU$1~9f6Ox1rGKH-fl+$`U3-ag-~=jFqz;;Gn##W z;OHB>=G6`?LFL$}eyCz(J_(d;dwuQk1o@olvxn3POupX(6#i>w2)c~wUEo-Mb zYRP7^1Oxj~zXN~3W4+z_Q8Ut&9f6}LGpdv-cLZ2{Ae3TNcCTHKyLT*~Vxm(H-FOTd zS7MyN%bNq&2Bu<&82Ffv-jDFO2M_(;|5f4geSb^g@_m1ig0J#X^)Vik`M44f^E zu&b}dHyRjNvC+0vu@kT(-D>#gBK1hh_NgsiJ6d}#LM*!af4fK=)=Yl%ZgRu2D;?sz~ zMAYf~Y?47h`)IX7l_hq)U#3F_mMEL|h z8x|rzA5`jJEku2*5bwSCXsuY<+B(lW4b#7iyv;tpugN>@n$CPGmsiw`S$Rn{UnD-M zB&IfAe`Dh%jdT5Tz0=V0GSOr-l#O2Gu+-%9&uE&hO!-Sq{ht+_e5w9_O>t~Qh+RP&c zi|3?dd7)St8>$lGIy9wZIvh%7{o(`QISdfXB`t1&36ibxL^6_zro?VL;WL>;E-F5< zsjEU=(I#;P`XGf#`Nh39wF;EtzjIv5O7vFd&@y6+ozR+2h4UF0%!wDYOun-dUTzeA zEKiteVFVs!vto-)U(+24<)Xu$zBOX9Uo1jzVD`mmkq+@E>|~{7>EcC;@-cC&D6uV@ z%}2!&EXbH&3Cc9T_>P@e@cU}44i=^&4yS}4V-j-~gcNs0KDT1Ss&KknIlnp{O|^$u z_9pT2sb=wu9*lUWWJMgZbJ*T&Xiq0nSQ?2m#$2f>lv1zzFG!FJn5)ogVr{A1nove` z5MP|mcP67GBP3hnp$v&MiACvjlElq+riGbIXtUT_$fgqR))^Ifzs{=2f44KY=Q84Z zg{&lZ>5L@$bv6<&6*Bq7fudY~G2qDN7k_f(^RtV{MW-5LO=A{l*iC6)m*jSHE8(9oGjr&P~KLyU{e8GhevUz19jk;_D*4T+g^W@G)| z8Eyz?^9|ulF5z2saygv}kyqer;a#}Oi*a?1FmC%0_2m-l;f85^7tdz6${~wVtruU6 z56LGOR?Xr`3g#%ja9A|N(_PVq4Vh3XoK9pL+B4}`Ce+o1Nlil_oJ@3QqYXEuGaIwr zp>QVVqwOn}7ztA)OYD#?-N#@IjF=juu>#E3A+(E>xlutWIG}Qv%*GVPSkq zshbW5O~Pof%~+d-(Wr1!l=FKN<_Bd}E|U+VLJYrkvoM-z9Tr8!uYef( zi)73WuDir0dIa0pKii$JGTEkvAY-o7-50NV7w^-U$Na9owN=lPx|G%B>bt4xucR)! zSyIWWpOKpXj+E>c=I?;>E><2cuS^z(N+UpvuD%xK=n~~oQx~a2 zecFs@aNS(ym!!(fj4KegFf&^J2HE=ix2|2{D^;CPlSO=eSXH+})s0%!c+Rhk-$TgAqc&!;Gsho&A|Qzbg%O|mogCB=Bo(UjKD9osqI{H*ml9d<`?@@U7 zX|)hI50L`**=2>doTo}Fdg5w)9Y&hys-2>2Q2%9!Z`(HRxAj(rg5B)252(I|w!yKvxR{~d7Ikk#tU>Rp?FnI6dqi1~CHe*ja2FdnC(0veM;m<%>Sbps zR&O`gBy``8c-gT2#~k_}AJ+en)?YFcH=fkq7c*4tJOIt#L5xE?d-PLwk7i~6geu*A zhp!VRr}MOWI=`K3Oi|6LyrVSs1mE}>Y|SpzluA~XXr&+VK3anIXH_Xs?_2^nbg6ZL z@jO(`DyWjFO4D9wc?)s3t?3tP+(#XA-B79t75vL$uhb$#>7t%N#KX{4{t&YJf=!M1 zg#Lg=5q)I7wy8aQPS{mR30;oS_xZhDx2Y1H9Nc=!%I{4b}6 zhgN{gI#h$?Nmqq1j=(wDCQmw#^34ao<|94;->SI|bTrZx!wW>?f6z`H1HmvyDOmso zF~q$r;2J1F0h`fO|IDf62X+BDl^m2K+GJBU+rKnI($$x&#JuuDDTIQb!KJ5qHF_~> zmGhxYNC@tM*!c>`IkDe3WP!7#Pjh7o|;Z)ABl;C7!gY7ZK zGs=-O@jAvD>SGZRXB%<_Y*b5O?u2sbL!Dm!%yr+-?Roi?_ea~oTooi>j1D_fzQ#8t8$ z3hHE973XVOnM|qXY)z|@DK(t26%?TZ)E=h^iFGBakaSv!E+n0vLdxjFa?(KXxJ%%o$5`oI!hcBW@T$@-ps?N?1}Zn z@(WTO3#__b9UUDzckaYf17PbqTw_pNUS|3GRy&6nyV`kb;2vYt*VnrYRo^^6aGzF4 z;aM5a>A=3lvd{f^Ho?F;t8saMiQbHmp9}7DM#;}LHP7cx zWSs`G=gNt!$b5qSZWd_a}Q_-8&V4Hz~9p5E#vH@axPTV5o zsNxcNOe|C&Jrj|#ggk(uEa5JR7i3BQRPjwh?(9;QaG%5rvZQ~l_$J|R6mAi!?@U4V zFw)*te3S4!gWUXYyz`Xa?Q z2`^T-MR>Wy3$iVs7b?C<*s5@gaI?edUsZgQ@HK^7gyoo7JKF=VYmAX;Ig@al!Y#r}Bwo-v z2lQOUHwop26W#^k6*9dbOS(;_gcBz#Qa7U5G8FUbA`^iIV$34f|^i|~1g z7i50{`ac!lBz#ff7U8QBFUbB5^lOT55*|>vMd(Inc9soiPgqmQzJPNuyjO+Go2cU@ zUeH?$`V7T42`3^NVkN;OJDKo2g@p!u8$-GRvY z&rt_o__CY3a-mMZTt>mT#xUSTGu^_MO6Q_J+~A#&3&n&lmdg9$p=@0EBAZjltRTic z$?3tBVqCf^B7)%ILJZ{<(w)o+AID#T!^%x~ZU6yRng^D`7mWvT{Mi)^#v{n7Dd7v} z(wQvGDew0wIQu}q0Y`sv`168R36p1^iC6~Esf&XPNTLN^%73v$$1C{0=!=Pem;mgM?Ufx zCL>}ST*}FN^k8^F>wp~%8TjSkT9*2FZ!8YEMmr5aP>!()@z3@hFWxKrD&(dhjd>Zg z+@-*=IF+e>F9Dl=c5ORZB33#kKhOLNN zAN%rtIHT7a!5 zX_t5Km!q?29%Z!;2Z7T+9VoZak)Y9cAfR!|K8eQJtup~?-GjiLa?>!OZ=(}-&^#W2 zYMiVa(cm7}jSjTtomL`uUOn!avhmnK%bi~$w`?-%Zv;7CiClat`iH|mT`!lG$UQj? zn_}7+Y-@B$iQLaG!puc0amcMKk(=gIZk`H@Eoc^6$kz%iz#kfisQSYm1U0OidG(TyjHZT0FKLw zRt7o#Dw;h+ES#Qa|hD&fa5hq4E&00I-ssk12YY_VO^gFz7R`6%ij`7 z`Lo0tK>p4M0Qo1#t8g{g|03-Yl_Cq+;-E|I^ZU2gVgF9h`p!4)e+~3*`~4fZq5e(K zPJey?`U!j9N_(Z{eI9%rSl%~4a9n4a;W|?s1=Qsiu3F(iM|9E?K}j>|XDMi&=ddS|zXCMB^B^UE4QRa|L-{mlz5hnK7qs3l zB+Zql-ajI}6SNLqAipS~-=IAFQTD6FA3^K=Ip+ThXwE07qZTtQYuLkwORioaoqx@~4dG@6BZ3C_M zqsYG>wBG+B&2vA!A4&R6(0c!s^!uQBfTi_)1X}O!kza=)Q}2h8z5w)LyM2szO%O9V zq#{2ni0^L!=yufCI=g&Vf#%5^s!j4g16uFDQePCb-VY@GSk5UJXWL__4NYL`?t)0KWM$5 zO8N=V&hq@2eDoJ8;Ap=eQ19PT{s`!A>-Oua6#Olx-k&7D0<``<)pDg`Z|@Osb%{eB zoXBKz`3)O@27|4uS6m%j-nMEre;^xNTtr>jI?TfAv77hiBfeR4=lDf8K_fCm(!p3V z-5E*-JU^!S?EOBw+JQz(yiWB4yaz$`)$5jhI-PS6&L{>l2Rae&4 zCZ_%4U0i?;$~8F;!guU%exd3h?6?r3?`Ps>7%NVzE4j4s zNiNXny3~8mJuG|CJzV?Bg|<1uB`@SCc}Hx>*>o@-N=1@U=dT(Z&45j+@C%3H+nUhm zu%oYS6+D5Hr+gjflxwG{M>Sx(U>ks^ROA{H=RY1JajSJZ8h+4L;EK zB%?o7ER3g$*)_#Nsdg+GmXp1zE}AC$HuB(pS(oi(9S@mfa*Kx1bk$dsOlYc1l%I#p zc2J&mnMkJ&%E>Y67M;W?dwlfBcm87gzg_@1E3qvmB>;TFASj9dk;cCXrHcSRr}1fx zpVBzGCi#D$@q?QG1&x0}ybWW^zAO~C3V|^Tqip7$dpKYlgzx7j z%OyXI($&cKh5zZJ{+=LL2&14nP)vtm5K`pWF~1U2!*VHIEJVlsqid;VQfUB`%VhkJ zSP$uyC|?cIS>jSIqb-f@gqdui1_C=?T!VmS=N#G}U zWV%oi0|yRl**fa?B-e?NvC*vqelH9eXe~M>6K9NrcVy$eS^6j4R3yNE>!l-jWv=+P z5(eKE6~N~GEG!fj@NNH4)7m9&i`TXM4fuBp#yI{J*K0-D&JxbCm?Z{x2}@X5&Jqrj zUD?9P=75@(C@ONjrK#M!cZg7`U!vxWI? z;%6n!mgYH{S55%$`S;JA`j@GHySi)Np8VO9;GDx__e1%`D5jr)z_qip68bmwj(6gd zeb6GJ_}j~;F1RnO1yX-CFgmHc@R!+P>UwCH8n6#(X4a=S>Y zzX6#uV_hzqP=DkGq<2rf(*@=je0ll-*uOM%^)TQ|L)RWbaeC<5slhJy^w8B)Zr61E zm-YIoq3frIu7eoAG}t9W3rZKGE1)H$mMf5=2rB#lplrg_D_sWC`Lnhd<{Zx_Ekd*Tu6OkGF znYv!DU7LEvefSXD)$B(pitnsZh!#MuJjMEo2f~Dix86CM&6I zI1vS5l#Gr=B7HNlTZFaD*+eJeKz$y1=@4`xChM_X!g}0`$p8~~-De=Q5%dHy{o-+y z!eyk1TVkGTxeT0;lcV0|owQv>&;>DxKgHI#=CVJPd{mr%a_1>50u2h3+ zPz=&xu)4`oPqKGS&jw|xcdn`bvw{!atN&k9T^M*+!U{P8jLiFvv{Uc3ZiBur2R-7Iy1FMf^QUZ23b;j1^HhZmdv>gzd$?L88}sl7$=l z4hq+8wXK#v1{6Drhqd%~`HVT-cC;{H$}ZSqJ0RDR(G*Z>yjCb?)iayQam`=To7|A> zQKU6dH3(9LbsINedpDj*Wx`r2Q;iDAy&tS*vqIDrm?ViUdlPV{jlw$7iQ%%vA=#jp z@Z<`|H$|y|d+x#f`3T^KEzqX-DD;sQu*>^keaBbOPO*ZOzoytu7ytrQk=r68Ng(3?KouLP%tZ+Is-J7A0BhCqDv1Y_2L+((0#koy$+M77i#_gK1xQQW+ z+@TpuBxAfbp*1bh^yLk@6kn>z2}usqM*}UtOf$Nad^&TaR?)2Gn$GhQw}T2df|*(ugS({F-+wwUjKI8*SzP~N<6nf^$zPFWQ&TT#oYmD9{uwc z`Wagc2X?+OpCe0(8f+1F{yOfL0&KgSm(`$)xF5<6e^(8;8}}<^yp+FHe(OQ^Vd!Xa z>F5hM1hmrj0v@F90bv0HeuKJ7+f(iQ3jeYh_!!v|?*2HN-|c zHp2QmW&IYT7hBOLdFY92dFZ120^A67P;FZ$nw^5ctw~TGh?{0{82T{`?dYd&DSLU7 z?yUgT79S_i`k%H1c*@HryjDvTN`)wy0ZWLdkZrLG&-aLZ_*XB4Ua?^X@51I@-D$Hr zQ=OmuOlK~aO4%`(0fU<;r&}}Z77+hlw&R7HwxbqSQ-xBdSi=NOH6f|-0xlCI1zUy` zE+tZhKDmFu_0XDJsg{z7K+<>i#(m9cYBPa9eFfWqX<0Vv9 zB{nyba}-N^pzXsH1%xiexav3Bzv3QP`_vJvE&vkOr zfyX$CYdt9^@3p~505^#~#l$lgmlf*cokSjTn>7uE^gYV6Bv)GJEy!SA6 zS)cg;GVeJE^R8nTa{WdKr5Qiot@53jbRBZOF$SUmS#qwKRKZrZ9YN!65bj52 zKRAaOTblKqxC`&MsiM&bvG*j#eG=7|SM}Xe;YtDHxWbhM#%qPEQRE%7!d2Ac-Lt~g zi#B(|j$A=hJXL%tCgY~U*$Z{|tZ;5iR2)<|R|51GaZKTAMlh}^oZA-6C&Uqj<9LK* z_8ktt10pdVv2=9wW86_V--?Pa3g^u?65|MxqgO`83x%tQX6~>ZeY4K_ulTpKK)^M) z`k2l6OtPcDFvxF55?@MkBRS$@4VZuq0GHp& zP+DTCcnBrGqoDx4MBZIq(C^#EHZ=tOY7;)!KG(k+P4+(zTz*54`Z~l{QC`#U-@@0A zKLOs{o^JscnooOk`};ciIEGfX8dEojsIBoZDIv*;~xq1 zmvM}D8Jt;*VEl` zrIhyccy@{~v+htK}EkOTiO z;=ngH?ERv?P=z32zVmm^k?#h60^`9B(*7v$|JHXui|hsBFmUrNg5wnc=e`P}kVibx zMA_FejtO~bGxpU#CT662)ZZzZ z36KxVem-5w790PmV0+nN{a1?_alRs))=W1z68vYzEP+5C>TdRDkpBLre`sI?H*DOH X%mtBO$@o#eRyvX#Kc+rRDdYbO>3z!8 literal 0 HcmV?d00001 diff --git a/plugins/org.eclipse.dd.tests.gdb/data/launch/bin/MemoryTestApp.exe b/plugins/org.eclipse.dd.tests.gdb/data/launch/bin/MemoryTestApp.exe new file mode 100755 index 0000000000000000000000000000000000000000..be5c37d13e43760a7e0d4c1fd281b81aa94b1520 GIT binary patch literal 39820 zcmd6Q3w&F}neQA~j^)@fcI-Hbi7bV@9762)87Dv<*h(-7A;bYfD5$a|+e&Q7k>orm zk3gUlQd$a>Lc68V-EOyAx=`8z1xnMBUj2SYbLM-^H{Z;BGiPSboU23Y*I1UN?4L&!DaIbS&g*MK_{s-0rcDKvPc^6o zYOb0D5OHmLL4!*ez*G#F7grH+h__t>Jg#cQc@an1yyQn-T=$hI#f$u^QsV{oG2n2W z0fya3l<5-hL2wZC2Z7^t1aV%(GYwv6gXe6d%`1pFFB`Y<7uncR5FdTN*T-uvaJ+2% z`M@JO=4Z=q8cOsv4aF7@C6c4N8#AfK7R?LQByVdsTp+yElRQ3Lv`Hy0s4e*<%>5%R z?Lr+$OFsSxCl7IAp9VFXaq{o!+5XTM*8S`NZu5R$HL;5jPQ^vN>|YQ!0Xu?_@m3T6 zGz63WDHDGXi88*<#2-h?p5j}rC^^-HWpp9h{owq;qbt4 zDjCjXBk627titE)3~!1LBr@4}x@#zs$;2}%ymdowwlk5+g!>|ycw0|0k?m>@?Hmu@ zE%5Nb?%m;$csi3xMurmEJ>i{8nC!4l5qAU8XgI@IGvOoI!E`(lV_fK>MzfytpjIrA z43B2wF(?|{9SKLW@!g3mBH)7z(Rw(NNUE+aTUMXd6K-y7RcqJxoP}t(wXsd#hg%?6 zptvIiek?ndrWaQ+O3(s?<;e0_g6rS!-;N?JRxcY^cHylk)*|&Y#Q7urJqYdct4t)O zu!g*5V3|MyRm!9O2XX$se5cnp35gy=Sb~I}VTkzi3{f~QFhq)n7@~r`%n)UM!HvJ@ z-S=DXVamAVnkWCMMydU`9X)pJ*!ADd79VZ|^zbkEw->UuT=MLb$J!qU=dpPQ@K2s& z^O)iwZ-4y?*pAI(%7euH`UQzogF$BF*9Rm{O$KK${(!`((O{7Adn8WH1{)Z^1#yJV zulaYE-T2deKR>c@^QOU7sB?oG@pt}(gP*?M>pT4SAb#VPydUzm@3+3aXR5oPYqtE= zS^Exn|NiF?f9$*WGT2{v{dY%SeX5vv>)9u7(e(EofLpo#Kz8aQOc*z%PkZMQcI*Y4 zrt;~~Q6gWRwLf(9sl7qU$KBK3>w_QHX4w}yYF%^XQL2B{51)NfBs*OG{TCbs`3J5g zqrSh<`%$vG*?xf3ZeBmviwqyzaTF5HKYTUvc$iib)h@pD=EzZ_^^6-sM{m5~t$kM> zwMLt-x$-R{HfUmFW$1M2lQ(DQtD7HRK#_=FbYbt|^Kg63lb6Cf?E7u`;ZOXpW5;fO>-%&-KT$bDRITKU8@mwAvpkN8sHb^4;j2d+hcvk!s&l*0Mj1{$$_5@=GoY zU;5kZeCt@YeBZ0yV=wG4+V|G6(Kq%T^j>l)t?jPUhpLdB zBT(aF)L;5nX^STpogTzJrPV5Y*L%Ed`cu%<1mBIY9Cn_La3UJE9+m~#-ncXbL#1PsW8X96kEz<% zZgYRF32!msJqXKjdEvL=MAXZW!#XgC{_)Mf982AUkos=E7Cr>wLBuB`EQa7RglxRi zaPdcbJ%Vb)OfJDionc?a{2kio_3{3BgzOurEc|e$NFIZX5q%8>QT!yT^rhxG$TWx<=mLC@k>yyq&#BkuPtY`$YG3W zj^YaE_w7XW;?jw2A4JoBk5ZS%)2XwDQqk=hbs3_Wc-F-3MNB&V=P$*8XE2f$xcU`h ziDWiD5H|pdy-~#S&TF;f-{OFXze7-#7w6cf~vLXU)8U|HVZdeodm&mF#Hk>M0LL|pTN*nWn>A>0HXV;QC0aW>Fr@8^Hbpa|P0@5V(b#)poNj^ORcK_v z)xAMf$4+JK9e}Al3U-5a?#F*8RAniXs%z0Aw7+*z8@=bohg0c2o8y`6>XDJgXjC-~ zriSB9{pmB#VKB010$iVh`4GV!Kesr2^DNF*B1GhM#AuH235bJA-MY55mp~z@5I@pv+N0sNtP#c5T$GWSW4{SOItzAeG70Ni(J>F#wBTppL;eOF0v#VrzC`8f%$ zJ|MxhKapVHTM}G19j&~y^!<$z+;ENrH;qcL|NRnt@E!@ibU=bHAC}-N73fV$OCM^K z;NeRcR4%_pg42If%h(y^=x9o(c6Fg|E}h!FL4r`10M~Aj*x3UT^xP`JIS)#(?ga_f z|51W-Po7Ek4eb(~w~0Z`*;h(%%ZDVm^`jEpcE1F-zaYU!C)JVij`|`|B~R7Q%)w|-JKGADlEZ0AC%zU&r9&>XC(OhBNF_>)LCTsOsfQ+ zy+ne~T`R%o@0Z{UFG+C!TM~S6rk@NCu9VdElc zQzUqFtptw^N$~hbB>37v37+_w1P4k3WcX%_1W#Tl!NK=Q@UQnu@YGWhJpGCU&rAxE z;n~w9c&=B1Z|#xb`8y=|_Ja}}dQpNOye`2jRq*GfHNRYfU~mSi|Os*-jUXrlf zI*PD#T4K%|2HQ4BkUS(o>W>nPRG{Z5owj4X1nCtLWRnu?+%LhddnDNNm;_gRUxF*& zlHjVqJhJcYmf)I%1lR7CVBcL5Tz9_&*B_GL{clNdgMU8xZtRrcrmzIx+9N9c+iLjZ z(rMowVBV&^aFN7byj5b~y;>*_-7Ud?cm(&-!xH=6k0f|`Hh^Wx6rN;LyWmZ%vd9p6 zu1GeOK7$?93T2gly;!OKp;RObUzALxhw=2fXDF_`vpzq?020Yq9M9eGi+IdcSKHu7 zUnUM;rR+F{F9NVsMb{*y@KB!Mqi`DTR1!N4o@@DXCL7MCBZ+KAtDwOJdIh1`Ntau2 zdj4aTou{HVn4_$!@VVg;>*GdRkBv9jm{FkIjIFkI6xB1#|J&>hZVNVA`%C z7^nPl3@O4rm@Qc|ob4Zq3}lqIZt0Y8Z@4d&8j1{!3`Ug2Xe^H2i#Pp=-I(9-@^&!3 zTlsjyaZDPsC#sUMp?H5*1$mc>X4L`3yL4h;Fst^8s7y408j|QwMAcpqnHfy&;$#hG z@JP$(NQxcaUXiZj8MRlWXSOFsb|E4OjAC}DZ?s?S)v1h*U>+wbl5|p$*tXG3wm%Uc zim3-Aai*i=&xvAE$2H(OQHC=|{l*sIcrvE;?)9qjS8Ow#Hxf?{r($Rcb=#?IWMo7e zh>bu5^kIHS@_|tFPmN}^VX|oq1hi$CO3H}JrLwZr6b1?;OM%|H+nC5eDi!O)M3QLS z7m<6(O+3|4xGtDTVu%r)Hsm7>3dxDT!4}^ek8h79(h&a$#rMSrwCLz)T4#p&cC3-n z)Q+5rb1}AH2BgfaT28SktFGEJ{e2##>gqh>Ou;obBb{`-KbpdmQb=772V@mlGXTu& zNk-$b@UBF5P$tk)s_x|RB(y9Uk2s{R)S_m#Kq*U9sjKx^)z4grsH(HB(xB-!sQPVq z0r&@1I{o}NK~p-t_oxJ$zc0aiiY_8BK39UlH4-Eu2rBMJ3YdM2@3AvJ63MdOEAN7j zO{vm#2zL*hByLEllZ}T}Ggou2tmHBzY|RRzToSaHXZ;;04@>zt%JUXaGDACWi5b@U z|A6!+q4KA*!O>(UF_4VMf-;;h@iPrK&MP{@}@K4n>3V44&>+9TLSAy z{!K=WS;QK}B`|3++uDMjto$@8pe2YHQuvBp04FuUlz?}~Xe36~(;F}lMm*Ku&*&{_ zL^UHxG4>WzM;nnJ>D9DRKJXE6JE=jDO$>8x3hef> za`ao;-%EwrL26VIGg5I33*qq&R@L*`z|iqR+Li6OG^v!n*2BUd`$_H-_Hd7q$2pIgcKzG2EaSqdA~o+d z#2dq{s(i}HARkF()RbAeASh6Gc~krs8TNWFT@Ccc<8lXd%ne z(Vj_G0kDwI$qsaZD(Ocy(BdawBAI;*SSyOzIyy!*`G+2>h9EHWF+0HLX{#Sz1B0E( zFELev5AqS)>PLUBCjZ#uM)08<2ywHM|I>{M@Il<_?;je?3?eBv6Q9kk{(*QlswRI; zs)e0S%*N3AlfUkgS3?vOWd?(MoEHHgn&EMIf2N|d6yUSI)z49kn*3+UxT~uPatgre zr#DlR2Ryo`VZ|5sum8j{K~55oPz$oG0!cctAm;a$dt48D*&)HlkhjY;mNznv2*+L-HQIj9d)eRNo{EIc3)W!=N`{!~P{vSu(Z3iX7oIadz&pvM#!b!$U0hF zHVmXwqa%3kRaL7s$kzZvum?(G7(CpU8d6njHKx3Q(0DSs$HAPfF_jHm0WV0pN8@S) zSCITU8aG35IThAv@T>+jmP9sz4x2+PRkdEjgAK{}K*R+xBD|K~AKqs$Pv))R4?)xIn{C z13aJMB8^x~Nl=}x9Qt3Tp^YTZLBkr_B-$5f)TePv3@$&Bm_{}WvOu$bjcYNue8xeI zY_+B4bV+GUo6VNPjA%@|3UFeQ?UU0oXnIvw()xOMtsDJfOQWPRR_zUvzTV4PTw)JO ztIzx}+**kll2)I44`TDCVahT)tWK-Gp&^S&9X!=ne}FAi>g{kCvpK5zMh)+`jCdq5E_AeSVLwJlE}o+ zzgOR)K|z8BhO-z*sp{M4pgnWu5_UNr!Bq9_Y?Y{Vs>E!_2&eEIiH>;o4)SxloVnH6r6+y+VocyNjC)rqO0NrJxFxFQSq^HC^&b| zK?1dX)@=kCP)NR1#dkC!SaLFmhx^iapivboWQ4B=54t#rhVfWxK~DdZR9n8y(2Dh> z$6`^|2t#nQCe6saLj|5?AjPU76vDP5@QXw)AwXhAM8b9vw@i-RT}lMG(7>?_v-Q2P zg}?;}jpm4{;>Ruu738vnm2vF4$5>5t7qyLXxo!bEW86<0GAT+!!6gkn;-DUHm{eHP zOl9C=2Zj<(TGteokm>)q8bUgg)&moeakT`)1V`M5$5q|PTk%n=3?!1 zM1H_crbjwljsb;{^YB;#F4S1Nu+o|u#v@v%DK}}x(lDeN1h|d^Du_WF{*bG+(U>a0 z^&LSEkEn_}-j+Jz*jfd+?jvZR&WxaH|5Q7gocJJD zkciiwsG_q-Q{>kP?TP|iW+JV$l0W1`sQ_1=h)GHwZ!OS5>aPlLT}l%%r*{?P#1L`S zN)s_ZH;pSP_=F)6!=uFvxGhhltHt2y17;3z{flzN48O?fUL%DNEW&CR(b-fCsam@0 z5i=2k=1N6^3mvL{Rq1r=_2T zoFt7a{!Q)Y0&>f+}Tpr&HUoMaW|N~h9mQ_1sGMa=|cdu%e!3sp>aQ%TFw!tM|%yC2B9 z8X&rW2L)*w=O^=UffogbCWo2OiWjt|k`)S9f!7Usq%V!~IqbrdNCmifNqeS+|KDAB z&CgX$;?aYvidS7|VGmv?XfqL8G09}kNnh7=50^xpRWMchi6$;2T3E+Z)9%Am{xS#G z3Rq~j;ykHU!++KEBuQh5ood>H`J{k_cJEePuhg`fp)48S6)sp4!)n+#D{tsFPSuNm znA|K_GW@HT+{RDBwYc}UTH8~W3O)^cvQV;^aa0u_u_W$poia0R#*pRSAeW#GJ(|`( zTH3x+N^GE}0dj>}Q;pL9e!*HM#ZW*tk1N=X;kGvAtBp477)@nWZHx|%<9p04sM@%W zdDT3Y4M^KTy4{ct>2bCp9o8|B{(~m%P?fd24C!vF=}6t9V?MQn6NAGe7_0RsF%9l?-^_J&Ca)I*z6}?mg0BH)VO+_L(zUxy>miW74na$R>+hhz)L8AU+8=U! zqXJxzCp@8QKdODWhI56U@F7(z)A07}3zzIItWHPJnpAB`k!xLos%Tfu_Flv6svy_) zrEb>-ip2VQRLZ2(Os@EI)+(-QFTsopWvL+7|2fo)V}hXeb~7U+N(H$mz#3vpshwTK zLb7UTUHMZ%ZWX}Di~U*cU{NkJx`hV0g@6My4)rpsHtX&iDc+EAivh@FKv+9u#Ly|o zBcmpo$qfkBjtu6oRc(2Z*1Rz5r&-wi6jQao*B&^?Z3>uRl6I?VFZO85IkS0cCO0rx z8O`(tW|}yytODN_D3_2R>$AC{t04l#%kfEoyB+j86UysR-T6qKNTln2fLkFn4LYCN zCv@LaKosOg2`jS)?*gEf|Cgyq+W6c&q1z6Oh+1asC*vb&K-$Z5=LE=P5LKHp_7fuU zwn1*Gu!eLYHWU@QwgC57NWFuOpVEz3k`Hj#g~=jNhjJ(}gvlc}YS?)M)%SJtF34nn zJ2x~HTEoBSe&3-{fz=KguBY}v?Rj$encOL2g+tQTZbr40x*Xg==+F>7er;`$R*(Ox zRh9x7$MH5$Zdhc(`l<8FXCmmWuK^O78OXk&C6vaE$lC6-3H>;n|K z1MPE8?NM{KA4l3!LkU@Vg6LB2MQOBp7o(j0ysekp_B#>3m{s(Y=1PLmZCM==R)$NE zt+^4aniQy?mpibif$5Dyr(0K<62pZ4+=Ri|dkN~j+>6xe{RjN}dF$t<1V3NNsmDB% zQtjVgs}y%sc~9v)BgxeXf0=b(ky3 zvR1S#0*9ej{;3wrus5^RKu}OD>LRQ9CzPyK^yiV+lH5fN0~+#QlU%P2thmkaq>-S% z&ZN+R6aYX1uYoj|z*B}eflVZsJM;$){W8#N7+AhP+s*Q(&BE1Q|6ErVurDZ9NWL;~ zn$9s6)wU~tLoN#hfEv1p_G-nYhB7)B$84Uz$w=;mDgt6-!!9Nixvjr$ZEVhJ<$Z2$ zY+_1c0#W&w8X?W?wiJU3Z4+tvlGw!b{OpRuw%UndjBNZXUCIm*1paYUkv6(w!D3U$ ziOe=^83OxSTa9L@5i{Trv%{+9D4}x_Htf+99+3PS$*K#T0JIvgZ39nkJBRMCSANX! z$rF?R;v63V@4)w>;lm4fn9ElFKF!H0ph4i>7Ijh-BXOo%ty+Rt!mKZ%VfaTiPjf4F z`A|(R^QSXlbUlAGFCFuo(9;|4&4fa|En!DID_af!)T&z?@q6B-c$iA$x8>xYf#G@$ z|J15)Ir6WZNIvw-v5Fh!pIYT>vU7gTM667^ImayBxGvzeWQKKzM`f2-{WrA;8eD@= zxmd!wVdzROR+s9v@(RPw1{8*wW2*kkMu`@PaKP@ywc7dx>b8HsL)ROQ50Bt&N$nKg z6sK_3LzMhExG%rQXE)1^@7TclCv1&mH)h9S2l0@NcpGw5N7)i1rv9KCk;{ncXmv=w zGd_uS+#MG>bU(1^#E@bRtwz=%`Dq@B#(vDf9=5Sg1=eZIe4Hd#xgS%N|Hqc0Hl0M* zuSoPFe7^q|+J=$d&?dNUWt|O#DJjW*S5>o3`a6e|P2Ei?6`^aHL;03NnNKI}thJf!FoY0R&I{Zpn`9G!=X_rkh5bG3eNgGrUpQ8MC zoAlcy4l4F?cENTnA?07#l)hl-61$Nm$B~9ccW7N(9Kt7bszN7^J8u2DuOS^KO#T0E z333zp>B98(~^#Ns$yk zgpSkLyDlW1-;2R#k1m%EY*J>$pTOPR>diVP2X6@)Pd=f|);vU(f21$^nqf&K(VVlPJ+;|iDV z1RFbTb^b68SAmHgK6l+r*b?f8jGaw}IB?IeoWk#_p?BM?{*%4BI=EQJRyy4of6rlR zDPS7U=q>{_F0-@RmCtxWmXFHgm0g>~_@>jRSiI$ey@vivwBUA$^3h{V!=XN^`^zq# z?Rh*Wq{|ppRCmSloEBIA^%6OOZJ!nM;fD>seuCn|ivPj~|XvrLc7iuOmQpZE|>jKZbY0 zS||KcN4mb^@Oz7;qC483P_5ZKUhTU~VvHGcNx0hV)lNE#-hDcG z?IJ%J)%6P}g;nn|g@PiPd;Hi-hj_xL&ODXpZ+Vxc@rPRAj2_@5u zN8|BRlCsgRan1@mPkY{FN~mdc1>>jWu0W z4U@!kv++LR$mniWf0G`}HMiv>_+YL_EfYMQ*GRiuan{OwnVCpG#@S}8IX)J;G0cK<5{$plmV z0cI7?iEU9<$-_Rbjjj_-sJ`0;M8H-tU&s@bc__C<- z|Bj`}hf#^+iGZ21p9s2Flaf=Y%Ks-r*v4of-4&$60$pwiTKWHC7@Ax25Mbq0u9L*W zWbNk`>-ulo8D^A|a0NMb?5!U|x_{@e`s*ecTL~+DXTGtV-bHnvvf572-;l>8MeVk* zlb-6nz+tNYX`YrC@VHr|Bv~k`Yd={|=F`*~lT3U1xY~6+Wpma4!K7ojj%$vtw{2E` zUw(q`kg=}Dvy7JYJ`M+26SS5SXKa`(&m)Wey(XRJR%Q(E3#BtzyrH89>v?v`*}v!%;B{M$e|m|ov&|F8$*Y68=8S{uOlInP-a(UzjgcXLZxM{qZfnqys|6=w zi$`q<^_y)C#!5K8Dc-il_%}_g$UD`DJt;|F`*&4caS|ZiY*lAOVUP#4h`Vr z&{uP=-u(#q_hkDKE7Ns`XQ|%Z64#R{Z^OITQ%-uc`%{~v{z{{#!(pCE+&oUVD32AY zYZ0bbB)$5Z$LEHs6Z5+@e~%;S?m|g0bDj{^H`R5Q!|;Vd2EEcXe!9YZw$}NHaTzDl zI9JWFS^!5?@BKMc@UtZ9z54$s?pwY3pU75$x39jtr)lhFwoX+qLzIpDM<5TUwUx#BmMaai1OCXSI!so0-Q>kBhgU4Q(J!d-s-FFsa z+{5vPwGN{sXWauMlT-93qmvZzn@N(!e>flm} z)zr{~e`F+)k@XlHx!`|P`w&S5TrM2A^aQDAJ-Ad;Jja~D`VN_&7>8No3Ya@TWtg!c z(ntC~x~mg@Ymi<7eX2Cecx<>KWcDtT?Jo4ey2ontMVMH!k)55U2Mr%if9g~Imvc;9 zZ6}aEfMaAnn7BA)glvY%|06Omvc~Qy?BJ-cNIhd4ss#>jS_~2hjf2jY^$c zf;|<1?hQ$%5lB$0Y=?d^s*SLaDrJdU>bz)n&j?7im3nc!gTSowlB2`%G)^H2Y`+7| zTthwQ@$3YaRbc2lNLWL?=gGS>f#GM-7if@g<5VyOl9xFGD>uG``#|bU2NK+XT_Y;6 z!>v~4lbm~V2;ul7)tfw z5SD;!sc;OzYNjy`@%jHlMNhR(hok#?j-PK(slc+l#Fm1a@Q_+GLlUa^%(*xj2(xTB z^W%K(X$eHFe}SAAB7#ZUXfWA^|V?TS&8SF|0bR!EXl*mLN_ zHsN(RQ}JZ?kCUaP298{bS$aQD;Zn+Hq6+GAu3?2#n=RBEzHXGjnaWr)4XnybTDE!Q z&=6Q;6|hLHQ-Q90zRo9!6+$9nH` z`1iAZ*L!L7R__l9;BCF!UikF+O0ki717Fgv0S9gER)Htw-4gl+IcF#ERDP}!vGLE? zSv3f8x`IDj$e}Cw67DgnW~x@rzu{k9bS>}EjsxFfvAQrb@31j1Vt<1mlz4d(AENkN z187Oa*xe_%;7%8ARliJTX7iWGajW;=5%u%7UT!bE{z9c_r<%YItSua^1%7Ag;hHMq z7CCV`85Q_%iJQ(C4jG6++ggPQ(1KW583*E zZyiR~?|@|F`TRvp{twn&=wEEmJ#cb?H>^LS2e3gmkm^lqkBe$EJ>nm&go|pF&h}4M z02rI`I)dJ^y1;m^PI2Y@UZjj%V$&)IBslX`yz$$4W!4__K&qRB9fE+ImNM??Vp0EQgoTJ&RrSzUbh~ zb9g~rbcCp@BvUF-;b4t#?k(GFr(EgaBxSW~HBsWWt7T+iH%)CJcg4=>t5)1bF639X z1BNrG31RKKYsV4N>}(v&QNl1BY1?K{EB|OD+S9Sd>m*pkW{)Ej-X}LxoFm38BBq_i zg=l@hN&AZTSQ)-RD_xKT9NXM+5@^=tDGOna57go}uG_e7LvI)jGvwr;MiROYsi~C* z3KG)2d|<(NshItsTyE11(@tXi1laV|$_CbT?OzaDOSAzLsLzgR7# z9eG_0f(J=Jc&qnoy!{Do>*coI%agx~SHSJeIO~__2}esG?f=8UG01q?c zYYt3N%{WY;c||7hK7$h3U!_2UxzM)-XU|VYe8KHgwmt;!w&1QQ9(Y8;EocH+N%sW`bZy@w%~J9&`I=Wo0sHHQj;gh z@P$9W1W)O+VU&57d)Phb12eK}-WBrV4LVBCS!<|WGra7)8$4DuIV^S7dmZ3SHn8S5 zK&kG}6Jrn0PF3?{y~X{G!8jXGW&1;nBR#zh=uJta`%i9Bi&v<5pI`+%5m_Ty$kLCK zT2|NT7t;!`@Vrk^i0hq)iS!xaMs4*Tu$fGEUFXR7#}k*4P*a!wu4gFdW-9af z6BIN&T&PUdR$In{CoW?=WiF*4?gX3nFa@26d9ej-)4GJauxcj3P^#;nD2scx<~??T zO39|Kgxk(qRQI1L%C1L?)V!~ssB$AiqMWw6l)jO;p0&!BxcE#p@5vL?akxh$y6S?F zcz2#eHSg&Y)p0m6zK-WwathtNZ=I;1HqxVNuuv_e*|S#WKEuqA;u*c%^wl*)x0d^`L6TS@>nACfg<7N=or3s|_HXxpl zWFdtIwe!psb8fpeGrV<~6WyuEelM=mC}IRRpE4p&c0^oe$wBXyycEUni2N%qWJiVP zUCMWCd4LAqoN^v~5W`tMoaK^NTJSCn<4csq??9B{bn{Pu_q{yc(0-7@Nw?N~lO7Ow zBRPd*{`NS)5furqU4PzLtJjCaJ+g;hpEhqT;O8FZ;ChkKpMY!INaN_HH7nGW%2`St=yh(L{~fxQVVZNx=*vWPWqle zReUExWi90C_gr<9nVe&)e?Q{IMf_&TLLP1CnH2V@Cu5jOl-CX| z%YPR}VB;RH*?$ln1BBu$C4=U4qFEtMN~6PRGqXK7MGkLYWO{}}9h$_Rj0q-&&{53# z?+NJpL(MIN5uB=;!~zOT9#Wq>mD#ouAAtXv_1eU2tz_FVn!vp0hRB8--=9!*XZ?O+ zz9r<-hb@QHznH{C#|5(2XKbEg@2q3P#BA@V)C~B)vV8@k&~-?c7-q>yekxHBVEY6-8G~a6^_RuQ?ZX#RcPRK%KBdz8>IWB&0|I;s_KfY?>Zn4+yW2AuA5{X0*|KiCV515U8&`FK)&Jk zV(?s7VLbw&nyNA>CuY}8wMyX;G%T3p+1Yi|tY%Pa(5j?9M7wUL^$LdB8n`#L1ow5b ztWRS`L4z<(2r-GEH8%(Ir0ztdZm#v8Ihc3EK3ThNfwjdEseB{mjP1Hpt*DbhRXJjx zwq3W_>T)zy!PL*0T(k9s9BkF_e-qYb&31D6!0y}#6ogAH$8lm#bt(zT?*YfkI z?W8&6x^BJoD@gc7R9oE~cU^a$^-Jibp)kBT__}Vh^#pRK!QP~OXm;I2*5fe01}i@g zJWt|H#k!r=D?inmYUx& zmQpYdrEkY>L%MVfX@^ERw3R#b8GQ3Q$B?!Q#-R-EkV8<^{AFV)1>;bz+JPmqkwGT93dSb%!k*~v)%-KZ5(>s9ROQ>@ zadB3}FpgtK4OlRfdq((piZ=~Mhow|yfz}}jndjRaAL`Nq|2S;)<(e&#w7E{?$vORd z)U^dxg;7MFlO=aO(e-`J=v*+)f^*lSk9QB&B{u;?39$)gFleErDb2{UEM^3O& z^>@QFes

    op+<#IGH!!KH3Yv;k90Z2MS_%`tH7cl>FO#`^c)Y=2cXe6;+&EQDsfF zD&a9bb5&W{3V`q+WNzWxy!sa7;5JoMvApc`vYzUd=p@MW0bFY=Ke;+HGl%mBA{nX;k9wN3&MJ{NGRgV`*=g^{V@ zlc+@%8eZyiq)e9EVhSv)2K5=3=qmS0ie+Uw%_$9l&zgeyq-uea-#1|VI+mbtkcU6woLMg2&3dJe+q8M$(IO7Ki~En~G? z;Yv?e5M60j7Qi)hl}i&+Yv^jRAoJvwaF&~v`gFMgPByv=64Hha6+p?qrhuQYwJthc zOj@P0bIr#|sRwyC&V;q(9GFLap=`o!K=Tg41Rbjh5(n^x$mi__rA>05lzh|4pT^xudUn$ zyti2UE6|WB(rBVKzK<@Dm}pM=8RfH(nOF{>%Px-Z5myt_&l~a#kc9rMO+4D5;n1cf z6AK~%Xs$Zj&}}(dyC~t>x96ZDmv$L4{JO$uRfcmiZEmEL%yGM*sj;-k!^l`#KzA5u zE-mIaos-~bHBP5F2L(CYu{5WP&gF$#E0XPSv7?1iDo^Qse z+ccU_4CebH81IVps2Bc3528>D|O``?w90FMv1chE9)L@*9MN0ddO#s5t z@Y%#1;{^bWq9;a4=swCq6X!v)Seb(Wt*qXqCOHO-hi)&1EhD2tSuNEZ&+W2`Hf;Z{ zm=>LPY!^Tnb311(X^KoX_enMl$vtx;PSxd@bhAT5ldySk*1xFI8vMwo4n4nQ@FR~s z_56yLFTVKV?4w>!(fpr#t)i`-2J6gz#OC>e{hkUmjmuFV{8}v-&T{|?bX?|qY%iqD&Xl}t;QF^~0cHR`4bE%oMSF(BiNm!-XkJgxMd4bVVbR&PAY`8%LJ~0y7SB|%T!TF zJ}{S!VArC&-Bw`p=4RIi4MWDoW77!OZJk|}M!(*p@L8CwrmqYRBM15$M=`k!^T8 zy9GLQ=&Aie-CHP8gCwhDOw(Vm-9Ab@`|M-zzRQ6JDwnVrNSy55~ph~UXRDcw+fKFR^Huo z^3}`p2RU;sHOno9YPZX>SP0!d9z1Y)R8|H77+mn)$B?5Mj~d0Sqy90@kql`W;!F~u zWjHMNIoc%RX^rOgp=QG%2zzpA~?|lrhyCE;RTM@ra(Smwgtrfji4UaomSM@tJNuEZ~2g5h_Pu^lBZ5(X|EA0oZJ85zo|Mn3H-eDxj=VvXD!0aQxfv}%kGhVfA-?6Mt< zfzytuMx3#XuR1oybg(T7Bt%B=Jc8tKW;y>FMYfjHhXa2b(V&L;Y3asTyl-?MjQ7j% zr7=p8=*VcF-q~&9sOl*j7wPN6cc1OpPy#Ot87k4vj=);>EyhOntw}}~!U_DJ3>sb2 zF=oF8WrYalQ=K1i{BbOfXB|`nrOpQ3*+2wwZ~r(<=dT?Xo+X8D5Ojl}{z%8G z8P^|=9ZON(J)pY>baQcENOwA5m^~4B2SIlbbhjYRX93)bEIx;H;nJ;Csm<4VeVZY; zm;~l$->yR(byL#ay3gy|3Z|)m+38XrUR!Ye#n26bZU}Vm1&rwuZ|8Ra_gHxq*z=%! z9&~I3wmi}?K7z}pI|RBzpj%?-FpnhiNXO<+U6~Hs7N37eXaDSUF^k~Pv3<1x!8Gh2 z>3Cg@%a->5=pF#Dff+ErN)uj>(57Qsei;hb&r2ksEdKW6A{|ArJ--1ur_lpu)6q5A zbVosV6m)X|vwt?-y#UyB!5h53AS&4hZ6bs=-RBJ*%%<-9nAdk7=x8_lXVX0h0OgVH z5zsvXy7Bb;s*COb=njC+mI0J={{-$?7L<1obO%9q#J~^;9pyib%TD*pcY1wa2Cz^b zDazDAduO=q*5UO?A&tx~@kC*3s#boDo36$~)@ zXWyP*K(`7FW|d8Z(6(O{?xoBOZZGJ(xN-80f(=s0JIv|rHiX%c7q*YR43vz_bsbcwS) z>-Y?bv)$_WOdU7>McBvX{uL?q*12C%o`+_BIKQ9!6{-4M1b0O$P!JCm#Ag@8PbrAw z)BzX7t6o1QiW?Z??y&>o)PVk)Bo=zw(-6`x>v*+VjvL#ama0)}iGV$rj-_U*3laX@ z*vnEg6gJzcS4??()D)FLyb^PT2+&TZri@f70hm#Bl~nWlClZr86M?6nVZ{w~7B+WbkxgV?J~$593Q{xjmM zkUzHEsYw4(#O?OP_%{qc&?<=Qg@X9c5oi0NC#XXEdKGcI{Y_OB>UBf^X*7MNUu&G% zgMc&MYT}RMo^kH%d&?zn0C77%mB>#Pac;v_;HUmqA^wV~A61?iYCqx|!M|1HO;Mjf z{IJ1SqI^D!xIOpG{Cx%SxhM~i!yCMQ>`}z+xohH|E8u?-@!L`Vm|^Psd&K`4>5+e` zXNoF?i?rvi$zOrE?Z2jSBx@Gi81U%>>uy*i%VbCU`*9l%cWpjzQ+Rz(@8)nAvF^Os zIb9BlkLyGDbWg0YeOYIV8ey;m46&4Xdp;~rD{{J_mPy)4L#COebW$_+#4zI!G(DPczvubR`#X=TCz88&7=|HqGKD3`oq5W3HUb~IQE4^`S2&_y z+%Eb=D@4?7JOLYk%z#WSkl6r>I`A8xgdVU0Jb^m;CdkCRfPZNdg24QuTj{0jbI<|q zMuuSk%cb4~x(xfv&`BTG2f#kLE}~JiY74MVv_+LgJ0RYV z)Kf($mNqQpUT;Lu6>!ytA7r~N9q zLCVWvt`ej&0Q7uOIpbD9M(XUm5j3`&~#c%=z(;}+dWGY`2 zBZm%cyLZ$d^zINlcaPpX;t!z+O%0-na*R027G{x!QQ}w`@=x`>3;wll9L4api0^@B zqW)9B92=K7pI=5FFN0<>;PoTGdhC`#V<>&AS`x%k=lU~c=g?aa== z=*sCO32m&;IVbK}2~Q&Id}DR}jQ!;sz%*WcmT0DX`qkPS-*2Jbc=_yUW&i9PLe2D< zu;)806GZ!YyN|NQE3i4WyU#`y8h>~d*8A#n8_y@_Y4^rQXOiIm>fpr}FPf)p^W^Tn&hy**oFAjUz+5ikq}?}r`K?CdWb#V=@hc*{WhQwgax+Ia z=b(d2_Q>ok=z4PAs6Re$|M6)^>0q`3sjT_RnWS?vd37dvHFB^T@ou)R97xlhpkqCR zTu08H3fGEL|9Cs~;6L=>{@FbspFI0rtnB(+=j?0$-DsS8VIDb8)%m;b{EH29x)Jsb z{%R)Kjgp+1WG4$`>8R*uzeTJ1_l+(8S^H`IT<0Sn_K%#MS>1Q`H2Zh|3k>p@c+W~a z-v~SFZ`h4jW~};rqjsf!&VJ;`S=zE-VIDHJa;=OOU9Q%zv8Y}wOx%sNhvMVSQO74eBl|rW19Sv`< zx|6{Nw9nhtWP0J%SY>VH1ZIr3QJ>Age*qip#FIW00kcG~tQu{LSv0ys|@ zD}~LW?=(caZP?s2U}wWlbUD+eP4CNEB>$8p^BsnSb7noTXf~t_i4!D_Nz-5fFIOthx7$t?imaeJSPyN3rmL~M-xi)aT$0Ac#!Wp@r=(J4}*)87&vh6n0X#FavmSgxaZst+UXt8+OYGs_3 zEi%P@plm}1aZrizTE37`znMgq2b>K<-X?EQi8h3lAV}oz*t`j++VONEU9Bb3l`!w^ ze`h)44v|-2-MHKKyO?2{g>m9O^qwh>$O?S}zb&XL2aZ-F>(^sRy@v^A-(M?)`2*_A zmrjdBt~41WCMv07x|FXb_Et*SN@{Wv+dv|jF67JAAn~zMN(a@%_We5&rApQd zl*-FwyfCPSRWF+vPh?VIDp5$)is@XUT1gA@pIG%at5&S$v&A6ergN!^FdVCzD^)^w zK`h6t%_@|z^(+x0?~R6d!R0w*q5;?0SQP}!o&*>;Ovz{Ipv-CA4q zu7+vU_Y2g&?cbp_?NrSZ=K8TG3&3t?F8C^cdaP6wN-- z(ee8bVMHPl9gX7|rC0$Qh1GRe$JUO~6@SoaV)JZWD@GaTjOC)c^kE4a(T zd3S3Mi*Qf`gYw?5^&w=8QR6u!_Mdm?Pb}b7iPRhBW{D#6u(QI@n2ob@GIXOFnET@ z7xST)hDwO10H)ZB-?y2)`vDdrieM-O-D2`MV|5w5iQao2?#*Ts2@}^e0}AdjR)3^0 zTOq8-dW>GP9<^#EkuRnTwM>v0&xchZngS7WMQblSUJj~WP9C^W4i_9M;N0|#lQ6v% zSts%Le`OW^ArHdrM5&L;Qh%GR=lqUZ&yCP(H+p+}P24-#Y;K9x4T}DH>{}g#6BV{94RK|aT+G_Sj}Udh8)HrZhQ8=e5v?r*Pg;y+vfrodG z4Ph!Pylk=N;K!4`m7nn{tkb2*$p8c6 zWrFcq)=%MFkj0}?#FlI0aInbdixVZSOO20Lf@7M)BVV9tSv$?3w=`KOp(d)Fs2DW} z@8EY8Y`8*s7M1U%V7L$HBv&sO22ecFNIUti355$@Cw1Btf`?D;8uZ8eS`K!1M=~He zM`_DPt6$+xMLXW-z5=^G(9Fw38^TtAn!xIw_Y&;B2pR8vAf*lOd)&G$fGijH!W;cknOEEK-uVOA@jgmB-gULzanP(Q%i-GUgkk`+PP$yKcx}h^bvG0zv=K1v2u}dC z9pBW?Ksc*A13LB{(=;-C?{99fsWr?F?A^`+8)@zUMOy-{%*CP0a53nB67VUHV__z8kaSL)skdbXia> z(0nV^V=mwNVRt!_X*<^AJb>+G{rC=g5yEDFs~n0oq?D-U2%@ zc{opW(!PHJ0n2B(d^21LJFTOwrZ0k~Kb>fIG$zpG>oCwXZ9j<}gmYIXmc=v=h}+G> zPG0_`c2VcRC~mhCi}@{9w#n{>CcEVILfjh5s7cB+O&3{A;4jAnn)I6NI`P00Z-?%e ztxa~1!H#33llHfx$!-^dWJwzVYrB0-cHe>BaLi8kAK#r~-5};+=W8c1e-v@8=~PC* zb`dnzLU0#=?LZgE*b?`5+Qn08EMv?ytd}OneM;1qH}&00@yY??xZ+g_jMs`+y~y`B z#jB{tcR9s##vR3TR8)LXJSGDYf{; z%3AW(jlA2W?``65ZQ^fRnCDd3;+GBCkjRR>>LDc{&l)gZQ)1xD+y{Vle;PPxa1QJK zG_Vuz1TVjRNc)?`gTVYQ0)+f4G`-KEam{-F{*A2p)>#d=D0; zoKM|88S(SO%PF-w2v?E}9$@=yIb@NxSA@bT}y`=b26j>=1ce^j^6 zTqdT#^B&C056gcXJkMER!6UvzS1lsm4)8F5TYNRFO-z9F{gDHE#{Au*`w#G=vA=x@ z_rZ|`6;A)}3ivyB@40u|Zhy~?9s839`~%zW-JN6$*iKwdDyids zP|Pe9$dBW~-~P}8+wLD75xm@}kJ2!cU#RiY>dPxsB-T%U{K`E%tiMmQ-M{%``$XB# zeN05|nm>RqakliG9DN$ESEgF>bE#sc5X39VRz_dfm$+(v4D@~6-I^MszThur8x*Ri r0(sfH);|dh568aOzr8Q=n>KIqvO(yV(|(w%6_0x3Q|e(~j)wRj31XAN literal 0 HcmV?d00001 diff --git a/plugins/org.eclipse.dd.tests.gdb/data/launch/bin/SpecialTestApp.exe b/plugins/org.eclipse.dd.tests.gdb/data/launch/bin/SpecialTestApp.exe new file mode 100755 index 0000000000000000000000000000000000000000..97775965e40792df4c7983d1ea27421660d19bd2 GIT binary patch literal 9446 zcmcIq3v650c|P|+={lwq+OiX8R$D5TW4Vb*NtRtZb{pAx*ou|-nar;1-caNf$(kZr z-b=?00>r7}Zk}gUK?AJAiojW2H0@AieXL8HwsYa2Zh!*Il5M~+V92l)kdbU~0k1RG zpxpPJheXLK@>q9>bN}c0|8vg$&-3z$k?~Q>vV=*ta0IEDr(ACU@bK+QG9Z$|6Fp*` z=oT$tQ8sWII>@pB3dO*4ksZoF4?GDuatCN;%4nNeCYEJx1%=G=BBABv{Rw2q+fiT; znSLp^0aif10y5@npqVMB59Zy_-wof)Nzlwjw(l2FZU)LTpLadx6_7C-`F_Yj-js~} zbg4LzF6B0qiskyrR9H#%tFow?Y}>8}AChHRPnPkJ*(bMXoK2H$1!O{1WupEPWY&ZF zEXzbbZBS2^>k(a~se5Yd`1iiK=ie>?U65E8lafF_VhBLef3E3o!{~D0&uDs9(`Pk} zrb+pqY5Itke?ik<(DX*orx7zADo=ZlA@4@tvMtNRtwNyB!YG%$`)+pFX5st!sY=-o zqf9OGec|7K!aoq?i(wShhDw<*3__}$Jn2`1T39J(O2z1uf1;OWrj!L>`E1q?N%fIm zjS96OlOrwlvf9(wUbx8>%YHo!a$>Sl4a%Zgk3un-EmgumOg>sGMgiQx2JFciO=XH@ zF?9Iwj-6wEUuvV+H9od;$nS?EgY}|eGI7K>ctDTkb5)9ewh0C*u6v7vF9)8fRXMVzVCxclIhD*J1nc(N``vHpNl0u{MDx z%QV)~bAjm9H&CpxmNh6)cJ))jn|$dIF~r{TK&zR#wfR5xjduvpG#ocICCjl{v!MeAWN>e-Q+c1h0gi$ zZWmQ(eD-Z<@1K6F8^UqK^6Y)^e`Vxa7WkEs>k+`Yk?UuNyWMjm*Uq}#vyI<08fQmt zoEy0TX8g)KUgU@L`*I)Tb!#>l9y8C{0ZX^NUs8?Lo%Y&Q7 zGvA@s^iQp=|6Tu=>6hb2KkXm8e6F+m@(laq;7goj5hTw^c%u=;r{8oNuby+JZ#3%H zr(brD9%H?lQ6O;AWK4CrX#pFa2cilgP(iZTO$c&H20foyM zCvJ%)uH|w9g`VvFcJGYsawctyN%|?)8u5+P42jdX$-6avK*L8gtOCZ7-liFHHGfNJiZxu6!~G~N#qmApGP)2aq90H z8oD>xgXM00av+7tG1>FbM72MB{rzz*VyTjc1Y1@9ob*Fj#9(`RnC%#^;cm>uA3B{l_FxUwFyt_ z8^n>m3x~|aZMT*C2;1_$OklSjQOrM*%$8>*Ggbm{+*q+33EPW(i%hTe41pW_9)Rn% z+E&X~fyGYXVcqcue8wDZKUz3($|l%i4=~q~vnsIkM7>zbsb?;o=i0xaKeaj4r&t@J zS`eg*8@Fu6Hg6)E&W81LwiXpr2j5%CW`igzFi4U+4ki&!TZDDG6WwKtW3oao;K`Ma zZ;Dz&ci)Zi^8upCT{!QivRRQXRHlOTWGz$9R*GSIU#*g_Wu~SuNvB7$rD8P<(vMbZ z$HQtS8-(fMgQMw6EuRXMD3!~lIA@2cd~PD0%S4%UDN`?J3+b?y6?RyBEbt={`^UdS z103#O+*Y?<4vYD6kV|F@nVPUXH!M_YQF4wgUt+6Us$iK|z(m;vC0le!Ss>;TxG_~u z7AC`MW-PGgwc5V_*?K023cA}qhS31JGC4_d=1C5YIU{aNi8c>V`1AyXx-l`g#r-CA zRa;u@(XsInVfXz6yw;rvc8&uZwl z&hvwEPBkq-2Mg6M@!Wtp(jmKa)LPuWC`J7WK@Rk+wdh`S*DKRHk+u+j-%9#CjI} zXRqn?d~`0h+D?~sQE~>*kHu0@t_Ww1?#L~=Yx{+>PP4Xqex;P-8x4aj#pt8{V|1?bdl&aNP6#Y9`kwoDu7*l5U0tJL)qZ(t1frrezk&^@*@?u9&8_ljTV=I-o`GVm-c7zAol?< z+BnzGao34k@4$p+$;sbxXoiy+Cp8vHR5MXQSS=hf_S1!gY@Q`Yko|NiF`2_W!SeRg zRha)Py5X8*i;n_ztty^L&>w8VF8^*OY-^ddw!LGi)4sZWnYG+XVEwea#nPpp01Fd_ zM$ueXp;(LXmfP=Lx^3xL$9-`dTfdgO#28m zcH&wewy58ROQ8;$ZSO+0(@?lI19ie#8wj|6 za(cADZUOU0vL4)f++2@(SW6en*-{+?G~Gm`CyKaFkR0q5(zusM7YF3l0XIY&^5uG3 zuIO`R#m!4K{PC8elEP4twTJVv6%-!#n$BsgwAqiopJUp4 zdj0RT;Tn3EW63*gP85r~3(lcU_eOHVaPz)pZrdR@2|AqTb!li$g#;7kLA;$w;^ls+_{$TD}l_nG~6T?sqoYk z7Dd3QreMKfsAo{Cid4B01u5KsZHO{?kwO%w3YoAVQn^!Q6jl&B8!0(~b-h?AFCcu# zaA2dpLaL=mq}WFS8%wN6sYwtJRk*nnsi5Fvt2!0k}|APZ!IR6(h?`Ow@uC zhQcLpU~pMGL!h?|ipAHU+KqV)?+RB#gF}nwcX?k9qWL^0haF^`L~*Sr_2j)a1WC{) zF{YS!*5aB%d%TM%KySO|0m#^+ZXfcm^t}P^DlS5=8$6a}q7L&mWEGg|4&!Igy8s^V zG=NGS-en9Sb5@dmapzG0@;YdfsLQkm8KEohD|lD29ff$`Vf?Z@^I>G(ZxH7l$3EzB zZJ=NBSU09T@)Bh7ct>&pdK?7C9`#69k&PbjRGx<(?^>wGdmN*83OMUZKO9?cK(80L zNyaZnveD!CN@C%45KH%b3l*%Y?9G?4h*Ar5%w-Z?^8wz(CGbz)ZCOuxfCZK10K{SW|7&xjVV~clG{O)s2^8lnC>v08{?O^?QXU>^$ zu|3j1Z_?wPn+Lrf@Jyl(^FJUPd%e)>g&yO?BxC!Z!GK8m07_R3{_jdC1@tt;3}w zzq^@a&^s6DWpOF_pGF8}gQgbg9YXN!GsXZ-zieBicM*DgMf^FBH1%d7fssc2<@^SGjw2hP`uR=vo(Wksu5k9W?BRxjGz2|IEHQS+&i zOEo!fDw?fOcg~9DwnWW?isnjy_F^7Wv>Fkd*A&fd3&xY)XE*|9BP6r$aQGb%iSrSm zqh~+PJBsF8LE_yqk|Vz);+@UWYGvenq2y{tCPtJlFn&o-OnNN=3_qF-tEcgmb{p7q5m?OFt(FmfZ zyU2VJCK$&(EVefKktFA=}!wg4aTtPPYWx=F3|E@8K8y!co>l1 z(EvcNl6RJu^!v84O%1`n)y{}NN6Wc52V^d%IcJWKfw0~hQ$6fP6dL?KRKbE~x-kh8GNTR*#A?HN~N7i!q z-%47ym-Ha*>68TAyNJ$$X8d!c@;mrvK%4Qg9OHwx8%*XqJg=8_H|c*Fw5d-5_4&Hi zp9SRipqDh=51jPRK@aHmFSA#Pe*(=0IB2O|#-&)YY|=z$#%jQED4GlS1tl}8h4_2v`3ziWK&&K=|a z-qF#6BZvG$J9dtbun}x3&Lg$VDW4al3mEd>2f`md^5BjK#)bsXGwL4+P?LX8z_$ck zkmA%d$A0(!QA}3-!lObLTl_DF!NK`|G%PyuqWk9kt3ON3Yxk*tQZzH5A6EQArkpFy z{hfmKWrOv drm = + new DataRequestMonitor(fSession.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + fWait.setReturnInfo(getData()); + } + fWait.waitFinished(getStatus()); + } + }; + + // Evaluate the expression (asynchronously) + fSession.getExecutor().submit(new Runnable() { + public void run() { + fExpressionService.getFormattedExpressionValue(formattedValueDMC, drm); + } + }); + + // Wait for completion + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + assertTrue(fWait.getMessage(), fWait.isOK()); + + // Return the string formatted by the back-end + String result = ""; + Object returnInfo = fWait.getReturnInfo(); + if (returnInfo instanceof FormattedValueDMData) + result = ((FormattedValueDMData) returnInfo).getFormattedValue(); + return new Addr64(result); + } + + /* ------------------------------------------------------------------------ + * getInstruction + * ------------------------------------------------------------------------ + * Issues a disassembly request. The result is stored in fWait. + * ------------------------------------------------------------------------ + * Typical usage: + * getInstruction(dmc, start, end); + * fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + * assertTrue(fWait.getMessage(), fWait.isOK()); + * ------------------------------------------------------------------------ + * @param dmc the data model context + * @param start the start address (null == $pc) + * @param end the end address + * @throws InterruptedException + * ------------------------------------------------------------------------ + */ + private void getInstruction(final IDisassemblyDMContext dmc, + final BigInteger startAddress, final BigInteger endAddress) + throws InterruptedException + { + // Set the Data Request Monitor + final DataRequestMonitor drm = + new DataRequestMonitor(fSession.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + fWait.setReturnInfo(getData()); + } + fWait.waitFinished(getStatus()); + } + }; + + // Issue the get memory request + fSession.getExecutor().submit(new Runnable() { + public void run() { + fDisassembly.getInstructions(dmc, startAddress, endAddress, drm); + } + }); + } + + /* ------------------------------------------------------------------------ + * getInstruction + * ------------------------------------------------------------------------ + * Issues a disassembly request. The result is stored in fWait. + * ------------------------------------------------------------------------ + * Typical usage: + * getInstruction(dmc, start, end); + * fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + * assertTrue(fWait.getMessage(), fWait.isOK()); + * ------------------------------------------------------------------------ + * @param dmc the data model context + * @param fucntion the function + * @param linenum the line + * @param count the instruction count + * @throws InterruptedException + * ------------------------------------------------------------------------ + */ + private void getInstruction(final IDisassemblyDMContext dmc, + final String function, final int linenum, final int count) + throws InterruptedException + { + // Set the Data Request Monitor + final DataRequestMonitor drm = + new DataRequestMonitor(fSession.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + fWait.setReturnInfo(getData()); + } + fWait.waitFinished(getStatus()); + } + }; + + // Issue the get memory request + fSession.getExecutor().submit(new Runnable() { + public void run() { + fDisassembly.getInstructions(dmc, function, linenum, count, drm); + } + }); + } + + /* ------------------------------------------------------------------------ + * getMixedInstruction + * ------------------------------------------------------------------------ + * Issues a disassembly request. The result is stored in fWait. + * ------------------------------------------------------------------------ + * Typical usage: + * getInstruction(dmc, start, end); + * fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + * assertTrue(fWait.getMessage(), fWait.isOK()); + * ------------------------------------------------------------------------ + * @param dmc the data model context + * @param start the start address (null == $pc) + * @param end the end address + * @throws InterruptedException + * ------------------------------------------------------------------------ + */ + private void getMixedInstruction(final IDisassemblyDMContext dmc, + final BigInteger startAddress, final BigInteger endAddress) + throws InterruptedException + { + // Set the Data Request Monitor + final DataRequestMonitor drm = + new DataRequestMonitor(fSession.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + fWait.setReturnInfo(getData()); + } + fWait.waitFinished(getStatus()); + } + }; + + // Issue the get memory request + fSession.getExecutor().submit(new Runnable() { + public void run() { + fDisassembly.getMixedInstructions(dmc, startAddress, endAddress, drm); + } + }); + } + + + /* ------------------------------------------------------------------------ + * getMixedInstruction + * ------------------------------------------------------------------------ + * Issues a disassembly request. The result is stored in fWait. + * ------------------------------------------------------------------------ + * Typical usage: + * getInstruction(dmc, start, end); + * fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + * assertTrue(fWait.getMessage(), fWait.isOK()); + * ------------------------------------------------------------------------ + * @param dmc the data model context + * @param start the start address (null == $pc) + * @param end the end address + * @throws InterruptedException + * ------------------------------------------------------------------------ + */ + private void getMixedInstruction(final IDisassemblyDMContext dmc, + final String function, final int linenum, final int count) + throws InterruptedException + { + // Set the Data Request Monitor + final DataRequestMonitor drm = + new DataRequestMonitor(fSession.getExecutor(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + fWait.setReturnInfo(getData()); + } + fWait.waitFinished(getStatus()); + } + }; + + // Issue the get memory request + fSession.getExecutor().submit(new Runnable() { + public void run() { + fDisassembly.getMixedInstructions(dmc, function, linenum, count, drm); + } + }); + } + + // ======================================================================== + // Test Cases + // ------------------------------------------------------------------------ + // Templates: + // ------------------------------------------------------------------------ + // @ Test + // public void basicTest() { + // // First test to run + // assertTrue("", true); + // } + // ------------------------------------------------------------------------ + // @ Test(timeout=5000) + // public void timeoutTest() { + // // Second test to run, which will timeout if not finished on time + // assertTrue("", true); + // } + // ------------------------------------------------------------------------ + // @ Test(expected=FileNotFoundException.class) + // public void exceptionTest() throws FileNotFoundException { + // // Third test to run which expects an exception + // throw new FileNotFoundException("Just testing"); + // } + // ======================================================================== + + /////////////////////////////////////////////////////////////////////////// + // getMemory tests + /////////////////////////////////////////////////////////////////////////// + + // ------------------------------------------------------------------------ + // readWithNullContext + // ------------------------------------------------------------------------ + @Test(timeout=20000) + public void readWithNullContext() throws Throwable { + + // Setup call parameters + BigInteger startAddress = null; + BigInteger endAddress = null; + + // Perform the test + fWait.waitReset(); + getInstruction(null, startAddress, endAddress); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + + // Verify the result + String expected = "Unknown context type"; + assertFalse(fWait.getMessage(), fWait.isOK()); + assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'", + fWait.getMessage().contains(expected)); + } + + // ------------------------------------------------------------------------ + // readWithInvalidAddress + // ------------------------------------------------------------------------ + @Test(timeout=20000) + public void readWithInvalidAddress() throws Throwable { + + // Setup call parameters + BigInteger startAddress = BigInteger.ZERO; + BigInteger endAddress = null; + + // Perform the test + fWait.waitReset(); + getInstruction(fGdbControlDmc, startAddress, endAddress); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + + // Verify the result + String expected = "Cannot access memory at address"; + assertFalse(fWait.getMessage(), fWait.isOK()); + assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'", + fWait.getMessage().contains(expected)); + } + + // ------------------------------------------------------------------------ + // readWithNullAddress + // ------------------------------------------------------------------------ + @Test(timeout=20000) + public void readWithNullAddress() throws Throwable { + + // Setup call parameters + BigInteger startAddress = null; + BigInteger endAddress = null; + + // Perform the test + fWait.waitReset(); + getInstruction(fGdbControlDmc, startAddress, endAddress); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + + // Verify the result + assertTrue(fWait.getMessage(), fWait.isOK()); + IInstruction[] result = (IInstruction[]) fWait.getReturnInfo(); + assertTrue("No instruction retrieved", result.length != 0); + } + + // ------------------------------------------------------------------------ + // readWithValidAddress + // ------------------------------------------------------------------------ + @Test(timeout=20000) + public void readWithValidAddress() throws Throwable { + + // Setup call parameters + Addr64 main = (Addr64) evaluateExpression("&main"); + BigInteger startAddress = main.getValue(); + BigInteger endAddress = null; + + // Perform the test + fWait.waitReset(); + getInstruction(fGdbControlDmc, startAddress, endAddress); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + + // Verify the result + assertTrue(fWait.getMessage(), fWait.isOK()); + IInstruction[] result = (IInstruction[]) fWait.getReturnInfo(); + assertTrue("No instruction retrieved", result.length != 0); + } + + // ------------------------------------------------------------------------ + // readWithInvalidFilename + // ------------------------------------------------------------------------ + @Test(timeout=20000) + public void readWithValidFunction() throws Throwable { + + // Setup call parameters + String filename = INVALID_FILE_NAME; + int linenum = 1; + int count = -1; + + // Perform the test + fWait.waitReset(); + getInstruction(fGdbControlDmc, filename, linenum, count); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + + // Verify the result + String expected = "Invalid filename"; + assertFalse(fWait.getMessage(), fWait.isOK()); + assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'", + fWait.getMessage().contains(expected)); + } + + // ------------------------------------------------------------------------ + // readWithInvalidLineNumber + // ------------------------------------------------------------------------ + @Test(timeout=20000) + public void readWithInvalidLineNumber() throws Throwable { + + // Setup call parameters + String filename = FILE_NAME; + int linenum = -1; + int count = -1; + + // Perform the test + fWait.waitReset(); + getInstruction(fGdbControlDmc, filename, linenum, count); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + + // Verify the result + String expected = "Invalid line number"; + assertFalse(fWait.getMessage(), fWait.isOK()); + assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'", + fWait.getMessage().contains(expected)); + } + + // ------------------------------------------------------------------------ + // readWithValidFilename + // ------------------------------------------------------------------------ + @Test(timeout=20000) + public void readWithValidFilename() throws Throwable { + + // Setup call parameters + String filename = FILE_NAME; + int linenum = LINE_NUMBER; + int count = -1; + + // Perform the test + fWait.waitReset(); + getInstruction(fGdbControlDmc, filename, linenum, count); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + + // Verify the result + assertTrue(fWait.getMessage(), fWait.isOK()); + IInstruction[] result = (IInstruction[]) fWait.getReturnInfo(); + assertTrue("No instruction retrieved", result.length != 0); + } + + // ------------------------------------------------------------------------ + // readWithLineCount + // ------------------------------------------------------------------------ + @Test(timeout=20000) + public void readWithLineCount() throws Throwable { + + // Setup call parameters + String filename = FILE_NAME; + int linenum = LINE_NUMBER; + int count = 5; + + // Perform the test + fWait.waitReset(); + getInstruction(fGdbControlDmc, filename, linenum, count); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + + // Verify the result + assertTrue(fWait.getMessage(), fWait.isOK()); + IInstruction[] result = (IInstruction[]) fWait.getReturnInfo(); + assertTrue("Wrong number of instructions retrieved, expected " + count + ", got " + result.length, + result.length == count); + } + + // ------------------------------------------------------------------------ + // readMixedWithValidAddress + // ------------------------------------------------------------------------ + @Test(timeout=20000) + public void readMixedWithValidAddress() throws Throwable { + + // Setup call parameters + Addr64 main = (Addr64) evaluateExpression("&main"); + BigInteger startAddress = main.getValue(); + BigInteger endAddress = null; + + // Perform the test + fWait.waitReset(); + getMixedInstruction(fGdbControlDmc, startAddress, endAddress); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + + // Verify the result + assertTrue(fWait.getMessage(), fWait.isOK()); + IMixedInstruction[] result = (IMixedInstruction[]) fWait.getReturnInfo(); + assertTrue("No instruction retrieved", result.length != 0); + } + + // ------------------------------------------------------------------------ + // readMixedWithLineCount + // ------------------------------------------------------------------------ + @Test(timeout=20000) + public void readMixedWithLineCount() throws Throwable { + + // Setup call parameters + String filename = FILE_NAME; + int linenum = LINE_NUMBER; + int count = 5; + + // Perform the test + fWait.waitReset(); + getMixedInstruction(fGdbControlDmc, filename, linenum, count); + fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + + // Verify the result + assertTrue(fWait.getMessage(), fWait.isOK()); + IMixedInstruction[] result = (IMixedInstruction[]) fWait.getReturnInfo(); + int total = 0; + for (IMixedInstruction mixed : result) { + IInstruction[] inst = mixed.getInstructions(); + total += inst.length; + } + assertTrue("Wrong number of instructions retrieved, expected " + count + ", got " + result.length, + total == count); + } + +} diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/LaunchSequence.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/LaunchSequence.java index 1519319ee3a..52cd80c287c 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/LaunchSequence.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/LaunchSequence.java @@ -34,6 +34,7 @@ import org.eclipse.dd.mi.service.CSourceLookup; import org.eclipse.dd.mi.service.ExpressionService; import org.eclipse.dd.mi.service.MIBreakpoints; import org.eclipse.dd.mi.service.MIBreakpointsManager; +import org.eclipse.dd.mi.service.MIDisassembly; import org.eclipse.dd.mi.service.MIMemory; import org.eclipse.dd.mi.service.MIRegisters; import org.eclipse.dd.mi.service.MIStack; @@ -226,6 +227,10 @@ public class LaunchSequence extends Sequence { public void execute(RequestMonitor requestMonitor) { new MIRegisters(fSession).initialize(requestMonitor); }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new MIDisassembly(fSession).initialize(requestMonitor); + }}, /*new Step() { public void execute(RequestMonitor requestMonitor) { new GDBVariables(fSession).initialize(requestMonitor); }},*/ diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/ShutdownSequence.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/ShutdownSequence.java index 787826a4a29..1a4ce69ad4f 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/ShutdownSequence.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/ShutdownSequence.java @@ -23,6 +23,7 @@ import org.eclipse.dd.mi.service.CSourceLookup; import org.eclipse.dd.mi.service.ExpressionService; import org.eclipse.dd.mi.service.MIBreakpoints; import org.eclipse.dd.mi.service.MIBreakpointsManager; +import org.eclipse.dd.mi.service.MIDisassembly; import org.eclipse.dd.mi.service.MIMemory; import org.eclipse.dd.mi.service.MIRegisters; import org.eclipse.dd.mi.service.MIStack; @@ -59,6 +60,7 @@ public class ShutdownSequence extends Sequence { requestMonitor.done(); } }, + new Step() { @Override public void execute(RequestMonitor requestMonitor) { shutdownService(MIDisassembly.class, requestMonitor); }}, new Step() { @Override public void execute(RequestMonitor requestMonitor) { shutdownService(MIRegisters.class, requestMonitor); }}, new Step() { // Uninstall the breakpoints before the service is shut down. diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java index 9ff059d98fe..114ee8324c7 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java @@ -89,7 +89,7 @@ public class TestLaunchDelegate extends AbstractCLaunchDelegate } } - private void launchLocalDebugSession( ILaunchConfiguration config, ILaunch l, IProgressMonitor monitor ) throws CoreException { + private void launchLocalDebugSession( final ILaunchConfiguration config, ILaunch l, IProgressMonitor monitor ) throws CoreException { if ( monitor.isCanceled() ) { return; } @@ -151,8 +151,9 @@ public class TestLaunchDelegate extends AbstractCLaunchDelegate GDBControl gdbControl = tracker.getService(GDBControl.class); if (gdbControl != null) { IMemoryBlockRetrieval memRetrieval = new DsfMemoryBlockRetrieval( - GDB_DEBUG_MODEL_ID, gdbControl.getGDBDMContext()); + GDB_DEBUG_MODEL_ID, config, gdbControl.getGDBDMContext()); launch.getSession().registerModelAdapter(IMemoryBlockRetrieval.class, memRetrieval); + ((DsfMemoryBlockRetrieval) memRetrieval).initialize(); } tracker.dispose(); return null; diff --git a/tests/.project b/tests/.project new file mode 100644 index 00000000000..ef6405948af --- /dev/null +++ b/tests/.project @@ -0,0 +1,11 @@ + + + tests + + + + + + + + From abc958a96ae75817276e0218bb620f05ecfdf047 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 4 Mar 2008 05:20:05 +0000 Subject: [PATCH 282/834] [220446] Updated the timers example for use with the "DSF Common Patterns" document. --- .../org.eclipse.dd.examples.dsf/plugin.xml | 2 +- .../filebrowser/FileBrowserVMProvider.java | 1 + .../dsf/filebrowser/FileVMContext.java | 5 + .../examples/dsf/filebrowser/FileVMNode.java | 2 +- .../dd/examples/dsf/timers/AlarmService.java | 365 ++++++------------ .../dsf/timers/AlarmStatusVMNode.java | 112 ------ .../dd/examples/dsf/timers/AlarmsVMNode.java | 217 +++-------- .../dsf/timers/ServicesShutdownSequence.java | 29 +- .../dsf/timers/ServicesStartupSequence.java | 13 +- .../dd/examples/dsf/timers/TimerService.java | 224 ++++------- .../examples/dsf/timers/TimersRootVMNode.java | 58 +++ ...ModelAdapter.java => TimersVMAdapter.java} | 35 +- .../dd/examples/dsf/timers/TimersVMNode.java | 172 +++++---- .../examples/dsf/timers/TimersVMProvider.java | 114 +++--- .../dd/examples/dsf/timers/TimersView.java | 238 +++++++----- .../timers/TimersViewColumnPresentation.java | 8 - ...Modifier.java => TriggerCellModifier.java} | 139 ++++--- .../examples/dsf/timers/TriggersVMNode.java | 203 ++++++++++ .../dd/examples/dsf/timers/package.html | 28 -- 19 files changed, 916 insertions(+), 1049 deletions(-) delete mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmStatusVMNode.java create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersRootVMNode.java rename plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/{TimersModelAdapter.java => TimersVMAdapter.java} (50%) rename plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/{AlarmCellModifier.java => TriggerCellModifier.java} (65%) create mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TriggersVMNode.java delete mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/package.html diff --git a/plugins/org.eclipse.dd.examples.dsf/plugin.xml b/plugins/org.eclipse.dd.examples.dsf/plugin.xml index 22ed17e9762..d6326a29615 100644 --- a/plugins/org.eclipse.dd.examples.dsf/plugin.xml +++ b/plugins/org.eclipse.dd.examples.dsf/plugin.xml @@ -13,7 +13,7 @@ icon="icons/timer.gif" category="org.eclipse.dd.examples.dsf" class="org.eclipse.dd.examples.dsf.timers.TimersView" - id="org.eclipse.dd.dsf.examples.model.TimersAlarmsView"> + id="org.eclipse.dd.examples.dsf.TimersView"> rm) { - rm.setStatus(new Status(IStatus.OK, DsfUIPlugin.PLUGIN_ID, IDsfService.NOT_SUPPORTED, "", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.NOT_SUPPORTED, "", null)); //$NON-NLS-1$ rm.done(); } diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmService.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmService.java index ec4ef5c0e6b..830580c4e57 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmService.java +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmService.java @@ -11,163 +11,114 @@ package org.eclipse.dd.examples.dsf.timers; import java.util.Hashtable; +import java.util.LinkedHashMap; import java.util.Map; -import java.util.TreeMap; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.AbstractDMContext; import org.eclipse.dd.dsf.datamodel.AbstractDMEvent; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.datamodel.IDMData; -import org.eclipse.dd.dsf.datamodel.IDMService; import org.eclipse.dd.dsf.service.AbstractDsfService; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; -import org.eclipse.dd.examples.dsf.timers.TimerService.TimerDMC; -import org.eclipse.dd.examples.dsf.timers.TimerService.TimerData; -import org.eclipse.dd.examples.dsf.timers.TimerService.TimerTickEvent; +import org.eclipse.dd.examples.dsf.timers.TimerService.TimerDMContext; +import org.eclipse.dd.examples.dsf.timers.TimerService.TimerTickDMEvent; import org.osgi.framework.BundleContext; /** - * Alarm service tracks a set of alarm objects which are occacionally - * triggered by the timers from the TimerService. + * The alarm service tracks triggers and alarms. Triggers have a specified + * value and can be created and removed independently. Alarms are created + * for a specific timer and a trigger, and can indicate whether an alarm is + * triggered. *

    * This service depends on the TimerService, so the TimerService has to be - * running before this service is initialized. However, the alarm objects - * themeselves do not depend on the timers, they can be listed, created, - * removed without any timers present. So a separate context object exists - * to track alarm status, which requires both an alarm and a timer in order - * to exist. + * initialized before this service is initialized. + *

    */ public class AlarmService extends AbstractDsfService - implements IDMService { - /** - * Event indicating that the list of alarms is changed and the clients - * which display alarms should re-query this list. - */ - public class AlarmsChangedEvent extends AbstractDMEvent { - AlarmsChangedEvent() { super(fAlarmsContext); } - } + /** Event indicating that the list of triggers is changed. */ + @Immutable + public static class TriggersChangedEvent {} - /** - * Context representing an alarm tracked by this service. - */ - public static class AlarmDMC extends AbstractDMContext { + /** Context representing an alarm tracked by this service. */ + @Immutable + public static class TriggerDMContext extends AbstractDMContext { /** Alarm number, also index into alarm map */ - final int fAlarm; + final int fNumber; - public AlarmDMC(AlarmService service, int alarm) { - super(service, new IDMContext[] { service.fAlarmsContext }); - fAlarm = alarm; + private TriggerDMContext(String sessionId, int number) { + super(sessionId, new IDMContext[0]); + fNumber = number; } @Override public boolean equals(Object other) { - return baseEquals(other) && ((AlarmDMC)other).fAlarm == fAlarm; + return baseEquals(other) && + ((TriggerDMContext)other).fNumber == fNumber; + } + + public int getTriggerNumber() { + return fNumber; } @Override - public int hashCode() { return baseHashCode() + fAlarm; } + public int hashCode() { + return baseHashCode() + fNumber; + } + @Override - public String toString() { return baseToString() + ".alarm[" + fAlarm + "]"; } //$NON-NLS-1$ //$NON-NLS-2$ + public String toString() { + return baseToString() + ".trigger[" + fNumber + "]"; + } } - /** - * Data object containing information about the alarm. This object - * references internal service data, so it has to guard agains this data - * being obsolete. - */ - public class AlarmData implements IDMData { - private int fAlarmNumber; - - AlarmData(int alarmNumber) { fAlarmNumber = alarmNumber; } - public boolean isValid() { return fAlarms.containsKey(fAlarmNumber); } - public int getAlarmNumber() { return fAlarmNumber; } - - public int getTriggeringValue() { - if (!isValid()) return -1; - return fAlarms.get(fAlarmNumber); - } - } - /** * Context representing the "triggered" status of an alarm with respect to - * a specific timer. Having this object separate from the alarm itself - * allows the alarm object to exist independently of the timers. + * a specific timer. */ - public class AlarmStatusContext extends AbstractDMContext { - /** - * An alarm status requires both a timer and alarm context, both of which - * become parents of the status context. - */ - public AlarmStatusContext(AbstractDsfService service, TimerDMC timerCtx, AlarmDMC alarmCtx) { - super(service.getSession().getId(), new IDMContext[] { timerCtx, alarmCtx }); + @Immutable + public static class AlarmDMContext extends AbstractDMContext { + // An alarm requires both a timer and alarm context, both of which + // become parents of the alarm context. + // Note: beyond the parent contexts this context does not contain + // any other data, because no other data is needed. + private AlarmDMContext(String sessionId, + TimerDMContext timerCtx, TriggerDMContext alarmCtx) + { + super(sessionId, new IDMContext[] { timerCtx, alarmCtx }); } @Override public boolean equals(Object other) { return baseEquals(other); } + @Override - public int hashCode() { return baseHashCode(); } + public int hashCode() { return baseHashCode(); } + @Override public String toString() { - return baseToString() + ":alarm_status"; //$NON-NLS-1$ + return baseToString() + ":alarm"; //$NON-NLS-1$ } } /** - * Data about alarm status. No surprises here. - * + * Event indicating that an alarm has been triggered by a timer. */ - public class AlarmStatusData implements IDMData { - private boolean fIsTriggered; - - public boolean isValid() { return true; } - AlarmStatusData(boolean triggered) { fIsTriggered = triggered; } - public boolean isTriggered() { return fIsTriggered; } - } - - /** - * Event indicating that an alarm has been triggered by a timer. The - * status context object's parents indicate which alarm and timer are - * involved. - */ - public class AlarmTriggeredEvent extends AbstractDMEvent { - public AlarmTriggeredEvent(AlarmStatusContext context) { + public class AlarmTriggeredEvent extends AbstractDMEvent { + public AlarmTriggeredEvent(AlarmDMContext context) { super(context); } } + private int fTriggerNumberCounter = 1; + private Map fTriggers = + new LinkedHashMap(); - /** Parent context for all alarms */ - private final IDMContext fAlarmsContext; - - /** Counter for generating alarm numbers */ - private int fAlarmCounter = 1; - - /** Map holding the alarms */ - private Map fAlarms = new TreeMap(); - - /** Constructor requires only the session for this service */ AlarmService(DsfSession session) { super(session); - fAlarmsContext = new AbstractDMContext(this, new IDMContext[0]) { - private final Object fHashObject = new Object(); - - @Override - public boolean equals(Object obj) { return (this == obj); }; - - @Override - public int hashCode() { return fHashObject.hashCode(); } - - @Override - public String toString() { return "#alarms"; } //$NON-NLS-1$ - }; } @Override @@ -181,17 +132,20 @@ public class AlarmService extends AbstractDsfService new RequestMonitor(getExecutor(), requestMonitor) { @Override protected void handleOK() { + // After super-class is finished initializing + // perform TimerService initialization. doInitialize(requestMonitor); }}); } - /** - * Initialization routine registers the service, and adds it as a listener - * to service events. - */ private void doInitialize(RequestMonitor requestMonitor) { + // Add this class as a listener for service events, in order to receive + // TimerTickEvent events. getSession().addServiceEventListener(this, null); + + // Register service register(new String[]{AlarmService.class.getName()}, new Hashtable()); + requestMonitor.done(); } @@ -204,158 +158,95 @@ public class AlarmService extends AbstractDsfService public boolean isValid() { return true; } - @SuppressWarnings("unchecked") - public void getModelData(IDMContext dmc, DataRequestMonitor rm) { - if (dmc instanceof AlarmDMC) { - getAlarmData((AlarmDMC)dmc, (DataRequestMonitor)rm); - return; - } else if (dmc instanceof AlarmStatusContext) { - getAlarmStatusData((AlarmStatusContext)dmc, (DataRequestMonitor)rm); - return; - } else if (dmc == fAlarmsContext) { - ((DataRequestMonitor)rm).setData(this); - } else { - rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ - } - rm.done(); - } - - /** - * Listener for timer ticks events. If a timer triggers an alarm, this - * service needs to issue an alarm triggered event. - * @param event - */ @DsfServiceEventHandler - public void eventDispatched(TimerTickEvent event) { - final TimerDMC timerContext = event.getDMContext(); + public void eventDispatched(TimerTickDMEvent event) { + final TimerDMContext timerContext = event.getDMContext(); - getServicesTracker().getService(TimerService.class).getTimerData( - event.getDMContext(), - new DataRequestMonitor(getExecutor(), null) { - @Override - protected void handleCompleted() { - if (!getStatus().isOK()) return; - checkAlarmsForTimer(timerContext, getData().getTimerValue()); - } - @Override public String toString() { return "Got timer data: " + getData(); } //$NON-NLS-1$ - }); + int timerValue = getServicesTracker().getService(TimerService.class). + getTimerValue(event.getDMContext()); + + // If a timer triggers an alarm, this service needs to issue an alarm + // triggered event. + checkAlarmsForTimer(timerContext, timerValue); } - /** - * Checks the existing alarms for whether they are triggered by given timer. - * @param timerContext Context of the timer that is changed. - * @param timerValue Current value of the timer. - */ - private void checkAlarmsForTimer(TimerDMC timerContext, int timerValue) { - for (Map.Entry entry : fAlarms.entrySet()) { + private void checkAlarmsForTimer(TimerDMContext timerContext, int timerValue) { + // Check the existing alarms for whether they are triggered by given + // timer. + for (Map.Entry entry : fTriggers.entrySet()) { if (timerValue == entry.getValue()) { - getSession().dispatchEvent(new AlarmTriggeredEvent( - new AlarmStatusContext(this, timerContext, new AlarmDMC(this, entry.getKey()))), - getProperties()); + // Generate the AlarmTriggeredEvent + AlarmDMContext alarmCtx = new AlarmDMContext( + getSession().getId(), timerContext, entry.getKey()); + getSession().dispatchEvent( + new AlarmTriggeredEvent(alarmCtx), getProperties()); } } } - /** - * Retrieves the list of alarm contexts. - * - *
    Note: this method doesn't need to be asynchronous, because all the - * data is stored locally. But using an asynchronous method makes this a - * more applicable example. - * - * @param rm Return data token. - */ - public void getAlarms(DataRequestMonitor rm) { - AlarmDMC[] alarmContexts = new AlarmDMC[fAlarms.size()]; - int i = 0; - for (int alarm : fAlarms.keySet()) { - alarmContexts[i++] = new AlarmDMC(this, alarm); + /** Returns the list of triggers. */ + public TriggerDMContext[] getTriggers() { + return fTriggers.keySet().toArray(new TriggerDMContext[fTriggers.size()]); + } + + /** Returns the trigger value. */ + public int getTriggerValue(TriggerDMContext alarmCtx) { + Integer value = fTriggers.get(alarmCtx); + if (value != null) { + return value; + } else { + return -1; } - rm.setData(alarmContexts); - rm.done(); } - /** - * Retrieves the data object for given alarm context. - * - *
    Note: likewise this method doesn't need to be asynchronous. - */ - public void getAlarmData(AlarmDMC alarmCtx, DataRequestMonitor rm) { - if (!fAlarms.containsKey(alarmCtx.fAlarm)) { - rm.setStatus(new Status( - IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, INVALID_HANDLE, "Alarm context invalid", null)); //$NON-NLS-1$ - rm.done(); - return; + /** Returns the alarm context for given timer and trigger contexts. */ + public AlarmDMContext getAlarmS(TriggerDMContext alarmCtx, TimerDMContext timerCtx) { + return new AlarmDMContext(getSession().getId(), timerCtx, alarmCtx); + } + + /** Returns true if the given alarm is triggered */ + public boolean isAlarmTriggered(AlarmDMContext alarmCtx) { + // Extract the timer and trigger contexts. They should always be part + // of the alarm. + TimerService.TimerDMContext timerCtx = DMContexts.getAncestorOfType( + alarmCtx, TimerService.TimerDMContext.class); + TriggerDMContext triggerCtx = DMContexts.getAncestorOfType( + alarmCtx, TriggerDMContext.class); + + assert triggerCtx != null && timerCtx != null; + + // Find the trigger and check whether the timers value has surpassed it. + if (fTriggers.containsKey(triggerCtx)) { + int timerValue = getServicesTracker().getService(TimerService.class). + getTimerValue(timerCtx); + + return timerValue >= fTriggers.get(triggerCtx); } - rm.setData(new AlarmData(alarmCtx.fAlarm)); - rm.done(); - } - - /** - * Returns the alarm status context object, for given timer and alarms. - * - *
    Note: this method is synchronous... for variety. - */ - public AlarmStatusContext getAlarmStatus(AlarmDMC alarmCtx, TimerDMC timerCtx) { - return new AlarmStatusContext(this, timerCtx, alarmCtx); - } - - /** - * Returns the data object for given alarm status object. - */ - public void getAlarmStatusData(AlarmStatusContext alarmStatusCtx, final DataRequestMonitor rm) { - final TimerService.TimerDMC timerCtx = DMContexts.getAncestorOfType( - alarmStatusCtx, TimerService.TimerDMC.class); - final AlarmDMC alarmCtx = DMContexts.getAncestorOfType( - alarmStatusCtx, AlarmDMC.class); - - assert alarmCtx != null && timerCtx != null; - getServicesTracker().getService(TimerService.class).getTimerData( - timerCtx, - new DataRequestMonitor(getExecutor(), rm) { - @Override - protected void handleOK() { - if (!fAlarms.containsKey(alarmCtx.fAlarm)) { - rm.setStatus(new Status( - IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, INVALID_HANDLE, "Alarm context invalid", null)); //$NON-NLS-1$ - rm.done(); - return; - } - boolean isTriggered = getData().getTimerValue() >= fAlarms.get(alarmCtx.fAlarm); - rm.setData(new AlarmStatusData(isTriggered)); - rm.done(); - } - }); + return false; } - /** - * Creates a new alarm object with given value. - * @return context of the new alarm. - */ - public AlarmDMC createAlarm(int value) { - int newAlarm = fAlarmCounter++; - fAlarms.put(newAlarm, value); - getSession().dispatchEvent(new AlarmsChangedEvent(), getProperties()); - return new AlarmDMC(this, newAlarm); + /** Creates a new alarm object with given value. */ + public TriggerDMContext createTrigger(int value) { + TriggerDMContext triggerCtx = + new TriggerDMContext(getSession().getId(), fTriggerNumberCounter++); + fTriggers.put(triggerCtx, value); + getSession().dispatchEvent(new TriggersChangedEvent(), getProperties()); + return triggerCtx; } /** Removes given alarm from service. */ - public void deleteAlarm(AlarmDMC alarmCtx) { - fAlarms.remove(alarmCtx.fAlarm); - getSession().dispatchEvent(new AlarmsChangedEvent(), getProperties()); + public void deleteTrigger(TriggerDMContext alarmCtx) { + fTriggers.remove(alarmCtx); + getSession().dispatchEvent(new TriggersChangedEvent(), getProperties()); } - /** - * Changes the value of the given alarm. - * @param dmc Alarm to change - * @param newValue New alarm value. - */ - public void setAlarmValue(AlarmDMC dmc, int newValue) { - if (fAlarms.containsKey(dmc.fAlarm)) { - fAlarms.put(dmc.fAlarm, newValue); + /** Changes the value of the given trigger. */ + public void setTriggerValue(TriggerDMContext ctx, int newValue) { + if (fTriggers.containsKey(ctx)) { + fTriggers.put(ctx, newValue); } - getSession().dispatchEvent(new AlarmsChangedEvent(), getProperties()); + getSession().dispatchEvent(new TriggersChangedEvent(), getProperties()); } } diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmStatusVMNode.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmStatusVMNode.java deleted file mode 100644 index 7f0213ade34..00000000000 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmStatusVMNode.java +++ /dev/null @@ -1,112 +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.examples.dsf.timers; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; -import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMNode; -import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; -import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; -import org.eclipse.dd.examples.dsf.timers.AlarmService.AlarmDMC; -import org.eclipse.dd.examples.dsf.timers.AlarmService.AlarmStatusContext; -import org.eclipse.dd.examples.dsf.timers.AlarmService.AlarmStatusData; -import org.eclipse.dd.examples.dsf.timers.TimerService.TimerDMC; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; -import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; - -/** - * View model node that determines whether an "alarm triggered" indicator is - * shown in the tree. This indicator is only shown if a given alarm is - * triggered for a given timer. - * - * @see AlarmStatusContext - */ -@SuppressWarnings("restriction") -class AlarmStatusVMNode extends AbstractDMVMNode - implements IElementLabelProvider -{ - public AlarmStatusVMNode(AbstractDMVMProvider provider, DsfSession session) { - super(provider, session, AlarmStatusContext.class); - } - - @Override - protected void updateElementsInSessionThread(final IChildrenUpdate update) { - if (!checkService(AlarmService.class, null, update)) return; - if (!checkService(TimerService.class, null, update)) return; - - AlarmDMC alarmDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), AlarmDMC.class); - TimerDMC timerDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), TimerDMC.class); - if (alarmDmc == null || timerDmc == null) { - update.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, "Required elements not found in path")); //$NON-NLS-1$ - update.done(); - return; - } - - // Get the alarm status DMC then check the triggered value to make sure it's triggered. - final AlarmStatusContext alarmStatusDmc = getServicesTracker().getService(AlarmService.class). - getAlarmStatus(alarmDmc, timerDmc); - getServicesTracker().getService(AlarmService.class).getAlarmStatusData( - alarmStatusDmc, - new DataRequestMonitor(getSession().getExecutor(), null) { - @Override - public void handleCompleted() { - if (isDisposed()) return; - if (!getStatus().isOK()) { - update.setStatus(getStatus()); - } else { - if (getData().isTriggered()) { - update.setChild(createVMContext(alarmStatusDmc), 0); - } - } - update.done(); - }}); - } - - public void update(ILabelUpdate[] updates) { - for (ILabelUpdate update : updates) { - update.setLabel("ALARM TRIGGERED", 0); //$NON-NLS-1$ - update.setImageDescriptor( - DsfExamplesPlugin.getDefault().getImageRegistry().getDescriptor( - DsfExamplesPlugin.IMG_ALARM_TRIGGERED), - 0); - update.done(); - } - } - - - public int getDeltaFlags(Object e) { - // This node generates delta if the timers have changed, or if the - // label has changed. - if (e instanceof AlarmService.AlarmTriggeredEvent) { - return IModelDelta.ADDED | IModelDelta.SELECT | IModelDelta.EXPAND; - } - return IModelDelta.NO_CHANGE; - } - - public void buildDelta(Object e, VMDelta parentDelta, int nodeOffset, RequestMonitor requestMonitor) { - // An element is added when and selected upon a triggered event. - // Parent element is also expanded allow element to be selected. - if (e instanceof AlarmService.AlarmTriggeredEvent) { - parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.EXPAND); - parentDelta.addNode( - createVMContext( ((AlarmService.AlarmTriggeredEvent)e).getDMContext() ), - 0, - IModelDelta.ADDED | IModelDelta.SELECT); - } - requestMonitor.done(); - } -} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmsVMNode.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmsVMNode.java index 885934bf736..3f86a7825c3 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmsVMNode.java +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmsVMNode.java @@ -10,203 +10,96 @@ *******************************************************************************/ package org.eclipse.dd.examples.dsf.timers; -import java.text.MessageFormat; -import java.util.concurrent.RejectedExecutionException; - -import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMNode; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; -import org.eclipse.dd.dsf.ui.viewmodel.properties.IElementPropertiesProvider; -import org.eclipse.dd.dsf.ui.viewmodel.properties.IPropertiesUpdate; -import org.eclipse.dd.dsf.ui.viewmodel.properties.LabelAttribute; -import org.eclipse.dd.dsf.ui.viewmodel.properties.LabelColumnInfo; -import org.eclipse.dd.dsf.ui.viewmodel.properties.LabelImage; -import org.eclipse.dd.dsf.ui.viewmodel.properties.LabelText; -import org.eclipse.dd.dsf.ui.viewmodel.properties.PropertyBasedLabelProvider; import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; -import org.eclipse.dd.examples.dsf.timers.AlarmService.AlarmDMC; -import org.eclipse.dd.examples.dsf.timers.AlarmService.AlarmData; +import org.eclipse.dd.examples.dsf.timers.AlarmService.AlarmDMContext; +import org.eclipse.dd.examples.dsf.timers.AlarmService.TriggerDMContext; +import org.eclipse.dd.examples.dsf.timers.TimerService.TimerDMContext; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementEditor; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; -import org.eclipse.jface.viewers.CellEditor; -import org.eclipse.jface.viewers.ICellModifier; -import org.eclipse.jface.viewers.TextCellEditor; -import org.eclipse.swt.widgets.Composite; - /** - * View model node that defines how alarm DMContexts are displayed in the view. Alarm - * nodes are fairly static, once they are created their label doesn't change. - * @see AlarmDMC + * View model node that determines whether an "alarm triggered" indicator is + * shown in the tree. This indicator is only shown if a given alarm is + * triggered for a given timer. + * + * @see AlarmDMContext */ @SuppressWarnings("restriction") class AlarmsVMNode extends AbstractDMVMNode - implements IElementEditor, IElementPropertiesProvider, IElementLabelProvider + implements IElementLabelProvider { - public static final String PROP_ALARM_NUMBER = "alarmNumber"; //$NON-NLS-1$ - public static final String PROP_ALARM_TRIGGER_VALUE = "alarmTriggerValue"; //$NON-NLS-1$ - - private AlarmCellModifier fAlarmCellModifier; - private PropertyBasedLabelProvider fLabelProvider; - - public AlarmsVMNode(AbstractDMVMProvider provider, DsfSession session) { - super(provider, session, AlarmDMC.class); - - fLabelProvider = new PropertyBasedLabelProvider(); - - LabelColumnInfo idCol = new LabelColumnInfo( - new LabelAttribute[] { - new LabelText(new MessageFormat("Alarm #{0}"), new String[] { PROP_ALARM_NUMBER }), //$NON-NLS-1$ - new LabelImage(DsfExamplesPlugin.getDefault().getImageRegistry().getDescriptor(DsfExamplesPlugin.IMG_ALARM)) - }); - fLabelProvider.setColumnInfo(TimersViewColumnPresentation.COL_ID, idCol); - - LabelText valueText = new LabelText(new MessageFormat("{0}"), new String[] { PROP_ALARM_TRIGGER_VALUE }); //$NON-NLS-1$ - LabelColumnInfo valueCol = new LabelColumnInfo( - new LabelAttribute[] { - new LabelText(new MessageFormat("{0}"), new String[] { PROP_ALARM_TRIGGER_VALUE }) //$NON-NLS-1$ - }); - fLabelProvider.setColumnInfo(TimersViewColumnPresentation.COL_VALUE, valueCol); - + super(provider, session, AlarmDMContext.class); } @Override protected void updateElementsInSessionThread(final IChildrenUpdate update) { + // Check that the services are available if (!checkService(AlarmService.class, null, update)) return; + if (!checkService(TimerService.class, null, update)) return; - // Retrieve the alarm DMContexts, create the corresponding VMCs array, and - // set them as result. - getServicesTracker().getService(AlarmService.class).getAlarms( - new DataRequestMonitor(getSession().getExecutor(), null) { - @Override - public void handleCompleted() { - if (!getStatus().isOK()) { - update.setStatus(getStatus()); - } else { - fillUpdateWithVMCs(update, getData()); - } - update.done(); - }}); + // Find the trigger and timer contexts. If not found, fail. + TriggerDMContext alarmDmc = findDmcInPath( + update.getViewerInput(), update.getElementPath(), TriggerDMContext.class); + TimerDMContext timerDmc = findDmcInPath( + update.getViewerInput(), update.getElementPath(), TimerDMContext.class); + if (alarmDmc == null || timerDmc == null) { + update.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, "Required elements not found in path")); + update.done(); + return; + } + + // Get the alarm context then check the triggered value. + final AlarmDMContext alarmStatusDmc = getServicesTracker().getService(AlarmService.class). + getAlarmS(alarmDmc, timerDmc); + boolean triggered = getServicesTracker().getService(AlarmService.class). + isAlarmTriggered(alarmStatusDmc); + + // Only return the alarm in list of elements if it is triggered. + if (triggered) { + update.setChild(createVMContext(alarmStatusDmc), 0); + } + update.done(); } public void update(ILabelUpdate[] updates) { - fLabelProvider.update(updates); - } - - public void update(final IPropertiesUpdate[] updates) { - try { - getSession().getExecutor().execute(new DsfRunnable() { - public void run() { - for (IPropertiesUpdate update : updates) { - updatePropertiesInSessionThread(update); - } - }}); - } catch (RejectedExecutionException e) { - for (IViewerUpdate update : updates) { - handleFailedUpdate(update); - } + for (ILabelUpdate update : updates) { + update.setLabel("ALARM TRIGGERED", 0); + update.setImageDescriptor( + DsfExamplesPlugin.getDefault().getImageRegistry().getDescriptor( + DsfExamplesPlugin.IMG_ALARM_TRIGGERED), + 0); + update.done(); } } - - @ConfinedToDsfExecutor("getSession#getExecutor") - protected void updatePropertiesInSessionThread(final IPropertiesUpdate update) { - final AlarmDMC dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), AlarmDMC.class); - if (!checkDmc(dmc, update) || !checkService(AlarmService.class, null, update)) return; - - getDMVMProvider().getModelData( - this, update, - getServicesTracker().getService(AlarmService.class, null), - dmc, - new DataRequestMonitor(getSession().getExecutor(), null) { - @Override - protected void handleCompleted() { - /* - * Check that the request was evaluated and data is still - * valid. The request could fail if the state of the - * service changed during the request, but the view model - * has not been updated yet. - */ - if (!getStatus().isOK() || !getData().isValid()) { - assert getStatus().isOK() || - getStatus().getCode() != IDsfService.INTERNAL_ERROR || - getStatus().getCode() != IDsfService.NOT_SUPPORTED; - handleFailedUpdate(update); - return; - } - - update.setProperty(PROP_ALARM_NUMBER, getData().getAlarmNumber()); - update.setProperty(PROP_ALARM_TRIGGER_VALUE, getData().getTriggeringValue()); - update.done(); - } - }, - getExecutor()); - } - public CellEditor getCellEditor(IPresentationContext context, String columnId, Object element, Composite parent) { - if (TimersViewColumnPresentation.COL_VALUE.equals(columnId)) { - return new TextCellEditor(parent); - } - return null; - } - - // Note: this method is synchronized because IElementEditor.getCellModifier can be called - // on any thread, even though in practice it should be only called on the UI thread. - public synchronized ICellModifier getCellModifier(IPresentationContext context, Object element) { - if (fAlarmCellModifier == null) { - fAlarmCellModifier = new AlarmCellModifier(getSession()); - } - return fAlarmCellModifier; - } public int getDeltaFlags(Object e) { - // Since the label for alarms doesn't change, this node will generate - // delta info only if the list of alarms is changed. - if (e instanceof AlarmService.AlarmsChangedEvent) { - return IModelDelta.CONTENT; + if (e instanceof AlarmService.AlarmTriggeredEvent) { + return IModelDelta.ADDED | IModelDelta.SELECT | IModelDelta.EXPAND; } return IModelDelta.NO_CHANGE; } - - - public void buildDelta(Object event, VMDelta parentDelta, int nodeOffset, RequestMonitor requestMonitor) { - if (event instanceof AlarmService.AlarmsChangedEvent) { - // The list of alarms has changed, which means that the parent - // node needs to refresh its contents, which in turn will re-fetch the - // elements from this node. - parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); + + public void buildDelta(Object e, VMDelta parentDelta, int nodeOffset, RequestMonitor requestMonitor) { + // The alarm element is added when and selected upon a triggered event. + // Parent element is also expanded allow the alarm to be selected. + if (e instanceof AlarmService.AlarmTriggeredEvent) { + parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.EXPAND); + parentDelta.addNode( + createVMContext( ((AlarmService.AlarmTriggeredEvent)e).getDMContext() ), + 0, + IModelDelta.ADDED | IModelDelta.SELECT); } requestMonitor.done(); - } - - @Override - public synchronized void dispose() { - synchronized(this) { - if (fAlarmCellModifier != null) { - fAlarmCellModifier.dispose(); - } - } - super.dispose(); - } - - public String getPropertyDescription(String property) { - // TODO Auto-generated method stub - return null; - } - - public String getPropertyName(String property) { - // TODO Auto-generated method stub - return null; } } diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/ServicesShutdownSequence.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/ServicesShutdownSequence.java index 8ad1baa9a9c..0df9281a21d 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/ServicesShutdownSequence.java +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/ServicesShutdownSequence.java @@ -20,15 +20,19 @@ import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; /** - * Shutdown sequence that stops the services in the timers session. - * + * Sequence that stops the services in the timers session. */ -class ServicesShutdownSequence extends Sequence { +public class ServicesShutdownSequence extends Sequence { - DsfSession fSession; + // Session to that the services are running in. + final private DsfSession fSession; + + // DSF Services is created as the first step of the sequence. It + // cannot be created by the constructor because it can only be called + // in the session thread. DsfServicesTracker fTracker; - ServicesShutdownSequence(DsfSession session) { + public ServicesShutdownSequence(DsfSession session) { super(session.getExecutor()); fSession = session; } @@ -43,6 +47,8 @@ class ServicesShutdownSequence extends Sequence { @Override public void rollBack(RequestMonitor requestMonitor) { + // Dispose the tracker in case shutdown sequence is aborted + // and is rolled back. fTracker.dispose(); fTracker = null; requestMonitor.done(); @@ -63,6 +69,7 @@ class ServicesShutdownSequence extends Sequence { new Step() { @Override public void execute(RequestMonitor requestMonitor) { + // Dispose the tracker after the services are shut down. fTracker.dispose(); fTracker = null; requestMonitor.done(); @@ -73,18 +80,18 @@ class ServicesShutdownSequence extends Sequence { @Override public Step[] getSteps() { return fSteps; } - /** - * Convenience method that shuts down given service. Only service class - * is used to identify the service. - */ + // A convenience method that shuts down given service. Only service class + // is used to identify the service. private void shutdownService(Class clazz, RequestMonitor requestMonitor) { IDsfService service = fTracker.getService(clazz); if (service != null) { service.shutdown(requestMonitor); } else { - requestMonitor.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, - "Service '" + clazz.getName() + "' not found.", null)); //$NON-NLS-1$ //$NON-NLS-2$ + requestMonitor.setStatus(new Status( + IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, + IDsfService.INTERNAL_ERROR, + "Service '" + clazz.getName() + "' not found.", null)); requestMonitor.done(); } } diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/ServicesStartupSequence.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/ServicesStartupSequence.java index 5ac0f2c7252..59b110e3da2 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/ServicesStartupSequence.java +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/ServicesStartupSequence.java @@ -16,16 +16,18 @@ import org.eclipse.dd.dsf.service.DsfSession; /** * Startup sequence for the timers session. With only two services, this is - * a very simple sequence. Last step creates the first timer and alarm. + * a very simple sequence. */ -class ServicesStartupSequence extends Sequence { +public class ServicesStartupSequence extends Sequence { - DsfSession fSession; + final private DsfSession fSession; + + // The reference to the services are saved to use in the last step. private TimerService fTimerService = null; private AlarmService fAlarmService = null; - ServicesStartupSequence(DsfSession session) { + public ServicesStartupSequence(DsfSession session) { super(session.getExecutor()); fSession = session; } @@ -46,8 +48,9 @@ class ServicesStartupSequence extends Sequence { new Step() { @Override public void execute(RequestMonitor requestMonitor) { + // Create the first timer and trigger. fTimerService.startTimer(); - fAlarmService.createAlarm(5); + fAlarmService.createTrigger(5); requestMonitor.done(); }} }; diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimerService.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimerService.java index 154e4ce1a8e..1ab01d63d93 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimerService.java +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimerService.java @@ -10,21 +10,18 @@ *******************************************************************************/ package org.eclipse.dd.examples.dsf.timers; +import java.util.HashMap; import java.util.Hashtable; +import java.util.LinkedHashMap; import java.util.Map; -import java.util.TreeMap; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.AbstractDMContext; import org.eclipse.dd.dsf.datamodel.AbstractDMEvent; 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.service.AbstractDsfService; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; @@ -32,121 +29,73 @@ import org.osgi.framework.BundleContext; /** * Timer service tracks a set of timers, which are created per user request. - * The timers and their data are provided by the service using the DSF data - * model interfaces. - *

    - * When each timer is created, an event is issued that the service contents are - * changed, and clients should re-query the list of timers. The timers - * increment their value at rate of one per second (but they are not synchronous), - * and an event is issued for every tick. + * The timers are represented using a Data Model context object, which + * implements {@link IDMContext}. Each timers value, which can be retrieved + * by calling {@link #getTimerValue(TimerDMContext)}, is incremented every + * second. When a timer value is incremented the TimerService issues a + * {@link TimerTickDMEvent}. */ public class TimerService extends AbstractDsfService - implements IDMService { - /** - * Event indicating that the list of timers is changed and the clients - * which display timers should re-query this list. - */ - public class TimersChangedEvent extends AbstractDMEvent { - TimersChangedEvent() { super(fTimersContext); } - } + /** Event indicating that the list of timers is changed. */ + @Immutable + public static class TimersChangedEvent {} - /** - * Timer context represents a timer in this service. Clients can use this - * context to retrieve timer data. This class implements the Comaparable - * interfaces so that the objects can be stored in a TreeMap, which keeps them sorted. - */ - public static class TimerDMC extends AbstractDMContext - implements Comparable - { - /** - * Timer number, which is also index to timers map. - */ - final int fTimer; + /** Data Model context representing a timer. */ + @Immutable + public static class TimerDMContext extends AbstractDMContext { + final int fNumber; - public TimerDMC(TimerService service, int timer) { - super(service, new IDMContext[] { service.fTimersContext }); - fTimer = timer; + public TimerDMContext(String sessionId, int timer) { + super(sessionId, new IDMContext[0]); + fNumber = timer; } - /** - * Timer context objects are created as needed and not cached, so the - * equals method implementation is critical. - */ + /** Returns the sequential creation number of this timer. */ + public int getTimerNumber() { + return fNumber; + } + + // Timer context objects are created as needed and not cached, so the + // equals method implementation is critical. @Override public boolean equals(Object other) { - return baseEquals(other) && ((TimerDMC)other).fTimer == fTimer; + return baseEquals(other) && + ((TimerDMContext)other).fNumber == fNumber; } @Override - public int hashCode() { return baseHashCode() + fTimer; } + public int hashCode() { return baseHashCode() + fNumber; } @Override public String toString() { - return baseToString() + ".timer[" + fTimer + "]"; //$NON-NLS-1$ //$NON-NLS-2$ - } - - public int compareTo(TimerDMC other) { - TimerDMC otherTimer = other; - return (fTimer < otherTimer.fTimer ? -1 : (fTimer == otherTimer.fTimer ? 0 : 1)); + return baseToString() + ".timer[" + fNumber + "]"; } } - /** - * Data about the timer in the service. This object references internal - * service data, so it has to guard agains this data being obsolete. - */ - public class TimerData implements IDMData { - TimerDMC fTimerDMC; - - TimerData(TimerDMC timer) { fTimerDMC = timer; } - public boolean isValid() { return fTimers.containsKey(fTimerDMC); } - public int getTimerNumber() { return fTimerDMC.fTimer; } - - public int getTimerValue() { - if (!isValid()) return -1; - return fTimers.get(fTimerDMC); - } - - @Override public String toString() { return "Timer " + fTimerDMC.fTimer + " = " + getTimerValue(); } //$NON-NLS-1$ //$NON-NLS-2$ - } - /** * Event indicating that a timer's value has incremented. The context in * the event points to the timer that has changed. */ - public class TimerTickEvent extends AbstractDMEvent { - public TimerTickEvent(TimerDMC context) { + public class TimerTickDMEvent extends AbstractDMEvent { + public TimerTickDMEvent(TimerDMContext context) { super(context); } } - /** Parnet context for all timers */ - private final IDMContext fTimersContext; - /** Counter for generating timer numbers */ - private int fTimerCounter = 1; + private int fTimerNumberCounter = 1; - /** Map holding the timers */ - private Map fTimers = new TreeMap(); + // Use a linked hash in order to be able to return an ordered list of timers. + private Map fTimers = + new LinkedHashMap(); + + private Map> fTimerFutures = + new HashMap>(); - private Map> fTimerFutures = new TreeMap>(); - /** Constructor requires only the session for this service */ TimerService(DsfSession session) { super(session); - fTimersContext = new AbstractDMContext(this, new IDMContext[0]) { - private final Object fHashObject = new Object(); - - @Override - public boolean equals(Object obj) { return (this == obj); }; - - @Override - public int hashCode() { return fHashObject.hashCode(); } - - @Override - public String toString() { return "#timers"; } //$NON-NLS-1$ - }; } @Override @@ -160,97 +109,72 @@ public class TimerService extends AbstractDsfService new RequestMonitor(getExecutor(), requestMonitor) { @Override public void handleOK() { + // After super-class is finished initializing + // perform TimerService initialization. doInitialize(requestMonitor); }}); } + private void doInitialize(RequestMonitor requestMonitor) { + // Register service + register( new String[]{ TimerService.class.getName() }, + new Hashtable() ); + requestMonitor.done(); + } + @Override public void shutdown(RequestMonitor requestMonitor) { - /* - * Go through all the timer futures and cancel them, so that they - * don't fire any more events. - */ + // Cancel timer futures to avoid firing more events. for (Future future : fTimerFutures.values()) { future.cancel(false); } unregister(); super.shutdown(requestMonitor); } - - /** - * Performs the relevant initialization for this service: registering and - * scheduling the timer. - * @param requestMonitor - */ - private void doInitialize(RequestMonitor requestMonitor) { - register(new String[]{TimerService.class.getName()}, new Hashtable()); - requestMonitor.done(); + + /** Retrieves the list of timer contexts. */ + public TimerDMContext[] getTimers() { + return fTimers.keySet().toArray(new TimerDMContext[fTimers.size()]); } - public boolean isValid() { return true; } - - @SuppressWarnings("unchecked") - public void getModelData(IDMContext dmc, DataRequestMonitor rm) { - if (dmc instanceof TimerDMC) { - getTimerData((TimerDMC)dmc, (DataRequestMonitor)rm); - return; - } else if (dmc == fTimersContext) { - ((DataRequestMonitor)rm).setData(this); - } else { - rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ - } - rm.done(); + /** Retrieves the timer value for the given context. */ + public int getTimerValue(TimerDMContext context) { + Integer value = fTimers.get(context); + if (value != null) { + return value; + } + return -1; } - /** - * Retrieves the list of timer contexts. - * - *
    Note: this method doesn't need to be asynchronous, because all the - * data is stored locally. But using an asynchronous method makes this a - * more applicable example. - * - * @param rm Return data token. - */ - public void getTimers(DataRequestMonitor rm) { - rm.setData( fTimers.keySet().toArray(new TimerDMC[fTimers.size()]) ); - rm.done(); - } - - /** - * Retrieves the data object for given timer context. - * - *
    Note: likewise this method doesn't need to be asynchronous. - */ - public void getTimerData(TimerDMC context, DataRequestMonitor rm) { - rm.setData(new TimerData(context)); - rm.done(); - } - - /** - * Creates a new timer and returns its context. - */ - public TimerDMC startTimer() { - final TimerDMC newTimer = new TimerDMC(this, fTimerCounter++); + /** Creates a new timer and returns its context. */ + public TimerDMContext startTimer() { + // Create a new timer context and add it to the internal list. + final TimerDMContext newTimer = + new TimerDMContext(getSession().getId(), fTimerNumberCounter++); fTimers.put(newTimer, 0); + + // Create a new runnable that will execute every second and increment + // the timer value. The returned future is the handle that allows + // for canceling the scheduling of the runnable. Future timerFuture = getExecutor().scheduleAtFixedRate( new Runnable() { public void run() { fTimers.put(newTimer, fTimers.get(newTimer) + 1); - getSession().dispatchEvent(new TimerTickEvent(newTimer), getProperties()); + getSession().dispatchEvent(new TimerTickDMEvent(newTimer), getProperties()); } @Override public String toString() { return "Scheduled timer runnable for timer " + newTimer; } //$NON-NLS-1$ }, 1, 1, TimeUnit.SECONDS); - fTimerFutures.put(newTimer, timerFuture); + fTimerFutures.put(newTimer, timerFuture); + + // Issue an event to allow clients to update the list of timers. getSession().dispatchEvent(new TimersChangedEvent(), getProperties()); return newTimer; } - /** - * Removes given timer from list of timers. - */ - public void killTimer(TimerDMC timerContext) { + /** Removes given timer from list of timers. */ + public void killTimer(TimerDMContext timerContext) { if (fTimers.containsKey(timerContext)) { fTimers.remove(timerContext); fTimerFutures.remove(timerContext).cancel(false); diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersRootVMNode.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersRootVMNode.java new file mode 100644 index 00000000000..bc59bf0ae24 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersRootVMNode.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.dsf.timers; + +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.RootDMVMNode; +import org.eclipse.dd.examples.dsf.timers.TimersVMProvider.TimersViewLayoutChanged; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; + +/** + * + */ +@SuppressWarnings("restriction") +public class TimersRootVMNode extends RootDMVMNode { + + public TimersRootVMNode(AbstractVMProvider provider) { + super(provider); + } + + @Override + public boolean isDeltaEvent(Object rootObject, Object e) { + if (e instanceof TimersViewLayoutChanged) { + return true; + } + return super.isDeltaEvent(rootObject, e); + } + + @Override + public int getDeltaFlags(Object e) { + if (e instanceof TimersViewLayoutChanged) { + return IModelDelta.CONTENT; + } + + return IModelDelta.NO_CHANGE; + } + + @Override + public void createRootDelta(Object rootObject, Object event, final DataRequestMonitor rm) { + rm.setData(new VMDelta(rootObject, 0, IModelDelta.NO_CHANGE)); + int flags = IModelDelta.NO_CHANGE; + if (event instanceof TimersViewLayoutChanged) { + flags |= IModelDelta.CONTENT; + } + rm.setData( new VMDelta(rootObject, 0, flags) ); + rm.done(); + } + +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersModelAdapter.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersVMAdapter.java similarity index 50% rename from plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersModelAdapter.java rename to plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersVMAdapter.java index bd694680da7..8010674b540 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersModelAdapter.java +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersVMAdapter.java @@ -14,49 +14,28 @@ import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.IVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMAdapter; -import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; /** * This is the adapter that implements the flexible hierarchy viewer interfaces - * for providing content, labels, and event proxy-ing for the viewer. This + * for providing content, labels, and event processing for the viewer. This * adapter is registered with the DSF Session object, and is returned by the * IDMContext.getAdapter() and IVMContext.getAdapter() methods, * which both call {@link DsfSession#getModelAdapter(Class)}. - *

    - * The adapter implementation for this excercise is hard-coded to provide - * contents for only one view. In turn the view contens are determined using - * the configurable ViewModelProvider. For demonstration purposes, this model - * adapter has two different layout configurations that can be used. These - * layout configurations can be set by calling the {@link #setViewLayout} method. - *

    - * This class is primarily accessed by the flexible hierarchy viewer from a - * non-executor thread. So the class is thread-safe, except for a view methods - * which must be called on the executor thread. - * - * @see AbstractDMVMProvider */ @SuppressWarnings("restriction") @ThreadSafe -public class TimersModelAdapter extends AbstractDMVMAdapter +public class TimersVMAdapter extends AbstractDMVMAdapter { - TimersVMProvider fViewModelProvider; - @Override protected IVMProvider createViewModelProvider(IPresentationContext context) { - /* - * In this example there is only one viewer, so there is only one - * VMProvider. - */ - return fViewModelProvider; + if ( TimersView.ID_VIEW_TIMERS.equals(context.getId()) ) { + return new TimersVMProvider(this, context, getSession()); + } + return null; } - public TimersModelAdapter(DsfSession session, IPresentationContext presentationContext) { + public TimersVMAdapter(DsfSession session, IPresentationContext presentationContext) { super(session); - fViewModelProvider = new TimersVMProvider(this, presentationContext, getSession()); } - - TimersVMProvider getTimersVMProvider() { - return fViewModelProvider; - } } diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersVMNode.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersVMNode.java index 52fd1a7f444..64c0186a12f 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersVMNode.java +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersVMNode.java @@ -10,38 +10,76 @@ *******************************************************************************/ package org.eclipse.dd.examples.dsf.timers; +import java.text.MessageFormat; import java.util.concurrent.RejectedExecutionException; -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMNode; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.properties.IElementPropertiesProvider; +import org.eclipse.dd.dsf.ui.viewmodel.properties.IPropertiesUpdate; +import org.eclipse.dd.dsf.ui.viewmodel.properties.LabelAttribute; +import org.eclipse.dd.dsf.ui.viewmodel.properties.LabelColumnInfo; +import org.eclipse.dd.dsf.ui.viewmodel.properties.LabelImage; +import org.eclipse.dd.dsf.ui.viewmodel.properties.LabelText; +import org.eclipse.dd.dsf.ui.viewmodel.properties.PropertyBasedLabelProvider; import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; -import org.eclipse.dd.examples.dsf.timers.TimerService.TimerDMC; -import org.eclipse.dd.examples.dsf.timers.TimerService.TimerData; +import org.eclipse.dd.examples.dsf.timers.TimerService.TimerDMContext; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; /** * View model node that defines how timer DMContexts are displayed in the view. Timers * change with every tick of the timer, so the label has to be repained * upon timer tick events. - * @see TimerDMC + * @see TimerDMContext */ @SuppressWarnings("restriction") class TimersVMNode extends AbstractDMVMNode - implements IElementLabelProvider + implements IElementLabelProvider, IElementPropertiesProvider { + private static final String PROP_TIMER_NUMBER = "alarmNumber"; + private static final String PROP_TIMER_VALUE = "alarmTriggerValue"; + + // Create and configure the label provider. + private static final PropertyBasedLabelProvider fgLabelProvider; + static { + fgLabelProvider = new PropertyBasedLabelProvider(); + + LabelColumnInfo idCol = new LabelColumnInfo( + new LabelAttribute[] { + new LabelText(new MessageFormat("Timer #{0}"), + new String[] { PROP_TIMER_NUMBER }), + new LabelImage(DsfExamplesPlugin.getDefault().getImageRegistry(). + getDescriptor(DsfExamplesPlugin.IMG_ALARM)) + }); + fgLabelProvider.setColumnInfo(TimersViewColumnPresentation.COL_ID, idCol); + + LabelColumnInfo valueCol = new LabelColumnInfo( + new LabelAttribute[] { + new LabelText(new MessageFormat("{0}"), + new String[] { PROP_TIMER_VALUE }) + }); + fgLabelProvider.setColumnInfo(TimersViewColumnPresentation.COL_VALUE, + valueCol); + + } + public TimersVMNode(AbstractDMVMProvider provider, DsfSession session) { - super(provider, session, TimerDMC.class); + super(provider, session, TimerDMContext.class); + } + + public void update(ILabelUpdate[] updates) { + fgLabelProvider.update(updates); } @Override @@ -50,93 +88,60 @@ class TimersVMNode extends AbstractDMVMNode // Retrieve the timer DMContexts, create the corresponding VMCs array, and // set them as result. - getServicesTracker().getService(TimerService.class).getTimers( - new DataRequestMonitor(getSession().getExecutor(), null) { - @Override - public void handleCompleted() { - if (!getStatus().isOK()) { - update.setStatus(getStatus()); - } else { - fillUpdateWithVMCs(update, getData()); - } - update.done(); - }}); + TimerDMContext[] timers = + getServicesTracker().getService(TimerService.class).getTimers(); + fillUpdateWithVMCs(update, timers); + update.done(); } - public void update(final ILabelUpdate[] updates) { + public void update(final IPropertiesUpdate[] updates) { + // Switch to the session thread before processing the updates. try { getSession().getExecutor().execute(new DsfRunnable() { public void run() { - updateLabelInSessionThread(updates); + for (IPropertiesUpdate update : updates) { + updatePropertiesInSessionThread(update); + } }}); } catch (RejectedExecutionException e) { - for (ILabelUpdate update : updates) { + for (IViewerUpdate update : updates) { handleFailedUpdate(update); } } } - - protected void updateLabelInSessionThread(ILabelUpdate[] updates) { - for (final ILabelUpdate update : updates) { - final TimerDMC dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), TimerDMC.class); - if (!checkDmc(dmc, update) || !checkService(TimerService.class, null, update)) continue; - - getDMVMProvider().getModelData( - this, update, - getServicesTracker().getService(TimerService.class, null), - dmc, - new DataRequestMonitor(getSession().getExecutor(), null) { - @Override - protected void handleCompleted() { - /* - * Check that the request was evaluated and data is still - * valid. The request could fail if the state of the - * service changed during the request, but the view model - * has not been updated yet. - */ - if (!getStatus().isOK() || !getData().isValid()) { - assert getStatus().isOK() || - getStatus().getCode() != IDsfService.INTERNAL_ERROR || - getStatus().getCode() != IDsfService.NOT_SUPPORTED; - handleFailedUpdate(update); - return; - } - - /* - * If columns are configured, call the protected methods to - * fill in column values. - */ - String[] localColumns = update.getPresentationContext().getColumns(); - if (localColumns == null) localColumns = new String[] { null }; - - for (int i = 0; i < localColumns.length; i++) { - fillColumnLabel(dmc, getData(), localColumns[i], i, update); - } - update.done(); - } - }, - getExecutor()); + @ConfinedToDsfExecutor("getSession#getExecutor") + private void updatePropertiesInSessionThread(final IPropertiesUpdate update) { + // Find the timer context in the element being updated + final TimerDMContext dmc = findDmcInPath( + update.getViewerInput(), update.getElementPath(), TimerDMContext.class); + + // If either update or service are not valid, fail the update and exit. + if (!checkDmc(dmc, update) || + !checkService(TimerService.class, null, update)) + { + return; } + + TimerService timerService = + getServicesTracker().getService(TimerService.class, null); + int value = timerService.getTimerValue(dmc); + + if (value == -1) { + handleFailedUpdate(update); + return; + } + + update.setProperty(PROP_TIMER_NUMBER, dmc.getTimerNumber()); + update.setProperty(PROP_TIMER_VALUE, value); + update.done(); } - protected void fillColumnLabel(TimerDMC dmContext, TimerData dmData, String columnId, int idx, - ILabelUpdate update) - { - if (TimersViewColumnPresentation.COL_ID.equals(columnId)) { - update.setLabel( Integer.toString(dmData.getTimerNumber()), idx ); - update.setImageDescriptor( - DsfExamplesPlugin.getDefault().getImageRegistry().getDescriptor(DsfExamplesPlugin.IMG_TIMER), idx); - } else if (TimersViewColumnPresentation.COL_VALUE.equals(columnId)) { - update.setLabel( Integer.toString(dmData.getTimerValue()), idx); - } - } - public int getDeltaFlags(Object e) { // This node generates delta if the timers have changed, or if the // label has changed. - if (e instanceof TimerService.TimerTickEvent) { + if (e instanceof TimerService.TimerTickDMEvent) { return IModelDelta.STATE; } else if (e instanceof TimerService.TimersChangedEvent) { return IModelDelta.CONTENT; @@ -145,10 +150,9 @@ class TimersVMNode extends AbstractDMVMNode } public void buildDelta(Object e, VMDelta parentDelta, int nodeOffset, RequestMonitor requestMonitor) { - if (e instanceof TimerService.TimerTickEvent) { - // Add delta indicating that the VMC for the given timer context - // has changed. - parentDelta.addNode( createVMContext(((TimerService.TimerTickEvent)e).getDMContext()), IModelDelta.STATE ); + if (e instanceof TimerService.TimerTickDMEvent) { + // Add delta indicating that the given timer has changed. + parentDelta.addNode( createVMContext(((TimerService.TimerTickDMEvent)e).getDMContext()), IModelDelta.STATE ); } else if (e instanceof TimerService.TimersChangedEvent) { // The list of timers has changed, which means that the parent // node needs to refresh its contents, which in turn will re-fetch the @@ -157,4 +161,14 @@ class TimersVMNode extends AbstractDMVMNode } requestMonitor.done(); } + + + public String getPropertyDescription(String property) { + return null; + } + + public String getPropertyName(String property) { + return null; + } + } diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersVMProvider.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersVMProvider.java index 92f55d00aec..a19d6e31528 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersVMProvider.java +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersVMProvider.java @@ -10,60 +10,42 @@ *******************************************************************************/ package org.eclipse.dd.examples.dsf.timers; -import org.eclipse.core.runtime.IAdaptable; +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; import org.eclipse.dd.dsf.ui.viewmodel.IRootVMNode; import org.eclipse.dd.dsf.ui.viewmodel.IVMNode; -import org.eclipse.dd.dsf.ui.viewmodel.RootVMNode; -import org.eclipse.dd.dsf.ui.viewmodel.DefaultVMModelProxyStrategy; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; +import org.eclipse.dd.examples.dsf.timers.AlarmService.TriggersChangedEvent; +import org.eclipse.dd.examples.dsf.timers.TimerService.TimersChangedEvent; import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; /** - * + * The View Model provider for the Timers view. This provider allows for + * switching between two different view layouts: + *

      + *
    1. Timers -> Triggers -> Alarms
    2. + *
    3. Triggers -> Timers -> Alarms
    4. + *
    + * A special event is sent when the layout is changed in order to generate + * a proper delta to refresh the view. */ @SuppressWarnings("restriction") public class TimersVMProvider extends AbstractDMVMProvider { - /** - * The object to be set to the viewer that shows contents supplied by this provider. - * @see org.eclipse.jface.viewers.TreeViewer#setInput(Object) - */ - private final IAdaptable fViewerInputObject = - new IAdaptable() { - /** - * The input object provides the viewer access to the viewer model adapter. - */ - @SuppressWarnings("unchecked") - public Object getAdapter(Class adapter) { - if ( adapter.isInstance(getVMAdapter()) ) { - return getVMAdapter(); - } - return null; - } - - @Override - public String toString() { - return "Timers View Root"; //$NON-NLS-1$ - } - }; - - private DefaultVMModelProxyStrategy fModelProxyStrategy; - - + /** Event indicating that the timers view layout has changed */ + public static class TimersViewLayoutChanged {} + /** Enumeration of possible layouts for the timers view model */ - public enum ViewLayout { ALARMS_AT_TOP, TIMERS_AT_TOP } + public enum ViewLayout { TRIGGERS_AT_TOP, TIMERS_AT_TOP } public TimersVMProvider(AbstractVMAdapter adapter, IPresentationContext presentationContext, DsfSession session) { super(adapter, presentationContext, session); - setViewLayout(ViewLayout.ALARMS_AT_TOP); - } - - - public Object getViewerInputObject() { - return fViewerInputObject; + // Set the initial view layout. + setViewLayout(ViewLayout.TIMERS_AT_TOP); } /** @@ -71,33 +53,30 @@ public class TimersVMProvider extends AbstractDMVMProvider { * @param layout New layout to use. */ public void setViewLayout(ViewLayout layout) { - if (layout == ViewLayout.ALARMS_AT_TOP) { - IRootVMNode root = new RootVMNode(this); - IVMNode alarmsNode = new AlarmsVMNode(this, getSession()); - IVMNode timersNode0 = new TimersVMNode(this, getSession()); - addChildNodes(root, new IVMNode[] { alarmsNode, timersNode0 }); + clearNodes(); + if (layout == ViewLayout.TRIGGERS_AT_TOP) { + IRootVMNode root = new TimersRootVMNode(this); + IVMNode alarmsNode = new TriggersVMNode(this, getSession()); + addChildNodes(root, new IVMNode[] { alarmsNode }); IVMNode timersNode = new TimersVMNode(this, getSession()); addChildNodes(alarmsNode, new IVMNode[] { timersNode }); - IVMNode alarmStatusNode = new AlarmStatusVMNode(this, getSession()); + IVMNode alarmStatusNode = new AlarmsVMNode(this, getSession()); addChildNodes(timersNode, new IVMNode[] { alarmStatusNode }); setRootNode(root); } else if (layout == ViewLayout.TIMERS_AT_TOP) { - IRootVMNode root = new RootVMNode(this); + IRootVMNode root = new TimersRootVMNode(this); IVMNode timersNode = new TimersVMNode(this, getSession()); addChildNodes(root, new IVMNode[] { timersNode }); - IVMNode alarmsNode = new AlarmsVMNode(this, getSession()); + IVMNode alarmsNode = new TriggersVMNode(this, getSession()); addChildNodes(timersNode, new IVMNode[] { alarmsNode }); - IVMNode alarmStatusNode = new AlarmStatusVMNode(this, getSession()); + IVMNode alarmStatusNode = new AlarmsVMNode(this, getSession()); addChildNodes(alarmsNode, new IVMNode[] { alarmStatusNode }); setRootNode(root); } - /* TODO: replace with an event - fModelProxyStrategy.fireModelChanged( - new ModelDelta(getRootElement(), IModelDelta.CONTENT)); - */ + handleEvent(new TimersViewLayoutChanged()); } - + @Override public IColumnPresentation createColumnPresentation(IPresentationContext context, Object element) { return new TimersViewColumnPresentation(); @@ -107,5 +86,36 @@ public class TimersVMProvider extends AbstractDMVMProvider { public String getColumnPresentationId(IPresentationContext context, Object element) { return TimersViewColumnPresentation.ID; } - + + // Add a handler for the triggers and timers changed events. The + // AbstractDMVMProvider superclass automatically registers this provider + // for all IDMEvent events, however these two events do not implement + // IDMEvent + @DsfServiceEventHandler + public void eventDispatched(final TriggersChangedEvent event) { + if (isDisposed()) return; + + try { + getExecutor().execute(new Runnable() { + public void run() { + if (isDisposed()) return; + handleEvent(event); + } + }); + } catch (RejectedExecutionException e) {} + } + + @DsfServiceEventHandler + public void eventDispatched(final TimersChangedEvent event) { + if (isDisposed()) return; + + try { + getExecutor().execute(new Runnable() { + public void run() { + if (isDisposed()) return; + handleEvent(event); + } + }); + } catch (RejectedExecutionException e) {} + } } diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersView.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersView.java index f9b4afe2be7..27b96b3ddf3 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersView.java +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersView.java @@ -12,19 +12,20 @@ package org.eclipse.dd.examples.dsf.timers; import java.util.concurrent.ExecutionException; +import org.eclipse.core.runtime.IAdaptable; import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor; import org.eclipse.dd.dsf.concurrent.DsfExecutor; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.viewmodel.IVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext; import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; -import org.eclipse.dd.examples.dsf.timers.TimerService.TimerDMC; +import org.eclipse.dd.examples.dsf.timers.TimerService.TimerDMContext; import org.eclipse.dd.examples.dsf.timers.TimersVMProvider.ViewLayout; import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.viewers.model.provisional.PresentationContext; import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer; import org.eclipse.jface.action.Action; @@ -33,6 +34,7 @@ import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.dialogs.IInputValidator; import org.eclipse.jface.dialogs.InputDialog; +import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; @@ -42,17 +44,23 @@ import org.eclipse.ui.part.ViewPart; /** - * Example view which displays data from timers and alarms DSF services. This - * starts a new DSF session and configures the services for it. Then it - * configures a data model provider to process the service data and display it - * in a flexible-hierarchy asynchronous viewer. + * Example view which displays data from timers and alarms services. It starts + * a new DSF session and configures the services for it. Then it configures + * a data model provider to process the service data and display it in a + * flexible-hierarchy asynchronous viewer. */ @SuppressWarnings("restriction") public class TimersView extends ViewPart { + /** Timers view ID */ + public static final String ID_VIEW_TIMERS = "org.eclipse.dd.examples.dsf.TimersView"; + /** Asynchronous tree viewer from the platform debug.ui plugin. */ private TreeModelViewer fViewer; + /** Presentation context of the timers viewer */ + private PresentationContext fPresentationContext; + /** DSF executor to use for a new session with timers and alarms services */ private DsfExecutor fExecutor; @@ -63,7 +71,7 @@ public class TimersView extends ViewPart { private DsfServicesTracker fServices; /** Adapter used to provide view model for flexible-hierarchy viewer */ - private TimersModelAdapter fTimersModelAdapter; + private TimersVMAdapter fTimersVMAdapter; /** Action which toggles the layout in the viewer */ private Action fToggleLayoutAction; @@ -71,45 +79,41 @@ public class TimersView extends ViewPart { /** Action that adds a new timer */ private Action fAddTimerAction; - /** Action that adds a new alarm */ - private Action fAddAlarmAction; + /** Action that adds a new trigger */ + private Action fAddTriggerAction; - /** Action that removes the selected alarm or timer */ + /** Action that removes the selected trigger or timer */ private Action fRemoveAction; public TimersView() {} /** - * This is a callback that will allow us to create the viewer and + * This is a call-back that will allow us to create the viewer and * initialize it. For this view, it creates the DSF session, along * with its services. Then it creates the viewer model adapter and * registers it with the session. */ @Override public void createPartControl(Composite parent) { - /* - * Create the Flexible Hierarchy viewer. Also create a presentation - * context which will be given to the content/label provider adapters - * to distinguish this view from other flex-hierarchy views. - */ - final IPresentationContext presentationContext = new PresentationContext("org.eclipse.dd.examples.dsf.timers"); //$NON-NLS-1$ - fViewer = new TreeModelViewer(parent, SWT.VIRTUAL | SWT.FULL_SELECTION, presentationContext); + // Create the Flexible Hierarchy viewer. Also create a presentation + // context which will be given to the content/label provider adapters + // to distinguish this view from other flexible-hierarchy views. + fPresentationContext = new PresentationContext(ID_VIEW_TIMERS); + fViewer = new TreeModelViewer( + parent, SWT.VIRTUAL | SWT.FULL_SELECTION, fPresentationContext); - /* - * Create the executor, which will be used exclusively with this view, - * as well as a session and a services tracker for managing references - * to services. - */ + // Create the executor, which will be used exclusively with this view, + // as well as a session and a services tracker for managing references + // to services. fExecutor = new DefaultDsfExecutor(); - fSession = DsfSession.startSession(fExecutor, "org.eclipse.dd.examples.dsf.timers"); //$NON-NLS-1$ - fServices = new DsfServicesTracker(DsfExamplesPlugin.getBundleContext(), fSession.getId()); + fSession = DsfSession.startSession(fExecutor, "Timers(DSF Example)"); + fServices = new DsfServicesTracker( + DsfExamplesPlugin.getBundleContext(), fSession.getId()); - /* - * Start the services using a sequence. The sequence runs in the - * dispatch thread, so we have to block this thread using Future.get() - * until it completes. The Future.get() will throw an exception if - * the sequence fails. - */ + // Start the services using a sequence. The sequence runs in the + // session executor thread, therefore the thread calling this method + // has to block using Future.get() until the sequence it completes. + // The Future.get() will throw an exception if the sequence fails. ServicesStartupSequence startupSeq = new ServicesStartupSequence(fSession); fSession.getExecutor().execute(startupSeq); try { @@ -118,20 +122,38 @@ public class TimersView extends ViewPart { } catch (ExecutionException e) { assert false; } - /* - * Create the flexible hierarchy content/label adapter. Then register - * it with the session. - */ - fTimersModelAdapter = new TimersModelAdapter(fSession, presentationContext); - fSession.registerModelAdapter(IElementContentProvider.class, fTimersModelAdapter); - fSession.registerModelAdapter(IModelProxyFactory.class, fTimersModelAdapter); - fSession.registerModelAdapter(IColumnPresentationFactory.class, fTimersModelAdapter); + // Create the flexible hierarchy content/label adapter. Then register + // it with the session. + fTimersVMAdapter = new TimersVMAdapter(fSession, fPresentationContext); + fSession.registerModelAdapter( + IElementContentProvider.class, fTimersVMAdapter); + fSession.registerModelAdapter( + IModelProxyFactory.class, fTimersVMAdapter); + fSession.registerModelAdapter( + IColumnPresentationFactory.class, fTimersVMAdapter); - /* - * Set the root element for the timers tree viewer. The root element - * comes from the content provider. - */ - fViewer.setInput(fTimersModelAdapter.getTimersVMProvider().getViewerInputObject()); + // Create the input object for the view. This object needs to return + // the VM adapter through the IAdaptable interface when queried for the + // flexible hierarchy adapters. + final IAdaptable viewerInputObject = + new IAdaptable() { + /** + * The input object provides the viewer access to the viewer model adapter. + */ + @SuppressWarnings("unchecked") + public Object getAdapter(Class adapter) { + if ( adapter.isInstance(fTimersVMAdapter) ) { + return fTimersVMAdapter; + } + return null; + } + + @Override + public String toString() { + return "Timers View Root"; //$NON-NLS-1$ + } + }; + fViewer.setInput(viewerInputObject); makeActions(); contributeToActionBars(); @@ -140,21 +162,24 @@ public class TimersView extends ViewPart { @Override public void dispose() { try { - /* - * First dispose the view model, which is the client of services. - * We are not in the dispatch thread - */ + // First dispose the view model, which is the client of services. + // This operation needs to be performed in the session executor + // thread. Block using Future.get() until this call completes. fSession.getExecutor().submit(new Runnable() { public void run() { fSession.unregisterModelAdapter(IElementContentProvider.class); fSession.unregisterModelAdapter(IModelProxyFactory.class); fSession.unregisterModelAdapter(IColumnPresentationFactory.class); - fTimersModelAdapter.dispose(); - fTimersModelAdapter = null; }}).get(); - - // Then invoke the shutdown sequence for the services. - ServicesShutdownSequence shutdownSeq = new ServicesShutdownSequence(fSession); + + // Dispose the VM adapter. + fTimersVMAdapter.dispose(); + fTimersVMAdapter = null; + + // Next invoke the shutdown sequence for the services. Sequence + // class also implements Future.get()... + ServicesShutdownSequence shutdownSeq = + new ServicesShutdownSequence(fSession); fSession.getExecutor().execute(shutdownSeq); try { shutdownSeq.get(); @@ -162,7 +187,7 @@ public class TimersView extends ViewPart { } catch (ExecutionException e) { assert false; } - // Finally end the session and the executor: + // Finally end the session and the executor. fSession.getExecutor().submit(new Runnable() { public void run() { DsfSession.endSession(fSession); @@ -173,7 +198,6 @@ public class TimersView extends ViewPart { } catch (InterruptedException e) { } catch (ExecutionException e) { } - //fViewer.dispose(); super.dispose(); } @@ -185,7 +209,7 @@ public class TimersView extends ViewPart { private void fillLocalToolBar(IToolBarManager manager) { manager.add(fToggleLayoutAction); manager.add(fAddTimerAction); - manager.add(fAddAlarmAction); + manager.add(fAddTriggerAction); manager.add(fRemoveAction); manager.add(new Separator()); } @@ -195,97 +219,105 @@ public class TimersView extends ViewPart { @Override public void run() { // Get the toggle state of the action while on UI thread. - final ViewLayout layout = isChecked() ? ViewLayout.ALARMS_AT_TOP : ViewLayout.TIMERS_AT_TOP; + final ViewLayout layout = isChecked() ? ViewLayout.TRIGGERS_AT_TOP : ViewLayout.TIMERS_AT_TOP; - // Switch to executor thread to perform the change in layout. - fExecutor.submit(new Runnable() { public void run() { - fTimersModelAdapter.getTimersVMProvider().setViewLayout(layout); - }}); + IVMProvider provider = fTimersVMAdapter.getVMProvider(fPresentationContext); + ((TimersVMProvider)provider).setViewLayout(layout); } }; fToggleLayoutAction.setToolTipText("Toggle Layout"); //$NON-NLS-1$ fToggleLayoutAction.setImageDescriptor(DsfExamplesPlugin.getDefault().getImageRegistry().getDescriptor( DsfExamplesPlugin.IMG_LAYOUT_TOGGLE)); - fAddTimerAction = new Action("Add New Timer") { //$NON-NLS-1$ + fAddTimerAction = new Action("Add New Timer") { @Override public void run() { - fExecutor.submit(new Runnable() { public void run() { - // Only need to create the new timer, the events will cause - // the view to refresh. - fServices.getService(TimerService.class).startTimer(); - }}); + fExecutor.execute(new Runnable() { + public void run() { + // Only need to create the new timer, the events will + // cause the view to refresh. + fServices.getService(TimerService.class).startTimer(); + } + }); } }; - fAddTimerAction.setToolTipText("Add new timer"); //$NON-NLS-1$ - fAddTimerAction.setImageDescriptor(DsfExamplesPlugin.getDefault().getImageRegistry().getDescriptor( - DsfExamplesPlugin.IMG_TIMER)); + fAddTimerAction.setToolTipText("Add a new timer"); + fAddTimerAction.setImageDescriptor( + getImage(DsfExamplesPlugin.IMG_TIMER)); - fAddAlarmAction = new Action("Add New Alarm") { //$NON-NLS-1$ + fAddTriggerAction = new Action("Add New Trigger") { @Override public void run() { - // Ask user for the new alarm value. + // Ask user for the new trigger value. InputDialog inputDialog = new InputDialog( - fViewer.getControl().getShell(), - "New Alarm", //$NON-NLS-1$ - "Please enter alarm time", //$NON-NLS-1$ - "", //$NON-NLS-1$ + getSite().getShell(), + "New Trigger", + "Please enter trigger value", + "", new IInputValidator() { public String isValid(String input) { try { int i= Integer.parseInt(input); if (i <= 0) - return "Please enter a positive integer"; //$NON-NLS-1$ + return "Please enter a positive integer"; } catch (NumberFormatException x) { - return "Please enter a positive integer"; //$NON-NLS-1$ + return "Please enter a positive integer"; } return null; } } ); if (inputDialog.open() != Window.OK) return; - int tmpAlarmValue = -1; + int tmpTriggerValue = -1; try { - tmpAlarmValue = Integer.parseInt(inputDialog.getValue()); + tmpTriggerValue = Integer.parseInt(inputDialog.getValue()); } catch (NumberFormatException x) { assert false; } - final int alarmValue = tmpAlarmValue; - fExecutor.submit(new Runnable() { public void run() { - // Create the new alarm. - fServices.getService(AlarmService.class).createAlarm(alarmValue); - }}); + final int triggerValue = tmpTriggerValue; + fExecutor.execute(new Runnable() { + public void run() { + // Create the new trigger + fServices.getService(AlarmService.class). + createTrigger(triggerValue); + } + }); } }; - fAddAlarmAction.setToolTipText("Add new alarm"); //$NON-NLS-1$ - fAddAlarmAction.setImageDescriptor(DsfExamplesPlugin.getDefault().getImageRegistry().getDescriptor( - DsfExamplesPlugin.IMG_ALARM)); + fAddTriggerAction.setToolTipText("Add a new trigger"); + fAddTriggerAction.setImageDescriptor( + getImage(DsfExamplesPlugin.IMG_ALARM)); - fRemoveAction = new Action("Remove") { //$NON-NLS-1$ + fRemoveAction = new Action("Remove") { @Override public void run() { - final Object selectedElement = ((IStructuredSelection)fViewer.getSelection()).getFirstElement(); + final Object selectedElement = + ((IStructuredSelection)fViewer.getSelection()).getFirstElement(); if (!(selectedElement instanceof IDMVMContext)) return; - final IDMContext selectedDmc = ((IDMVMContext)selectedElement).getDMContext(); - // Based on the DMC from the selection, call the appropriate service to - // remove the item. - if (selectedDmc instanceof TimerDMC) { - fExecutor.submit(new Runnable() { public void run() { + final IDMContext selectedCtx = + ((IDMVMContext)selectedElement).getDMContext(); + // Based on the context from the selection, call the + // appropriate service to remove the item. + if (selectedCtx instanceof TimerDMContext) { + fExecutor.execute(new Runnable() { public void run() { fServices.getService(TimerService.class).killTimer( - ((TimerDMC)selectedDmc)); + ((TimerDMContext)selectedCtx)); }}); - } else if (selectedDmc instanceof AlarmService.AlarmDMC) { - fExecutor.submit(new Runnable() { public void run() { - fServices.getService(AlarmService.class).deleteAlarm( - (AlarmService.AlarmDMC)selectedDmc); + } else if (selectedCtx instanceof AlarmService.TriggerDMContext) { + fExecutor.execute(new Runnable() { public void run() { + fServices.getService(AlarmService.class).deleteTrigger( + (AlarmService.TriggerDMContext)selectedCtx); }}); } } }; - fRemoveAction.setToolTipText("Remove selected item"); //$NON-NLS-1$ - fRemoveAction.setImageDescriptor(DsfExamplesPlugin.getDefault().getImageRegistry().getDescriptor( - DsfExamplesPlugin.IMG_REMOVE)); + fRemoveAction.setToolTipText("Remove selected item"); + fRemoveAction.setImageDescriptor( getImage(DsfExamplesPlugin.IMG_REMOVE) ); } + private ImageDescriptor getImage(String key) { + return DsfExamplesPlugin.getDefault().getImageRegistry().getDescriptor(key); + } + /** * Passing the focus request to the viewer's control. */ diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersViewColumnPresentation.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersViewColumnPresentation.java index ba24f6b68dc..fb3052863ae 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersViewColumnPresentation.java +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersViewColumnPresentation.java @@ -25,18 +25,14 @@ public class TimersViewColumnPresentation implements IColumnPresentation { public static final String COL_ID = ID + ".COL_ID"; //$NON-NLS-1$ public static final String COL_VALUE = ID + ".COL_VALUE"; //$NON-NLS-1$ - // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#init(org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext) public void init(IPresentationContext context) {} - // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#dispose() public void dispose() {} - // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getAvailableColumns() public String[] getAvailableColumns() { return new String[] { COL_ID, COL_VALUE }; } - // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getHeader(java.lang.String) public String getHeader(String id) { if (COL_ID.equals(id)) { return "ID"; //$NON-NLS-1$ @@ -46,22 +42,18 @@ public class TimersViewColumnPresentation implements IColumnPresentation { return null; } - // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getId() public String getId() { return ID; } - // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getImageDescriptor(java.lang.String) public ImageDescriptor getImageDescriptor(String id) { return null; } - // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getInitialColumns() public String[] getInitialColumns() { return getAvailableColumns(); } - // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#isOptional() public boolean isOptional() { return true; } diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmCellModifier.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TriggerCellModifier.java similarity index 65% rename from plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmCellModifier.java rename to plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TriggerCellModifier.java index e0ae7d54606..8b02fb5b788 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmCellModifier.java +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TriggerCellModifier.java @@ -11,6 +11,7 @@ package org.eclipse.dd.examples.dsf.timers; import java.util.concurrent.ExecutionException; +import java.util.concurrent.RejectedExecutionException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IStatus; @@ -23,8 +24,7 @@ import org.eclipse.dd.dsf.service.DsfServices; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; -import org.eclipse.dd.examples.dsf.timers.AlarmService.AlarmDMC; -import org.eclipse.dd.examples.dsf.timers.AlarmService.AlarmData; +import org.eclipse.dd.examples.dsf.timers.AlarmService.TriggerDMContext; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.ICellModifier; import org.eclipse.swt.widgets.Shell; @@ -32,58 +32,56 @@ import org.osgi.framework.InvalidSyntaxException; import org.osgi.util.tracker.ServiceTracker; /** - * + * Cell modifier used to edit the trigger value. */ -@ThreadSafeAndProhibitedFromDsfExecutor("") -public class AlarmCellModifier implements ICellModifier { +@ThreadSafeAndProhibitedFromDsfExecutor("fSession.getExecutor()") +public class TriggerCellModifier implements ICellModifier { private final DsfSession fSession; - /** - * Need to use the OSGi service tracker here (instead of DsfServiceTracker), - * because we're accessing it in non-dispatch thread. DsfServiceTracker is not - * thread-safe. - */ + // Need to use the OSGi service tracker (instead of DsfServiceTracker), + // because it's being accessed on multiple threads. @ThreadSafe private ServiceTracker fServiceTracker; /** - * Constructor for the modifier requires a valid DSF session in order to + * Constructor for the modifier requires a valid session in order to * initialize the service tracker. * @param session DSF session this modifier will use. */ - public AlarmCellModifier(DsfSession session) { + public TriggerCellModifier(DsfSession session) { fSession = session; } public boolean canModify(Object element, String property) { - return TimersViewColumnPresentation.COL_VALUE.equals(property) && getAlarmDMC(element) != null; + return TimersViewColumnPresentation.COL_VALUE.equals(property) && + getAlarmDMC(element) != null; } public Object getValue(Object element, String property) { - if (!TimersViewColumnPresentation.COL_VALUE.equals(property)) return ""; //$NON-NLS-1$ + if (!TimersViewColumnPresentation.COL_VALUE.equals(property)) return ""; - // Get the DMC and the session. If element is not an alarm DMC, or - // session is stale, then bail out. - AlarmDMC dmc = getAlarmDMC(element); - if (dmc == null) return ""; //$NON-NLS-1$ - DsfSession session = DsfSession.getSession(dmc.getSessionId()); - if (session == null) return ""; //$NON-NLS-1$ + // Get the context and the session. If element is not an trigger + // context or if the session is stale then bail out. + TriggerDMContext triggerCtx = getAlarmDMC(element); + if (triggerCtx == null) return ""; + DsfSession session = DsfSession.getSession(triggerCtx.getSessionId()); + if (session == null) return ""; - /* - * Create the query to request the value from service. - * Note: no need to guard against RejectedExecutionException, because - * DsfSession.getSession() above would only return an active session. - */ - GetValueQuery query = new GetValueQuery(dmc); - session.getExecutor().execute(query); + // Create the query to request the value from service. + GetValueQuery query = new GetValueQuery(triggerCtx); + try { + session.getExecutor().execute(query); + } catch (RejectedExecutionException e) { + return ""; + } try { return query.get().toString(); } catch (InterruptedException e) { assert false; - return ""; //$NON-NLS-1$ + return ""; } catch (ExecutionException e) { - return ""; //$NON-NLS-1$ + return ""; } } @@ -91,7 +89,7 @@ public class AlarmCellModifier implements ICellModifier { public void modify(Object element, String property, Object value) { if (!TimersViewColumnPresentation.COL_VALUE.equals(property)) return; - AlarmDMC dmc = getAlarmDMC(element); + TriggerDMContext dmc = getAlarmDMC(element); if (dmc == null) return; DsfSession session = DsfSession.getSession(dmc.getSessionId()); if (session == null) return; @@ -105,31 +103,32 @@ public class AlarmCellModifier implements ICellModifier { try { intValue = new Integer(((String)value).trim()); } catch (NumberFormatException e) { - MessageDialog.openError(shell, "Invalid Value", "Please enter a positive integer"); //$NON-NLS-1$ //$NON-NLS-2$ + MessageDialog.openError(shell, "Invalid Value", + "Please enter a positive integer"); return; } if (intValue.intValue() <= 0) { - MessageDialog.openError(shell, "Invalid Value", "Please enter a positive integer"); //$NON-NLS-1$ //$NON-NLS-2$ + MessageDialog.openError(shell, "Invalid Value", + "Please enter a positive integer"); return; } } - /* - * Create the query to write the value to the service. - * Note: no need to guard against RejectedExecutionException, because - * DsfSession.getSession() above would only return an active session. - */ + // Create the query to write the value to the service. SetValueQuery query = new SetValueQuery(dmc, intValue); - session.getExecutor().execute(query); - + try { + session.getExecutor().execute(query); + } catch (RejectedExecutionException e) { + // View must be shutting down, no need to show error dialog. + } try { // Return value is irrelevant, any error would come through with an exception. query.get().toString(); } catch (InterruptedException e) { assert false; } catch (ExecutionException e) { - // View must be shutting down, no need to show erro dialog. + // View must be shutting down, no need to show error dialog. } } @@ -151,15 +150,16 @@ public class AlarmCellModifier implements ICellModifier { return null; } - private AlarmDMC getAlarmDMC(Object element) { + private TriggerDMContext getAlarmDMC(Object element) { if (element instanceof IAdaptable) { - return (AlarmDMC)((IAdaptable)element).getAdapter(AlarmDMC.class); + return (TriggerDMContext)((IAdaptable)element).getAdapter(TriggerDMContext.class); } return null; } @ThreadSafe - private synchronized AlarmService getService(AlarmDMC dmc) { + private synchronized AlarmService getService(TriggerDMContext dmc) { + // Create and initialize the service tracker if needed. String serviceId = DsfServices.createServiceFilter( AlarmService.class, fSession.getId() ); if (fServiceTracker == null) { try { @@ -172,26 +172,25 @@ public class AlarmCellModifier implements ICellModifier { return null; } } + // Get the service. return (AlarmService)fServiceTracker.getService(); } + private class GetValueQuery extends Query { + final TriggerDMContext fDmc; - final AlarmDMC fDmc; - - private GetValueQuery(AlarmDMC dmc) { + private GetValueQuery(TriggerDMContext dmc) { super(); fDmc = dmc; } @Override protected void execute(final DataRequestMonitor rm) { - /* - * Guard against the session being disposed. If session is disposed - * it could mean that the executor is shut-down, which in turn - * could mean that we can't execute the "done" argument. - * In that case, cancel to notify waiting thread. - */ + // Guard against the session being disposed. If session is disposed + // it could mean that the executor is shut-down, which in turn + // could mean that we can't execute the "done" argument. + // In that case, cancel to notify waiting thread. final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); if (session == null) { cancel(false); @@ -201,34 +200,30 @@ public class AlarmCellModifier implements ICellModifier { AlarmService service = getService(fDmc); if (service == null) { rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, - "Service not available", null)); //$NON-NLS-1$ + "Service not available", null)); + rm.done(); return; } - service.getAlarmData(fDmc, new DataRequestMonitor(session.getExecutor(), rm) { - @Override - protected void handleCompleted() { - // We're in another dispatch, so we must guard against executor shutdown again. - if (DsfSession.isSessionActive(session.getId())) { - super.handleCompleted(); - } - } - - @Override - protected void handleOK() { - rm.setData(getData().getTriggeringValue()); - rm.done(); - } - }); + int value = service.getTriggerValue(fDmc); + if (value == -1) { + rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, + "Invalid context", null)); + rm.done(); + return; + } + + rm.setData(value); + rm.done(); } } private class SetValueQuery extends Query { - AlarmDMC fDmc; + TriggerDMContext fDmc; int fValue; - SetValueQuery(AlarmDMC dmc, int value) { + SetValueQuery(TriggerDMContext dmc, int value) { super(); fDmc = dmc; fValue = value; @@ -247,13 +242,13 @@ public class AlarmCellModifier implements ICellModifier { AlarmService service = getService(fDmc); if (service == null) { rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, - "Service not available", null)); //$NON-NLS-1$ + "Service not available", null)); rm.done(); return; } // Finally set the value and return. - service.setAlarmValue(fDmc, fValue); + service.setTriggerValue(fDmc, fValue); // Return value is irrelevant. rm.setData(new Object()); diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TriggersVMNode.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TriggersVMNode.java new file mode 100644 index 00000000000..9934e2e8d6e --- /dev/null +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TriggersVMNode.java @@ -0,0 +1,203 @@ +/******************************************************************************* + * 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.examples.dsf.timers; + +import java.text.MessageFormat; +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.properties.IElementPropertiesProvider; +import org.eclipse.dd.dsf.ui.viewmodel.properties.IPropertiesUpdate; +import org.eclipse.dd.dsf.ui.viewmodel.properties.LabelAttribute; +import org.eclipse.dd.dsf.ui.viewmodel.properties.LabelColumnInfo; +import org.eclipse.dd.dsf.ui.viewmodel.properties.LabelImage; +import org.eclipse.dd.dsf.ui.viewmodel.properties.LabelText; +import org.eclipse.dd.dsf.ui.viewmodel.properties.PropertyBasedLabelProvider; +import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; +import org.eclipse.dd.examples.dsf.timers.AlarmService.TriggerDMContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementEditor; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ICellModifier; +import org.eclipse.jface.viewers.TextCellEditor; +import org.eclipse.swt.widgets.Composite; + + +/** + * View model node that defines how alarm DMContexts are displayed in the view. Alarm + * nodes are fairly static, once they are created their label doesn't change. + * @see TriggerDMContext + */ +@SuppressWarnings("restriction") +class TriggersVMNode extends AbstractDMVMNode + implements IElementEditor, IElementPropertiesProvider, IElementLabelProvider +{ + private static final String PROP_TRIGGER_NUMBER = "alarmNumber"; + private static final String PROP_TRIGGER_VALUE = "alarmTriggerValue"; + + // Create and configure the label provider. + private static final PropertyBasedLabelProvider fgLabelProvider; + static { + fgLabelProvider = new PropertyBasedLabelProvider(); + + LabelColumnInfo idCol = new LabelColumnInfo( + new LabelAttribute[] { + new LabelText(new MessageFormat("Trigger #{0}"), + new String[] { PROP_TRIGGER_NUMBER }), + new LabelImage(DsfExamplesPlugin.getDefault().getImageRegistry(). + getDescriptor(DsfExamplesPlugin.IMG_ALARM)) + }); + fgLabelProvider.setColumnInfo(TimersViewColumnPresentation.COL_ID, idCol); + + LabelColumnInfo valueCol = new LabelColumnInfo( + new LabelAttribute[] { + new LabelText(new MessageFormat("{0}"), + new String[] { PROP_TRIGGER_VALUE }) + }); + fgLabelProvider.setColumnInfo(TimersViewColumnPresentation.COL_VALUE, + valueCol); + } + + private TriggerCellModifier fAlarmCellModifier; + + public TriggersVMNode(AbstractDMVMProvider provider, DsfSession session) { + super(provider, session, TriggerDMContext.class); + } + + @Override + protected void updateElementsInSessionThread(final IChildrenUpdate update) { + if (!checkService(AlarmService.class, null, update)) return; + + TriggerDMContext[] triggers = + getServicesTracker().getService(AlarmService.class).getTriggers(); + fillUpdateWithVMCs(update, triggers); + update.done(); + } + + public void update(ILabelUpdate[] updates) { + fgLabelProvider.update(updates); + } + + public void update(final IPropertiesUpdate[] updates) { + // Switch to the session thread before processing the updates. + try { + getSession().getExecutor().execute(new DsfRunnable() { + public void run() { + for (IPropertiesUpdate update : updates) { + updatePropertiesInSessionThread(update); + } + }}); + } catch (RejectedExecutionException e) { + for (IViewerUpdate update : updates) { + handleFailedUpdate(update); + } + } + } + + @ConfinedToDsfExecutor("getSession#getExecutor") + private void updatePropertiesInSessionThread(final IPropertiesUpdate update) { + // Find the trigger context in the element being updated + TriggerDMContext triggerCtx = findDmcInPath( + update.getViewerInput(), update.getElementPath(), TriggerDMContext.class); + + // If either update or service are not valid, fail the update and exit. + if (!checkDmc(triggerCtx, update) || + !checkService(AlarmService.class, null, update)) + { + return; + } + + // Calculate and set the update properties. + AlarmService alarmService = + getServicesTracker().getService(AlarmService.class, null); + int value = alarmService.getTriggerValue(triggerCtx); + + if (value == -1) { + handleFailedUpdate(update); + return; + } + + update.setProperty(PROP_TRIGGER_NUMBER, triggerCtx.getTriggerNumber()); + update.setProperty(PROP_TRIGGER_VALUE, value); + update.done(); + } + + public CellEditor getCellEditor(IPresentationContext context, String columnId, + Object element, Composite parent) + { + // Create a cell editor to modify the trigger value. + if (TimersViewColumnPresentation.COL_VALUE.equals(columnId)) { + return new TextCellEditor(parent); + } + return null; + } + + // Note: this method is synchronized because IElementEditor.getCellModifier can be called + // on any thread, even though in practice it should be only called on the UI thread. + public ICellModifier getCellModifier(IPresentationContext context, + Object element) + { + // Create the cell modifier if needed. + if (fAlarmCellModifier == null) { + fAlarmCellModifier = new TriggerCellModifier(getSession()); + } + return fAlarmCellModifier; + } + + public int getDeltaFlags(Object e) { + // Since the label for triggers doesn't change, this node will generate + // delta info only if the list of alarms is changed. + if (e instanceof AlarmService.TriggersChangedEvent) { + return IModelDelta.CONTENT; + } + return IModelDelta.NO_CHANGE; + } + + + public void buildDelta(Object event, VMDelta parentDelta, int nodeOffset, + RequestMonitor requestMonitor) + { + if (event instanceof AlarmService.TriggersChangedEvent) { + // The list of alarms has changed, which means that the parent + // node needs to refresh its contents, which in turn will re-fetch the + // elements from this node. + parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); + } + requestMonitor.done(); + } + + @Override + public void dispose() { + if (fAlarmCellModifier != null) { + fAlarmCellModifier.dispose(); + } + super.dispose(); + } + + public String getPropertyDescription(String property) { + return null; + } + + public String getPropertyName(String property) { + return null; + } +} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/package.html b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/package.html deleted file mode 100644 index a4b276be052..00000000000 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/package.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - - Eclipse Device Debug - Debugger Services Framework - Data Model - - -Example demostrationg use of Debugger Services Framework (DSF) data -model interfaces.
    -

    Package Specification

    -The example consists of two services, one that monitors a set of timers -(TimerService), and another that tracks a set of alarms -(AlarmService).  The timers are incremented at a rate of one per -second, although for visual interest, timers are not synchronous as -each timer is incremented at a slightly different moment.  There -is also a "Timers" view that displays the timers and alarms, and has -actions for adding and removing new timers and alarms.  Most -interestingly, the view has a toggle action, which switches the layout -of the view from having timers at the root level, with alarms listed -below each timer, to having alarms at the root level with timers listed -below each alarm.
    -
    -
    -
    - - From 2e76289006deffaa0b8482f52c5bbb4e5a7ce9b0 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 6 Mar 2008 18:55:21 +0000 Subject: [PATCH 283/834] [220446] Updated the "DSF Common Patterns" document. --- .../docs/common/data_model_1.dia | Bin 0 -> 1382 bytes .../docs/common/data_model_1.png | Bin 0 -> 4299 bytes .../docs/common/data_model_2.dia | Bin 0 -> 1740 bytes .../docs/common/data_model_2.png | Bin 0 -> 6953 bytes .../docs/common/dsf_common_patterns.html | 793 +++++++++++++++++- .../docs/common/request_monitor_1.dia | Bin 0 -> 2088 bytes .../docs/common/request_monitor_1.png | Bin 0 -> 13914 bytes .../docs/common/timers_1.png | Bin 0 -> 9451 bytes 8 files changed, 768 insertions(+), 25 deletions(-) create mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/common/data_model_1.dia create mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/common/data_model_1.png create mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/common/data_model_2.dia create mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/common/data_model_2.png create mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/common/request_monitor_1.dia create mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/common/request_monitor_1.png create mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/common/timers_1.png diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/common/data_model_1.dia b/plugins/org.eclipse.dd.doc.dsf/docs/common/data_model_1.dia new file mode 100644 index 0000000000000000000000000000000000000000..8dbabe73f156d5a14eef900e42ec956a3567e8df GIT binary patch literal 1382 zcmV-s1)2IEiwFP!000001MON%Z{s!)zUNm6%2g|ilxT^Ybr!q8wmlT+p=qxMZ80*t zv}j0l9PgpOz0@PI_3}fHY#rD@UJNxKhno4m8A_i%KQFoVM5CCAaH0d#(lr{+h0nrZ zqW|^q%Lh;Ye1G%FXXK;$3L>)9)D>Zz{58=RQm#IZMw`vX(JM;S^2!V;3CqV2%qS;kLgDr z%ur>trtNX!IpHeA4!PCAi$^A$_&BjZhqU3`SLwVIed3{$C${h zHHw7qQAE-CA`z^aPvaxOR-DsdX^~GG9ozNtyi+$O8!Ab53c<;iM!ET~JF(XC8=Ujb z-Y$sQKXfj0_kN{fNfpjq`=C8UN)dkumR$T&f~W$7`4jyQtGG*Lzm!cygOzPsiPuP2?I`Z`<96TRv@;C(H(S6%d@bN{6y_gDW}WnTts2DNa)9{ z6d&i_iSBaL@4&sq)?`c?U5`Q->OxS zFxIt{_fu-hF8z)2Cz^2OKH;Cgf=Y@UYdg<}D2Cmsq1Ohf*hQRJO0)q|oq7;1Y5mRH ziSel$SKA|;mjqAglA7y+6RB=4!cb+bVwSj)Q7`||7K)4VSd=1_Np1JviSAXKpOVpD z#M$mlcxYI0hR&Wi<5Zl->i0pL74&|@8Jf7*VL0zdt)0%n>*kc{3@O)e{3_QjO61zh zeP@RNI7ZYK`$%97~I;xccz)oN>z5t#4rtY?4 z$E#5GER^NIyNcw+h$I?VBpb-i?St&l&}4@YbPbrE;n@ky(Cm>QO5{>-q^3dB{r^=GeI9!c@@BSLOBWo&mP(DMEirqDX9-V;sVcrl*{S z!QnR-P*;ef??#}Xa@gK{EvT<)tT)PX+|yyF%DjP(>s_2ai}Y*@CT|$o0H=B6y3iXs z!E0QsJKr}I=fG=jzt7w*9n6h8ABvWN^z95Eo~3oHpxG5@dJu6!yu_yM8`}3ZnAhD!)u~U+3;?)38;vJRupm;YCR&^O>mpf|W zI{E3zBK#_d43FoR#SBI6B~&YaJvt&&Lfh9cE54Y*rEu*tN+4qJ=1|b>{rQVj(-tW0Z{`mW)Uf&K5P(eXKE-uCCXC~d8TD!ygQjy02%cr>8^oOH( zQy2mpoInq5`<|Mb%FN6RG%bvvdzqUL5#Vi~sdvnyZejM?k2czhj~pBvq{0?{3uu-b zjS&1=ZMXB|IYd%BVy0RtW$2E=-3V(dE34q(;Nm0ymc@)(B3&UnqjYB`Xo!`G@sLdI zJack%%yZA}@yYsSm>UbdXW=QkKv>gCH%gM&(7@N`>f z?c^bSt=50G-L8PVb7*2>5`MdI2AD@hLqp7iJM!#gUkK)y>@IzIt;#`Kby)p!+<6H! zrM@>2)8tP&-JACBS6Vpj>gww5?w*}>>Lh93zP%CHLZ{P_aBVCd>F2jWp;X_f0ak4O z@qZSp32U7vd(*TDgnxBoF=eJ@=Vf_;$u+(m+5pPC$p2nOMuvid0=~Tb18#J5G&VN& z!C+o8{G-Zuzve8#uE|N;;NZqdLRHlog)$a=i;tt)se}IZDYK1@jjPja*i!z3LabUJ zgNCN2f9nc9J3CvJ`6_~xSk6Z8dH0uurn_m_T1_)xw;x5%Z)tIn^_G~2hey1AZO7iX zj4KX+#eoZV_4T6(YvSsDTHyzEgth&dAlxKJzkFeML*QbcRk@j*RO}&rRn#=;JeEve zDvWgMKm!(4R%)PkE9$vg@^f<^IW~#j#L{2Co8LSP&sF!|SXucJ+|kx{bb3V9#_Um4 zCmdhBc_Xq{xwp4BGBP3{Zzd}hRq#7jB|T?YDdlN1v6V0}F@Z}=?f} z-Eo!VoI1EHGX^{T?VDu8!8{(12UfU9X`!i?{IaTQ2i+0T8R_RYNZz`xrq)*q9I49h zex$}nnKL^hP{`E!-p0np@J0xAc0I5q;)DjXVuQrx@MA~wa_;^!?AhT`p%D1bYTNqX zmw!{JIGLZHfA);6e01gUjTyiFw{M?lAy>yL|j`Oi>#e-)pM1$uh=%ND?JHF4f@l9@FuGS52g=O&5t~+-jVR9zRP;AP* zxPkoY7$U#gs3#})hPTbGhq8@lm)n%Ih2bwFa`5$B2pO#0XS{NRNc;T@G4}L^>?ZfQ zG?vEQaX}}&$M)MMX``@`v@XYJ8%uPy6mBXF||cv*^;5_x=Q-aadjAgo!@H*pf+L6?E8^3^G{* z|L4_DkJX6)t&_^bf><^z>lbLg(AVTIy?-a9bDt}sM#f+RuWbb=g#FIb!>Mk2=LxaP zwljs**yp9V;(!iG`ENeGsf0%?)K*sgZur1AH>h|8F;i!2lu5AH=RyVXOm{50&OAGT z0SnO^gFkIx(?^(I+92qdMi)caLs>b+xPglAa7G;Hhfy&05UcTLY-dphs0Kp4`BNfa z#|z7vXHxqFVUTRG@B19o{|qFBshj%fo=9p12@0Lrf+VZ8*JAu$j1@2c(2ebT(XEnK zLeDXbj69>$)`9{9`}+H*r>7SqatFRnO@&SSHZLwN-pn6tqY{teq#_Qs`ytfUHNx>f zsm7t%%*?FE=LI0RUmg4h1_rKxK&Z_w_C>kvql+wFiIc9&Cj7VdZt(J)KY!uE1whc~ zC#PFm0h#^d6BF|04s9Xp6Nt$5{iAX`z953WQc_Y9y!KUe-{*U)s^_Kg@o^)ZB;3|E zD=Q22BVNAAXNrGFn#`TbnCJG~;Ina3V4*k!+4lWDu$R3(J(X2ei(b7rsmwS}PtWV7 zM_av8Ntisd2cPc%Bg=<9M5FB;`8879qvVnj`p>esNFZ~=9(}X&pooZB)O9d;tviyF=i^4n5FBAGUhQ`bZs$wVzJk;v(xLzd3*hFgRzhMBMWbw-x;HMSTP-iJafud<^)P(G}#4i+;@*XJ=`O*Oz_8+GGNOkdngR z@){me_rh{Rn2&0dZGq~on)wEU&2@l+EzA&a&;3uL0gidFQ~2CTWi}p9e8L03%^gdu zjjeVa;^xD?RW4K!f!NMf$5{rm0z^PN`p{7DTp4Wn5-(o0*(w=fZsfAQ32@CF+gk z6Jq>t^c?#H{;a0I?lNODjnmGw`tSR0v(Ya@6K2V8+ut+qs;0`?^f=0L?wSgiV7b+O z=TvzAKkW9emH!_kRJWP*X<8!AkR&LgR%kXi%pQE zB^L6uqD^cuS)TcJg8*A#`aRQ7RcpkhF}b4KrydO0Xc-t zho5Mv=C=D2Vop!h!+-?2%ftKH6~fA^WCYuArc28YVN2N}sv#;(Nz(E?Zj~N*#oCd~ zsTT~WL&Ak}Ti24;#CE74b(sawvpE>y0NDOunoaSIdYmO3%j(D_H1Q_N!WyyXVce~G z-;gG>sbtw+Do{}Yp+*UEl2JBeFh28uoc#PN0FEgr0EMIoysD53;z|0by3EiXmDK4q ziU**T3eeX}@steoQB7E=94;`@>*C%~$)$i^iBQ1PgIfvOXU98Ewd&|spWLr~>UUEk zT&;QUZ9|Gl7>0BnUsF+e6+rHJ_UxGo0D3n9x>2u7OG_IXu4!sw#w%@neSLfM1q1{D z;Ry>1`|#nzkk-!U&a+c6#{bbHhemIkkdP1n;Easo0<4?PE={jcsff-9ETCCHa}1{K zYQo^);Ix0|Ep2UW!}?TRSbU7$Y`t4=u0QdQCK8IAl&=}ur_atSiEMG~{Y%2Z*7gAS zB0wRN1~SspkVs^nX6Ob^`xJG&)tj4}>p@LVPY3Md;^G3HLPA17&$PHGwA96mii(Pq z^>y0O37Je*%B-rbH7{uQ91yFWXnXS}E8*?AF69?@Ws$u~SFQj}6b=gd6N zSS8eqD*1c(SV99?0r32r@|Q1H0KgKSJ|E{65#c1s-_Kls>+035g;ev|$M1MD;UU?} zSHWQDdFf?^xOXzVtUS^X2xNKxMZHAWr4PJNtc~5#<<{-#W&rC?j(pjE?Xf?Jm?f;H zs=Bze#LLS&G%&EzN(9iAgC*nYoR0L|&S9ce@O(FGnDwl9e77%aUh(wh@3MlFu`z31 z-L9!u50W$=czSYjasu4BTk$*&z|`ZJmZ0t7I z<^m#xot>SNlamQ}Xuc&PY#i8P;LxJc==a3{U>6t5ly*tt$_a$QH5%ZbT3T-6dPgTG zLDP1Biir@O92)S)8Z1@g@t%NaBhQA1Elf?5CQs+0d4ZF#9@5sohz6n{k0Su9+xKTN zK>P-zi5iFf`8X*t8kX9zuK)(GhhW0O4re3p9( z`dE1^6M6F!2U4ZS0>KzPlEPN;AU>CfbiGh8CvCR zE2Ve1P*nTGb*oNnA@HsfLa!`}&$_|H3BlOX;9~dCBc+LGoxoyvcOj#R$Yjs@j?UL7 z?}9Z>V;`~AeiuU%;!_ZcDN3=aq}z8YZ@&Ez)&y|*C)cgxs5HF>y51Dhb8(xyuRiD7y;v$LG}=346Gr-v<*?x`O*o;#O;qRJ9=SDx*- z>$&{rx1Zi4`P1#qN82GE_`kJJwi3U?4Wi%X@+J&-AEwj8;h?Z%Ktj(~n6p;`I{lY0 zMy8x-D&O8n(sKqj2}yJh z7k}hw%4VA3bB6bhtm)FH>Q&uCJrfD^gv z+jpP!cgd2{3nyM>3#}9qZi&Bk+@c)5H!Rr*s2~U--wXpItXjGS9`~faxMjcMSij=@ ze#JS#V(0mxPn@tQa_M=D5;u_=`g_`3POu`3o7g$ET4-_SgrRp~{da@~*C>!&e)6`u zp1bxP`@G|3C@Q!d96Q`B9?or-sz9UpjwJ$);so3~fwN?^Ob5pe6A5~I_Q!76=burG z;iubM+C;*wGDz5n8q}yCB-VS!rojbc%hFVE+N5ODOS_(@yLMxeOSzC8i(uqP{gnNe zQ?QoO2b|*0vt96(|Ik&Ks`oSXwv@|RN$;iKsT-2D=gOxHgy$cQJ(qt|vzwGxi?ie? zSlFeV_hd@Ym_V3Uy9gas%$LhNZ=dTx+%=;qe_g@A0uu-ntQ+P`Z~_mHE*pMZytu|rDdxMP_rM&bjZ_@`;fT+^^q1OH}XSdjR zzVpN5_`%L9m&+k)i{Zc&I;#$ZBo`AXY>ADaEj9um78`+@#YSNDgpDl}8?kZ3#t|Eb zfsNmMvZFsd$1VX!*hS)qL?@1z1C^y9yNTKS80U zWqzX%;WN_&scD+6O;exn+{+MYoKUflu5oiwkP5UJH&dut6OMDLW;GNXM!RugNSLFk zdaCi+iVR)u7{*@?JxHM9D8`w|WmR0{QMXK7bX~e5TZbL_s)!rNQk)yaFqGW-3uX5- zil@($g8C~c_{XJbe|-^Io4d;Hnuy6xZm-NWn+PJzS-V?W{^U;C+O@k@I+v~I0r&Be zsuRa6L2l)_E_YXsDM7)V9{(b3I0~hP7u(N4cEPMxQy@C=3;xtvK~J6qZqITSXB(>LTMZG@s(KW$?HRaT1p;1*5^lWjMy= zZsT&%@W#MAn80ia4$Kv3hdU@jIQj@KLZGVQ2}Dmt2m+QiiQ@Dis*uk%*@e^}3lRZ@ zNY?g7yc-POX@c?YSH~^uAp^CGt_xOF9SiLWYD!XqU~JBSu0&@^8+Qextz1yoj+LmZ zTDjLXY&mnwTJ7=+I5BQmvbgqw_`Y|jHsr=F@<-MSM&0%KDV)((#Kk$E@gjYJ>U%+Y zFUZ~t`f_E^MWx1lOk|;EC4P*I8BbsO@#2D3r6i*Zzcm-mRS;%hZV0<5Aq>&MG&;^_ zq@fh`5=wLLc$E;K(FNa@3xXC=R1+LUD;fZx^=UH*CQuXG0l-dO(+rvBGorr!zl4vGfB4Nquh8=hR;FdLrZgs1xn&)D!B zDB!^tYIqu50G=VbN0O9hNsok=XN`{()ajC(FVG@_=>3MKD;cY_*H)#0o;l;xviyC-#>0TIWE#j| z3)Grymtg%6}i zje-z*N2K@A6G8|O(&jqvy_q#-tyynovR2By>y&-Z*=O(H{wK!7NQd*(C>VCw_4uFzPm(bYT2I!5KJ z!-5y6$L@-5b3A*n2x2R0hp?H&!`S}3ie=N)LL7>FL;s%}EK-LHRAuGlc#+|ro*N7z zl7-@vKYVa6t-v^I`m3L#sp&vNDB1GU!-4Vf)G=&rGJ)RtU`i;y{oA*1@2)7H;^3h2 z6~_@`Vf1-@NaJ}Vy%hv&AU4rdx1Mty4Va0Jj-H#F>+S80iHUj1&J`38AR{Y#EC6CH zrMmAJcQMzEv3WPe^@P2-NK7O?zOEs8~je&G;%^)uAb(uegyo2eNYvZ{?wm+qUI#>cMj%c2J}U@67*m#9&H`AL<65&Lt~ z({|)|HToP^*9UQF30K5w64b8f^XHzP9&s_Ti7zf_#1?Ia#XQ2L@;F^uRn^YMMnzTC zn;&ShxxW6zwZ+<}F_5-dqwHQipb}5bi~2}d1U0v{euYy;pxEuCvShU9c;zZijalxe zzOYYPz;SSJp!pSV-??)~Qqsi2B5-HL)Nn|`t|1wNk(ZOp&-w{0WL8!gQeS_lvI_%2 zuG|y2O{|{ZoUHYqsP=l7>Lp|Bj(F1W_i5?^*DbZQTHD)SGgsT&b?xovCVa47HvI}; zva{8*6zZ5vW|A0mO<;6nq^hRIBUMgWxjvk_je#LT$10v2Oj0|H5!;k9AzcXokcna#zH z1QZIDn*Z6lhVUbXCpAA}_e<7@n(oTC=STAL@<0+czT?ihp=MIRwe|HdINT^hi86pj z$lzbJ;XFo5H&<8nf}%!Bpz`wa$o&=p1hH{X#xM-{1O{p%XAoD^xVXyziz_PwTwU9> zJbHR~(qWHotYvQT8pXp-yjb_E3fm(K_=f@9C zD0K9IvW|jgMeL5Hr>E!V-&kmu?o&xfNbq0j&)%Pqm6wNFSlHGDbZD77rV1-#2W|G8 zYJA_&HMniiB}f)+CYD$HQKhSC_uhbGY0%nmQCnNvix)5GbUJWqdV7r)@;E>ei+H?U zeNd0Wb{Uef9zhI)HA5n<#(dr9ZGw?+rhYP%TUF~K%wKhMbOatJUUyM|wU5iuiUl?i z_PL;7ImIP&l}OCW$gut5+*5;PY|@BW7;<&KHTJjbk$dFT_P=wj>6F^mTiV)2P}W9{ zaqvE@{5hL5R!ZY|*k0|o1Vu`JfN4CjM#h83ofj{cof0f1M(x zqs&$2GD^EKo$YRUXkxzCPZhoN*`bRk91e?^g zB@CrP&~(=~E;+O9_i%6p*mq2V67nh*)bANaPjf_yC*C1H7 zyTZ4z-5gOrw2quOatt5ePCxwY^(1`|!;u}Uy&JbLCSs*^pz?l)b}u^F>W^}c&aGq< zmHN|WkHIIqAhBatON4U9`feEx@n>vQYx!!YgkBTEegd63_TlW=b7$b_ku&qDy4sDQ z=XdE9F!PuZ&>yM}hl{<&y%VDzWa!NGK!O7kEf{fK52Qk0tD1#@qa?6&(ey-iZX^3b zyNlz3&=1|Y+)GgIq*I}kmJXZBx6oS;P-p)r!JFRP7F$`1tUj>k8UO2qSBu7Vj%Cwm zvRKB2llGK*t%b&}VmwS<=lef@S(v8;_F0G z3O?v~GR#cW`$l;Wp-_rCvJxd5<9OT4>&!LmHOol@IL+M5ZMhI6sy7HWYPoLTm`wFHez}74#4a%oQ?B{ z_Y6cFPF)ZkW_Of>{oqZl3)TLZ1sod0%L`U~>I8?wA3y$BT)eh2 zklW@aX8CC!NN#F(?nD4|vN=%$v15TnkQ@h=rA}tTB8G>=}LEIV~ zzNKEk2z*4I1;^n-uWd}#2Ln*jRxraL1cPop+}ilkcUecyYka2!#^}tdKJGSJYKxCS zE_Ej5B3e*@P=VIv8KBU|`I(=D9UM*9yq^KzLV6~tx zL)is;!%bI;2CY^dap)OKsfJg9wv~3wZ+r1G?9?57x`l(C5#e z|FfZehPf-hkQX0+mLX0OCkoHznRc`DtAr+=(SD9^nzT5cX zq7%Tdi;Iizuj}6s7M3-nEvvDttgPH7Yk()IsR?#=ZVU18^CL|+h85)Jm)bSf0p5E> zIq0G=)Y5X7LYZm^{Zdv|mXkBTHP<2ntC&{6%}h1-W+>NqP2elfpY-6PaoQGusy;5R z&DCkTy_Q_RxSa_DPR_!@f?QeL#_RRi{r9k@W&Mg+T40a3bv3_IfbLKwkFe1S?AdQ; zRP&pU%y$FmO#77P)p#Zo5xf2tjh^wtU1{q$xDZg*xcev~BBB%XNxt`Iu)K$lPg!Xx z_{x>4P{iBht2hF7(pKgY#gdCiT_S7-m3sPdz_vX$$EyGU{rmKqxdX{lDOzbfcB1`T zZ)#&X3~eTdE1*{|HJ3+8i2S(oPz z21&!#cP2-K@A$VlAP(Nc0DKAz3~X#{92y$p;o$);*GJ2YgQA>tY+!!^ulo84qsZ2P zpGFbki$n?p*3U81(L;_pLbX&_+@6YJUP-xj_|8HE8`AvYt1w*}mKBtbuTdr^-p9aw(Ex6<$3=-{B)qen_IGKt#;9Hc12 zhMwK0T+&IFTp(dSAHM^M*qG(iA?L0Onv_XWp0ag~H)9QoJ^1Vs(WS7B@(EwyfbBN} zho{H(UFhiANJ$oattdV|zN4eV5%+E?bUEYf(COmhVx_R%jqdL5u`e!SqM`son>8)E zF7W5p*46@H3OKXi&bY;i!*YH8hNzL2sg6e{@b7Ccy?Z2q85rxfxRXPLl0mR=DPiGd zpmb@A2MRS;8TjnCL;e`YX;~SW005csOTS;AA62=}G)0^pdK|)}E{lnY`9FQy+12I9 z6c-!QPfbAizm2^9bVr=-)M}6lYf7{;cc4i6!z(Z+XGz*5VTHPU8>tLRUUO;M+2#ss z8Ij1(Be%p-=Ce{7XRM!(v?%lptQfOY%HiGF>AHvXevR!cV|ag_NJxVHlr=a|W@Iy7 z`tl-Q392A-1T#irsY#Dx{WZ+eKUxLIF_5%BBFVZxP7mgNvKyS4k((AIj6RW;@SHn# zuls#wborI$P$wxP4cW+zZlMya+S%s8S1|3L6UlBTJ=`QfFw^Ein(EK&e@B-xZlp*1;XIp@Zi?O3F?o^Jo%lMy?53zj-4 zg+BLG9-Y34y%}*@eeOyA^g_aj5Z?6kD7l?9icXvslxjFCJ913D(Gh&9p<4(?y^y^V zudC@CvN}u?HS2`F19XA2edKmSL~TH&TS#P6;3Hk-06FFEVyFFZ0bi$tTTS2J{?IHxUZ{Z9fk8lDh|oTkeC*l*nh!i%jaMBQ*_7%xz6V-d>__=K3I2G&cuJrj%{> zX&0Hi@PZ(L2x3MSlCC>4STbG~l07vQS#7Uw64-ET0FuQDNrUG>%XCDdL~m(~Bv+dH z3?Ca7LNXZx9}Q|93&+bM9he&7`Axa}{_CG2j*5~RVbAF#8(D;gXpV`_q#ld)GhvJt zjk?_e`TFiC1&6(Gv+=O)mKL2U)-RP1&37{Ao8ak64n=jFVeV>{QE!vyz7&7jJW{3u z2U$P&(`qI8gs0csIurs+5Y7Gze+9t75e{KvF4v1K`<7G{jM@=OOYlW9RWu+20e=1QrCId zR?Zpms+T|EPJk&rSv%tdq@T9%7}hrh;i;adVxmQ#i=N&$fju)Ybpw+a5W)I~xP*^e zZ`wN{No!}mDeF;>eFJsyhWVwj*;DfjrVfP&-@>x(Uqy6azMhQ3z}$zgJPY0iL@7u& z2e#kvSv%eABY~}fCk4h9o(*9=l|S^HMQ`kf5#ni@+1K!<8s7=nNZvbFYnM#WlLHq6 zx`s%!iTT~zPhWAIZ&P^#nq}(4PwD!o4GTu_A0KCa!y+Nx1FzdXrH60$8RTd8s4ro5 zwC)vXLj*CGg(Sb)9j#}*|LVH3Sk1o{uY6gHNz1()8*P-=beA`&&F*f*Nnh6W;DLU< ze+-CVk@fR{{&r|?#2Ttj5Pp7`seh1@ZJrB?(?^}XXafoFg;01oGm04+3PnoO;Y6q) z4I&HNxF7NSmME(6*}=REqNvVwWtecK`QBzc-iJt^K^9d4H`dQK8#kJQG|}N*kSY+T zt=!Jplq62aZk*~t1Ix^3pucDw5}8oE(6fgCYJ;)ATvsXz3Usj>muwM~;XVeY7%+Tu z`VW<1up4u?_Z7V}Q|lhai=hQ~n)te%hi%%#IyeM+dU}$8f*u3`^YMK_IQ{}p{F^qn zz?Z+<{94k)5uBkK0S72mOG}H4@3Ag-(DLx`xXW@$9;M&6tb(x)M)#(IXO>m>Y60bF zY(acd_FI*XKtw>t`|B>f>3YkC@k{5^bT~OVTUuH&GBSYV&CUhhSXps(cR#h5pDN!W zVFrUC0S$vdAOM0>f=JnH`60V$!hC1bFsG!sCl~+{kD#ER`#YUUVt^5(;2ngyF|Evr zL~Y~qdHe2NsdY^$kjgh}X2AUXGT6Fc;&f+c=j7yMo<4>!-8exX1UMvkI;aE>cXxPLn2WRX#!jyr?ht4=Qzte5?{eU-vUe6u zUReJdzz0c5Nt|3<>se>GxG+gcQ+0v*tjeY)CLqMMb^M0JiZlPf#zu!}3mD9&;XJu5 zI{J8Se`-EuZ?DXzc2J=fi=9ERi`!jop5<6tHVq343k;+H+ep`+UXCB7zfohZm6Un^ z`s;hRQ%f`_mfGX9gC>*7!otER%udE2&}_T&p5@Ilcg} z76G_)6bGn@+^dX#2`HO@VAkNb5baz`%uo(4wey?mND%G`G_EG1v~%&uRe){(2F4w! zUiGm>#y7CD@y+DIe+Yp$mr_=HA+hb@gxY0r#LmF}0-wCMr<>b=%w~V~y@S0gz#bhO z9CXhF+cd%{=EiqqZ{NPHs2IBOt6Z7bFk} zT3QNJ8bJBz;E+>N;=wqev<3194h3F$mUuo>2hgH{$_OK2yZ!LhFfovvxhP)($j=1A zJGJSlDO+pn5+ofE*mD{hRD^{K0IrJy*-1+LcX)=cQ)AJ|fTJiXDgq7)u%T3G!`~>D z0kcQFEHKJ&_w>AV^JaTrpO35S%EpFFsU!AfQ0INbciE_AQ#!QiP*1LFMcQ>odPDS( zJp3$5$=e0)^yg(0HgbD+psWp(?ygW0hZsI&Cy59sU7x*$-OnaF6`tO3th}~RdE0vz zwhEJJZZL?d^*SMqk58$uR&0mxa(WE22T2-zQY=OqP3ICb-dyhi3?>%-aq-Bs)v#nM6KHy6?YMN? zOJ$Mu4+_ArbdBp@E*Z~2Iz-*7SPlbQFV@s?x?9b4@RPrXg$+w9lO`ESe`V_J0h3Of z-jh7u@TJh+6H)GZ^m(x}UuFpRd`W5uVD219G^Hox0HJ5u!NLG-zh_sEy>z*fo;-fz z7huwUEZkW*vmSfyCz%C|Eadt?fp07ErE{t824IxXi3hS1TR&cM!$w$u#i*T+z3vOt z{8y&S=}r(fUsPx!*#GLVQe$CtaY)7LpHSsa&>CChfdD60tb3kk+!NrxFE%|bBh6Bc H$1nZ`msD$l literal 0 HcmV?d00001 diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/common/dsf_common_patterns.html b/plugins/org.eclipse.dd.doc.dsf/docs/common/dsf_common_patterns.html index 79f481f79fb..0fd59f1a441 100644 --- a/plugins/org.eclipse.dd.doc.dsf/docs/common/dsf_common_patterns.html +++ b/plugins/org.eclipse.dd.doc.dsf/docs/common/dsf_common_patterns.html @@ -96,7 +96,7 @@ Following is the snippet from a the "hello world" example of using a request monitor:
    - @@ -172,7 +172,7 @@ value to the caller.  DataRequestMonitor can be used for that purpose. A simple example of using the data request monitor:

    -
    @@ -226,7 +226,7 @@ The following snipped from the AsyncQuicksort example shows a simple example of using the CountingRequestMonitor:

    -
    @@ -280,7 +280,7 @@ execution paths!
    Excercise 2: Converting a -synchronous method into an asynchronous one, is another common task in +synchronous method into an asynchronous one is another common task in DSF.  This excercise converts the AsyncQuicksort.partition() method into asynchronous AsyncQuicksort.asyncPartition(). 

    Look @@ -301,7 +301,7 @@ viewer and an asynchronous data generator.
    data access methods:

    - @@ -355,7 +355,7 @@ following snippet from SyncDataViewer.getElements()  shows the use of Query:

    -
    @@ -407,7 +407,8 @@ an executor. 
    java.util.concurrent.Future.get() method, implemented by Query, until the request monitor from the execute() method is completed. -
    +
    Image 1: Sequence diagram of Query use in -getElements().
    + style="font-weight: bold;">Image 1: Detailed sequence of calling +IDataGenerator.getCount() in SyncDataViewer.getElements().
    -
    -

    -
    -

    TODO -?: add a sequence diagram of the deadlock scenario
    -

    Synchronization

    Managing race conditions and deadlocks is one of the most challanging @@ -455,7 +450,7 @@ to the executor thread.  The following is an example of this from the DataGeneratorWithExecutor:

    - @@ -503,7 +498,8 @@ left out.
    - +
    @@ -535,7 +531,7 @@ thread-based implementation this loop is implemented in the run method of the generator's thread:

    -

    Image 1: Synchronization using multiple + style="font-weight: bold;">Image 2: Synchronization using multiple locks on data.
    Image 2: Synchronization using a single + style="font-weight: bold;">Image 3: Synchronization using a single DSF executor thread.
    @@ -592,7 +588,7 @@ servicing the queue, which is called by every method that adds a new request to the queue:

    -
    @@ -780,17 +776,764 @@ module.

    +

    Timers Example

    +The Timers example, found in the org.eclipse.dd.examples.dsf.timers +package, is used as a reference throughout the following +sections.  It is useful to get familiar with this example at this +time.
    +

    Timer example defines the following two services:
    +

    +
      +
    • TimerService - +This service manages a set of timers where each timer's value is +incremented every second.  The timer service contains the +following features:
      +
    • +
        +
      • startTimer() method - +Allows user to create a new timer.  It returns the Data Model +context for the new timer.
        +
      • +
      • killTimer() method - +Allows the user to delete the given timer.  It requires a timer +context.
        +
      • +
      • getTimers() method - +Returns the array of contexts for existing timers.
        +
      • +
      • getTimerValue() method +- Returns the current value for the given timer context.
        +
      • +
      • TimerTickEvent event +class - An event that is generated for every timer, every time its +value changes (once per second).  The event contains the timer's +context.
        +
      • +
      +
    • AlarmService - +This service manages a set of triggers and alarms.  Triggers can +be created and destroyed independently.  Alarms represent a timer +and a trigger combined.  The Alarm service has the following +features:
    • +
        +
      • createTrigger() method +- Creates a new trigger with a given value.  It returns a context +to the new trigger.
        +
      • +
      • deleteTrigger() method +- Deletes the trigger for the given context.
        +
      • +
      • setTriggerValue() +method - Sets the value of a trigger to the given value.
        +
      • +
      • getAlarm() method - +Gets the alarm for the specified timer and trigger contexts.  It +returns an alarm context object.
        +
      • +
      • AlarmTriggeredDMEvent +event class - An event that is generated for every timer that trips the +given trigger by surpassing its value.  The event contains an +alarm context.
        +
      • +
      +
    +The Timers example also features a user interface for displaying and +manipulating the data in the example's services.  The principal +component of this UI is a view that can be opened by following the +menus: Window->Show View->Other, +then selecting DSF +Examples->Timers View in the selection dialog.  This +view contains a tree viewer which displays the timers, triggers, and +alarms in a hierarchy.  The alarms are only shown when triggered +and are automatically selected upon a triggered event.
    + + + + + + + + + +

    +
    Image 4: Screen shot of the Timers view.
    +
    +Other features of the Timers example UI include:
    +
      +
    • New Timer action +- Adds a new timer, which immediately shows up in the view.
    • +
    • New Trigger action +- Opens a dialog where the user enters the value of the new +trigger.  Upon OK, the dialog creates a new trigger that is added +to the view.
    • +
    • Remove action - +Removes a timer or a trigger, whichever is currently selected in the +viewer.
      +
    • +
    • Toggle Layout action +- Switches the hierarchy in the tree to either Timers->Triggers->Alarm or Triggers->Timers->Alarm
    • +
    • Edit Trigger Value cell +editor - changes the value of the selected trigger.
      +
    • +

    Services

    OSGi

    +DSF builds on top of OSGi services APIs.   OSGi offers a rich +API for managing services and it is important to understand some of the +OSGi service API basics in order to use DSF
    +
      +
    • Registration - +Services need to register and unregister themselves with OSGi framework
    • +
        +
      • BundleContext.registerService() +- registers a service, it returns a ServiceRegistration object which +should be retained by the caller.
      • +
      • ServiceRegistration.unregister() +- unregisters a service.
      • +
      +
    • References - +Clients wishing to use a service, need to obtain a reference to the +service.  OSGi features reference counting for services.
    • +
        +
      • BundleContext.getServiceReference(), +BundleContext.getServiceReferences(), +BundleContext.getAllServiceReferences() - methods for retrieving a +reference to a service using a class name and/or a property filter.
      • +
      • BundleContext.ungetService() - Releases a service reference and +decrements its use count.
      • +
      +
    • Events - Clients +using services should listen to service events.  Events are issued +when services are added/removed/modified.
    • +
        +
      • org.osgi.framework.ServiceListener - interface for a service +listener.  Objects implementing this interface can be registered +with the BundleContext
      • +
      +
    +
    + + + + + + +
    Note: The service APIs all use the +BundleContext and they require the BundleContext to be active.  +This means DSF-based debugger integrations initialize after the plugin +is started, but  that they also shut down before the plugin is +stopped.  The first part is not difficult, but the second part +usually requires that the plugin's BundleActivator.stop() method shuts +down the debugger.
    +
    +

    Session

    +DSF-based debugger integrations can register many services and there +can be multiple instances of debuggers registering services with the +same interfaces.  To help coordinate services in a give debugger +instance and distinguish the services between the instances of +debuggers, DSF services are organized into sessions.
    +

    DSF Session features include:
    +

    +
      +
    • Unique Session ID +- This ID is used to distinguish services from different +sessions.  Clients may also obtain a session instance using an ID +through a static method.
      +
    • +
    • Session Lifecycle Events - Clients may register to listen when +sessions are started and ended.
      +
    • +
    • DSF Executor - +Eash session has a (single-threaded) DSF Executor  associated with +it, though multiple sessions could share a single executor.  More +about session executor in the next section.
    • +
    • Service Events - +The session is used to dispatch service events.  More on events in +following sections.
    • +
    • Model Adapters - +A session allws an adapter to be registered, which will be returned by +all Data Model contexts in a given session for a given adapter +type.  More information about Data Model is described in the Data +Model section.
      +
    • +
    +

    Executor

    +All the services registered with the same session share a single DSF +Executor.  By convention, all public service interfaces should be +restricted to being called in this executor thread.  This point +goes back to the primary synchronization mechanism of DSF.  +Following this rule greatly simplifies the task of protecting the +integrity of service state information.
    +
    + + + + + + +
    Note: All service public methods +should be called using the session's DSF executor.
    +

    Tracker

    +Using the OSGi APIs for accessing services directly can be very +cumbersome.  A client retrieving a service reference is +responsible for retaining the ServiceReference object and for calling +BundleContext.ungetService() to avoid leaking the refernce.  Also, +since a service may be un-registered at any time, the clients need to +listen for events indicating when a service is unregistered.  +Fortunately there are two utilities which help with this task
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    org.osgi.util.tracker.ServiceTracker
    +
    org.eclipse.dd.dsf.service.DsfServicesTracker
    +
    Services +tracked
    +
    Tracks all services with a given +class name or filter. 
    +
    Tracks all services within a +given DSF session. 
    +
    Thread +safetyThread safeRestricted to the session +executor thread.
    Accessor +methods
    +
    +
      +
    • getService() - +return the first service instance matching the class/filter
    • +
    • getServices() - +returns all references matching the specified class/filter.
    • +
    +
      +
    +
    +
      +
    • getService(Class) +- Returns the first service instance matching given class
    • +
    • getService(Class, String) +- Returns the first service instance matching given class and filter.
      +
    • +
    +
    Activation/Disposal +methods
    +
    +
      +
    • open() - Starts +tracking maching services.
    • +
    • close() - Shuts +down and un-gets all service references.
    • +
    +
    +
      +
    • <constructor> +- DSF services tracker can be used immediately after being constucted.
    • +
    • dispose() - +Disposes and un-gets all service references held by the tracker.
      +
    • +
    +
    + + + + + + +
    Note: All service trackers must be +disposed (or closed).  Failing to dispose a tracker results in a +service reference leak.
    +
    +

    Initialization / Shutdown

    +Every DSF service must +implement the IDsfService.initialize() and IDsfService.shutdown() +methods.  These methods can only be called in the session executor +thread  and are asynchronous.  As the last step in +initialization, a service should register itself.  Likewise as the +first step of shut-down a service should unregister itself.  Also +during initialization, each service should call +DsfSession.getAndIncrementServiceStartupCounter(), in order to obtain +the startup number of the service.  This number is used in +prioritizing the service events.
    +

    Starting up a large number of DSF services requires calling a number +of asynchronous method in a pre-defined sequence.  Implementing +this startup code can be cumbersome and DSF provides a quitility for +implementing it: org.eclipse.dd.dsf.concurrent.Sequence. 
    +

    +

    Here's +an example of how the Sequence is extended to perform the task of +shutting down the services in the +Timers example:
    +

    +
    + + + + + + + + + + +
    org.eclipse.dd.examples.dsf.timers.ServicesStartupSequence
    +

    +
    +
     25: public class ServicesShutdownSequence extends Sequence {

    27: // Session to that the services are running in.
    28: final private DsfSession fSession;
    29:
    30: // DSF Services is created as the first step of the sequence. It
    31: // cannot be created by the constructor because it can only be called
    32: // in the session thread.
    33: DsfServicesTracker fTracker;

    35: public ServicesShutdownSequence(DsfSession session) {
    36: super(session.getExecutor());
    37: fSession = session;
    38: }
    39:
    40: Step[] fSteps = new Step[] {
    41: new Step() {
    42: @Override
    43: public void execute(RequestMonitor requestMonitor) {
    44: fTracker = new DsfServicesTracker(DsfExamplesPlugin.getBundleContext(), fSession.getId());
    45: requestMonitor.done();
    46: }
    47:
    48: @Override
    49: public void rollBack(RequestMonitor requestMonitor) {
    50: // Dispose the tracker in case shutdown sequence is aborted
    51: // and is rolled back.
    52: fTracker.dispose();
    53: fTracker = null;
    54: requestMonitor.done();
    55: }
    56: },
    57: new Step() {
    58: @Override
    59: public void execute(RequestMonitor requestMonitor) {
    60: shutdownService(AlarmService.class, requestMonitor);
    61: }
    62: },
    63: new Step() {
    64: @Override
    65: public void execute(RequestMonitor requestMonitor) {
    66: shutdownService(TimerService.class, requestMonitor);
    67: }
    68: },
    69: new Step() {
    70: @Override
    71: public void execute(RequestMonitor requestMonitor) {
    72: // Dispose the tracker after the services are shut down.
    73: fTracker.dispose();
    74: fTracker = null;
    75: requestMonitor.done();
    76: }
    77: }
    78: };
    79:
    80: @Override
    81: public Step[] getSteps() { return fSteps; }

    83: // A convenience method that shuts down given service. Only service class
    84: // is used to identify the service.
    85: private <V extends IDsfService> void shutdownService(Class<V> clazz, RequestMonitor requestMonitor) {
    86: IDsfService service = fTracker.getService(clazz);
    87: if (service != null) {
    88: service.shutdown(requestMonitor);
    89: }
    90: else {
    91: requestMonitor.setStatus(new Status(
    92: IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID,
    93: IDsfService.INTERNAL_ERROR,
    94: "Service '" + clazz.getName() + "' not found.", null));
    95: requestMonitor.done();
    96: }
    97: }
    99: }
    +
    +
    +
      +
    • Line 40 initializes an array of Step objects which are invoked by +the Sequence logic.  Each Step class is an inner class with access +to
      +shared data in the ServicesShutdownSequence class.
    • +
    • Line 81 implements the protected method used by the Sequence +class to access the steps.
    • +
    • Line 85 encapsulates the repetitive logic of finding and shutting +down a given service.
    • +
    • Line 73 disposes the DsfServicesTracker used by the sequence.
    • +
    +

    +Below is the code snipped that invokes the ServicesShutdownSequence in +the Timers example:
    +

    +
    + + + + + + + + + + +
    org.eclipse.dd.examples.dsf.timers.TimersView
    +

    +
    +
    181:             ServicesShutdownSequence shutdownSeq = 
    182: new ServicesShutdownSequence(fSession);
    183: fSession.getExecutor().execute(shutdownSeq);
    184: try {
    185: shutdownSeq.get();
    186: } catch (InterruptedException e) { assert false;
    187: } catch (ExecutionException e) { assert false;
    188: }
    +
    +
    +
      +
    • Line 183 submits the sequence to the session executor. 
      +
    • +
    • Line 185 calls the Future.get() method of the sequence to block +the calling thread until the sequence completes.
    • +
    + + + + + + +
    Note: Sequence implements the +java.util.concurrent.Future interface just like the DSF Query +object.  However, if the sequence needs to be invoked from the +executor thread, the Future.get() method cannot be used (or a deadlock +would occur).  Instead the sequence should be constructed with a +custom request monitor to be invoked at the completion of the sequence.
    +
    +
    +

    Events

    +DSF provides a somewhat unusual event mechanism, where event listeners +do not implement any particular listener interface.  Instead, +event listeners use the DsfServiceEventHandler +annotation to identify listener methods.  DSF finds the annotated +listener methods using reflection. 
    +

    To generate an event a service must:
    +

    +
      +
    1. Call DsfSession.dispatchEvent(Object +event, Dictionary<String, String> serviceProperties) +method.  The second parameter allows service listeners to filter +events using specific service properties.
    2. +
    +In order to receive DSF events a client must:
    +
      +
    1. Declare a public event +listener method (method name is not important), which takes an event parameter. The type of the +event parameter depends on the event, where the listener will receive +all service events which can be cast to the declared type.  A +second optional parameter of type Dictionary<String, +String> allows the event listener to examine the properties +of the service that is sending the event.
    2. +
    3. Add itself as a service event listener by calling DsfSession.addServiceEventListener().
    4. +
    + + + + + + +
    Note: DsfSession.dispatchEvent() +calls event listeners in a separate Runnable submitted to the session +executor.  This is significant because the event listeners may +call other service methods changing the overall state of the +system.  It also implies that the event listeners are always +called in the session executor thread.
    +
    +
    + + + + + + +
    Note: Service events are +prioritized.  Listeners which themselves are services are called +first, in the order that they were initialized.  All other +listenres are called after the services.
    +

    Data Model

    -

    View Model

    -

    Adapter, Provider, Node

    -

    Timers

    +The term Data Model refers to +the natural structure of data that is being retrieved by the DSF +services.  One of the great challanges of creating an user +interface for a debugger is that the amount of of data that is +available on the target is much greater than what can be practially +presented to the user.  Therefere the debugger services need to +break up the data into chunks with appropriate granularity to achieve +maximum performance and usability.
    +

    IDMContext

    +The IDMContext represents a handle to a chunk of data in the Data +Model.  This interface is a minimal, yet central feature of the +Data Model API.
    +

    What a Data Model context is:
    +

    +
      +
    • It is hierarchical.  +Contexts can have other contexts as parents.  The hierarchy of +contexts in a given system roughly defines that system's overall Data +Model.  More on context hierarchy
      +
    • +
    • It extends the org.eclipse.core.runtime.IAdaptable interface.  This +allows decorators, retargetable actions, etc. to be associated with a +context.
    • +
    • It is associated with a +single DSF session.  The IDMContext.getSessionID() returns +the session ID of the given context.  This allows all clients to +get a handle on the session and the executor needed to access the DSF +services that the context originated from.
      +
    • +
    • It is thread safe. +This allows context objects to be stored and compared in viewers, +caches, and other clients which may implement their own threading model.
      +
    • +
    • It is light-weight and +preferably immutable. This allows contexts to be stored by +clients that may persist beyond the life of the services that +originated them.  If a context holds references to a lot of data +or it may prevent that data from being garbage collected.
    • +
    +What a Data Model context is NOT:
    +
      +
    • It is NOT a reference +to a service.  Context should not return a reference to a +service directly because clients should use the appropriate OSGi APIs +to obtain references to DSF services. 
      +
    • +
    • It is NOT persistable.  +Since a context returns a context ID, it is valid only for the life of +a single DSF session. 
    • +
    +
    + + + + + + +
    Note: An IDMContext object can be +used to retrieve any +type of data object from the service.  Although there is an +IDMData marker interface defined, its presence it historical and its +use is optional.
    +
    +

    Context Hierarchy

    +One of the most powerful features of the IDMContext interface is that +is is hierarchical.  The IDMContext.getParents() +method returns the immediate ancestors of a given context and following +the parents' parents allows clients to traverse the full hierarchy of a +context. 
    +

    The use of the context hierarchy may be best explained with use of +the Timers example.  In the timers example there are three +contexts that are used:
    +

    +
      +
    +
      +
    1. Timer - no +parent contexts
      +
    2. +
    3. Trigger - no +parent contexts
      +
    4. +
    5. Alarm - requires +both a timer and a trigger as parent contexts
    6. +
    +
      +
    +From these, only the third one has any parents (and any hierarchy), the +code snippet below shows how these parents are used in the AlarmService:

    - + + + + + + + + + +
    org.eclipse.dd.examples.dsf.timers.AlarmService.isAlarmTriggered()
    +

    +
    +
    209:     public boolean isAlarmTriggered(AlarmDMContext alarmCtx) {
    210: // Extract the timer and trigger contexts. They should always be part
    211: // of the alarm.
    212: TimerService.TimerDMContext timerCtx = DMContexts.getAncestorOfType(
    213: alarmCtx, TimerService.TimerDMContext.class);
    214: TriggerDMContext triggerCtx = DMContexts.getAncestorOfType(
    215: alarmCtx, TriggerDMContext.class);

    217: assert triggerCtx != null && timerCtx != null;

    219: // Find the trigger and check whether the timers value has surpassed it.
    220: if (fTriggers.containsKey(triggerCtx)) {
    221: int timerValue = getServicesTracker().getService(TimerService.class).
    222: getTimerValue(timerCtx);
    223:
    224: return timerValue >= fTriggers.get(triggerCtx);
    225: }
    226:
    227: return false;
    228: }
    +
    +
    +
      +
    • Lines 212 and 214 search the context hierarchy of the alarm +context for the timer and trigger contexts. 
      +
    • +
    + + + + + + +
    Note: Methods that take a context +as an argument can specify the generic IDMContext as the argument type, +then search this context for a specific context type.  The benefit +of this technique is increased flexibility, at the cost of compile-time +type checking, and it is used throughout DSF to avoid dependencies +between service interfaces.
    +
    +

    DMContexts

    +Searching the context hierarchy can be tedious to implement, the +DMContexts utility class contains a few static methods to simplify this +task:
    +
      +
    • getAncestorOfType() +- Searches for a context of a specific type in the hierarchy of the +given context.
    • +
    • isAncestorOf() - +Checks whether the one of the argument contexts is in the hierarchy of +the other.
    • +
    • toList() - +Converts all the contexts in a hierarchy of the give context into a +list.
    • +
    +

    View Model

    +View Model refers to the ideal user-presentable +structure of the data.  This is in contrast to the Data Model, +which refers to the natural +data structure, although the two often end up being the same.  +Never the less, the needs of the user presentation often change so the +central feature of the View Model is the ability to customize it.
    +

    Flexible Hierarchy

    +View Model builds on the flexible +hierarchy API introduced by Debug +Platform team in release 3.2.  The flexible hierarchy API has a +few distinguishing features:
    +
      +
    1. There are provider interfaces for every aspect of data +presentation in the viewer (content, label, columns, etc.). 
      +
    2. +
    3. The provider interfaces are retrieved by the viewer for each element in the +viewer.  This allows the +view content to be populated from multiple sources.
    4. +
    5. Provider interfaces are asynchronous. 
      +
    6. +
    + + + + + + +
    Note: Flexible Hierarchy is still +a provisional API in Eclipse Platform 3.4.  This virtually +guarantees that DSF will break backward API compatibility in future +releases.  However, these APIs have now been widely used by open +source projects such as DD and CDT and also by many commercial Eclipse +integrations, so the API changes are likely to be small and mostly +related to packaging.
    +
    +

    Adapter Problem
    +

    +The number two feature of flexible hierarchy API is implemented using +the adapter pattern.  One down-side of the adapter pattern is that +there can only be one instance of an adapter of a particular type +registered for a given element.  For flexible hierarchy providers, +it means that each provider must implement the element presentation +logic for every view that the element appears in, and as a result +adding a new view can force changing a large number of modules.
    +

    TODO: add a diagram of the +adapter pattern used by multiple views.
    +

    +

    To overcome the adapter pattern limitation, the View Model uses +wrapper objects.  The wrapper objects are held by the viewer and +they redirect the requests for different flexible hierarchy providers +to the appropriate modules.
    +

    +

    TODO: add a diagram of the View +Model hierarchy adapter pattern use
    +

    +

    IVMAdapter -> IVMProvider -> IVMNode -> IVMContext

    +
    +
    +
    +
    +
    + diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/common/request_monitor_1.dia b/plugins/org.eclipse.dd.doc.dsf/docs/common/request_monitor_1.dia new file mode 100644 index 0000000000000000000000000000000000000000..c2bd2b8b805fc8b53d42e9c117d0a00fc4f40ee2 GIT binary patch literal 2088 zcmV+@2-o)?iwFP!000001MOW~Z`(E$e$THk+?NeVX_C6PO^R;VumLRwY%TU^&=O;7 zl_gJ-}hM z;9>acDf=3ZifTp&^&F{tL8f#PQ}R_@HDq6o)1>MJjmy=}7g6G~BI$ZjDI%zc|J*B6 zluB5kaQgV_gZ?USQgLBdS6xGeM$$Qnr+!$q!}=!3I|2h6W6V0kaBK%!x`j4&V?O9D2;j=9ysizh!#qZ93aB0+MF z1Nr6cY`b*kPGjFYK5-992x?jRUOF4U9P2I!u+hB7asz952A=)Ip9Hkd2R}@63wrzN z*WFZKenuIF?{057Ci2>Zi-c!WgBq7F64Ryc(d5KnJ1irpX;u^)o$B>+xpO-vzf@YX zGZO(>)3~Vqr`=*bC?0TuJA1tlP5z;7TDbS+)5pQZ4S7jyg+0qS22nLHAE3{^kVmvj$NQGuwaJ)$zSlM1L1I5u|fHQ?w_ z*Ey;>2pb$@HDqedET_CTPOyej84(rE#MVK%k}jJQKm6fGfi^orWkfg`g=w8Retqyn z=6Jc-^zH<1EhrisUJh_l-zi4yvDMl8|W~rfS`Y zW~cGoIafDZ_cqXt99Io)(CkMyJLS+=9kMoepYuq`z}f?L*D>Y|!*v-FrnHvfUSxs| zXEFakEqedN_|}2R1clR!;L=;qMuU%8$(k#(u~A$Y0!_E|+fiJ9(tnq1z4#P`ej3F} zc}Z7Z)gh_G*X@Zfqb)RPP_p=92Dajh{m#S}MgU6}UuC}pC3stu_!5dFv#~TiF1~CP zVprgiB_8xs46u(==e1#tkt(lB`3Qk*py4JBkBOh1=zmzM4^~NZ*x` zK5=l!>LxgZAdns$av0w$LPLB{u$R!#pLn|Im=+ppY&*D1_i?cG-#evb&1X zTGF$dm<_ziZgTqA`>OFwIAI;N0d_=#K}i}6D*>hi*tH5Ur?mh>K)U|oCbj{03+T{6 zwbniodRR*P!UpFVeP)8Z<*-zO5jH@mqkGyjY#`s@9%&+8} zAo|{-3%-9Dc3ym}J6#5)=`sd;Jo}eD?OtRVLY-tJvdMzwXC-ngc$=1J^{_Km=bWgN zrFO@TC^IBQmZ_~VrOd82F%jWT5)P0i9b5Gb7pl`bQ5fqyPe$%+WHwM{gb^L~yPbu64e4*#*0?4p#G9jNj);*slHR~TNbwxS zbG~^5`a|s2A*{2n1 zyl%cl#@ro~IF44$V~VG09tSj>rn6%kd~F*)&JL65zycovY<#hqkW`kM&0hvHHg$@i zeH!tpVh;zqKR*nsgQDhURNRd5;mxRev`MK+9lb=~I&&I1_sEt!xg9>sOb6BGvZN?QJiaok%)l_7Y)X@(Nm+sxva1W-p?y zFv1cq!`t3b!rADv`q@#kx|x%X^dJkvf5+NHS+Lo|c2dPNK@n`Ky`*D% zNs@vrxUn=+VHOo;k&mo)H+%JlDx>w{*DSGi$+f;@Se_u%8Kz8DRdRWpe%S**-#2#uNYu4>?9ou zBk2dQV7Pw*i`mx+EEt_Wf<*-e)a!o=R#lSe4pmV%v=w9NZ`hcQqj5XX#zmf~!9Ht1 zhtTYWzLtCxVXUV1L9XL18(sEWHf%tc{TzRQyE*wA+42K-*529Qy^x=ZXM!S%{HR?K z#eWq4IRsX%8(@`u;BcM+q5-SO0Kwd%(+jZb;8apSYUBU+PkU%~=EF_DV*`PWvxkgj zB)4wzQ;~L~I``(>Q zNu#4suiTgfn;LpH>a$fjfAbahaO_8&bE1i>PW|}CZ@x;LlU5d#LYJSwn19ax8SUfU S!GEiLy!#)WTQCRLegFW0xB&wI literal 0 HcmV?d00001 diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/common/request_monitor_1.png b/plugins/org.eclipse.dd.doc.dsf/docs/common/request_monitor_1.png new file mode 100644 index 0000000000000000000000000000000000000000..f9fec21cd3e277bd802b455aafc290ec5bc51133 GIT binary patch literal 13914 zcma)j2RN1g`~R^b*()P)Bt=${Eu4fTCnF-WvS-;_wp5ZNSxHE;lD)~wPWIk=@BO=} zKA-yZ{a@GrxvuIs&Ul{p^S&GxorvJKUgb@J>R zI#LB}3QV@s*x2nTZj1HxDjq90*4(2#d@(ekLoHaLwp z(0ikrTU)P43kwP9*S%`)?-v_8eFP^zCjNT(T7dS>(ASW24=vo67m9bgiv^1vmqu#R zXC-Y@7EfRelWvSU=6=0&v2OJVe+tXe_YWlFd7N5vq{J03+0~ZD#rDI9`itGPS%THr zsf4!R=gm@Fh7(rZQgU`rFSg6kIqkoonMIYxT=s2C(F}j~Ok6rRI5^|er>7?bFThD0 z>s8D)@BLa==e)N$?%Dl{_|is+d3Hvu)A}6!ZPD1dBJRrhy!@g?#)Z%79N`>}g+;~1 z`$H80)+-BxVmtHwRCI70Y585nY2`d7QUyDsOx*joaJ$`p7 zyLi`3LnET*-W@uw&{`))M{0iQ*VA41&3PMdciU9urnoveIXOEQv>NMCk7@6XYBMo0 zt7$kP{d-UjzZz#JO z>KKPsK~7edt)bz>TyH)O4o;)kzR2+Ng#88Leaq#s`qI+Up`jt)la7A6)VUh+>$tV| zF0fMI&##-G)ls$5(RuUk-N>LXLwxM%)2H3m?cD6(J^S0m`?WPSou7@!%ehkv*VI*1 zRM2R&o!xp1T5MJjEokBw5FqThGO@5=DJ?B+Zq7OUDYCn(>!kC7gm3wvrGPTq&1=_= z-G1}t&46n0R!Fnq%-r1GD3_bsty|SOofiq(&rju&J&`Ie3a}sSK{WbC^XnD#(>Da1 zTrIIx&6rjfXqjG3OiWZsYQ2;GE-o(f^Jn|_&^{_*PgoWpOa${R2HKs>I9_@S% z7vQhZn!+%y%|4CHOk9PTlU>ZeE%ermP4zh<$&_Qju^pnPYy zf8WK`b&sb}q?}vM#%6VCw6?I{aE7UeUgXprGs*Z}J=N9K)$;^AA|f*)a#&7YrKJ+N z8VxxGjd0UCG0FVBbgBI%%e2bgnDT`yv)Lr`yb!b_BqJy9?(Uwnj#KRH=#cTv&(9wo z9;WdL6LqpRF*z66(bF??uy!)?@|@?+O;1c%ax@a9s%K8YqVBG=ppB}0Ii9_GCDWfr zP_B`0%W?jE5NuHDb%&`GvNa(A?Fc&VsX=~Ynt40lX*Q(@+^qc9k#v=vZU?2jKHtBe z58E)aU29pRF+$Mlb$Ga7_Ty#40Xy=138@poW@ctruU=hA-h~QvTWOa5xjc7!G{|DO z?wg-(r?1N0nlD`MvuYHT)}Ec2QDzGvD8FZ55E>fl^vdLm)ZKqJqS;8w(22dZZVLvt zoyGU>&*qIW1yz@8%oqx+qUnjGO-!bT1I1itI?fAeG6nfn+)2MBV)TvKHXI&?*GnC{ zm8{a}@Kx=yre^O{Ytr!0(DUcdFKy58_?QU8t&@ckj*s7440N;RAX~`?!!hZV4TnAS!NH;t)(Ht8<#i7U+a{c=CsA^lI`#z~ZiwqFO4in&wNew#1l7Le$amg+U~SFY zy}mL@I5an~_`&UK?uVHLSWC8Z=eD=E>4~a(^X)Y4xDCQJQlq0p92A?{(a_<^$jG4Z zs<`D86~EPo^Gj1i@fbXvHh3+`L_g&r_Z)m-Fv;`i=;+W;yWK6D@OsWap%6kiIq#P zrl#z@k?cV--+OwTHst(Yp^MFYyGZ+l|J=p5d+9gHto!DP3?gvX{0Pg`G7K(W zyy)WMA}A=BTCnsLy8dL;1J%Z@)oFfQO?O=SRVxig)3LCa1|_g zjN@yzH}G&}XXUrH8)w3S7FonbGV|~(uS~WyT-^BF{G$cji$AaByul!BYuZ=fK<0mM zt|xbNbTn%Gj`a4{*2sh0<#n{)h0aJ}J8B7q0wTF zD`(5O^)m#|oH=vhf?~{#v~}!N$K7vn*G`jNg{?C0w(pdMYM^CfW20if#TX<5^BrZO zRlGSC4s+A0cPxd&y2vFgJiNBAXoS6vNT7XQ?{tBsS&h996hWQg&(*NPlG33bJHP>O zlTpWgFtKy_K#n~K**h_ zRze_L8POPsjfWyQhymOs3WPhu;gcIL6E<*9ik14{yusep65s#l7k|9Ea{JWzT+p?*OGl|Cxs+zkSqBA4SPI`#sjj_`Cn>0&>0(!S}8Fds$I#v}9?z7-uDl zk2i_^d7Zy5XW`MC`CxIK!yl3N*FEylcN-=*f+!IPyM2lTJ`5jXW`u0hJWlqm(opXs zqyq-xtj6CTRlqc{%}hf5`?3-q-RPo0oSs<6{C9DGed*zf|GkFQEzjKhFC4DPAFup% zZ{W%Q{Y4z7{(rxyO0rJLnio;Rz;Y+bhjHg6sXN(<6Y`aV<6xP$S$Ed%N`lzx*v+I? z^;@^jhSowMc3Tu*$0PNZ)YH?esi`6J|6-nP(VKTO<^}*ocpVWD(YM^L?(SCORVecW zxv)>r6r-X}b_r7YOIo{IRYvcvBy?w)ZTIi*YB%^exKbimK8lYg_L}dvMDM+8nS34` ztZhGt>fO7sTB#N=>}F=(kxx%etvD9e>!0J`D6|~(&`RZ}eG+^I z&B@007DpvjE4gLT@$jJHP*=WjLtJc^+9w7pg2#1Z(3hb6!WRX{~B%k@vU*a2&0qQ^H|=Zp9EEcV7Mq~zpeWZqz9TlC9cyLQTpn_$>dphH+5 z>a=${wK%1HdeXmOI`XU?k0M`qy?%xo`^&4rEdCWkq|1&6%XgyT#p=ShSJxD0XbKe* zBgEYH0LLq+s*cwuMeHis3b3+Hj@5^!1cdV#$irQ8b1N<%%yC-h+?;MTZ{%rfZ7p1^ zq+1?uOfXo{cH7PDHD6zXHA%yaOlW9`7Av-yZu35N+;Mp-%dA`F!Sn#O7JeJ>Ulht`P}`{araxSvKz5%F0Ttbl|ti zs;Bhf{1#D?Oku)y<_->mk)!qe{Ska-wDh+8rx5O`k_7G9g%f&`4WX49WFjQ~Id<43 zlBXutQR4H`*GU@qGrgSd!ONZ{>{aNW^Pps$L87s+OYuq8L^Q>`-(21(gBMRH*q_9A zS8b|sSGXTNpTF%)vLY>AV!v6rTyT1E4u|A~h8Q8HGYf{->HdawQtZ1@#dCBsDhMwj ziQ?-`Vyj#d3?~o+TBWfh${>Wk>k0?itr+l zuRy?~J86&YupdkE`U zfsSI5!a(Hg?+YR}CkD9^%X11+>8Mn%A+WL6V-I?MqTAHLa$@!ye(b**<=emuHE8hJN*8i=k4Q_ zR^U<<#fUo~*V)Syk#PL@aRUPba@2QYo2ys-i^H++!hL|oS1|foZJ78gE`xJgO3G8B z+w3oCc=Q3L3aP8AhQ59+)Uc(tySoeXA2zDjGrK;A@sfvFa5=WwuuRg2K0@0jE z(@LG6pD(swWTF>!-bhnP8a0vdC8Af)w>3kdFpp9hwnaN3{7f|5i*Iu&w`}xUSz1o>!5U9a9KRX*Ynyiw9is25E^CAh7v0fM` zeevRjpC4X`Y->}K_%RA9Dya4_xivuKfnA9F-Xfc66>rpenUk0ix@etO{h%&d?_m{?KZil$7MsRgH*6MfrHPCaF$a=S3YJ zR|2RgDJV!#uDjFP^Ie(KeT7a?%d4x??Lg&AJ#mdTySlofcV`S9>Qou?C8)+?poGR^3mNNY8Y>omI%_BJ*aP%MZLb=-9@R5-PZPSDfC^CEQ>ou=(& zGuF8p=Df6>ODw@xV{X{@eLxhIZMq8BkA)fVnRQuDw{iHE-(R28^wGsb5{s@hrQfZR zV`L&7|k#2oPI282Vf3 z+BzB=f6z)bkZz0?i;jw#+r`JU$8w-0tK6(OmC*^36DbXi5jQoTd5_E)W8T+Es;TPi zRKDf9+1*Ex{~;3XsoKR3%VW2*%?SwzCam)m=$`$D5817cUZlM)A@Q*0-qhqI%#syb za-?KZYg=2}rNuAgUeD_4>RJ-e!tDd*obu|)wm?En;S3L17p1VefZgcQ6MB~DO#%<+4_;3iT*k8dLoNEFFnz&sF(17~f2&_Ivi?7awp7Or!?ScNzf5J9wdiK5Ybq+1sn(MmadyI{IjJ^wrX$U@qIL|Bsoh+UT8^bIkllm%@h&67YVung zzj=?}lP9CGVdU3t?Omk@9@8geJ<-&aX=3z>3)_F3_LiP(fva+(0l3ucL#)gKBULCV*$+xrFC>|v$ zB^YORK^sI>FAi6=e^eVTU`$rIt*J@h5#rh8y~pYmLoaOmN{+>|)Dlj#t4m$zK7eXK zsL9F692^`VX>PC0nr;FC%rIyqA|QC*I@Qyofs*;VuOr{Z#7M*`3UZx2bt<-~=#sn1 z5hP*gEF(dE7!N>S9%7LN1QLWny;2Vxg7Ug3(QSAV(Bc^{UVeVD&5>Y$tt?)Cl5hL^ z`k)Jwp+JGSbLY-S6%$$6um0p`sJOJ`@XpgdF)}ieidA3=A|NEZ8mDM0VVf^{;lj5& z>DUIM-t6qD(M)J0!Bytxfc^q1?x6e*n=L{4<5$$sB{J3hYkS#*WDSr%!107+u0|gW ztQ%)L$_fh$1CDcn?EO&d^5C&rk&4YrUNK%?UTbT%LOpG5Qn*9I!;xnytE!w*N_Dt9 zO!@MAc+;#+S+{A-Mo7J{0F0tRFY16-P6+p(Od9%();(fGL1v_Rj{#r7QItP zF+9pl`Nl^^B&DR_enJg?8*YOq#>S*T#g&$Z2e0e()$PA1T$i4;buuzaR7`v!8wY11 z9e7fYIzBZO%^7NEW7GVco}T_f*i1vDFotHf<)F*nV`QQSPX9RZ(T+5ff` T!)(4 zRXmV`*g}lQ8zM{1Uod))t}2Zf$t<{*e-exQ@)RL)urB-I_*f?^F-W$aB_IjU<1;c= zx417o3oMd4^OmYi{1tuWMiB)N^CmGu4~5i^PRlVIeznVk*!*{~E;n`4?6%xs?ioI+ z!*qF{_g#7^t$t`2qKDMlpe$R2a^(X)Ex_rO7&kWV4H+yvwH(*q3A|Qm2o*Ku&jMyO z=k(l%Rs`tqXF-zntRXh=8>f%GPji;)d|x1Fy0yK1oKxeLwl;ddx9Im$B$S~;D&q;= zvn(P;4mQPH21*g9D~oqkUcTY$SD^1TI?_wwP!*?9R#Xm_}{xT?Th z#_DLcrrh?|-CD$?A8;JVqitnns9X)s;F>krc`vx_;W%O6U z^!E0G%2r!lZ7Fa99>3OTKo#vAh#09Rq^Ahs`x~`NiOOHs80d+7WtblboB)xsMr^l5jF5;Z3N(BmWpj^6 zQOsmD3kzwIOZ#q_GuNXYw8h^zOG`&biH~#pV|KRP;!uTDY;)@E5+{L;!!0qsO|JeM zP>82PzWey`Blr-ls@idpN_G_!D_L25%eEj@Qx6UG&&z(#9@ZoE&86_pI%%wRE%&eoX$SaxeT-xqE$>edVRZv1AKz_(=TB=>%jPm|0-DeERg9pI-==qL-?lewRsD$8Kx2avx%Lw=_cg!F; z=Xbok79SD9qaK%hyzp+*?O-_IljGf?*ui(e*CnFC$M77FLHx^Dp&k6*oPq)O&jJHMoAt?#mE)Y>Jhy7EK><_hCie1Ab(RR$&QVU0=`8gI=e1Axumi z??5aZ2$p0zA6{>rlbYISHF!9o8lOgqxm^+!?G1c_wZJpNy1>f8VFt1IVhhQ`Kq z4S~a5{)j&L#|Vn1!yAx>&uRgZy|6hRUG?RQ$ks$`SXfxpF~HG#2NoFkwnvfBmkyX^ zwz(#w`UjQCK?H*8$Uzq1=m0|w10@;Dj1LDVr#XQ5j~|u)oi3zv(l}vn`i~uGlZ13a z&l0%xL4Z9_ba(%hhLJ~Yu}b)7xOVSz&@p~zM0-m#5zAq`Vsx%ma!#&7_n6)Ma@O4) z)Q1})W2fG>rKUM}UIA63ClC|V(5(cCfn5uWO0}a1Y_cCa?O^Ui-q2{k!gHC3#>ZM# zEj6$H;vL9)ATVQk%HZIs{i7y>JYt~pnrf3cmql#Qoege;+tEMmTRJNxC5Z(VqMv`zW9K%Z=E)oTaxIASTa5G9ndUc;c%j))~V;u z$y|?P5902&SduU`kHO|rx)#a_7TA&p&N0wX%S-rm>Tbsu7Z(>46ny;n_-WB{gD@`9 z32JKUfmEXsj(f!Vz-PTVUT{r;-e|{Fv@vAiw%rY+;ovipQj73y1Dq`uXTZ! zLh$3fN!v$o<9FbFuLZ5fKB{HNM_;PvGll8AxVQ+W)WLP_Zm&z5VL54f%r04G1zXMj z8uD9*Lw+^K4#$fJ*4@D>wm3e1Y^E~c~Hep_9AVgYVBJTx+c(M?d^G{+_kYDK4yV7BhsOy`U>u^Dx` znn0~(O5_1AWN%pRGUZEDp2`y{;gaxu?6)|I86h)r+hO6G0RPAFgv}@KBc8g#4ofZG z%L5~Lya251LCc(TU`WpO7jsbs97URb6bOB%WJq^{2sasePfB9qRnE{r!$!X@rc1aza!_zR^x2b z&N~;vz=g0DiZpq+v$F%0H{G7vZJGt@qhY2xN=8AUxh?rNNRnphx6FHT(sj#^sNafh zrl6om%QWJp<vk zAMocn2!?$Dn^dmJBn`F!F#jg>$5p8N)#?Mr3lk$labg?$BXHj#a0 z9jP5Lv$Sv?&c7t?>FS_UrREeR9fQscl~qkC|k4O-)T9vU>SZ`zvJlhYkd{)}dP4r=Q_)R!K?83aT6&{!I1A@bGJA_;`8W zE3;+ENl8h$xD>i|;}4*VG|9?Nzq?PnzuI!+6q$csUfzVD@O?ql#CsX$soB{`K`R#I zJwwB@EG(7AnPjM66eZ3ZcHX^v?<(#b-H-)bX(a)6=Rtl8B)4X1hWfg?6%G5{t<`97v!LOk z@g`?xL;y=d8Z=GW83%GvQs3@FiH{ee*1#%-fSe%6t6K z*Z#G6fBEV5QM_`J8@Den;Eu4$S(|1t-O`N!eC_s7$NPSn>J+B&cZ-lbr;XTrwHvOc zqYhqnB*oafqS_+S3}EoiDgcqap+ zn<^?Q4xBphVgR}?++3Dq9EfH@YdI%zIT3T9i2S;7y z6FOgC-%0DgAw6Dt_be#C5Y&UM(Q2IO>FMe9Y`7{gRV|~^LE;C@Pdj%;2QF~1GySe_ z&AkiM1fiUoACi;f$p0R?4KGs@69u7rm6W)vCxi5Q+Uv#3ms&ZN5~=Mlj%$L?9H*ot zMbXmILM&_9;|CwW%F!?LnNC26G5Jj=SdG;I#Hhm}77@pT?WUHdgHg^6GTSA15_aQJ zWPN=-`qJhI7$io*kVyhN^eP?%lpgu}r>iHkva+6$kGNG}e;)b8kT*Uq&c@E}THLpo z7$h)s&T8{)X(=gn_LuI-uir#-d5^DR?D#P*DKiE2KopgoiX3&Ag43hc|MCS`J}?iB zzAWn(4XEyUO94rypz^^RKZl_QM^ATmzWw5z*kpralhHY2EBr(mC3C3S+i}|N?QE{BSnsJa%0W-{lKxNJNa4q{B8TXZ zFYVIu^77JBigvMiMrVpf?%P)5qsSj+*H8hW81lYGSqqaA%2lh1U5$=l!)MYwh%w3w^Nn0r`45Ah$+hb2k z2mBJ0R1B?%>q|;zyjR(kFqe1u-eyN%&25|0cm3$kc;WFZn1-{{>JUT93B`{*REfu zH`x6M{{7O@(x*=sP}Rco1y%zk524RT8<&LQ=qdwk!VXqR5`8d&N8dKR3U2IiF0FU5 zzQhdiZh18UmwkznHS_t9$cH~`yn^$%I~R;RPY_%))kR&lR#=tdKWgNDN=Wb}Spr9p zUF{PyaD&sQ^#F`N$Suf*dzr1C3~=q<1yYpcUo(p1#&1y*QDdwb+ik!~l=v0EY%1o(gz0z0aLv?JfH~?5fhv6z77=I>(I|2MS&O-4)HpG%%o5)-Bk>3a{G%NHk@5E zpFVvW8M)^_BHgc$`(KgXcI$`IUj7u6_o*r4Xub<2@4-FRS)FPXicCp3I1HNKUV*@z z*E8+?t#*+3^6cjO+O^$WAeQ$;%4%UiLcJ&}Yt2AxI}FU3SP0J>K0h25OPWQIUAfpEel@SGw3J{W#unwrhn`B&@v!&A?&iniyR5J zC~^Sn+9>Kkw}TRujeBmzsSeISBw%W_x~@MPpk4z1;n=q2Jrwu*YU_^;aER?4zldEv zFz`l$(}0>qP%szhTx_hTJS1$c$;v`Lg`m7(XQ`IKWrZ|S9&d7XR&P8+h8eW~FrI|m zTnEYelTR7`%-tr4DH`DZNg8N;93bKv z_<3l;ZEY$-Jv}{j@}V-!*1fFZ^(-N>h5a8I0uWmE(PEggY`UMxM7IA8z&egJYvX=z zZB5oH6yoIMglG$Rtaqu$It`)^f&jhd+G#ouL2X=qDxf&|kJIWXC!7!hI^JObhe=)x zO|2luPStJ7CuEwbZe$xS7e6s!Sg5tXP)-afP6+=%78FGKa5)xYtNVQ2ncTvfoS}42 zq_PTX?kS$7h{~RNpF})N`qJUi@~-7V9Z#ca*XK#tq(r{M;Gq$elb}vIPQ-w77$z4F zU}7I6Or%%AT9*m%ZUF%0cLPQF^uAIMQv#v>oSEs+@9yP={i_F;a})V`X54aic6M?S zrZ+b^AR=eHzEo6j06hU|6`%^U*FAlGDk`c=YaMq%ayvP;)I>I3HnZ}lVzf<(z2H;4 zq`ac)`hg)LtbPoN0%nG1Y1;i^DIsX!8jx?glP++A2rLo2n(AuE96+~r9P~aeqMGBn zy9K^yf1ZsA}!Aepg- z$lF?4^88MK*+9hrUHbXyYehRt*VI4d<*6qs3!Nac)he?YGEKi_E!6v%h6g-Qh)oDy z6G8)6fd3)^(Pp-g_=E%oQO6g9LjC-Ij+L2wFS%*t~UX=z_MmVB%6r)WBwjZv3NcxSIVI}!NiSJ~Q6 z_--kSZQOQn*o3JMU4eea2U`Me4ZvtUy|`c5O#<5h7T)=2GLARnSGOYqi^#sHykZ3Q zzg>MQ@cZ}g%q%QN@;SJhz4fBDb{$;qPUPVa6<1=X+eP~S>%3y@d{NrB{$5Ru=I47? zMmmatNwC`zMD0U!QPHIrAH~IG9rJRYeEA+G_M_-!mo@u}be6fL#6cH_oKqvqc~r+*JBs%fq&7jopsI zcf5&#*!d$-N_aHq879e*Ut;*b3OV@9PlUM-Q2L=Xj*l2n{YQm_q$^+yZwhyA_rI>? z-%}piJdC*ho~yl#$@vcPzpU*6N{wM60tvUqqeMt1g|nQLaPS$?yGPcL66(OtT62?PSssVFOG zfk0>Az&+u@dEkos^4CxZ zTz?&Ipp&0WaC+T4s!Osh>Rq-PLsWgM@FbO1H^_Ka|3a|a_d~-~zl2p(Wed46ePp3x ze#r0mE|BL#=i5h##&3oXEQDeb+l_~fkzMmg)9o!?7_`^0FV?xizKCsBxs^)W920qK zcmgkV76b}h-T2bEm|x*QC|R$vxr6rH)KUe1-2N3I0TVnZiHxPQk{^93mMFMy;D@(v zd=g|(v0N<|b<=mts_7Cepk=abak6G)lZ(}~I6+Oeko#}$SdFT)4Y->(cvOlR&fjAS z4{K$pgh`}1cdSe;`ng!N`QB8Lr2l$W<{f*Q%>P;N=4?Z7T0ZuZ@P~RGb!o4A`;G?) zH`9>DslTjOeP(rI(v|wC|HaxpLet=rc3dBswv2kxZ_{6^h|JQb?1$IW`H6|W-|>Fk zVxM2L^ID}p$ZKyo(n{ZI-uKvvOpP1^kFFtCkqri(%xZf-sI$(t9XKQ*?U77 zc+7^$H+O%_tAU%8{Mk0X5;z{-|0qIm-&H{_m>!XEn~N~jjwU@>qYAx-BmXKBDUaDBcQ65*T)vDCnYiXq=CMy(ZwijYiDAK zOU~z;C=H`MLRbL=$>Zp_-1m;qT<;KMfOUmZthYDK@l9nmNT=e&=mG1n(vAf(v)a4_ z0xCI#ZeETNaa{XdFBu-GD+Z~$MSI*-^Tu_MbYLKM&^4LwrHH>Rxk|`>^1RJlA6=YV zCy(68nf-K?!Ov=*IX*fmY|o@hpUOWwx8>5w z5DHAC|5Hq*r0eSE26%azEOl7AhGa>l!US%AqJ64|9QGmA~vd`Rh4 zjV{WO2*%yE+uB>jLNX5n8W;Q*;r#_;Sq!?$ysS2@#|QjgPJKNdr02J+Cp!4t8jU0C z)O4{UBJM&BjfzloF7eUa11x(jR4>2gO~hfC^}_MtZ^t32t>ok$vOLW;PBm}!xfoMH z5b*;<9rntrHTSISz-O}0jgUwD1E2iauu|#G&Cl=@Ji687W9Z2N4N~0A`7T%h{qb8e zt4Xp5X!|~V)=y&>xBm5)$q41NcV-{ z2!7eOFIjsqswnzfu`9t5TRlnOM5MWL$mg1yQ_ARBWxp!D`U!tkR{#CgT(VbX{r!2v z5!$m2y$Gk=*+p4YEz)yPZ~)oF{<2BjJ(-oV%?N}aVB-PAig?GLk!WQj1|_Qild&?b zUqkb*m4$;6*rr66)=2l^r_}7)h}1R@LN?=sj$65QTwGi}n#0c6@*MLhR30+Y{BAI>OX2dh+Ho=DoLGelL20bRVs4%xs!= z9(eTm2Wz9ZMLBcFN5;M8Z+BW}Kq-5|XU7hpWPHF!i7vH(Lk5l8kJ+lFg-{NDV7RF^ z!D%$ZwsmbQUv05%@Q7H|aeOGJhP-6i7Cjd?SGAwG*s-`y`aPzkqoZ@Le6q-b4_=X3 zDIY5Nf{V#aeW7g3qkV`Y0SY~HM-#a-7o(*XzR;6|;^rtA%F<81 z6Vy8^`ha+o+vF~{%gozxlN%R&fB8Nw0(TBg2h*P|?ZQ`|=^S9d86;N5|yyiMcXFcAc^BrsV8$J~R}zSJjk> zA=oW9aQDM|>4FMxy%*N4bd5lJ zp!1CdTUArakGqrcQ5lu18q(WRx_Wx&-%XUP6&62zvFINmSNn>uhwT2-e3+aqym7b? z_2Qz>{sbx6u9Bj)luI|nT2h(nUCA?=_a)T?>N5?5P>;JOs4M1tW$w zF4X0T?F(5owPJsXWM^=F`0boX<@^vUpw5dffMc%8w$z9V9%T4 z`-{Tbh+o3bUGW;_AqG$p}^P=baOQVLe+2@ouu*j*JF&ab4HTtGXvyHZyhIX%_?E zb=W31zFb;U!?=bq>v7%oyEeKxbGsfXBe3UNPY`zCzjytTZ>2b%dthhDdJ^OK@QP{! zSaYAieu$!VYxjvt!g>q-5F*kmNvZxgM8BmM>XY^QZsRD`%a^mXe%v_WSN^+lWw!J+FxFDztN-^GySpp(MhQpI-PBut zORr0UiGu?xqUMLeH>CBWFHcesrrh(cDppdet&3)gN}-n6UF4YP;2&L7WTZ%Stl@)j z@29+R%RDpP3w7>zXZDY{$w?wB(s-@0EZpP1cwBG4s<+x=1*7d~`0r^OEfW*@XJEt9 zkZrG{`A%Z!S&TA~a*||w2j3F9+qAw71i6Mj?F5CePTDNQ%WoNCe5Gboa0EFgMwtABy!alTU2iSqHDV8pG{qE zCsMxkEU)AxuFOPoZL7iGDwN)7EI*uqLnq2>$rC28)r9&>OAWeF76Q>1b5NR}M~+oK z@83!i61aBxqWD-v4dVaeAVfxTV$NMw=1A4i!!*qqHm`q?_}Dsra2|G z#~$Dp#{$M^e-jtr*)Y5<*Z=m!X_}nT5G5LsCPg2-!?8xBSAXMwBnj7%SSiOH{T7yB z-GBX|!GF}Du>?yLwfY)jxv$y&ekS$%kNAc^N56?vZw_=Itvok&l6z0o(}rXYe`Rm) z95m2UKP7sJ`?%+{W_~MfcqVQFS2Sz&Af?4^S&e(I++O}G*@5k#$v3-i4i&px8qra`JPx6fHrDIJCk`FGBFK z`^!a*$NEWPil|f{JsOy=p*92iAe-jPgUiF54XNXe*1gUz@V=Fg z$e|?dYT5ZUKamdpVR_+YZ_tbqc+8^u8FTODap7xdoC;PbLQ#UwTVq$T=9-R?QQpEE zlwMIjt-HOAO)L)>>W)$`f7;#sLR4gM*)d!n$<^ID39g4#kYKsroNR9tQ2aO_t`g)> zMB&;aT-Zkj!F}Si+8a}%r>Fhzd4UQq5-$0Y-y^}|D0=`J+@MY^^Y)E|PtKAi7{XWHiY2pHl@SssJqO^bA0^YaU6mjfnauBiB zm{~Cmf85e>8=h%68fo{-X%96l*J6}`)IEG2KHll1kNr+^&u!8l(oI;B4`s-Qn{Dj8 zEjf8eGhhmfElCi#6+ssiDzY$Gq~A%~IqzDe=TfTUhM3WujT{oYYM+{C%oVV58)Mo}=qRkIyB$rMmR`2McT(IqVhJOscF|ICMsT0Lo)f#mb~lPApwKHrvHE)rdH> ziVjJ=eGOzF=93GjoDlG_w1sENmec9niD^vdue?FS{Y1- zzRSNCH@MNilQ$4T$4CTSn*c*e3ZBgy!$k%Is-FHW!;9M{`~%dI{+i~TON#j1BgZYK zuNMPKzVOF*Yq|wby2W)#9#R_z$xUe1@YHnddWdH~V}p9=7d7tYYEx>CGb(~V+oW~d zAgba8SbGDjhzOXH=5B7m%7@65!zV}dHSRkK)rW`D@sQaZt-G0`5eh?H*ZGM1o6s`% zFE93v2(&G?B#m}fp(xn~R3k%VURAT>ftj6Et+vUe`>?iuxc%MEN2ohvcf`YT6x%u>cYt`3eEhV_f4`nXoIt&uJvsEC0?_wftHO>xBM+g5{Z=F=t?6h!e`ecpa|9wrL??m8-jupN(aYrAu%)!Kt1{04rl^uTWoR zxJgdf?GA}5_&)s&SGmh-E*d#lw{5>}2)-iE7`fV|^n3h8X>S^5s+`WxB@bZ;Cq2ce04gBBAbl_e`jb4w( zo^hBnJi#I6?d5W=1fB(29HwV?(>PNI*eC5%y?@qDO!UslHnW33Y=Q9&U0%o3lPz9k zMmgTKlZLESn|bb4Do`|4jWqAIiGF?soU8(609TM zY_iOqU6-@8+zWq;i}xjJR}p)_0_6WMQdd=ZBCmCWcC2qv1*QG z0U=c`KQM|Kn1Fc&kC%I4kGWKV(GzE<490Ou9A`TUe9~tAK?WF_oo*6z;dJE232X{v z=DtCD0|c5YDcibqd--v6^-9xXk%p@ziDm*jtY^0nitgN>KOuz%WaQ`bwx)UsdGSFXP1IRXuZPBl2QiuL_fQ2yl?k%GVIJDt)IxyJHeS7Bwf6U<{L|-{1 z^L;AbNgr4_Tr_$8(bDLeC;6yFu2e(@x(5PXSNu`ra4C7986--(PG}r(IF$!?Z2nlrrV$E#Dlwgi_-}+hML?aG?0moRsa8|Ys&u+84P1CTowe^v-t=KFB z7>$#6y2vHb*A_QzbK}c${EG)KjzlP%>l8s1!qQUo*c$z@hr9cSo$7b-fUUO_B-!iR zvS?JUZSKz&RM`AU!PSp?v5DWT!LNV7Fala{bIYr$QN)Nt7>9=SfJBm~TR=F2zj5OR zuSz%z{{Dc&OJLvuz@Kg6WEih-I1PYf3m8oswxnZ6V(A*^-c#{Ew*&NYinyk zM?1!X3AnMbdDmK=gVaGsXJ>}9&EBU@#VLPw@`z;|tkpC{Dm^qztcu(4$eMlf)AsYv zLj`D)!hcSEAr%NGboKhcpMmuX^%cd|_~`V-026KP%;DkTzu*B=9f%4IXhPfFEytgPR$!{ljlC49=QLLsgg?xq#k0?DN2=x5kYU0)P9}@l*+A*p*OZ$I%o{(mhq(XJ) zrtzRT_nB}5*w0Ijo6WZXJv_g&`U^wDH>?l7wL<92Lf)4g9(wxe%)zxCu0hr>gm>-P z^8n@QbthL_pSF!3yI}z%WfN$eJy-H95y{e+%Rjux*@JNu0##~PX}2jYA)l4-^8L?p!g z=Qy!Wk|8h4AqfM#xp%mGc(7k$%W?16`8eBZKN^#TEVCVy0!7D{uuiK>%q`d5v+nnc zk&UJ?*9>7|+MgMs`9bc?F;3@Bp^={mWne8hxyYX2O9Mh)gg>9sk$Bea_}m|yS6KfH znA9t>4UntMB3n>8t38D@#QY|9J?tg=>m$M~VL}Zkkf)hlT$=i0%ziEe#3|5{`lDS4 zBw*Nk>LrDj;V1C7bJ>=lpQ`XdR#0?=c@(1uNbf!Ssh^pT&<@Uzzo+JWj-x$!ZFTBs zIVIu-K~d#t^6j9HF$bpt-8_^o!jY!%Ur!GJ()Q(3E}OV7EfW>Xx~D$9MP+vJR9Ma= z+L^XqF#RzQ1g@;7(GduM_y3i+ILDeN_?*Z|vRio&UXe)i>#r!s5qM=jw8Dbg-Kp$r+7hl-LL zKkZCD4s%^yGh?y6MX%Fl?LYxV|1j_6*dH!7DPR`RI}6=Neu2^}H27X=kG*?)hbPbd z^=9rZ%VY5QFVHJ9m4f?6t=}~FDYwQ02Q|lQKG1?Puk1BbPgXaP*DB67IM~I39v&W< z6vjLRJ#lp?^*yA9nV6WUCOEyvZy)et7Pr-eGS1z(JsVQZat1&$jgf7d#`Sfl6vW=B zZQ^tS#iP>H8IPinb{JagnePm_kg1~50euR^Wur}1^!sA6utuciC0noG%nBJ`#90|L z2hvkeplH>f)M0ySj7+7H`uTtI~Pt=h)$c%|s*+6}&aPDTi)RSVU9J@0cuR6poJLP|Ku zte|nt%bQ{jeRJ(G^KTzpCcT;JoqlVxHP@~}Bcs9(m|o$X_CDnVI~~xz6E21}=w!05 zjpUH)`N0GN83=JDxUdQu=jP{(^Rmmk4t>vFH6%gmF z;YJ%ga&3|LX1?EkBil%Di0fu>T3-nr^^?fphK;|xhz%sd7bSKTiKU3xKhjrR`s9me zPqaX7F(s_G_JNbd_h*lp2_$q6bXaW*VP0z2q6BePF#1@aPMB>@mD^~boE!m(+BR{b z>7-TLx4|RL|7eNQGxAJ>_iHe0op*@}6sYsLgS470u%yxt=)`@e0zOE~uVXEEiDyMe^(UUe>m=nWaF0x;|dbo_%7uizu6H zWi3h@qD~E{(LqsLcKDwMs!XdagCfQX;o_zG3@bo7XXw?_Z28}r#q|zPDpV%U(axKcyhH@xexd-r3-H>XRd#Xp zSiyJ_?pIk6^w%lXRgN+@(2>M0JhP&3J><@S$gF3%q-opMxm^+|T6`0K`Z%%Di`WGvDkl0eK{LR@WT)v{$tTSnb`X!dq{Us8?am z1%}m|-9!fzdVCV)D45O8>;f{ihmQvvcE{Ut2X48?(6+K^d9oE!`6l8`$tPBpq7Ut* z_qc%qfFBLrt0$Z0Rl|gMh=B>39H&KrYx`&&Y+#unA;gn1h7tJgGHbG>?pbd`>WGN7 zTx4~wS0-EFEm-Y+$G-vFGl$qRUc2nW4gNxNqyMV+OgAKMUY$oBdhx?4W+s#{#tB<> z3}%txjO^m0@Rq{Q30?0w@2F^jMqWzuyh z_`UMeF4ebmFy{i&VTA6L^QU|G-XS^p%6gd>nRVZUc$X>cwMP_I?#t#iawJ9}MCFbD z=0aSTH+Ss>VCAS5(~LW(<{o2y3G^=iA0YS}9savJ{3AWw-Cc7BfzCRd{x863vGuoe z{j=Em2gLlx9P>}&{~MeBE$#2F>Yoe$P5d9W@vl?=qeuIvwEu-|fK-s+eGUD^r+>GJ zp?zh53jf~P6R}IRpU3cIDqbL&ME~NqHolt&b{&byA_u^~X#uo0LJ4ZgToWl+oT{io z1$r2^SK0XV4(I$WJQ5S^Va3_hrU(-ypor-1!W(AKr>53x6oU1LGE)UHRips&SnEE8jnBSl{pm< zRuU>Q|FF~C`7OIp_p~tE5^*3t;Uo+9OO3m$<+B99@^WsL?+RZi*kJ!+!^Y8~$Ar%! zZ^iA=*WJHXL_^Ot=vO($zj~Q|aZ#gR1zQ@;L{Q6kKU+3^24pr}BkQhv`D0wm?=)f4 z&IEKH#-sN#tzT(XW?O;_`IAuY!Q1pEO?2bTpbFMSLokJFV29q`R768~rUvwUazV~H zng=nrRUl&3QSkvobsaw|35I`6XyLIPuW`YZc@#Kde1eCI5We11YK2z4a{YZkL{};D znY8k%gqZKI_tFxGL>60Pki{#*uTb|jx+G&s-Bt`e-yq#z*Kgy4?nyj&`-amNTZ|og zyGZGC9xncr)PlSOcPlRZ({p>w{n$X?%=5cB`lZn4zu*vahU?nG=o)B@8Y*NpO0SOU zy3D!fPun&bKeFr{zjE4JH9S19i2B`S?$VMPFftWrU?b2U=f-Nc7zy6;m2S~gxD3m` z+!b2RWTqY$8=GISZKj0>eSU+x=@3WtdhVeL!J|$TzV`q)PQ+dHuU8(08q&j&kG^us zGg<|8_a)bE?=BSUTYcCSw~V=CVPkyi$(szT?(`-@ zMUG)9=@MoZrlpPo*8OH Date: Thu, 6 Mar 2008 20:04:34 +0000 Subject: [PATCH 284/834] [221728] Fixed an assertion error in BreakpiontsMediator. --- .../org/eclipse/dd/dsf/debug/service/BreakpointsMediator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/BreakpointsMediator.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/BreakpointsMediator.java index ee8b08bc760..8b011e0a79f 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/BreakpointsMediator.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/BreakpointsMediator.java @@ -311,7 +311,7 @@ public class BreakpointsMediator extends AbstractDsfService implements IBreakpoi // Install the individual breakpoints on the executor thread // Requires a counting monitor to know when we're done final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm); - countingRm.setDoneCount(platformBPs.size()); + countingRm.setDoneCount(initialPlatformBPs.size()); for (final IBreakpoint bp : initialPlatformBPs.keySet()) { final List> attrs = initialPlatformBPs.get(bp); From e75b2b1a1fbddb4af76ceca3dbe9129dbf98efcc Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 6 Mar 2008 23:22:16 +0000 Subject: [PATCH 285/834] [220446] Updated the "DSF Common Patterns" document. --- .../docs/common/dsf_common_patterns.html | 694 +++++++++++++++--- .../docs/pda/pda_tutorial_outline.html | 56 +- 2 files changed, 662 insertions(+), 88 deletions(-) diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/common/dsf_common_patterns.html b/plugins/org.eclipse.dd.doc.dsf/docs/common/dsf_common_patterns.html index 0fd59f1a441..96a68ec621e 100644 --- a/plugins/org.eclipse.dd.doc.dsf/docs/common/dsf_common_patterns.html +++ b/plugins/org.eclipse.dd.doc.dsf/docs/common/dsf_common_patterns.html @@ -4,12 +4,71 @@ DSF Common Patterns -

    DSF Common Patterns
    +

    DSF Common Patterns

    -

    Summary

    -

    Examples
    + +

    1 Introduction

    +This document contains a tutorial for the basic features of the +Debugger Services Framework (DSF), created by the DSDP Device Debugging +project.
    +

    2 Examples

    -Running example code is and performing included excercises is very +Running example code is and performing included exercises is very helpful in following this tutorial.  In order to run the examples in this tutorial the following is needed:
      @@ -39,7 +98,7 @@ directory.
    1. Build the examples plugin:
      1. Execute the build the first time to build and run the -excercises preprocessor.
      2. +exercises preprocessor.
      3. Refresh the resources in the plugin (right-click on project in Navigator and select Refresh), in order to recognize the @@ -48,28 +107,29 @@ sources generated by the preprocessor.
    2. Launch the examples
      1. -
      2. Examples in data org.eclipse.dd.examples.dsf.requestmonitor and -org.eclipse.dd.examples.dsf.dataviewer packages each contain a public +
      3. Examples in data org.eclipse.dd.examples.dsf.requestmonitor +and org.eclipse.dd.examples.dsf.dataviewer +packages each contain a public main() function.  They can be launched using the Java Application launch type.
      4. -
      5. TODO: Launching timers -example
      6. +
      7. The timers example in org.eclipse.dd.examples.dsf.timers +requires an Eclipse Application to be launched (see the Timers Example section for more details).
        +
    -

    Asynchronous Methods

    +

    3 Asynchronous Methods

    One of the central features of DSF is that it relies very heavily on the use of asynchronous methods.  Asynchronous methods here mean simply methods that use a callback object to indicate their completion. The use of asynchronous -methods can be very contageous in a system, where if a lower level API +methods can be very contagious in a system, where if a lower level API is composed of asynchronous methods, a higher level system which uses those methods also has to have asynchronous methods in its interface -(or risk blocking its calling thread).
    -
    -TODO? : -diagram of a layered system with asynchronous APIs
    -

    Request Monitor

    +(or risk blocking its calling thread).
    +

    3.1 Request Monitor

    There is a standard callback object used in DSF, the request monitor.  A request monitor has the following features:
      @@ -137,13 +197,30 @@ program does not perform any processing after the callback is invoked, so it does not override RequestMonitor's completion methods.
    • Line 36 marks the callback as completed and -implicilty invokes +implicitly invokes the callback method.  As a contract with the caller, the asynchronous method has to invoke done() when its finished.  As there is no compiler support for ensuring that the asynchronous method completes the request monitor,  failure to do so results in common -but often suble and difficult to track down bug
    • +but often subtle and difficult to track down bug
    +
    + + + + + + + + +

    +
    Image 1: Sequence diagram of the +AsyncHelloWorld example.
    +
    @@ -151,12 +228,12 @@ but often suble and difficult to track down bug @@ -164,7 +241,8 @@ module.

    Excercise 1: A common + style="text-decoration: underline;">Exercise 1: A common problem in DSF is implementing nested asynchronous methods, this -excercise adds a second-level asynchronous method to +exercise adds a second-level asynchronous method to AsyncHelloWorld. 

    Look -for comments preceeded with "// TODO Excercise 1" in the +for comments preceded with "// TODO Exercise 1" in the org.eclipse.dd.examples.dsf.requestmonitor.AsyncHelloWorld module.


    -

    Data Request Monitor

    +

    3.2 Data Request +Monitor

    The base request monitor is useful for returning status of the asynchronous method, but they do not have an option of returning a @@ -214,7 +292,8 @@ methods. the calculation to the console.
    -

    Multi-Request Monitor

    +

    3. 4 Multi-Request +Monitor

    A common problem when using asynchronous is that several asynchronous methods need to be called in parallel, so the calling method needs to somehow manage the completion of several request monitors.  @@ -279,19 +358,19 @@ execution paths!
    Excercise 2: Converting a + style="text-decoration: underline;">Exercise 2: Converting a synchronous method into an asynchronous one is another common task in DSF.  This excercise converts the AsyncQuicksort.partition() method into asynchronous AsyncQuicksort.asyncPartition(). 

    Look -for comments preceeded with "// TODO Excercise 2" in the +for comments preceeded with "// TODO Exercise 2" in the org.eclipse.dd.examples.dsf.requestmonitor.AsyncQuicksort module.

    -

    Concurrency

    +

    4 Concurrency

    The simple examples in previous section used asynchronous method signatures, however no real asynchronous work was performed since all execution was performed in the main thread.  This section examines @@ -343,7 +422,7 @@ synchronous IStructuredContentProvider interface.
  • AsyncDataViewer - Table-based viewer which implements an asynchronous ILazyContentProvider interface.
  • -

    Query

    +

    4.1 Query

    DSF is designed to facilitate use of asynchronous APIs.  However, sometimes there are situations where a synchronous method has to be implemented to call an asynchronous method.  One utility used to @@ -418,7 +497,7 @@ the request monitor from the execute() method is completed. Image 1: Detailed sequence of calling + style="font-weight: bold;">Image 2: Detailed sequence of calling IDataGenerator.getCount() in SyncDataViewer.getElements().
    @@ -440,7 +519,7 @@ for completion of the asynchronous methods called by execute().

    -

    Synchronization

    +

    4.2 Synchronization

    Managing race conditions and deadlocks is one of the most challanging problems of large multi-threaded systems.  DSF uses a single-threaded executor as the primary mechanism for safe-guarding @@ -513,11 +592,11 @@ left out.
    Image 2: Synchronization using multiple + style="font-weight: bold;">Image 3: Synchronization using multiple locks on data.
    Image 3: Synchronization using a single + style="font-weight: bold;">Image 4: Synchronization using a single DSF executor thread.
    @@ -668,21 +747,21 @@ threads can call a request monitor when finished.
    Excercise 3: One benefit of + style="text-decoration: underline;">Exercise 3: One benefit of the single-threaded executor concurrency model is that as long as a method is guaranteed to run in the executor thread, this method may access and modify any of the variables protected by this executor.  This excercise demonstrates performing a somewhat more complicated operation on protected state data.

    Look -for comments preceeded with "// TODO Excercise 3" in the +for comments preceeded with "// TODO Exercise 3" in the org.eclipse.dd.examples.dsf.dataviewer.DataGeneratorWithExcecutor module.

    -

    Annotations

    +

    4.3 Annotations

    In any multi-threaded system it can become very difficult to determine what are the rules governing access to the various data objects.  In a DSF system, it is even more important to identify which data @@ -742,12 +821,12 @@ add them.
    -

    Excercise 4: +

    Exercise 4: This excercise adds the appropriate synchronization annotations to the methods and fields of DataProviderWithExecutor.

    Look -for comments preceeded with "// TODO Excercise 4" in the +for comments preceeded with "// TODO Exercise 4" in the org.eclipse.dd.examples.dsf.dataviewer.DataGeneratorWithExcecutor module.

    @@ -763,20 +842,21 @@ module.

    Excercise 5: It is all too + style="text-decoration: underline;">Exercise 5: It is all too easy to get into a deadlock situation.  This excercise purposefully puts the data viewer system into a deadlock.  The deadlock first renders the data viewer unusable, but the main thread also gets deadlocked when attempting to exit the program.

    Look -for comments preceeded with "// TODO Excercise 5" in the +for comments preceeded with "// TODO Exercise 5" in the org.eclipse.dd.examples.dsf.dataviewer.SyncDataViewer module.

    -

    Timers Example

    +

    5 Timers Example

    The Timers example, found in the org.eclipse.dd.examples.dsf.timers @@ -859,7 +939,7 @@ and are automatically selected upon a triggered event.
    Image 4: Screen shot of the Timers view.
    + style="font-weight: bold;">Image 5: Screen shot of the Timers view.
    @@ -885,8 +965,8 @@ editor - changes the value of the selected trigger.
    -

    Services

    -

    OSGi

    +

    6 Services

    +

    6.1 OSGi

    DSF builds on top of OSGi services APIs.   OSGi offers a rich API for managing services and it is important to understand some of the OSGi service API basics in order to use DSF
    @@ -938,7 +1018,7 @@ down the debugger.

    -

    Session

    +

    6.2 Session

    DSF-based debugger integrations can register many services and there can be multiple instances of debuggers registering services with the same interfaces.  To help coordinate services in a give debugger @@ -952,24 +1032,24 @@ debuggers, DSF services are organized into sessions.
    sessions.  Clients may also obtain a session instance using an ID through a static method.
    -
  • Session Lifecycle Events - Clients may register to listen when +
  • Session Life cycle Events - Clients may register to listen when sessions are started and ended.
  • DSF Executor - -Eash session has a (single-threaded) DSF Executor  associated with +Each session has a (single-threaded) DSF Executor  associated with it, though multiple sessions could share a single executor.  More about session executor in the next section.
  • Service Events - The session is used to dispatch service events.  More on events in following sections.
  • Model Adapters - -A session allws an adapter to be registered, which will be returned by +A session allows an adapter to be registered, which will be returned by all Data Model contexts in a given session for a given adapter type.  More information about Data Model is described in the Data Model section.
  • -

    Executor

    +

    6.3 Executor

    All the services registered with the same session share a single DSF Executor.  By convention, all public service interfaces should be restricted to being called in this executor thread.  This point @@ -988,11 +1068,12 @@ should be called using the session's DSF executor.
    -

    Tracker

    +

    6.4 Tracker

    Using the OSGi APIs for accessing services directly can be very cumbersome.  A client retrieving a service reference is responsible for retaining the ServiceReference object and for calling -BundleContext.ungetService() to avoid leaking the refernce.  Also, +BundleContext.ungetService() to avoid leaking the reference.  +Also, since a service may be un-registered at any time, the clients need to listen for events indicating when a service is unregistered.  Fortunately there are two utilities which help with this task
    @@ -1027,7 +1108,7 @@ safety executor thread. - Accessor + Accessors methods
    @@ -1057,7 +1138,7 @@ methods
    • open() - Starts -tracking maching services.
    • +tracking matching services.
    • close() - Shuts down and un-gets all service references.
    @@ -1065,7 +1146,7 @@ down and un-gets all service references.
    • <constructor> -- DSF services tracker can be used immediately after being constucted.
    • +- DSF services tracker can be used immediately after being constructed.
    • dispose() - Disposes and un-gets all service references held by the tracker.
    • @@ -1086,7 +1167,8 @@ service reference leak.
      -

      Initialization / Shutdown

      +

      6.5 Initialization / +Shutdown

      Every DSF service must implement the IDsfService.initialize() and IDsfService.shutdown() methods.  These methods can only be called in the session executor @@ -1099,7 +1181,7 @@ the startup number of the service.  This number is used in prioritizing the service events.

      Starting up a large number of DSF services requires calling a number of asynchronous method in a pre-defined sequence.  Implementing -this startup code can be cumbersome and DSF provides a quitility for +this startup code can be cumbersome and DSF provides a utility for implementing it: org.eclipse.dd.dsf.concurrent.Sequence. 

      Here's @@ -1247,7 +1329,7 @@ custom request monitor to be invoked at the completion of the sequence.

      -

      Events

      +

      6.6 Events

      DSF provides a somewhat unusual event mechanism, where event listeners do not implement any particular listener interface.  Instead, event listeners use the DsfServiceEventHandler @@ -1298,21 +1380,21 @@ called in the session executor thread.
      Note: Service events are prioritized.  Listeners which themselves are services are called first, in the order that they were initialized.  All other -listenres are called after the services.
      +listeners are called after the services.
      -

      Data Model

      +

      7 Data Model

      The term Data Model refers to the natural structure of data that is being retrieved by the DSF -services.  One of the great challanges of creating an user +services.  One of the great challenges of creating an user interface for a debugger is that the amount of of data that is -available on the target is much greater than what can be practially -presented to the user.  Therefere the debugger services need to +available on the target is much greater than what can be practically +presented to the user.  Therefore the debugger services need to break up the data into chunks with appropriate granularity to achieve maximum performance and usability.
      -

      IDMContext

      +

      7.1 IDMContext

      The IDMContext represents a handle to a chunk of data in the Data Model.  This interface is a minimal, yet central feature of the Data Model API.
      @@ -1371,7 +1453,7 @@ use is optional.
      -

      Context Hierarchy

      +

      7.2 Context Hierarchy

      One of the most powerful features of the IDMContext interface is that is is hierarchical.  The IDMContext.getParents() method returns the immediate ancestors of a given context and following @@ -1453,7 +1535,7 @@ between service interfaces.
      -

      DMContexts

      +

      7.3 DMContexts

      Searching the context hierarchy can be tedious to implement, the DMContexts utility class contains a few static methods to simplify this task:
      @@ -1468,14 +1550,14 @@ the other. Converts all the contexts in a hierarchy of the give context into a list.
    -

    View Model

    +

    8 View Model

    View Model refers to the ideal user-presentable structure of the data.  This is in contrast to the Data Model, which refers to the natural data structure, although the two often end up being the same.  Never the less, the needs of the user presentation often change so the central feature of the View Model is the ability to customize it.
    -

    Flexible Hierarchy

    +

    8.1 Flexible Hierarchy

    View Model builds on the flexible hierarchy API introduced by Debug Platform team in release 3.2.  The flexible hierarchy API has a @@ -1507,7 +1589,7 @@ related to packaging.
    -

    Adapter Problem
    +

    8.2 Adapter Problem

    The number two feature of flexible hierarchy API is implemented using the adapter pattern.  One down-side of the adapter pattern is that @@ -1515,22 +1597,76 @@ there can only be one instance of an adapter of a particular type registered for a given element.  For flexible hierarchy providers, it means that each provider must implement the element presentation logic for every view that the element appears in, and as a result -adding a new view can force changing a large number of modules.
    -

    TODO: add a diagram of the -adapter pattern used by multiple views.
    -

    -

    To overcome the adapter pattern limitation, the View Model uses +adding a new view can force changing a large number of modules. + + + + + + + + + +

    +
    Image 6: Diagram illustrating problem of +multiple views sharing a single element, when using the adapter +mechanism.
    +
    +To overcome the adapter pattern limitation, the View Model uses wrapper objects.  The wrapper objects are held by the viewer and they redirect the requests for different flexible hierarchy providers to the appropriate modules.
    -

    -

    TODO: add a diagram of the View -Model hierarchy adapter pattern use
    -

    -

    IVMAdapter -> IVMProvider -> IVMNode -> IVMContext

    -
    -
    -
    + + + + + + + + + +

    +
    Image 7: Diagram illustrating use of +wrappers to allow different adapters to be associated with the same +element, for use with different views.
    +
    +

    8.4 API

    +The View Model uses four principal types of elements when processing +adapter requests from flexible hierarchy viewers.  These are:
    +
      +
    1. IVMAdapter - The +adapter is the top-level object in the view model hierarchy. It +implements some of the flexible hierarchy provider interfaces and it is +returned by the elements as the single adapter implementing those +interfaces  The main function the VM Adapter is to redirect the +provider requests based on the view ID that the requests originated +from.
      +
    2. +
    3. IVMProvider - In +the View Model hierarchy, the provider object supplies view content for +a single view.
    4. +
    5. IVMNode - The +node allows for grouping of like-elements in the view.  Examples +of such nodes are: threads node, stack frames node, variables node, etc.
    6. +
    7. IVMContext - The +VM Context is the interface of the wrapper objects that are held by the +flexible hierarchy viewers.  The context holds a reference to the +element that is being wrapped, as well as to the VM Node and VM Adapter +that it originated from.
      +
    8. +
    +

    8.5 Content Provider

    +The most important job of the View Model is to supply the content, in +form of element wrappers, to the viewers.  The flexible hierarchy +interface for this provider is listed below:

    -
    org.eclipse.dd.examples.dsf.requestmonitor.Async2Plus2
    + style="font-family: monospace; font-weight: bold;">org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider


    +
    +
     20: public interface IElementContentProvider {

    22: /**
    23: * Updates the number of children for the given parent elements in the
    24: * specified requests.
    25: *
    26: * @param updates Each update specifies an element to update and provides
    27: * a store for the result. The update array is guaranteed to have at least
    28: * one element, and for all updates to have the same presentation context.
    29: */
    30: public void update(IChildrenCountUpdate[] updates);
    31:
    ...
    39: public void update(IChildrenUpdate[] updates);
    40:
    ...
    48: public void update(IHasChildrenUpdate[] updates);
    49:
    50: }

    +Notice that each request for data is +encapsulated inside an update +object.  Every update +implements the IViewerUpdate interface listed here:
    +
    +
    + + + + + + + + + + +
    org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate +

    +
    +
     23: public interface IViewerUpdate extends IRequest {

    25: /**
    26: * Returns the context this update was requested in.
    27: *
    28: * @return context this update was requested in
    29: */
    30: public IPresentationContext getPresentationContext();
    31:
    32: /**
    33: * Returns the model element associated with this request.
    34: *
    35: * @return associated model element
    36: */
    37: public Object getElement();
    38:
    39: /**
    40: * Returns the viewer tree path to the model element associated with this
    41: * request. An empty path indicates a root element.
    42: *
    43: * @return tree path, possibly empty
    44: */
    45: public TreePath getElementPath();
    46:
    47: /**
    48: * Returns the element that was the viewer input at the time the
    49: * request was made, possibly <code>null</code>.
    50: *
    51: * @return viewer input element, possibly <code>null</code>
    52: */
    53: public Object getViewerInput();
    54: }
    +
    +
    +
    +These update requests are received by the adapter object in the View +Model hierarchy and are channeled to the correct node that should +process the given update.  This procedure is described in a few +steps:
    +
      +
    1. VM Adapter receives the update request.  For example the +update(IChildrenUpdate[]) method is called by a viewer.
    2. +
    3. VM Adapter retrieves the ID in the IPresentationContext object +associated with the update.
    4. +
    5. VM Adapter finds the VM Provider that is assigned for that +presentation context, creating it if necessary.
    6. +
    7. VM Provider finds and calls the VM Node (or nodes) that should +process the +given update. 
      +
    8. +
    9. VM Node retrieves fills the data in the update and marks it as +completed.
    10. +
    +
    -

    +
    Note: In Step 4, the logic used to +determine which VM Node should process the content request is +customizable.  However, in general VM Nodes are arranged in a +parent-child hierarchy which mirrors the layout of elements in the view.

    -
    - +
    Excercise abc: xyz Note: Also in Step 4, the VM +Provider may be customized to do additional processing on the +update.  For example, the provider may cache the results of +previous updates and return cached results without ever calling the VM +Node.
    +

    +As a sample from the Timers example of the VM Node logic that fulfills +the content update request:

    +
    + + + + + + + + + + +
    org.eclipse.dd.examples.dsf.timers.TimersVMNode
    +

    +
    +
     86:     protected void updateElementsInSessionThread(final IChildrenUpdate update) {
    87: if (!checkService(AlarmService.class, null, update)) return;

    89: // Retrieve the timer DMContexts, create the corresponding VMCs array, and
    90: // set them as result.
    91: TimerDMContext[] timers =
    92: getServicesTracker().getService(TimerService.class).getTimers();
    93: fillUpdateWithVMCs(update, timers);
    94: update.done();
    95: }
    +
    +
    +
      +
    • Lines 91-92 retrieve the Data Model contexts from the service.
    • +
    • Line 93 calls a convenience method which creates VM Context +wrappers for each element in the timers +array, and sets those VM Contexts to the update.
    • +
    • Line 94 completes the update.
      +
    • +
    +

    8.6 Model Event Proxy

    +Another important job of the View Model is to translate the events that +originate from the Data Model into generic events (deltas) that the viewer can +understand.  For this purpose, the Flexible Hierarchy has the IModelProxy interface which is used +in the following manner:
    +
      +
    1. An root element is +added into the view.  The root +element could be the view input or another element which is designated +as the root of a model hierarchy.
    2. +
    3. The viewer gets the IModelProxyFactory +adapter from the element.
    4. +
    5. The viewer calls IModelProxyFactory.createModelProxy() +which returns the IModelProxy instance.
    6. +
    7. The viewer adds itself as a listener +to model events with the model proxy +object.
    8. +
    9. The model proxy notifies its listeners (including the viewer) +with model deltas whenever +the model has changed.
    10. +
    11. When the root element is removed from the viewer, the viewer +disposes the model proxy.
      +
    12. +
    +For View Model users, much of the logic of creating the model proxy +factory is implemented using abstract base classes in the org.eclipse.dd.dsf.ui.viewmodel +package.  Instead, a typical DSF application only has to implement +two interfaces in order to support event proxying:
    +

    Event handling in VM +Provider
    +
    The following listing from the Timers example shows the handling +of a model event:
    +

    +
    + + + + + + + + + + +
    org.eclipse.dd.examples.dsf.timers.TimersVMProvider +

    +
    +
    108:     @DsfServiceEventHandler
    109: public void eventDispatched(final TimersChangedEvent event) {
    110: if (isDisposed()) return;

    112: try {
    113: getExecutor().execute(new Runnable() {
    114: public void run() {
    115: if (isDisposed()) return;
    116: handleEvent(event);
    117: }
    118: });
    119: } catch (RejectedExecutionException e) {}
    120: }
    +
    +
    +
      +
    • Line 108 declares the eventDispatched() +method as a service event handler.
    • +
    • Line 113 switches execution to the View Model executor +thread.  The event handler is called on the session executor +thread, however the standard View Model implementation classes have +their own single-threaded executor which is used to protect its state.
    • +
    • Line 116 calls the AbstractVMProvider.handleEvent() protected +method which continues the event processing.
      +
    • +
    +Processing events in VM Nodes
    +The following listing shows how the nodes translate the events into +model delta components:
    +
    +
    + + + + + + + + + + +
    org.eclipse.dd.examples.dsf.timers.TimersVMNode +

    +
    +
    141:     public int getDeltaFlags(Object e) {
    142: // This node generates delta if the timers have changed, or if the
    143: // label has changed.
    144: if (e instanceof TimerService.TimerTickDMEvent) {
    145: return IModelDelta.STATE;
    146: } else if (e instanceof TimerService.TimersChangedEvent) {
    147: return IModelDelta.CONTENT;
    148: }
    149: return IModelDelta.NO_CHANGE;
    150: }

    152: public void buildDelta(Object e, VMDelta parentDelta, int nodeOffset, RequestMonitor requestMonitor) {
    153: if (e instanceof TimerService.TimerTickDMEvent) {
    154: // Add delta indicating that the given timer has changed.
    155: parentDelta.addNode( createVMContext(((TimerService.TimerTickDMEvent)e).getDMContext()), IModelDelta.STATE );
    156: } else if (e instanceof TimerService.TimersChangedEvent) {
    157: // The list of timers has changed, which means that the parent
    158: // node needs to refresh its contents, which in turn will re-fetch the
    159: // elements from this node.
    160: parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT);
    161: }
    162: requestMonitor.done();
    163: }
    +
    +
    +
      +
    • Lines 141 declares the getDeltaFlags() +method, which tells the event processing logic what flags if any can be +generated by the given node for the given event.  Depending on its +return value, the event processing logic may or may not call the buildDelta() method.
    • +
    • Lines 144-148 return appropriate flags for the events that this +node can process.
    • +
    • Lines 153-155 process the TimerTickEvent. +They add a delta element corresponding to the changed timer instructing +the viewer to repaint this timer.
    • +
    • Lines 156-160 process the TimersChangedEvent.  +They add a flag to the parent delta element, instructing it to refresh +all the elements managed by this node.
      +
    • +
    +

    8.7 Property Provider +/ Label Provider
    +

    +The IElementPropertyProvider +interface is not actually part of the Flexible Hierarchy API, but an +extension interface added by DSF.  View Model implementers can use +the property provider to configure an  IElementLabelProvider +object +that the Flexible Hierarchy viewers call in order to get element +presentation details.
    +

    Below is the listing from the Timers VM Node that configures the +label provider:
    +

    +
    + + + + + + + + + + +
    org.eclipse.dd.examples.dsf.timers.TimersVMNode +

    +
    +
     53:     private static final PropertyBasedLabelProvider fgLabelProvider;
    54: static {
    55: fgLabelProvider = new PropertyBasedLabelProvider();

    57: LabelColumnInfo idCol = new LabelColumnInfo(
    58: new LabelAttribute[] {
    59: new LabelText(new MessageFormat("Timer #{0}"),
    60: new String[] { PROP_TIMER_NUMBER }),
    61: new LabelImage(DsfExamplesPlugin.getDefault().getImageRegistry().
    62: getDescriptor(DsfExamplesPlugin.IMG_ALARM))
    63: });
    64: fgLabelProvider.setColumnInfo(TimersViewColumnPresentation.COL_ID, idCol);
    65:
    66: LabelColumnInfo valueCol = ...
    ...
    74: }
    +
    +
    +
      +
    • Line 55 creates the label provider.
    • +
    • Lines 58-62 create the display attributes to use in the Name +column.  These attributes use named properties as parameters in +calculating the data, such as the label string.
    • +
    • Line 64 registers the column info object with the label provider.
    • +
    +All that is left is to implement the property provider:
    +
    +
    + + + + + + + + + + +
    org.eclipse.dd.examples.dsf.timers.TimersVMNode +

    +
    +
     98:     public void update(final IPropertiesUpdate[] updates) {
    99: // Switch to the session thread before processing the updates.
    100: try {
    101: getSession().getExecutor().execute(new DsfRunnable() {
    102: public void run() {
    103: for (IPropertiesUpdate update : updates) {
    104: updatePropertiesInSessionThread(update);
    105: }
    106: }});
    107: } catch (RejectedExecutionException e) {
    108: for (IViewerUpdate update : updates) {
    109: handleFailedUpdate(update);
    110: }
    111: }
    112: }

    114: @ConfinedToDsfExecutor("getSession#getExecutor")
    115: private void updatePropertiesInSessionThread(final IPropertiesUpdate update) {
    116: // Find the timer context in the element being updated
    117: final TimerDMContext dmc = findDmcInPath(
    118: update.getViewerInput(), update.getElementPath(), TimerDMContext.class);
    119:
    120: // If either update or service are not valid, fail the update and exit.
    121: if (!checkDmc(dmc, update) ||
    122: !checkService(TimerService.class, null, update))
    123: {
    124: return;
    125: }
    126:
    127: TimerService timerService =
    128: getServicesTracker().getService(TimerService.class, null);
    129: int value = timerService.getTimerValue(dmc);
    130:
    131: if (value == -1) {
    132: handleFailedUpdate(update);
    133: return;
    134: }

    136: update.setProperty(PROP_TIMER_NUMBER, dmc.getTimerNumber());
    137: update.setProperty(PROP_TIMER_VALUE, value);
    138: update.done();
    139: }
    +
    +
    +
    +
      +
    • Lines 98-112 handle switching into the session executor thread.
    • +
    • Lines 117-118 call a convenience method to extract the Data Model +timer context from the viewer update.  Normally this requires +casting the object returned by IViewerUpdate.getElement() to the +expected VM Context class.  Then extracting the model object from +the VM Context wrapper.
    • +
    • Line 127 retrieves element data from the service.
    • +
    • Lines 136-137 write the element properties into the property +update.
      +
    • +
    diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/pda/pda_tutorial_outline.html b/plugins/org.eclipse.dd.doc.dsf/docs/pda/pda_tutorial_outline.html index b9582503897..d85019cd9b3 100644 --- a/plugins/org.eclipse.dd.doc.dsf/docs/pda/pda_tutorial_outline.html +++ b/plugins/org.eclipse.dd.doc.dsf/docs/pda/pda_tutorial_outline.html @@ -10,9 +10,63 @@

    DSF

    • Customizing, componentization, performance.
    • -
    • GDB Reference Implementation
      +
    • GDB Reference Implementation
    • +
    +

    Debug Services

    +Use of services is intended to allow for maximum level of extendability +and customization.  To achieve this, service interfaces should +encapsulate functionality that logically belongs together and at the +same time allow for a managable number of services which have a clear +hierarchy.  DSF defines a set of standard debug interfaces (in the +org.eclipse.dd.dsf.debug plugin), and supplies a set of classes that +populate the standard debug views using those interfaces (in the +org.eclipse.dd.dsf.debug.ui plugin).  However there are very few +dependencies in these service interfaces and a given debugger +implementation may leave out or replace any of them as its custom +functionality dictates. 
    +

    The standard debug service interfaces include:

    +
      +
    • BreakpiontsMediator +- Not actually an interface, but a utility service implementation which +mediates between IDE and target-side  breakpoints.
      +
    • +
    • IBreakpionts - +Service for managing target-side breakpoints.
      +
    • +
    • IDisassembly - +Service for retrieving lines of disassembly.
      +
    • +
    • IExpressions - +Service for evaluating expressions, including variables.
      +
    • +
    • IMemory - +Service for reading target memory.
      +
    • +
    • IModules - +Service for examining target executable module information.
      +
    • +
    • IRegisters - +Service for reading register data.
      +
    • +
    • IRunControl - +Service for controlling execution state of the target.
      +
    • +
    • ISourceLookup - +Service for mapping target-side to host-side source paths.  This +service is intended to be used by other services and not to replace the +platform source lookup APIs.
      +
    • +
    • IStack - Service +for reading stack information.
      +
    • +
    • ISymbols - +Service for reading symbol information about the loaded modules.
    +


    +

    +
    +

    Push Down Automata (PDA)

      From 60cb898c865ce54df19dcd4850e533f197d80b08 Mon Sep 17 00:00:00 2001 From: Francois Chouinard Date: Fri, 7 Mar 2008 19:33:00 +0000 Subject: [PATCH 286/834] Breakpoint action for DSF --- .../service/MIBreakpointsActionManager.java | 185 ------------------ .../dd/mi/service/MIBreakpointsManager.java | 85 +++++++- .../actions/BreakpointActionAdapter.java | 44 +++++ .../actions/MILogActionEnabler.java | 82 ++++++++ .../actions/MIResumeActionEnabler.java | 44 +++++ 5 files changed, 247 insertions(+), 193 deletions(-) delete mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointsActionManager.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/breakpoint/actions/BreakpointActionAdapter.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/breakpoint/actions/MILogActionEnabler.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/breakpoint/actions/MIResumeActionEnabler.java diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointsActionManager.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointsActionManager.java deleted file mode 100644 index 9cc46e6c481..00000000000 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointsActionManager.java +++ /dev/null @@ -1,185 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 Ericsson 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: - * Ericsson - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.dd.mi.service; - -import java.io.StringReader; -import java.util.ArrayList; -import java.util.Iterator; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; - -import org.eclipse.cdt.debug.core.CDebugCorePlugin; -import org.eclipse.cdt.debug.core.breakpointactions.IBreakpointAction; -import org.eclipse.core.resources.IMarker; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IExtension; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.debug.core.model.IBreakpoint; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.InputSource; -import org.xml.sax.helpers.DefaultHandler; - -public class MIBreakpointsActionManager { - - public static final String BREAKPOINT_ACTION_ATTRIBUTE = "BREAKPOINT_ACTIONS"; //$NON-NLS-1$ - private static final String BREAKPOINT_ACTION_DATA = "BreakpointActionManager.actionData"; //$NON-NLS-1$ - - private ArrayList breakpointActions = null; - - public MIBreakpointsActionManager() { - } - - public void executeActions(final IBreakpoint breakpoint, final IAdaptable context) { - if (breakpoint != null) { - IMarker marker = breakpoint.getMarker(); - String actionNames = marker.getAttribute(BREAKPOINT_ACTION_ATTRIBUTE, ""); //$NON-NLS-1$ - final String[] actions = actionNames.split(","); - if (actions.length > 0){ - Job job = new Job("Execute breakpoint actions") { - public IStatus run(final IProgressMonitor monitor) { - return doExecuteActions(breakpoint, context, actions, monitor); - } - }; - job.schedule(); - try { - // wait for actions to execute - job.join(); - } - catch (InterruptedException e) { - e.printStackTrace(); - } - } - } - } - - private IStatus doExecuteActions(final IBreakpoint breakpoint, final IAdaptable context, String[] actions, IProgressMonitor monitor) { - try { - for (int i = 0; i < actions.length && !monitor.isCanceled(); i++) { - String actionName = actions[i]; - IBreakpointAction action = findBreakpointAction(actionName); - if (action != null) { - monitor.setTaskName(action.getSummary()); - IStatus status = action.execute(breakpoint, context, monitor); - if (status.getCode() != IStatus.OK) { - // do not log status if user canceled. - if (status.getCode() != IStatus.CANCEL) - CDebugCorePlugin.log(status); - return status; - } - } - monitor.worked(1); - } - } catch (Exception e) { - return new Status( IStatus.ERROR, CDebugCorePlugin.getUniqueIdentifier(), CDebugCorePlugin.INTERNAL_ERROR, "Internal Error", e ); - } - return monitor.isCanceled() ? Status.CANCEL_STATUS : Status.OK_STATUS; - } - - public IBreakpointAction findBreakpointAction(String name) { - for (Iterator iter = getBreakpointActions().iterator(); iter.hasNext();) { - IBreakpointAction action = (IBreakpointAction) iter.next(); - if (action.getName().equals(name)) - return action; - } - return null; - } - - public ArrayList getBreakpointActions() { - if (breakpointActions == null) { - breakpointActions = new ArrayList(); - loadActionData(); - } - return breakpointActions; - } - - private void loadActionData() { - - String actionData = CDebugCorePlugin.getDefault().getPluginPreferences().getString(BREAKPOINT_ACTION_DATA); - - if (actionData == null || actionData.length() == 0) - return; - - Element root = null; - DocumentBuilder parser; - try { - parser = DocumentBuilderFactory.newInstance().newDocumentBuilder(); - parser.setErrorHandler(new DefaultHandler()); - root = parser.parse(new InputSource(new StringReader(actionData))).getDocumentElement(); - - NodeList nodeList = root.getChildNodes(); - int entryCount = nodeList.getLength(); - - for (int i = 0; i < entryCount; i++) { - Node node = nodeList.item(i); - short type = node.getNodeType(); - if (type == Node.ELEMENT_NODE) { - Element subElement = (Element) node; - String nodeName = subElement.getNodeName(); - if (nodeName.equalsIgnoreCase("actionEntry")) { //$NON-NLS-1$ - String name = subElement.getAttribute("name"); //$NON-NLS-1$ - if (name == null) - throw new Exception(); - String value = subElement.getAttribute("value"); //$NON-NLS-1$ - if (value == null) - throw new Exception(); - String className = subElement.getAttribute("class"); //$NON-NLS-1$ - if (className == null) - throw new Exception(); - - IBreakpointAction action = createActionFromClassName(name, className); - action.initializeFromMemento(value); - } - } - } - - } catch (Exception e) { - e.printStackTrace(); - } - } - - private IBreakpointAction createActionFromClassName(String name, String className) { - - IBreakpointAction action = null; - IExtension[] actionExtensions = CDebugCorePlugin.getDefault().getBreakpointActionManager().getBreakpointActionExtensions(); - - try { - - for (int i = 0; i < actionExtensions.length && action == null; i++) { - IConfigurationElement[] elements = actionExtensions[i].getConfigurationElements(); - for (int j = 0; j < elements.length && action == null; j++) { - IConfigurationElement element = elements[j]; - if (element.getName().equals(CDebugCorePlugin.ACTION_TYPE_ELEMENT)) { - if (element.getAttribute("class").equals(className)) { //$NON-NLS-1$ - action = (IBreakpointAction) element.createExecutableExtension("class"); //$NON-NLS-1$ - action.setName(name); - CDebugCorePlugin.getDefault().getBreakpointActionManager().addAction(action); - } - } - } - } - - } catch (CoreException e) { - e.printStackTrace(); - } - - return action; - } - -} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointsManager.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointsManager.java index 2246915bdd4..044e384a6e9 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointsManager.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointsManager.java @@ -9,7 +9,8 @@ * Wind River - Initial API and implementation * Ericsson - High-level breakpoints integration * Ericsson - Added breakpoint filter support - * Ericsson - Re-factored the service and put a few comments + * Ericsson - Re-factored the service and put a few comments + * Ericsson - Added Action support *******************************************************************************/ package org.eclipse.dd.mi.service; @@ -24,6 +25,8 @@ import java.util.Set; import java.util.Vector; import java.util.concurrent.RejectedExecutionException; +import org.eclipse.cdt.debug.core.CDebugCorePlugin; +import org.eclipse.cdt.debug.core.breakpointactions.BreakpointActionManager; import org.eclipse.cdt.debug.core.model.ICBreakpoint; import org.eclipse.cdt.debug.core.model.ICBreakpointExtension; import org.eclipse.cdt.debug.core.model.ICLineBreakpoint; @@ -65,10 +68,13 @@ import org.eclipse.dd.mi.internal.MIPlugin; import org.eclipse.dd.mi.service.MIBreakpoints.BreakpointAddedEvent; import org.eclipse.dd.mi.service.MIBreakpoints.BreakpointRemovedEvent; import org.eclipse.dd.mi.service.MIBreakpoints.BreakpointUpdatedEvent; +import org.eclipse.dd.mi.service.MIBreakpoints.MIBreakpointDMContext; import org.eclipse.dd.mi.service.MIRunControl.MIExecutionDMC; +import org.eclipse.dd.mi.service.breakpoint.actions.BreakpointActionAdapter; import org.eclipse.dd.mi.service.command.events.MIBreakpointHitEvent; import org.eclipse.dd.mi.service.command.events.MIGDBExitEvent; import org.eclipse.dd.mi.service.command.events.MIWatchpointScopeEvent; +import org.eclipse.dd.mi.service.command.events.MIWatchpointTriggerEvent; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.IBreakpointListener; import org.eclipse.debug.core.IBreakpointManager; @@ -98,7 +104,7 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo ISourceLookup fSourceLookup; IBreakpoints fBreakpoints; IBreakpointManager fBreakpointManager; // Platform breakpoint manager (not this!) - // FIXME: MIBreakpointsActionManager fBreakpointActionManager; + BreakpointActionManager fBreakpointActionManager; /////////////////////////////////////////////////////////////////////////// // Breakpoints tracking @@ -159,7 +165,6 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo /////////////////////////////////////////////////////////////////////////// // String constants - // FIXME: Extract to some centralized location /////////////////////////////////////////////////////////////////////////// private static final String NULL_STRING = ""; //$NON-NLS-1$ @@ -230,7 +235,7 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo fSourceLookup = getServicesTracker().getService(ISourceLookup.class); fBreakpoints = getServicesTracker().getService(IBreakpoints.class); fBreakpointManager = DebugPlugin.getDefault().getBreakpointManager(); - // FIXME: fBreakpointActionManager = new MIBreakpointsActionManager(); + fBreakpointActionManager = CDebugCorePlugin.getDefault().getBreakpointActionManager(); // Register to the useful events getSession().addServiceEventListener(this, null); @@ -1134,20 +1139,23 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo // IServiceEventListener /////////////////////////////////////////////////////////////////////////// + //------------------------------------------------------------------------- + // Breakpoints + //------------------------------------------------------------------------- + @DsfServiceEventHandler public void eventDispatched(BreakpointAddedEvent e) { + // Nothing to do - already handled by breakpointAdded() } @DsfServiceEventHandler public void eventDispatched(BreakpointUpdatedEvent e) { + // Nothing to do - already handled by breakpointChanged() } @DsfServiceEventHandler public void eventDispatched(BreakpointRemovedEvent e) { - } - - @DsfServiceEventHandler - public void eventDispatched(MIBreakpointHitEvent e) { + // Nothing to do - already handled by breakpointRemoved() } /* @@ -1160,6 +1168,67 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo public void eventDispatched(MIWatchpointScopeEvent e) { } + //------------------------------------------------------------------------- + // Breakpoint actions + //------------------------------------------------------------------------- + + @DsfServiceEventHandler + public void eventDispatched(MIBreakpointHitEvent e) { + performBreakpointAction(e.getNumber()); + } + + @DsfServiceEventHandler + public void eventDispatched(MIWatchpointTriggerEvent e) { + performBreakpointAction(e.getNumber()); + } + + private void performBreakpointAction(int number) { + // Identify the platform breakpoint + final ICBreakpoint breakpoint = findPlatformBreakpoint(number); + + // FIXME: Temporary hack to have a context + Object[] contexts = fTargetBPs.keySet().toArray(); + final IBreakpointsTargetDMContext context = (IBreakpointsTargetDMContext) contexts[0]; + + // Perform the actions asynchronously (otherwise we can have a deadlock...) + new Job("Breakpoint action") { //$NON-NLS-1$ + { setSystem(true); } + @Override + protected IStatus run(IProgressMonitor monitor) { + // FIXME: Rename MyAdaptableType to something more relevant + fBreakpointActionManager.executeActions(breakpoint, new BreakpointActionAdapter(getExecutor(), getServicesTracker(), context)); + return Status.OK_STATUS; + }; + }.schedule(); + } + + // Helper function to locate the platform breakpoint corresponding + // to the target breakpoint/watchpoint that was just hit + // FIXME: Need a way to identify the correct context where the BP was hit + // because it impacts the action (expression evaluation and resume delay). + // This means that the Breakpoint/WatchpointHitEvent will need to + // provide some extra info... + private ICBreakpoint findPlatformBreakpoint(int targetBreakpointID) { + Set targets = fTargetBPs.keySet(); + for (IBreakpointsTargetDMContext target : targets) { + Map bps = fTargetBPs.get(target); + Set contexts = bps.keySet(); + for (IBreakpointDMContext context : contexts) { + if (context instanceof MIBreakpointDMContext) { + MIBreakpointDMContext ctx = (MIBreakpointDMContext) context; + if (ctx.getReference() == targetBreakpointID) { + return bps.get(context); + } + } + } + } + return null; + } + + //------------------------------------------------------------------------- + // Session exit + //------------------------------------------------------------------------- + @DsfServiceEventHandler public void eventDispatched(MIGDBExitEvent e) { terminated(); diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/breakpoint/actions/BreakpointActionAdapter.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/breakpoint/actions/BreakpointActionAdapter.java new file mode 100644 index 00000000000..745820ca899 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/breakpoint/actions/BreakpointActionAdapter.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2008 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.breakpoint.actions; + +import org.eclipse.cdt.debug.core.breakpointactions.ILogActionEnabler; +import org.eclipse.cdt.debug.core.breakpointactions.IResumeActionEnabler; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.service.DsfServicesTracker; + +public class BreakpointActionAdapter implements IAdaptable { + + private final DsfExecutor fExecutor; + private final DsfServicesTracker fServiceTracker; + private final IDMContext fContext; + + public BreakpointActionAdapter(DsfExecutor executor, DsfServicesTracker serviceTracker, IDMContext context) { + fExecutor = executor; + fServiceTracker = serviceTracker; + fContext = context; + } + + @SuppressWarnings("unchecked") + public Object getAdapter(Class adapter) { + if (adapter.equals(ILogActionEnabler.class)) { + return new MILogActionEnabler(fExecutor, fServiceTracker, fContext); + } + if (adapter.equals(IResumeActionEnabler.class)) { + return new MIResumeActionEnabler(fExecutor, fServiceTracker, fContext); + } + return null; + } + +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/breakpoint/actions/MILogActionEnabler.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/breakpoint/actions/MILogActionEnabler.java new file mode 100644 index 00000000000..8b9c509bedb --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/breakpoint/actions/MILogActionEnabler.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2008 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.breakpoint.actions; + +import java.util.concurrent.ExecutionException; + +import org.eclipse.cdt.debug.core.breakpointactions.ILogActionEnabler; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.Query; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.IExpressions; +import org.eclipse.dd.dsf.debug.service.IFormattedValues; +import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData; +import org.eclipse.dd.dsf.service.DsfServicesTracker; + +public class MILogActionEnabler implements ILogActionEnabler { + + private final DsfExecutor fExecutor; + private final DsfServicesTracker fServiceTracker; + private final IBreakpointsTargetDMContext fContext; + + public MILogActionEnabler(DsfExecutor executor, DsfServicesTracker serviceTracker, IDMContext context) { + fExecutor = executor; + fServiceTracker = serviceTracker; + // FIXME: Although it looks optimistic, we know it works + // How can we guarantee that it always will? + fContext = (IBreakpointsTargetDMContext) context; + } + + public String evaluateExpression(final String expression) throws Exception { + // Use a Query to synchronize the call + Query query = new Query() { + @Override + protected void execute(final DataRequestMonitor drm) { + final IExpressions expressionService = fServiceTracker.getService(IExpressions.class); + if (expressionService != null) { + final IExpressionDMContext expressionDMC = expressionService.createExpression(fContext, expression); + String formatId = IFormattedValues.NATURAL_FORMAT; + FormattedValueDMContext valueDmc = expressionService.getFormattedValueContext(expressionDMC, formatId); + expressionService.getFormattedExpressionValue( + valueDmc, + new DataRequestMonitor(fExecutor, drm) { + @Override + protected void handleCompleted() { + String result = expression + ": evaluation failed."; //$NON-NLS-1$ + if (getStatus().isOK()) { + result = getData().getFormattedValue(); + } + drm.setData(result); + drm.done(); + } + } + ); + } + } + }; + fExecutor.execute(query); + + try { + // The happy case + return query.get(); + } catch (InterruptedException e) { + return "Error evaluating \"" + expression + "\" (InterruptedException)."; //$NON-NLS-1$ //$NON-NLS-2$ + } catch (ExecutionException e) { + return "Error evaluating \"" + expression + "\" (ExecutionException)."; //$NON-NLS-1$ //$NON-NLS-2$ + } + } + +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/breakpoint/actions/MIResumeActionEnabler.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/breakpoint/actions/MIResumeActionEnabler.java new file mode 100644 index 00000000000..1334f9e167f --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/breakpoint/actions/MIResumeActionEnabler.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2008 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.breakpoint.actions; + +import org.eclipse.cdt.debug.core.breakpointactions.IResumeActionEnabler; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.dsf.service.DsfServicesTracker; + +public class MIResumeActionEnabler implements IResumeActionEnabler { + + @SuppressWarnings("unused") + private final DsfExecutor fExecutor; + private final DsfServicesTracker fServiceTracker; + private final IExecutionDMContext fContext; + + public MIResumeActionEnabler(DsfExecutor executor, DsfServicesTracker serviceTracker, IDMContext context) { + fExecutor = executor; + fServiceTracker = serviceTracker; + // FIXME: Although it looks optimistic, we know it works + // How can we guarantee that it always will? + fContext = (IExecutionDMContext) context; + } + + public void resume() throws Exception { + final IRunControl runControlService = fServiceTracker.getService(IRunControl.class); + if (runControlService != null) { + runControlService.resume(fContext, new RequestMonitor(fExecutor, null)); + } + } + +} From f3284051209db934762629dfee35e90c8a460d69 Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Fri, 7 Mar 2008 19:46:13 +0000 Subject: [PATCH 287/834] Bugzilla's 221898 & 219127. --- .../dd/dsf/debug/ui/viewmodel/modules/ModulesVMNode.java | 2 +- .../debug/ui/viewmodel/register/RegisterBitFieldVMNode.java | 4 ++++ .../dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java | 1 + .../dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java | 3 +++ 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMNode.java index 40bafae38c3..84d84de0a4a 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMNode.java @@ -43,7 +43,7 @@ public class ModulesVMNode extends AbstractDMVMNode @Override protected void updateElementsInSessionThread(final IChildrenUpdate update) { - if (!checkService(IRegisters.class, null, update)) return; + if (!checkService(IModules.class, null, update)) return; final ISymbolDMContext symDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), ISymbolDMContext.class) ; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java index 3d29b733e04..bf368b39e59 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java @@ -273,6 +273,8 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode protected void updateLabelInSessionThread(ILabelUpdate[] updates) { for (final ILabelUpdate update : updates) { + if (!checkService(IRegisters.class, null, update)) continue; + final IBitFieldDMContext dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IRegisters.IBitFieldDMContext.class); getDMVMProvider().getModelData( @@ -367,6 +369,8 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode return; } + if (!checkService(IRegisters.class, null, update)) return; + getServicesTracker().getService(IRegisters.class).getBitFields( regDmc, new DataRequestMonitor(getSession().getExecutor(), null) { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java index ca83235aacb..835a6e7731e 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java @@ -132,6 +132,7 @@ public class RegisterGroupVMNode extends AbstractExpressionVMNode @Override protected void updateElementsInSessionThread(final IChildrenUpdate update) { + if (!checkService(IRegisters.class, null, update)) return; getServicesTracker().getService(IRegisters.class).getRegisterGroups( createCompositeDMVMContext(update), new DataRequestMonitor(getSession().getExecutor(), null) { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java index 71ce6399069..1a35a3efe39 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java @@ -161,6 +161,8 @@ public class RegisterVMNode extends AbstractExpressionVMNode */ private void updateFormattedRegisterValue(final ILabelUpdate update, final int labelIndex, final IRegisterDMContext dmc) { + if (!checkService(IRegisters.class, null, update)) return; + final IRegisters regService = getServicesTracker().getService(IRegisters.class); /* * First select the format to be used. This involves checking so see that the preference @@ -362,6 +364,7 @@ public class RegisterVMNode extends AbstractExpressionVMNode @Override protected void updateElementsInSessionThread(final IChildrenUpdate update) { + if (!checkService(IRegisters.class, null, update)) return; getServicesTracker().getService(IRegisters.class).getRegisters( createCompositeDMVMContext(update), new DataRequestMonitor(getSession().getExecutor(), null) { From 5893454304c7eb755f14fc38f6c79ecb80ccdd87 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Mon, 10 Mar 2008 16:09:40 +0000 Subject: [PATCH 288/834] [221795] Added a suspended event handler to the source locator. --- .../dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java index c869bd4f8e1..ce9154d8885 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java @@ -546,4 +546,9 @@ public class MISourceDisplayAdapter implements ISourceDisplay public void eventDispatched(StepQueueManager.ISteppingTimedOutEvent e) { startAnnotationClearingJob(e.getDMContext()); } + + @DsfServiceEventHandler + public void eventDispatched(IRunControl.ISuspendedDMEvent e) { + fPrevModelContext = null; + } } From ca2922f0bb394b7242fd58721abc9cda3d6a0f17 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Mon, 10 Mar 2008 18:23:58 +0000 Subject: [PATCH 289/834] Got rid of an unused import statement. --- .../eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMNode.java | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMNode.java index 84d84de0a4a..9cccf07505d 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMNode.java @@ -17,7 +17,6 @@ import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.service.IModules; -import org.eclipse.dd.dsf.debug.service.IRegisters; import org.eclipse.dd.dsf.debug.service.IRunControl; import org.eclipse.dd.dsf.debug.service.IModules.IModuleDMContext; import org.eclipse.dd.dsf.debug.service.IModules.IModuleDMData; From ec69c08687c84e94a15f1bff3e47249166efbcac Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Mon, 10 Mar 2008 19:53:15 +0000 Subject: [PATCH 290/834] New org.eclipse.dd.gdb.launch plugin to separate the launch logic --- plugins/org.eclipse.dd.gdb.launch/.classpath | 7 + plugins/org.eclipse.dd.gdb.launch/.project | 28 ++ .../.settings/org.eclipse.jdt.core.prefs | 7 + .../META-INF/MANIFEST.MF | 20 ++ plugins/org.eclipse.dd.gdb.launch/about.html | 24 ++ .../build.properties | 7 + plugins/org.eclipse.dd.gdb.launch/plugin.xml | 24 ++ .../gdb/launch/internal/GdbLaunchPlugin.java | 120 +++++++ .../dd/gdb/launch/launching/GdbLaunch.java | 175 ++++++++++ .../launching/GdbLocalLaunchDelegate.java | 291 +++++++++++++++++ .../launching/GdbRemoteLaunchDelegate.java | 301 ++++++++++++++++++ .../IGDBLaunchConfigurationConstants.java | 7 + .../gdb/launch/launching/LaunchSequence.java | 233 ++++++++++++++ .../launch/launching/ShutdownSequence.java | 179 +++++++++++ 14 files changed, 1423 insertions(+) create mode 100644 plugins/org.eclipse.dd.gdb.launch/.classpath create mode 100644 plugins/org.eclipse.dd.gdb.launch/.project create mode 100644 plugins/org.eclipse.dd.gdb.launch/.settings/org.eclipse.jdt.core.prefs create mode 100644 plugins/org.eclipse.dd.gdb.launch/META-INF/MANIFEST.MF create mode 100644 plugins/org.eclipse.dd.gdb.launch/about.html create mode 100644 plugins/org.eclipse.dd.gdb.launch/build.properties create mode 100644 plugins/org.eclipse.dd.gdb.launch/plugin.xml create mode 100644 plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/internal/GdbLaunchPlugin.java create mode 100644 plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/GdbLaunch.java create mode 100644 plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/GdbLocalLaunchDelegate.java create mode 100644 plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/GdbRemoteLaunchDelegate.java create mode 100644 plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/IGDBLaunchConfigurationConstants.java create mode 100644 plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/LaunchSequence.java create mode 100644 plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/ShutdownSequence.java diff --git a/plugins/org.eclipse.dd.gdb.launch/.classpath b/plugins/org.eclipse.dd.gdb.launch/.classpath new file mode 100644 index 00000000000..304e86186aa --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.launch/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/plugins/org.eclipse.dd.gdb.launch/.project b/plugins/org.eclipse.dd.gdb.launch/.project new file mode 100644 index 00000000000..116145f8919 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.launch/.project @@ -0,0 +1,28 @@ + + + org.eclipse.dd.gdb.launch + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/plugins/org.eclipse.dd.gdb.launch/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.dd.gdb.launch/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000000..8af0c69cefb --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.launch/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +#Mon Mar 03 11:58:56 EST 2008 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/plugins/org.eclipse.dd.gdb.launch/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.gdb.launch/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..d63b2e1a771 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.launch/META-INF/MANIFEST.MF @@ -0,0 +1,20 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Debug Services Framework GDB Launch Plug-in +Bundle-Vendor: Eclipse.org +Bundle-SymbolicName: org.eclipse.dd.gdb.launch; singleton:=true +Bundle-Version: 1.0.0 +Bundle-Activator: org.eclipse.dd.gdb.launch.internal.GdbLaunchPlugin +Require-Bundle: org.eclipse.core.runtime, + org.eclipse.dd.dsf, + org.eclipse.dd.dsf.debug, + org.eclipse.dd.mi, + org.eclipse.dd.gdb, + org.eclipse.debug.core, + org.eclipse.cdt.core, + org.eclipse.cdt.launch, + org.eclipse.cdt.debug.core, + org.eclipse.cdt.debug.mi.core +Bundle-ActivationPolicy: lazy +Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Export-Package: org.eclipse.dd.gdb.launch.launching diff --git a/plugins/org.eclipse.dd.gdb.launch/about.html b/plugins/org.eclipse.dd.gdb.launch/about.html new file mode 100644 index 00000000000..cb740ae8bc8 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.launch/about.html @@ -0,0 +1,24 @@ + + + + +About +

      About This Content

      + +

      June 5, 2007

      +

      License

      + +

      The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at http://www.eclipse.org/legal/epl-v10.html. +For purposes of the EPL, "Program" will mean the Content.

      + +

      If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at http://www.eclipse.org.

      + + \ No newline at end of file diff --git a/plugins/org.eclipse.dd.gdb.launch/build.properties b/plugins/org.eclipse.dd.gdb.launch/build.properties new file mode 100644 index 00000000000..cf2d90c8779 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.launch/build.properties @@ -0,0 +1,7 @@ +source.. = src/ +output.. = bin/ +bin.includes = plugin.xml,\ + META-INF/,\ + .,\ + icons/,\ + about.html diff --git a/plugins/org.eclipse.dd.gdb.launch/plugin.xml b/plugins/org.eclipse.dd.gdb.launch/plugin.xml new file mode 100644 index 00000000000..4b4a09485e8 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.launch/plugin.xml @@ -0,0 +1,24 @@ + + + + + + + + + + diff --git a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/internal/GdbLaunchPlugin.java b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/internal/GdbLaunchPlugin.java new file mode 100644 index 00000000000..3e2a6d9e678 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/internal/GdbLaunchPlugin.java @@ -0,0 +1,120 @@ +/******************************************************************************* + * Copyright (c) 2008 Ericsson 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: + * Ericsson - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.gdb.launch.internal; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Plugin; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.Query; +import org.eclipse.dd.gdb.launch.launching.GdbLaunch; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunch; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class GdbLaunchPlugin extends Plugin { + + // The plug-in ID + public static final String PLUGIN_ID = "org.eclipse.dd.gdb"; //$NON-NLS-1$ + + // The shared instance + private static GdbLaunchPlugin plugin; + + private static BundleContext fgBundleContext; + + /** + * The constructor + */ + public GdbLaunchPlugin() { + } + + /* + * (non-Javadoc) + * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext) + */ + @Override + public void start(BundleContext context) throws Exception { + fgBundleContext = context; + super.start(context); + plugin = this; + } + + /* + * (non-Javadoc) + * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext) + */ + @Override + public void stop(BundleContext context) throws Exception { + shutdownActiveLaunches(); + plugin = null; + super.stop(context); + fgBundleContext = null; + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static GdbLaunchPlugin getDefault() { + return plugin; + } + + public static BundleContext getBundleContext() { + return fgBundleContext; + } + + /** + * Shuts down any active launches. We must shutdown any active sessions + * and services associated with this plugin before this plugin is stopped. + * Any attempts to use the plugins {@link BundleContext} after the plugin + * is shut down will result in exceptions. + */ + private void shutdownActiveLaunches() { + for (ILaunch launch : DebugPlugin.getDefault().getLaunchManager().getLaunches()) { + if (launch instanceof GdbLaunch && ((GdbLaunch)launch).getSession().isActive()) { + final GdbLaunch gdbLaunch = (GdbLaunch)launch; + + Query launchShutdownQuery = new Query() { + @Override + protected void execute(DataRequestMonitor rm) { + gdbLaunch.shutdownSession(rm); + } + }; + + try { + gdbLaunch.getSession().getExecutor().execute(launchShutdownQuery); + } catch (RejectedExecutionException e) { + // We can get this exception if the session is shutdown concurrently + // to this method running. + break; + } + + // The Query.get() method is a synchronous call which blocks until the + // query completes. + try { + launchShutdownQuery.get(); + } catch (InterruptedException e) { + getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, "InterruptedException while shutting down PDA debugger launch " + gdbLaunch, e.getCause())); //$NON-NLS-1$ + } catch (ExecutionException e) { + getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, "Exception while shutting down PDA debugger launch " + gdbLaunch, e.getCause())); //$NON-NLS-1$ + } + } + } + } + +} diff --git a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/GdbLaunch.java b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/GdbLaunch.java new file mode 100644 index 00000000000..b98cd3783a2 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/GdbLaunch.java @@ -0,0 +1,175 @@ +/******************************************************************************* + * 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.gdb.launch.launching; + +import java.util.concurrent.ExecutionException; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; +import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.concurrent.Sequence; +import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.gdb.launch.internal.GdbLaunchPlugin; +import org.eclipse.dd.gdb.service.command.GDBControl; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.Launch; +import org.eclipse.debug.core.model.ISourceLocator; +import org.eclipse.debug.core.model.ITerminate; + +/** + * The only object in the model that implements the traditional interfaces. + */ +@ThreadSafe +public class GdbLaunch extends Launch + implements ITerminate +{ + private DefaultDsfExecutor fExecutor; + private DsfSession fSession; + private DsfServicesTracker fTracker; + private boolean fInitialized = false; + private boolean fShutDown = false; + + + public GdbLaunch(ILaunchConfiguration launchConfiguration, String mode, ISourceLocator locator) { + super(launchConfiguration, mode, locator); + + // Create the dispatch queue to be used by debugger control and services + // that belong to this launch + final DefaultDsfExecutor dsfExecutor = new DefaultDsfExecutor(GdbLocalLaunchDelegate.GDB_DEBUG_MODEL_ID); + dsfExecutor.prestartCoreThread(); + fExecutor = dsfExecutor; + fSession = DsfSession.startSession(fExecutor, GdbLocalLaunchDelegate.GDB_DEBUG_MODEL_ID); + } + + public DsfExecutor getDsfExecutor() { return fExecutor; } + + @ConfinedToDsfExecutor("getExecutor") + public void initializeControl() + throws CoreException + { + + Runnable initRunnable = new DsfRunnable() { + public void run() { + fTracker = new DsfServicesTracker(GdbLaunchPlugin.getBundleContext(), fSession.getId()); + fSession.addServiceEventListener(GdbLaunch.this, null); + + fInitialized = true; + fireChanged(); + } + }; + + // Invoke the execution code and block waiting for the result. + try { + fExecutor.submit(initRunnable).get(); + } catch (InterruptedException e) { + new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Error initializing launch", e); //$NON-NLS-1$ + } catch (ExecutionException e) { + new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Error initializing launch", e); //$NON-NLS-1$ + } + } + + public DsfSession getSession() { return fSession; } + + /////////////////////////////////////////////////////////////////////////// + // IServiceEventListener + @DsfServiceEventHandler public void eventDispatched(GDBControl.ExitedEvent event) { + shutdownSession(new RequestMonitor(ImmediateExecutor.getInstance(), null)); + } + + /////////////////////////////////////////////////////////////////////////// + // ITerminate + @Override + public boolean canTerminate() { + return super.canTerminate() && fInitialized && !fShutDown; + } + + @Override + public boolean isTerminated() { + return super.isTerminated() || fShutDown; + } + + + @Override + public void terminate() throws DebugException { + if (fShutDown) return; + super.terminate(); + } + // ITerminate + /////////////////////////////////////////////////////////////////////////// + + /** + * Shuts down the services, the session and the executor associated with + * this launch. + *

      + * Note: The argument request monitor to this method should NOT use the + * executor that belongs to this launch. By the time the shutdown is + * complete, this executor will not be dispatching anymore and the + * request monitor will never be invoked. Instead callers should use + * the {@link ImmediateExecutor}. + *

      + * @param rm The request monitor invoked when the shutdown is complete. + */ + @ConfinedToDsfExecutor("getSession().getExecutor()") + public void shutdownSession(final RequestMonitor rm) { + if (fShutDown) { + rm.done(); + return; + } + fShutDown = true; + + Sequence shutdownSeq = new ShutdownSequence( + getDsfExecutor(), fSession.getId(), + new RequestMonitor(fSession.getExecutor(), rm) { + @Override + public void handleCompleted() { + fSession.removeServiceEventListener(GdbLaunch.this); + if (!getStatus().isOK()) { + GdbLaunchPlugin.getDefault().getLog().log(new MultiStatus( + GdbLaunchPlugin.PLUGIN_ID, -1, new IStatus[]{getStatus()}, "Session shutdown failed", null)); //$NON-NLS-1$ + } + // Last order of business, shutdown the dispatch queue. + fTracker.dispose(); + fTracker = null; + DsfSession.endSession(fSession); + // endSession takes a full dispatch to distribute the + // session-ended event, finish step only after the dispatch. + fExecutor.shutdown(); + fExecutor = null; + fireTerminate(); + + rm.setStatus(getStatus()); + rm.done(); + } + }); + fExecutor.execute(shutdownSeq); + } + + @SuppressWarnings("unchecked") + @Override + public Object getAdapter(Class adapter) { + // Must force adapters to be loaded. + Platform.getAdapterManager().loadAdapter(this, adapter.getName()); + return super.getAdapter(adapter); + } +} diff --git a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/GdbLocalLaunchDelegate.java b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/GdbLocalLaunchDelegate.java new file mode 100644 index 00000000000..d5e5c57f478 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/GdbLocalLaunchDelegate.java @@ -0,0 +1,291 @@ +/******************************************************************************* + * Copyright (c) 2004, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.gdb.launch.launching; + +import java.io.File; +import java.io.IOException; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.atomic.AtomicReference; + +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; +import org.eclipse.cdt.launch.AbstractCLaunchDelegate; +import org.eclipse.cdt.launch.internal.ui.LaunchMessages; +import org.eclipse.cdt.launch.internal.ui.LaunchUIPlugin; +import org.eclipse.cdt.utils.pty.PTY; +import org.eclipse.cdt.utils.spawner.ProcessFactory; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.dd.dsf.debug.model.DsfMemoryBlockRetrieval; +import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryDMContext; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.gdb.launch.internal.GdbLaunchPlugin; +import org.eclipse.dd.gdb.service.command.GDBControl; +import org.eclipse.dd.mi.service.command.AbstractCLIProcess; +import org.eclipse.dd.mi.service.command.MIInferiorProcess; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchManager; +import org.eclipse.debug.core.IStatusHandler; +import org.eclipse.debug.core.model.ILaunchConfigurationDelegate2; +import org.eclipse.debug.core.model.IMemoryBlockRetrieval; +import org.eclipse.debug.core.model.IPersistableSourceLocator; +import org.eclipse.debug.core.model.ISourceLocator; +import org.eclipse.debug.core.sourcelookup.IPersistableSourceLocator2; + +/** + * The launch configuration delegate for the CDI debugger session types. + */ +@ThreadSafe +public class GdbLocalLaunchDelegate extends AbstractCLaunchDelegate + implements ILaunchConfigurationDelegate2 +{ + public final static String GDB_DEBUG_MODEL_ID = "org.eclipse.dd.gdb"; //$NON-NLS-1$ + + /* (non-Javadoc) + * @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#launch(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.debug.core.ILaunch, org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public void launch( ILaunchConfiguration config, String mode, ILaunch launch, IProgressMonitor monitor ) throws CoreException { + if ( monitor == null ) { + monitor = new NullProgressMonitor(); + } + if ( mode.equals( ILaunchManager.DEBUG_MODE ) ) { + launchDebugger( config, launch, monitor ); + } + } + + private void launchDebugger( ILaunchConfiguration config, ILaunch launch, IProgressMonitor monitor ) throws CoreException { + monitor.beginTask("Launching debugger session", 10); //$NON-NLS-1$ + if ( monitor.isCanceled() ) { + return; + } + try { + String debugMode = config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN ); + if ( debugMode.equals( ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN ) ) { + launchLocalDebugSession( config, launch, monitor ); + } + } + finally { + monitor.done(); + } + } + + private void launchLocalDebugSession( final ILaunchConfiguration config, ILaunch l, IProgressMonitor monitor ) throws CoreException { + if ( monitor.isCanceled() ) { + return; + } + final GdbLaunch launch = (GdbLaunch)l; + + monitor.subTask( "Debugging local C/C++ application" ); //$NON-NLS-1$ + IPath exePath = verifyProgramPath( config ); + ICProject project = verifyCProject( config ); + if ( exePath != null ) { + verifyBinary( project, exePath ); + } + + setDefaultSourceLocator(launch, config); + + monitor.worked( 1 ); + + + // Create and invoke the launch sequence to create the debug control and services + final LaunchSequence launchSequence = + new LaunchSequence(launch.getSession(), launch, exePath); + launch.getSession().getExecutor().execute(launchSequence); + try { + launchSequence.get(); + } catch (InterruptedException e1) { + throw new DebugException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, "Interrupted Exception in dispatch thread", e1)); //$NON-NLS-1$ + } catch (ExecutionException e1) { + throw new DebugException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Error in launch sequence", e1.getCause())); //$NON-NLS-1$ + } + + launch.initializeControl(); + + // Add the CLI and "inferior" process objects to the launch. + final AtomicReference cliProcessRef = new AtomicReference(); + final AtomicReference inferiorProcessRef = new AtomicReference(); + try { + launch.getDsfExecutor().submit( new Callable() { + public Object call() throws CoreException { + DsfServicesTracker tracker = new DsfServicesTracker(GdbLaunchPlugin.getBundleContext(), launch.getSession().getId()); + GDBControl gdb = tracker.getService(GDBControl.class); + if (gdb != null) { + cliProcessRef.set(gdb.getCLIProcess()); + inferiorProcessRef.set(gdb.getInferiorProcess()); + } + tracker.dispose(); + return null; + } + }).get(); + launch.addProcess(DebugPlugin.newProcess(launch, cliProcessRef.get(), "gdb")); //$NON-NLS-1$ + launch.addProcess(DebugPlugin.newProcess(launch, inferiorProcessRef.get(), exePath.lastSegment())); + } catch (InterruptedException e) { + throw new CoreException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, 0, "Interrupted while waiting for get process callable.", e)); //$NON-NLS-1$ + } catch (ExecutionException e) { + throw (CoreException)e.getCause(); + } catch (RejectedExecutionException e) { + throw new CoreException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, 0, "Debugger shut down before launch was completed.", e)); //$NON-NLS-1$ + } + + // Create a memory retrieval and register it with session + try { + launch.getDsfExecutor().submit( new Callable() { + public Object call() throws CoreException { + DsfServicesTracker tracker = new DsfServicesTracker(GdbLaunchPlugin.getBundleContext(), launch.getSession().getId()); + GDBControl gdbControl = tracker.getService(GDBControl.class); + if (gdbControl != null) { + IMemoryBlockRetrieval memRetrieval = new DsfMemoryBlockRetrieval( + GDB_DEBUG_MODEL_ID, config, (IMemoryDMContext)gdbControl.getControlDMContext()); + launch.getSession().registerModelAdapter(IMemoryBlockRetrieval.class, memRetrieval); + ((DsfMemoryBlockRetrieval) memRetrieval).initialize(); + } + tracker.dispose(); + return null; + } + }).get(); + } catch (InterruptedException e) { + throw new CoreException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, 0, "Interrupted while waiting for get process callable.", e)); //$NON-NLS-1$ + } catch (ExecutionException e) { + throw (CoreException)e.getCause(); + } catch (RejectedExecutionException e) { + throw new CoreException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, 0, "Debugger shut down before launch was completed.", e)); //$NON-NLS-1$ + } + } + + + /* (non-Javadoc) + * @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#getPluginID() + */ + @Override + protected String getPluginID() { + return LaunchUIPlugin.getUniqueIdentifier(); + } + + /** + * Performs a runtime exec on the given command line in the context of the + * specified working directory, and returns the resulting process. If the + * current runtime does not support the specification of a working + * directory, the status handler for error code + * ERR_WORKING_DIRECTORY_NOT_SUPPORTED is queried to see if + * the exec should be re-executed without specifying a working directory. + * + * @param cmdLine + * the command line + * @param workingDirectory + * the working directory, or null + * @return the resulting process or null if the exec is + * cancelled + * @see Runtime + */ + protected Process exec( String[] cmdLine, String[] environ, File workingDirectory, boolean usePty ) throws CoreException { + Process p = null; + try { + if ( workingDirectory == null ) { + p = ProcessFactory.getFactory().exec( cmdLine, environ ); + } + else { + if ( usePty && PTY.isSupported() ) { + p = ProcessFactory.getFactory().exec( cmdLine, environ, workingDirectory, new PTY() ); + } + else { + p = ProcessFactory.getFactory().exec( cmdLine, environ, workingDirectory ); + } + } + } + catch( IOException e ) { + if ( p != null ) { + p.destroy(); + } + abort( "Error starting process.", e, ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR ); //$NON-NLS-1$ + } + catch( NoSuchMethodError e ) { + // attempting launches on 1.2.* - no ability to set working + // directory + IStatus status = new Status( IStatus.ERROR, LaunchUIPlugin.getUniqueIdentifier(), ICDTLaunchConfigurationConstants.ERR_WORKING_DIRECTORY_NOT_SUPPORTED, LaunchMessages.getString( "LocalDsfLaunchDelegate.9" ), e ); //$NON-NLS-1$ + IStatusHandler handler = DebugPlugin.getDefault().getStatusHandler( status ); + if ( handler != null ) { + Object result = handler.handleStatus( status, this ); + if ( result instanceof Boolean && ((Boolean)result).booleanValue() ) { + p = exec( cmdLine, environ, null, usePty ); + } + } + } + return p; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#preLaunchCheck(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public boolean preLaunchCheck( ILaunchConfiguration config, String mode, IProgressMonitor monitor ) throws CoreException { + // no pre launch check for core file + if ( mode.equals( ILaunchManager.DEBUG_MODE ) ) { + if ( ICDTLaunchConfigurationConstants.DEBUGGER_MODE_CORE.equals( config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN ) ) ) + return true; + } + return super.preLaunchCheck( config, mode, monitor ); + } + + /////////////////////////////////////////////////////////////////////////// + // ILaunchConfigurationDelegate2 + @Override + public boolean buildForLaunch(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException { + return false; + } + + @Override + public boolean finalLaunchCheck(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException { + return true; + } + + @Override + public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) throws CoreException { + // Need to configure the source locator before creating the launch + // because once the launch is created and added to launch manager, + // the adapters will be created for the whole session, including + // the source lookup adapter. + ISourceLocator locator = getSourceLocator(configuration); + + return new GdbLaunch(configuration, mode, locator); + } + + private ISourceLocator getSourceLocator(ILaunchConfiguration configuration) throws CoreException { + String type = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_ID, (String)null); + if (type == null) { + type = configuration.getType().getSourceLocatorId(); + } + if (type != null) { + IPersistableSourceLocator locator = DebugPlugin.getDefault().getLaunchManager().newSourceLocator(type); + String memento = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_MEMENTO, (String)null); + if (memento == null) { + locator.initializeDefaults(configuration); + } else { + if(locator instanceof IPersistableSourceLocator2) + ((IPersistableSourceLocator2)locator).initializeFromMemento(memento, configuration); + else + locator.initializeFromMemento(memento); + } + return locator; + } + return null; + } +} diff --git a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/GdbRemoteLaunchDelegate.java b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/GdbRemoteLaunchDelegate.java new file mode 100644 index 00000000000..77f554e2b57 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/GdbRemoteLaunchDelegate.java @@ -0,0 +1,301 @@ +/******************************************************************************* + * Copyright (c) 2008 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.gdb.launch.launching; + +import java.io.File; +import java.io.IOException; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.atomic.AtomicReference; + +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; +import org.eclipse.cdt.launch.AbstractCLaunchDelegate; +import org.eclipse.cdt.launch.internal.ui.LaunchMessages; +import org.eclipse.cdt.launch.internal.ui.LaunchUIPlugin; +import org.eclipse.cdt.utils.pty.PTY; +import org.eclipse.cdt.utils.spawner.ProcessFactory; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.dd.dsf.debug.model.DsfMemoryBlockRetrieval; +import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryDMContext; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.gdb.launch.internal.GdbLaunchPlugin; +import org.eclipse.dd.gdb.service.command.GDBControl; +import org.eclipse.dd.mi.service.command.AbstractCLIProcess; +import org.eclipse.dd.mi.service.command.MIInferiorProcess; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; +import org.eclipse.debug.core.ILaunchManager; +import org.eclipse.debug.core.IStatusHandler; +import org.eclipse.debug.core.model.ILaunchConfigurationDelegate2; +import org.eclipse.debug.core.model.IMemoryBlockRetrieval; +import org.eclipse.debug.core.model.IPersistableSourceLocator; +import org.eclipse.debug.core.model.ISourceLocator; +import org.eclipse.debug.core.sourcelookup.IPersistableSourceLocator2; + +/** + * The launch configuration delegate for the CDI debugger session types. + */ +@ThreadSafe +public class GdbRemoteLaunchDelegate extends AbstractCLaunchDelegate +implements ILaunchConfigurationDelegate2 +{ + public final static String GDB_DEBUG_MODEL_ID = "org.eclipse.dd.gdb"; //$NON-NLS-1$ + + /* (non-Javadoc) + * @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#launch(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.debug.core.ILaunch, org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public void launch( ILaunchConfiguration config, String mode, ILaunch launch, IProgressMonitor monitor ) throws CoreException { + if ( monitor == null ) { + monitor = new NullProgressMonitor(); + } + if ( mode.equals( ILaunchManager.DEBUG_MODE ) ) { + launchDebugger( config, launch, monitor ); + } + } + + private void launchDebugger( ILaunchConfiguration config, ILaunch launch, IProgressMonitor monitor ) throws CoreException { + monitor.beginTask("Launching debugger session", 10); //$NON-NLS-1$ + if ( monitor.isCanceled() ) { + return; + } + try { + // Hack until we fix the tabs + try { + ILaunchConfigurationWorkingCopy wc = config.getWorkingCopy(); + wc.setAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE ); + wc.doSave(); + } + catch( CoreException e ) { + } + // END HACK + String debugMode = config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE ); + if ( debugMode.equals( IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE ) ) { + launchRemoteDebugSession( config, launch, monitor ); + } + } + finally { + monitor.done(); + } + } + + private void launchRemoteDebugSession( final ILaunchConfiguration config, ILaunch l, IProgressMonitor monitor ) throws CoreException { + if ( monitor.isCanceled() ) { + return; + } + final GdbLaunch launch = (GdbLaunch)l; + + monitor.subTask( "Debugging remote C/C++ application" ); //$NON-NLS-1$ + IPath exePath = verifyProgramPath( config ); + ICProject project = verifyCProject( config ); + if ( exePath != null ) { + verifyBinary( project, exePath ); + } + + setDefaultSourceLocator(launch, config); + + monitor.worked( 1 ); + + + // Create and invoke the launch sequence to create the debug control and services + final LaunchSequence launchSequence = + new LaunchSequence(launch.getSession(), launch, exePath); + launch.getSession().getExecutor().execute(launchSequence); + try { + launchSequence.get(); + } catch (InterruptedException e1) { + throw new DebugException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, "Interrupted Exception in dispatch thread", e1)); //$NON-NLS-1$ + } catch (ExecutionException e1) { + throw new DebugException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Error in launch sequence", e1.getCause())); //$NON-NLS-1$ + } + + launch.initializeControl(); + + // Add the CLI and "inferior" process objects to the launch. + final AtomicReference cliProcessRef = new AtomicReference(); + final AtomicReference inferiorProcessRef = new AtomicReference(); + try { + launch.getDsfExecutor().submit( new Callable() { + public Object call() throws CoreException { + DsfServicesTracker tracker = new DsfServicesTracker(GdbLaunchPlugin.getBundleContext(), launch.getSession().getId()); + GDBControl gdb = tracker.getService(GDBControl.class); + if (gdb != null) { + cliProcessRef.set(gdb.getCLIProcess()); + inferiorProcessRef.set(gdb.getInferiorProcess()); + } + tracker.dispose(); + return null; + } + }).get(); + launch.addProcess(DebugPlugin.newProcess(launch, cliProcessRef.get(), "gdb")); //$NON-NLS-1$ + launch.addProcess(DebugPlugin.newProcess(launch, inferiorProcessRef.get(), exePath.lastSegment())); + } catch (InterruptedException e) { + throw new CoreException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, 0, "Interrupted while waiting for get process callable.", e)); //$NON-NLS-1$ + } catch (ExecutionException e) { + throw (CoreException)e.getCause(); + } catch (RejectedExecutionException e) { + throw new CoreException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, 0, "Debugger shut down before launch was completed.", e)); //$NON-NLS-1$ + } + + // Create a memory retrieval and register it with session + try { + launch.getDsfExecutor().submit( new Callable() { + public Object call() throws CoreException { + DsfServicesTracker tracker = new DsfServicesTracker(GdbLaunchPlugin.getBundleContext(), launch.getSession().getId()); + GDBControl gdbControl = tracker.getService(GDBControl.class); + if (gdbControl != null) { + IMemoryBlockRetrieval memRetrieval = new DsfMemoryBlockRetrieval( + GDB_DEBUG_MODEL_ID, config, (IMemoryDMContext)gdbControl.getControlDMContext()); + launch.getSession().registerModelAdapter(IMemoryBlockRetrieval.class, memRetrieval); + ((DsfMemoryBlockRetrieval) memRetrieval).initialize(); + } + tracker.dispose(); + return null; + } + }).get(); + } catch (InterruptedException e) { + throw new CoreException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, 0, "Interrupted while waiting for get process callable.", e)); //$NON-NLS-1$ + } catch (ExecutionException e) { + throw (CoreException)e.getCause(); + } catch (RejectedExecutionException e) { + throw new CoreException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, 0, "Debugger shut down before launch was completed.", e)); //$NON-NLS-1$ + } + } + + + /* (non-Javadoc) + * @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#getPluginID() + */ + @Override + protected String getPluginID() { + return LaunchUIPlugin.getUniqueIdentifier(); + } + + /** + * Performs a runtime exec on the given command line in the context of the + * specified working directory, and returns the resulting process. If the + * current runtime does not support the specification of a working + * directory, the status handler for error code + * ERR_WORKING_DIRECTORY_NOT_SUPPORTED is queried to see if + * the exec should be re-executed without specifying a working directory. + * + * @param cmdLine + * the command line + * @param workingDirectory + * the working directory, or null + * @return the resulting process or null if the exec is + * cancelled + * @see Runtime + */ + protected Process exec( String[] cmdLine, String[] environ, File workingDirectory, boolean usePty ) throws CoreException { + Process p = null; + try { + if ( workingDirectory == null ) { + p = ProcessFactory.getFactory().exec( cmdLine, environ ); + } + else { + if ( usePty && PTY.isSupported() ) { + p = ProcessFactory.getFactory().exec( cmdLine, environ, workingDirectory, new PTY() ); + } + else { + p = ProcessFactory.getFactory().exec( cmdLine, environ, workingDirectory ); + } + } + } + catch( IOException e ) { + if ( p != null ) { + p.destroy(); + } + abort( "Error starting process.", e, ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR ); //$NON-NLS-1$ + } + catch( NoSuchMethodError e ) { + // attempting launches on 1.2.* - no ability to set working + // directory + IStatus status = new Status( IStatus.ERROR, LaunchUIPlugin.getUniqueIdentifier(), ICDTLaunchConfigurationConstants.ERR_WORKING_DIRECTORY_NOT_SUPPORTED, LaunchMessages.getString( "LocalDsfLaunchDelegate.9" ), e ); //$NON-NLS-1$ + IStatusHandler handler = DebugPlugin.getDefault().getStatusHandler( status ); + if ( handler != null ) { + Object result = handler.handleStatus( status, this ); + if ( result instanceof Boolean && ((Boolean)result).booleanValue() ) { + p = exec( cmdLine, environ, null, usePty ); + } + } + } + return p; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#preLaunchCheck(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public boolean preLaunchCheck( ILaunchConfiguration config, String mode, IProgressMonitor monitor ) throws CoreException { + // no pre launch check for core file + if ( mode.equals( ILaunchManager.DEBUG_MODE ) ) { + if ( ICDTLaunchConfigurationConstants.DEBUGGER_MODE_CORE.equals( config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN ) ) ) + return true; + } + return super.preLaunchCheck( config, mode, monitor ); + } + + /////////////////////////////////////////////////////////////////////////// + // ILaunchConfigurationDelegate2 + @Override + public boolean buildForLaunch(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException { + return false; + } + + @Override + public boolean finalLaunchCheck(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException { + return true; + } + + @Override + public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) throws CoreException { + // Need to configure the source locator before creating the launch + // because once the launch is created and added to launch manager, + // the adapters will be created for the whole session, including + // the source lookup adapter. + ISourceLocator locator = getSourceLocator(configuration); + + return new GdbLaunch(configuration, mode, locator); + } + + private ISourceLocator getSourceLocator(ILaunchConfiguration configuration) throws CoreException { + String type = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_ID, (String)null); + if (type == null) { + type = configuration.getType().getSourceLocatorId(); + } + if (type != null) { + IPersistableSourceLocator locator = DebugPlugin.getDefault().getLaunchManager().newSourceLocator(type); + String memento = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_MEMENTO, (String)null); + if (memento == null) { + locator.initializeDefaults(configuration); + } else { + if(locator instanceof IPersistableSourceLocator2) + ((IPersistableSourceLocator2)locator).initializeFromMemento(memento, configuration); + else + locator.initializeFromMemento(memento); + } + return locator; + } + return null; + } +} diff --git a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/IGDBLaunchConfigurationConstants.java b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/IGDBLaunchConfigurationConstants.java new file mode 100644 index 00000000000..fff7667d916 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/IGDBLaunchConfigurationConstants.java @@ -0,0 +1,7 @@ +package org.eclipse.dd.gdb.launch.launching; + +public class IGDBLaunchConfigurationConstants { + + public static final String DEBUGGER_MODE_REMOTE = "remote"; + +} diff --git a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/LaunchSequence.java b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/LaunchSequence.java new file mode 100644 index 00000000000..624517fad07 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/LaunchSequence.java @@ -0,0 +1,233 @@ +/******************************************************************************* + * 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.gdb.launch.launching; + +import org.eclipse.cdt.debug.core.CDebugCorePlugin; +import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; +import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector; +import org.eclipse.cdt.debug.mi.core.IMILaunchConfigurationConstants; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.concurrent.Sequence; +import org.eclipse.dd.dsf.debug.service.StepQueueManager; +import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.gdb.launch.internal.GdbLaunchPlugin; +import org.eclipse.dd.gdb.service.GDBRunControl; +import org.eclipse.dd.gdb.service.command.GDBControl; +import org.eclipse.dd.mi.service.CSourceLookup; +import org.eclipse.dd.mi.service.ExpressionService; +import org.eclipse.dd.mi.service.MIBreakpoints; +import org.eclipse.dd.mi.service.MIBreakpointsManager; +import org.eclipse.dd.mi.service.MIDisassembly; +import org.eclipse.dd.mi.service.MIMemory; +import org.eclipse.dd.mi.service.MIModules; +import org.eclipse.dd.mi.service.MIRegisters; +import org.eclipse.dd.mi.service.MIStack; +import org.eclipse.dd.mi.service.command.commands.MIBreakInsert; +import org.eclipse.dd.mi.service.command.commands.MIExecRun; +import org.eclipse.dd.mi.service.command.output.MIBreakInsertInfo; +import org.eclipse.dd.mi.service.command.output.MIInfo; +import org.eclipse.debug.core.DebugException; + +public class LaunchSequence extends Sequence { + + Step[] fSteps = new Step[] { + // Create and initialize the Connection service. + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + // + // Create the connection. + // + fCommandControl = new GDBControl( + fSession, getGDBPath(), fExecPath, GDBControl.SessionType.RUN, 30); + fCommandControl.initialize(requestMonitor); + } + }, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new GDBRunControl(fSession).initialize(requestMonitor); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new StepQueueManager(fSession).initialize(requestMonitor); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new MIMemory(fSession).initialize(requestMonitor); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new MIModules(fSession).initialize(requestMonitor); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new MIStack(fSession).initialize(requestMonitor); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new ExpressionService(fSession).initialize(requestMonitor); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + fSourceLookup = new CSourceLookup(fSession); + fSourceLookup.initialize(requestMonitor); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + fSourceLookup.setSourceLookupDirector( + fCommandControl.getGDBDMContext(), + ((CSourceLookupDirector)fLaunch.getSourceLocator())); + requestMonitor.done(); + }}, + new Step() { @Override + public void execute(final RequestMonitor requestMonitor) { + // Create the low-level breakpoint service + final MIBreakpoints bpService = new MIBreakpoints(fSession); + bpService.initialize(new RequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleOK() { + requestMonitor.done(); + } + }); + }}, + new Step() { @Override + public void execute(final RequestMonitor requestMonitor) { + // Create high-level breakpoint service and install breakpoints + // for the GDB debug context. + final MIBreakpointsManager bpmService = new MIBreakpointsManager(fSession, CDebugCorePlugin.PLUGIN_ID); + bpmService.initialize(new RequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleOK() { + bpmService.startTrackingBreakpoints(fCommandControl.getGDBDMContext(), requestMonitor); + } + }); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new MIRegisters(fSession).initialize(requestMonitor); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new MIDisassembly(fSession).initialize(requestMonitor); + }}, + /* + * If needed, insert breakpoint at main and run to it. + */ + new Step() { + private boolean fStopInMain = false; + private String fStopSymbol = null; + + /** + * @return The return value actually indicates whether the get operation succeeded, + * not whether to stop. + */ + private boolean readStopAtMain(RequestMonitor requestMonitor) { + try { + fStopInMain = fLaunch.getLaunchConfiguration().getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN, false ); + } catch (CoreException e) { + requestMonitor.setStatus(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, -1, "Cannot retrieve the entry point symbol", e)); //$NON-NLS-1$ + requestMonitor.done(); + return false; + } + return true; + } + + private boolean readStopSymbol(RequestMonitor requestMonitor) { + try { + fStopSymbol = fLaunch.getLaunchConfiguration().getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN_SYMBOL, ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_SYMBOL_DEFAULT ); + } catch (CoreException e) { + requestMonitor.setStatus(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, DebugException.CONFIGURATION_INVALID, "Cannot retrieve the entry point symbol", e)); //$NON-NLS-1$ + requestMonitor.done(); + return false; + } + return true; + } + + @Override + public void execute(final RequestMonitor requestMonitor) { + if (!readStopAtMain(requestMonitor)) return; + if (!fStopInMain) { + // Just start the program. + fCommandControl.queueCommand( + new MIExecRun((IContainerDMContext)fCommandControl.getControlDMContext(), new String[0]), + new DataRequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleOK() { + requestMonitor.done(); + } + } + ); + } else { + if (!readStopSymbol(requestMonitor)) return; + + // Insert a breakpoint at the requested stop symbol. + fCommandControl.queueCommand( + new MIBreakInsert( + (IBreakpointsTargetDMContext)fCommandControl.getControlDMContext(), + true, false, null, 0, fStopSymbol, 0), + new DataRequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleOK() { + + // After the break-insert is done, execute the -exec-run command. + fCommandControl.queueCommand( + new MIExecRun((IContainerDMContext)fCommandControl.getControlDMContext(), new String[0]), + new DataRequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleOK() { + requestMonitor.done(); + } + } + ); + } + }); + } + } + }, + }; + + DsfSession fSession; + GdbLaunch fLaunch; + IPath fExecPath; + + GDBControl fCommandControl; + CSourceLookup fSourceLookup; + + public LaunchSequence(DsfSession session, GdbLaunch launch, IPath execPath) { + super(session.getExecutor()); + fSession = session; + fLaunch = launch; + fExecPath = execPath; + } + + @Override + public Step[] getSteps() { + return fSteps; + } + + private IPath getGDBPath() { + IPath retVal = new Path("gdb.exe"); //$NON-NLS-1$ + try { + retVal = new Path( fLaunch.getLaunchConfiguration().getAttribute( IMILaunchConfigurationConstants.ATTR_DEBUG_NAME, IMILaunchConfigurationConstants.DEBUGGER_DEBUG_NAME_DEFAULT ) ); + } catch (CoreException e) { + } + return retVal; + } + +} diff --git a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/ShutdownSequence.java b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/ShutdownSequence.java new file mode 100644 index 00000000000..4ddab9e913f --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/ShutdownSequence.java @@ -0,0 +1,179 @@ +/******************************************************************************* + * 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.gdb.launch.launching; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.concurrent.Sequence; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.gdb.launch.internal.GdbLaunchPlugin; +import org.eclipse.dd.gdb.service.GDBRunControl; +import org.eclipse.dd.gdb.service.command.GDBControl; +import org.eclipse.dd.mi.service.CSourceLookup; +import org.eclipse.dd.mi.service.ExpressionService; +import org.eclipse.dd.mi.service.MIBreakpoints; +import org.eclipse.dd.mi.service.MIBreakpointsManager; +import org.eclipse.dd.mi.service.MIDisassembly; +import org.eclipse.dd.mi.service.MIMemory; +import org.eclipse.dd.mi.service.MIModules; +import org.eclipse.dd.mi.service.MIRegisters; +import org.eclipse.dd.mi.service.MIStack; + +public class ShutdownSequence extends Sequence { + + String fSessionId; + + String fApplicationName; + + String fDebugModelId; + + DsfServicesTracker fTracker; + + public ShutdownSequence(DsfExecutor executor, String sessionId, RequestMonitor requestMonitor) { + super(executor, requestMonitor); + fSessionId = sessionId; + } + + @Override + public Step[] getSteps() { + return fSteps; + } + + private final Step[] fSteps = new Step[] { new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + assert GdbLaunchPlugin.getBundleContext() != null; + fTracker = new DsfServicesTracker(GdbLaunchPlugin.getBundleContext(), fSessionId); + requestMonitor.done(); + } + + @Override + public void rollBack(RequestMonitor requestMonitor) { + fTracker.dispose(); + fTracker = null; + requestMonitor.done(); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(MIDisassembly.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(MIRegisters.class, requestMonitor); + } +// TODO: As Pawel about the necessity of this step +// Not clear on the purpose of this step since the next one does it also +// (stopTrackingBreakpoints() is called as part of the shutdown method) +// Besides, the run control is already gone so removing breakpoints from +// the back-end is bound to fail... +// }, new Step() { +// @Override +// public void execute(final RequestMonitor requestMonitor) { +// MIBreakpointsManager bpm = fTracker.getService(MIBreakpointsManager.class); +// GDBControl commandControl = fTracker.getService(GDBControl.class); +// if (bpm != null && commandControl != null) { +// bpm.stopTrackingBreakpoints( +// commandControl.getGDBDMContext(), +// new RequestMonitor(getExecutor(), requestMonitor) { +// @Override +// protected void handleCompleted() { +// // If un-installing breakpoints fails, log the error but continue shutting down. +// if (!getStatus().isOK()) { +// DsfGdbLaunchPlugin.getDefault().getLog().log(getStatus()); +// } +// requestMonitor.done(); +// } +// }); +// } else { +// requestMonitor.setStatus(new Status(IStatus.ERROR, DsfGdbLaunchPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, +// "Needed services not found.", null)); //$NON-NLS-1$ +// requestMonitor.done(); +// } +// } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(MIBreakpointsManager.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(MIBreakpoints.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(CSourceLookup.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(ExpressionService.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(MIStack.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(MIModules.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(MIMemory.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(GDBRunControl.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(GDBControl.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + fTracker.dispose(); + fTracker = null; + requestMonitor.done(); + } + } }; + + @SuppressWarnings("unchecked") + private void shutdownService(Class clazz, final RequestMonitor requestMonitor) { + IDsfService service = fTracker.getService(clazz); + if (service != null) { + service.shutdown(new RequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleCompleted() { + if (!getStatus().isOK()) { + GdbLaunchPlugin.getDefault().getLog().log(getStatus()); + } + requestMonitor.done(); + } + }); + } else { + requestMonitor.setStatus(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, + "Service '" + clazz.getName() + "' not found.", null)); //$NON-NLS-1$//$NON-NLS-2$ + requestMonitor.done(); + } + } +} From 63a5c79e44e6066547bf39883653ad61d7c17cd4 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Mon, 10 Mar 2008 19:57:43 +0000 Subject: [PATCH 291/834] Separation of launch logic. These changes are necessary to start using the two new plugins: org.eclipse.dd.gdb.launch org.eclipse.dd.gdb.launch.ui --- .../META-INF/MANIFEST.MF | 6 +- .../icons/full/obj16/c_app.gif | Bin 1042 -> 0 bytes plugins/org.eclipse.dd.gdb.ui/plugin.xml | 16 +- .../dd/gdb/internal/ui/GdbAdapterFactory.java | 10 +- .../CBreakpointGdbThreadFilterPage.java | 4 +- .../ui/breakpoints/GdbThreadFilterEditor.java | 2 +- .../DsfMIlRunLaunchConfigurationTabGroup.java | 36 --- .../org.eclipse.dd.gdb/META-INF/MANIFEST.MF | 5 +- plugins/org.eclipse.dd.gdb/plugin.xml | 13 - .../eclipse/dd/gdb/internal/GdbPlugin.java | 51 --- .../eclipse/dd/gdb/launching/GdbLaunch.java | 175 ----------- .../dd/gdb/launching/GdbLaunchDelegate.java | 291 ------------------ .../dd/gdb/launching/LaunchSequence.java | 233 -------------- .../dd/gdb/launching/ShutdownSequence.java | 179 ----------- .../org.eclipse.dd.mi/META-INF/MANIFEST.MF | 2 - .../command/commands/MITargetSelect.java | 24 ++ .../META-INF/MANIFEST.MF | 3 +- .../dd/tests/gdb/framework/BaseTestCase.java | 2 +- .../tests/gdb/launching/LaunchSequence.java | 2 +- .../gdb/launching/TestLaunchDelegate.java | 2 +- 20 files changed, 43 insertions(+), 1013 deletions(-) delete mode 100644 plugins/org.eclipse.dd.gdb.ui/icons/full/obj16/c_app.gif delete mode 100644 plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/DsfMIlRunLaunchConfigurationTabGroup.java delete mode 100644 plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunch.java delete mode 100644 plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunchDelegate.java delete mode 100644 plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/LaunchSequence.java delete mode 100644 plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/ShutdownSequence.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MITargetSelect.java diff --git a/plugins/org.eclipse.dd.gdb.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.gdb.ui/META-INF/MANIFEST.MF index 004856ef92b..750ac57e684 100644 --- a/plugins/org.eclipse.dd.gdb.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.gdb.ui/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: Debug Services Framework GDB UI Plug-in Bundle-Vendor: Eclipse.org Bundle-SymbolicName: org.eclipse.dd.gdb.ui;singleton:=true -Bundle-Version: 1.0.0.qualifier +Bundle-Version: 1.0.0 Bundle-Activator: org.eclipse.dd.gdb.internal.ui.GdbUIPlugin Require-Bundle: org.eclipse.ui, org.eclipse.core.runtime, @@ -11,11 +11,11 @@ Require-Bundle: org.eclipse.ui, org.eclipse.dd.dsf, org.eclipse.dd.dsf.ui, org.eclipse.debug.ui, - org.eclipse.cdt.launch, org.eclipse.cdt.debug.core, org.eclipse.dd.mi, org.eclipse.dd.gdb, org.eclipse.dd.dsf.debug, - org.eclipse.cdt.debug.ui + org.eclipse.cdt.debug.ui, + org.eclipse.dd.gdb.launch Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/plugins/org.eclipse.dd.gdb.ui/icons/full/obj16/c_app.gif b/plugins/org.eclipse.dd.gdb.ui/icons/full/obj16/c_app.gif deleted file mode 100644 index 805a1d0ab8b0dc4b86212fc35178db4d5af5a274..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1042 zcmZ?wbhEHb6krfwcs_+eBWape%5?qo83ySyUCLIum9KWISnXN4#}3>Djrk z%_5_3Pe%WqWu4|Z6Zd6L+Pk{jtZ>Tu{K@kH=C2`df zhPA8MHmzk?v(zSI^TVy1g>$z)%HQ^A&koKl8@zU}EZMzN``}*oid|2(ZLB(anBmAl zsg?uJ_U&joa>Vw~{=~DVWF{PYari*P*)t}W&dHoVt9S04&atCqmoJK4zNmEZjQ{!b zLG#YM+Ij5w?&Bvmo_=xXmhS3HZ|~f;xOv<8&TZ?fSIQpVm%Vs9|IuUdhmU2p-+2Gv zLGtap8(zOPIDGHp<0n;b-Wt7mYxDGJ)zcS6Z$6m6eiQNWv;LV!pI^SIy#DaztJj_H zKZU*fnEdMX#LG{=eEq5a=408bSIb|&?|t*3_1Vj#@4uA3{ZjYsm+!a##;@LO`1RNB z(Yw!&KRmno`Tz3|pI(0W{Qm2SS0BE-{P_9Nmp_lb{(bS~`=f9F9)J7y|K1sz?nT;i3$qHU+=kB0C!VlFaEfHjx zXCWxS!QXGyAM)q-19l;mHO(xHmy+9Er`wzTEBtWzgy1!8*QS)h$4Wjj`kqEVJg0E1 zo~h*%Rj^R$xL1#q*dG}umeeCGI+@1~oGgBFY*M|@9|fu24gq;1ivt-8i_?$pXJ6zg v{^~RH$vLua-+ug - - - - - - - - + adaptableType="org.eclipse.dd.gdb.launch.launching.GdbLaunch"> diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java index c690ec99f9a..c38adc21aff 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java @@ -27,8 +27,9 @@ import org.eclipse.dd.dsf.debug.ui.sourcelookup.MISourceDisplayAdapter; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.gdb.internal.ui.actions.DsfTerminateCommand; import org.eclipse.dd.gdb.internal.ui.viewmodel.GdbViewModelAdapter; -import org.eclipse.dd.gdb.launching.GdbLaunch; -import org.eclipse.dd.gdb.launching.GdbLaunchDelegate; +import org.eclipse.dd.gdb.launch.launching.GdbLaunch; +import org.eclipse.dd.gdb.launch.launching.GdbLocalLaunchDelegate; +import org.eclipse.dd.gdb.launch.launching.GdbRemoteLaunchDelegate; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchesListener2; @@ -48,7 +49,7 @@ import org.eclipse.debug.ui.sourcelookup.ISourceDisplay; /** * This implementation of platform adapter factory only retrieves the adapters - * for the launch object. But it also manages the creation and descruction + * for the launch object. But it also manages the creation and destruction * of the session-based adapters which are returned by the * IDMContext.getAdapter() methods. */ @@ -101,7 +102,8 @@ public class GdbAdapterFactory fDebugModelProvider = new IDebugModelProvider() { // @see org.eclipse.debug.core.model.IDebugModelProvider#getModelIdentifiers() public String[] getModelIdentifiers() { - return new String[] { GdbLaunchDelegate.GDB_DEBUG_MODEL_ID }; + return new String[] { GdbLocalLaunchDelegate.GDB_DEBUG_MODEL_ID, + GdbRemoteLaunchDelegate.GDB_DEBUG_MODEL_ID}; } }; session.registerModelAdapter(IDebugModelProvider.class, fDebugModelProvider); diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/CBreakpointGdbThreadFilterPage.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/CBreakpointGdbThreadFilterPage.java index bec7fdadec9..29ff31a6c1d 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/CBreakpointGdbThreadFilterPage.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/CBreakpointGdbThreadFilterPage.java @@ -13,7 +13,7 @@ package org.eclipse.dd.gdb.internal.ui.breakpoints; import org.eclipse.cdt.debug.core.model.ICBreakpoint; import org.eclipse.core.runtime.CoreException; import org.eclipse.dd.gdb.breakpoints.CBreakpointGdbThreadsFilterExtension; -import org.eclipse.dd.gdb.launching.GdbLaunchDelegate; +import org.eclipse.dd.gdb.launch.launching.GdbLocalLaunchDelegate; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; @@ -50,7 +50,7 @@ public class CBreakpointGdbThreadFilterPage extends PropertyPage { try { CBreakpointGdbThreadsFilterExtension filter = (CBreakpointGdbThreadsFilterExtension) bp.getExtension( - GdbLaunchDelegate.GDB_DEBUG_MODEL_ID, CBreakpointGdbThreadsFilterExtension.class); + GdbLocalLaunchDelegate.GDB_DEBUG_MODEL_ID, CBreakpointGdbThreadsFilterExtension.class); filter.initialize(bp); return filter; } catch (CoreException e) {} diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/GdbThreadFilterEditor.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/GdbThreadFilterEditor.java index eb7017ee052..cec2b7a7564 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/GdbThreadFilterEditor.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/GdbThreadFilterEditor.java @@ -30,7 +30,7 @@ import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.gdb.breakpoints.CBreakpointGdbThreadsFilterExtension; import org.eclipse.dd.gdb.internal.ui.GdbUIPlugin; -import org.eclipse.dd.gdb.launching.GdbLaunch; +import org.eclipse.dd.gdb.launch.launching.GdbLaunch; import org.eclipse.dd.gdb.service.GDBRunControl; import org.eclipse.dd.gdb.service.GDBRunControl.GDBThreadData; import org.eclipse.dd.gdb.service.command.GDBControl; diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/DsfMIlRunLaunchConfigurationTabGroup.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/DsfMIlRunLaunchConfigurationTabGroup.java deleted file mode 100644 index 7c15f7b8ebb..00000000000 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/DsfMIlRunLaunchConfigurationTabGroup.java +++ /dev/null @@ -1,36 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005 QNX Software 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: - * QNX Software Systems - Initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.gdb.internal.ui.launching; - -import org.eclipse.cdt.launch.ui.CDebuggerTab; -import org.eclipse.cdt.launch.ui.CMainTab; -import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup; -import org.eclipse.debug.ui.CommonTab; -import org.eclipse.debug.ui.ILaunchConfigurationDialog; -import org.eclipse.debug.ui.ILaunchConfigurationTab; -import org.eclipse.debug.ui.sourcelookup.SourceLookupTab; - -public class DsfMIlRunLaunchConfigurationTabGroup extends AbstractLaunchConfigurationTabGroup { - - /* (non-Javadoc) - * @see org.eclipse.debug.ui.ILaunchConfigurationTabGroup#createTabs(org.eclipse.debug.ui.ILaunchConfigurationDialog, java.lang.String) - */ - public void createTabs(ILaunchConfigurationDialog dialog, String mode) { - ILaunchConfigurationTab[] tabs = new ILaunchConfigurationTab[] { - new CMainTab(true), - new CDebuggerTab(false), - new SourceLookupTab(), - new CommonTab() - }; - setTabs(tabs); - } - -} diff --git a/plugins/org.eclipse.dd.gdb/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.gdb/META-INF/MANIFEST.MF index ec667323401..4ed8a929be6 100644 --- a/plugins/org.eclipse.dd.gdb/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.gdb/META-INF/MANIFEST.MF @@ -11,12 +11,9 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.dd.mi, org.eclipse.debug.core, org.eclipse.cdt.core, - org.eclipse.cdt.launch, - org.eclipse.cdt.debug.core, - org.eclipse.cdt.debug.mi.core + org.eclipse.cdt.debug.core Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: J2SE-1.5 Export-Package: org.eclipse.dd.gdb.breakpoints, - org.eclipse.dd.gdb.launching, org.eclipse.dd.gdb.service, org.eclipse.dd.gdb.service.command diff --git a/plugins/org.eclipse.dd.gdb/plugin.xml b/plugins/org.eclipse.dd.gdb/plugin.xml index d302c281fab..cc5d8ab3398 100644 --- a/plugins/org.eclipse.dd.gdb/plugin.xml +++ b/plugins/org.eclipse.dd.gdb/plugin.xml @@ -1,18 +1,6 @@ - - - - - - diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/GdbPlugin.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/GdbPlugin.java index 679534ccf74..eabdcb2f9ba 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/GdbPlugin.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/GdbPlugin.java @@ -1,16 +1,6 @@ package org.eclipse.dd.gdb.internal; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.RejectedExecutionException; - -import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Plugin; -import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.Query; -import org.eclipse.dd.gdb.launching.GdbLaunch; -import org.eclipse.debug.core.DebugPlugin; -import org.eclipse.debug.core.ILaunch; import org.osgi.framework.BundleContext; /** @@ -49,7 +39,6 @@ public class GdbPlugin extends Plugin { */ @Override public void stop(BundleContext context) throws Exception { - shutdownActiveLaunches(); plugin = null; super.stop(context); fgBundleContext = null; @@ -67,44 +56,4 @@ public class GdbPlugin extends Plugin { public static BundleContext getBundleContext() { return fgBundleContext; } - - /** - * Shuts down any active launches. We must shutdown any active sessions - * and services associated with this plugin before this plugin is stopped. - * Any attempts to use the plugins {@link BundleContext} after the plugin - * is shut down will result in exceptions. - */ - private void shutdownActiveLaunches() { - for (ILaunch launch : DebugPlugin.getDefault().getLaunchManager().getLaunches()) { - if (launch instanceof GdbLaunch && ((GdbLaunch)launch).getSession().isActive()) { - final GdbLaunch gdbLaunch = (GdbLaunch)launch; - - Query launchShutdownQuery = new Query() { - @Override - protected void execute(DataRequestMonitor rm) { - gdbLaunch.shutdownSession(rm); - } - }; - - try { - gdbLaunch.getSession().getExecutor().execute(launchShutdownQuery); - } catch (RejectedExecutionException e) { - // We can get this exception if the session is shutdown concurrently - // to this method running. - break; - } - - // The Query.get() method is a synchronous call which blocks until the - // query completes. - try { - launchShutdownQuery.get(); - } catch (InterruptedException e) { - getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, "InterruptedException while shutting down PDA debugger launch " + gdbLaunch, e.getCause())); //$NON-NLS-1$ - } catch (ExecutionException e) { - getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, "Exception while shutting down PDA debugger launch " + gdbLaunch, e.getCause())); //$NON-NLS-1$ - } - } - } - } - } diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunch.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunch.java deleted file mode 100644 index 95592eafde4..00000000000 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunch.java +++ /dev/null @@ -1,175 +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.gdb.launching; - -import java.util.concurrent.ExecutionException; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.MultiStatus; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; -import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor; -import org.eclipse.dd.dsf.concurrent.DsfExecutor; -import org.eclipse.dd.dsf.concurrent.DsfRunnable; -import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.concurrent.Sequence; -import org.eclipse.dd.dsf.concurrent.ThreadSafe; -import org.eclipse.dd.dsf.service.DsfServiceEventHandler; -import org.eclipse.dd.dsf.service.DsfServicesTracker; -import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; -import org.eclipse.dd.gdb.internal.GdbPlugin; -import org.eclipse.dd.gdb.service.command.GDBControl; -import org.eclipse.debug.core.DebugException; -import org.eclipse.debug.core.ILaunchConfiguration; -import org.eclipse.debug.core.Launch; -import org.eclipse.debug.core.model.ISourceLocator; -import org.eclipse.debug.core.model.ITerminate; - -/** - * The only object in the model that implements the traditional interfaces. - */ -@ThreadSafe -public class GdbLaunch extends Launch - implements ITerminate -{ - private DefaultDsfExecutor fExecutor; - private DsfSession fSession; - private DsfServicesTracker fTracker; - private boolean fInitialized = false; - private boolean fShutDown = false; - - - public GdbLaunch(ILaunchConfiguration launchConfiguration, String mode, ISourceLocator locator) { - super(launchConfiguration, mode, locator); - - // Create the dispatch queue to be used by debugger control and services - // that belong to this launch - final DefaultDsfExecutor dsfExecutor = new DefaultDsfExecutor(GdbLaunchDelegate.GDB_DEBUG_MODEL_ID); - dsfExecutor.prestartCoreThread(); - fExecutor = dsfExecutor; - fSession = DsfSession.startSession(fExecutor, GdbLaunchDelegate.GDB_DEBUG_MODEL_ID); - } - - public DsfExecutor getDsfExecutor() { return fExecutor; } - - @ConfinedToDsfExecutor("getExecutor") - public void initializeControl() - throws CoreException - { - - Runnable initRunnable = new DsfRunnable() { - public void run() { - fTracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), fSession.getId()); - fSession.addServiceEventListener(GdbLaunch.this, null); - - fInitialized = true; - fireChanged(); - } - }; - - // Invoke the execution code and block waiting for the result. - try { - fExecutor.submit(initRunnable).get(); - } catch (InterruptedException e) { - new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Error initializing launch", e); //$NON-NLS-1$ - } catch (ExecutionException e) { - new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Error initializing launch", e); //$NON-NLS-1$ - } - } - - public DsfSession getSession() { return fSession; } - - /////////////////////////////////////////////////////////////////////////// - // IServiceEventListener - @DsfServiceEventHandler public void eventDispatched(GDBControl.ExitedEvent event) { - shutdownSession(new RequestMonitor(ImmediateExecutor.getInstance(), null)); - } - - /////////////////////////////////////////////////////////////////////////// - // ITerminate - @Override - public boolean canTerminate() { - return super.canTerminate() && fInitialized && !fShutDown; - } - - @Override - public boolean isTerminated() { - return super.isTerminated() || fShutDown; - } - - - @Override - public void terminate() throws DebugException { - if (fShutDown) return; - super.terminate(); - } - // ITerminate - /////////////////////////////////////////////////////////////////////////// - - /** - * Shuts down the services, the session and the executor associated with - * this launch. - *

      - * Note: The argument request monitor to this method should NOT use the - * executor that belongs to this launch. By the time the shutdown is - * complete, this executor will not be dispatching anymore and the - * request monitor will never be invoked. Instead callers should use - * the {@link ImmediateExecutor}. - *

      - * @param rm The request monitor invoked when the shutdown is complete. - */ - @ConfinedToDsfExecutor("getSession().getExecutor()") - public void shutdownSession(final RequestMonitor rm) { - if (fShutDown) { - rm.done(); - return; - } - fShutDown = true; - - Sequence shutdownSeq = new ShutdownSequence( - getDsfExecutor(), fSession.getId(), - new RequestMonitor(fSession.getExecutor(), rm) { - @Override - public void handleCompleted() { - fSession.removeServiceEventListener(GdbLaunch.this); - if (!getStatus().isOK()) { - GdbPlugin.getDefault().getLog().log(new MultiStatus( - GdbPlugin.PLUGIN_ID, -1, new IStatus[]{getStatus()}, "Session shutdown failed", null)); //$NON-NLS-1$ - } - // Last order of business, shutdown the dispatch queue. - fTracker.dispose(); - fTracker = null; - DsfSession.endSession(fSession); - // endSession takes a full dispatch to distribute the - // session-ended event, finish step only after the dispatch. - fExecutor.shutdown(); - fExecutor = null; - fireTerminate(); - - rm.setStatus(getStatus()); - rm.done(); - } - }); - fExecutor.execute(shutdownSeq); - } - - @SuppressWarnings("unchecked") - @Override - public Object getAdapter(Class adapter) { - // Must force adapters to be loaded. - Platform.getAdapterManager().loadAdapter(this, adapter.getName()); - return super.getAdapter(adapter); - } -} diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunchDelegate.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunchDelegate.java deleted file mode 100644 index 3824fecf5ec..00000000000 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunchDelegate.java +++ /dev/null @@ -1,291 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2004, 2006 QNX Software 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: - * QNX Software Systems - Initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.gdb.launching; - -import java.io.File; -import java.io.IOException; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.atomic.AtomicReference; - -import org.eclipse.cdt.core.model.ICProject; -import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; -import org.eclipse.cdt.launch.AbstractCLaunchDelegate; -import org.eclipse.cdt.launch.internal.ui.LaunchMessages; -import org.eclipse.cdt.launch.internal.ui.LaunchUIPlugin; -import org.eclipse.cdt.utils.pty.PTY; -import org.eclipse.cdt.utils.spawner.ProcessFactory; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.concurrent.ThreadSafe; -import org.eclipse.dd.dsf.debug.model.DsfMemoryBlockRetrieval; -import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryDMContext; -import org.eclipse.dd.dsf.service.DsfServicesTracker; -import org.eclipse.dd.gdb.internal.GdbPlugin; -import org.eclipse.dd.gdb.service.command.GDBControl; -import org.eclipse.dd.mi.service.command.AbstractCLIProcess; -import org.eclipse.dd.mi.service.command.MIInferiorProcess; -import org.eclipse.debug.core.DebugException; -import org.eclipse.debug.core.DebugPlugin; -import org.eclipse.debug.core.ILaunch; -import org.eclipse.debug.core.ILaunchConfiguration; -import org.eclipse.debug.core.ILaunchManager; -import org.eclipse.debug.core.IStatusHandler; -import org.eclipse.debug.core.model.ILaunchConfigurationDelegate2; -import org.eclipse.debug.core.model.IMemoryBlockRetrieval; -import org.eclipse.debug.core.model.IPersistableSourceLocator; -import org.eclipse.debug.core.model.ISourceLocator; -import org.eclipse.debug.core.sourcelookup.IPersistableSourceLocator2; - -/** - * The launch configuration delegate for the CDI debugger session types. - */ -@ThreadSafe -public class GdbLaunchDelegate extends AbstractCLaunchDelegate - implements ILaunchConfigurationDelegate2 -{ - public final static String GDB_DEBUG_MODEL_ID = "org.eclipse.dd.gdb"; //$NON-NLS-1$ - - /* (non-Javadoc) - * @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#launch(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.debug.core.ILaunch, org.eclipse.core.runtime.IProgressMonitor) - */ - @Override - public void launch( ILaunchConfiguration config, String mode, ILaunch launch, IProgressMonitor monitor ) throws CoreException { - if ( monitor == null ) { - monitor = new NullProgressMonitor(); - } - if ( mode.equals( ILaunchManager.DEBUG_MODE ) ) { - launchDebugger( config, launch, monitor ); - } - } - - private void launchDebugger( ILaunchConfiguration config, ILaunch launch, IProgressMonitor monitor ) throws CoreException { - monitor.beginTask("Launching debugger session", 10); //$NON-NLS-1$ - if ( monitor.isCanceled() ) { - return; - } - try { - String debugMode = config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN ); - if ( debugMode.equals( ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN ) ) { - launchLocalDebugSession( config, launch, monitor ); - } - } - finally { - monitor.done(); - } - } - - private void launchLocalDebugSession( final ILaunchConfiguration config, ILaunch l, IProgressMonitor monitor ) throws CoreException { - if ( monitor.isCanceled() ) { - return; - } - final GdbLaunch launch = (GdbLaunch)l; - - monitor.subTask( "Debugging local C/C++ application" ); //$NON-NLS-1$ - IPath exePath = verifyProgramPath( config ); - ICProject project = verifyCProject( config ); - if ( exePath != null ) { - verifyBinary( project, exePath ); - } - - setDefaultSourceLocator(launch, config); - - monitor.worked( 1 ); - - - // Create and invoke the launch sequence to create the debug control and services - final LaunchSequence launchSequence = - new LaunchSequence(launch.getSession(), launch, exePath); - launch.getSession().getExecutor().execute(launchSequence); - try { - launchSequence.get(); - } catch (InterruptedException e1) { - throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, "Interrupted Exception in dispatch thread", e1)); //$NON-NLS-1$ - } catch (ExecutionException e1) { - throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Error in launch sequence", e1.getCause())); //$NON-NLS-1$ - } - - launch.initializeControl(); - - // Add the CLI and "inferior" process objects to the launch. - final AtomicReference cliProcessRef = new AtomicReference(); - final AtomicReference inferiorProcessRef = new AtomicReference(); - try { - launch.getDsfExecutor().submit( new Callable() { - public Object call() throws CoreException { - DsfServicesTracker tracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), launch.getSession().getId()); - GDBControl gdb = tracker.getService(GDBControl.class); - if (gdb != null) { - cliProcessRef.set(gdb.getCLIProcess()); - inferiorProcessRef.set(gdb.getInferiorProcess()); - } - tracker.dispose(); - return null; - } - }).get(); - launch.addProcess(DebugPlugin.newProcess(launch, cliProcessRef.get(), "gdb")); //$NON-NLS-1$ - launch.addProcess(DebugPlugin.newProcess(launch, inferiorProcessRef.get(), exePath.lastSegment())); - } catch (InterruptedException e) { - throw new CoreException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, 0, "Interrupted while waiting for get process callable.", e)); //$NON-NLS-1$ - } catch (ExecutionException e) { - throw (CoreException)e.getCause(); - } catch (RejectedExecutionException e) { - throw new CoreException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, 0, "Debugger shut down before launch was completed.", e)); //$NON-NLS-1$ - } - - // Create a memory retrieval and register it with session - try { - launch.getDsfExecutor().submit( new Callable() { - public Object call() throws CoreException { - DsfServicesTracker tracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), launch.getSession().getId()); - GDBControl gdbControl = tracker.getService(GDBControl.class); - if (gdbControl != null) { - IMemoryBlockRetrieval memRetrieval = new DsfMemoryBlockRetrieval( - GDB_DEBUG_MODEL_ID, config, (IMemoryDMContext)gdbControl.getControlDMContext()); - launch.getSession().registerModelAdapter(IMemoryBlockRetrieval.class, memRetrieval); - ((DsfMemoryBlockRetrieval) memRetrieval).initialize(); - } - tracker.dispose(); - return null; - } - }).get(); - } catch (InterruptedException e) { - throw new CoreException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, 0, "Interrupted while waiting for get process callable.", e)); //$NON-NLS-1$ - } catch (ExecutionException e) { - throw (CoreException)e.getCause(); - } catch (RejectedExecutionException e) { - throw new CoreException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, 0, "Debugger shut down before launch was completed.", e)); //$NON-NLS-1$ - } - } - - - /* (non-Javadoc) - * @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#getPluginID() - */ - @Override - protected String getPluginID() { - return LaunchUIPlugin.getUniqueIdentifier(); - } - - /** - * Performs a runtime exec on the given command line in the context of the - * specified working directory, and returns the resulting process. If the - * current runtime does not support the specification of a working - * directory, the status handler for error code - * ERR_WORKING_DIRECTORY_NOT_SUPPORTED is queried to see if - * the exec should be re-executed without specifying a working directory. - * - * @param cmdLine - * the command line - * @param workingDirectory - * the working directory, or null - * @return the resulting process or null if the exec is - * cancelled - * @see Runtime - */ - protected Process exec( String[] cmdLine, String[] environ, File workingDirectory, boolean usePty ) throws CoreException { - Process p = null; - try { - if ( workingDirectory == null ) { - p = ProcessFactory.getFactory().exec( cmdLine, environ ); - } - else { - if ( usePty && PTY.isSupported() ) { - p = ProcessFactory.getFactory().exec( cmdLine, environ, workingDirectory, new PTY() ); - } - else { - p = ProcessFactory.getFactory().exec( cmdLine, environ, workingDirectory ); - } - } - } - catch( IOException e ) { - if ( p != null ) { - p.destroy(); - } - abort( "Error starting process.", e, ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR ); //$NON-NLS-1$ - } - catch( NoSuchMethodError e ) { - // attempting launches on 1.2.* - no ability to set working - // directory - IStatus status = new Status( IStatus.ERROR, LaunchUIPlugin.getUniqueIdentifier(), ICDTLaunchConfigurationConstants.ERR_WORKING_DIRECTORY_NOT_SUPPORTED, LaunchMessages.getString( "LocalDsfLaunchDelegate.9" ), e ); //$NON-NLS-1$ - IStatusHandler handler = DebugPlugin.getDefault().getStatusHandler( status ); - if ( handler != null ) { - Object result = handler.handleStatus( status, this ); - if ( result instanceof Boolean && ((Boolean)result).booleanValue() ) { - p = exec( cmdLine, environ, null, usePty ); - } - } - } - return p; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#preLaunchCheck(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.core.runtime.IProgressMonitor) - */ - @Override - public boolean preLaunchCheck( ILaunchConfiguration config, String mode, IProgressMonitor monitor ) throws CoreException { - // no pre launch check for core file - if ( mode.equals( ILaunchManager.DEBUG_MODE ) ) { - if ( ICDTLaunchConfigurationConstants.DEBUGGER_MODE_CORE.equals( config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN ) ) ) - return true; - } - return super.preLaunchCheck( config, mode, monitor ); - } - - /////////////////////////////////////////////////////////////////////////// - // ILaunchConfigurationDelegate2 - @Override - public boolean buildForLaunch(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException { - return false; - } - - @Override - public boolean finalLaunchCheck(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException { - return true; - } - - @Override - public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) throws CoreException { - // Need to configure the source locator before creating the launch - // because once the launch is created and added to launch manager, - // the adapters will be created for the whole session, including - // the source lookup adapter. - ISourceLocator locator = getSourceLocator(configuration); - - return new GdbLaunch(configuration, mode, locator); - } - - private ISourceLocator getSourceLocator(ILaunchConfiguration configuration) throws CoreException { - String type = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_ID, (String)null); - if (type == null) { - type = configuration.getType().getSourceLocatorId(); - } - if (type != null) { - IPersistableSourceLocator locator = DebugPlugin.getDefault().getLaunchManager().newSourceLocator(type); - String memento = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_MEMENTO, (String)null); - if (memento == null) { - locator.initializeDefaults(configuration); - } else { - if(locator instanceof IPersistableSourceLocator2) - ((IPersistableSourceLocator2)locator).initializeFromMemento(memento, configuration); - else - locator.initializeFromMemento(memento); - } - return locator; - } - return null; - } -} diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/LaunchSequence.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/LaunchSequence.java deleted file mode 100644 index 240bc0ba787..00000000000 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/LaunchSequence.java +++ /dev/null @@ -1,233 +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.gdb.launching; - -import org.eclipse.cdt.debug.core.CDebugCorePlugin; -import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; -import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector; -import org.eclipse.cdt.debug.mi.core.IMILaunchConfigurationConstants; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.concurrent.Sequence; -import org.eclipse.dd.dsf.debug.service.StepQueueManager; -import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; -import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; -import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.gdb.internal.GdbPlugin; -import org.eclipse.dd.gdb.service.GDBRunControl; -import org.eclipse.dd.gdb.service.command.GDBControl; -import org.eclipse.dd.mi.service.CSourceLookup; -import org.eclipse.dd.mi.service.ExpressionService; -import org.eclipse.dd.mi.service.MIBreakpoints; -import org.eclipse.dd.mi.service.MIBreakpointsManager; -import org.eclipse.dd.mi.service.MIDisassembly; -import org.eclipse.dd.mi.service.MIMemory; -import org.eclipse.dd.mi.service.MIModules; -import org.eclipse.dd.mi.service.MIRegisters; -import org.eclipse.dd.mi.service.MIStack; -import org.eclipse.dd.mi.service.command.commands.MIBreakInsert; -import org.eclipse.dd.mi.service.command.commands.MIExecRun; -import org.eclipse.dd.mi.service.command.output.MIBreakInsertInfo; -import org.eclipse.dd.mi.service.command.output.MIInfo; -import org.eclipse.debug.core.DebugException; - -public class LaunchSequence extends Sequence { - - Step[] fSteps = new Step[] { - // Create and initialize the Connection service. - new Step() { - @Override - public void execute(RequestMonitor requestMonitor) { - // - // Create the connection. - // - fCommandControl = new GDBControl( - fSession, getGDBPath(), fExecPath, GDBControl.SessionType.RUN, 30); - fCommandControl.initialize(requestMonitor); - } - }, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - new GDBRunControl(fSession).initialize(requestMonitor); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - new StepQueueManager(fSession).initialize(requestMonitor); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - new MIMemory(fSession).initialize(requestMonitor); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - new MIModules(fSession).initialize(requestMonitor); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - new MIStack(fSession).initialize(requestMonitor); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - new ExpressionService(fSession).initialize(requestMonitor); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - fSourceLookup = new CSourceLookup(fSession); - fSourceLookup.initialize(requestMonitor); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - fSourceLookup.setSourceLookupDirector( - fCommandControl.getGDBDMContext(), - ((CSourceLookupDirector)fLaunch.getSourceLocator())); - requestMonitor.done(); - }}, - new Step() { @Override - public void execute(final RequestMonitor requestMonitor) { - // Create the low-level breakpoint service - final MIBreakpoints bpService = new MIBreakpoints(fSession); - bpService.initialize(new RequestMonitor(getExecutor(), requestMonitor) { - @Override - protected void handleOK() { - requestMonitor.done(); - } - }); - }}, - new Step() { @Override - public void execute(final RequestMonitor requestMonitor) { - // Create high-level breakpoint service and install breakpoints - // for the GDB debug context. - final MIBreakpointsManager bpmService = new MIBreakpointsManager(fSession, CDebugCorePlugin.PLUGIN_ID); - bpmService.initialize(new RequestMonitor(getExecutor(), requestMonitor) { - @Override - protected void handleOK() { - bpmService.startTrackingBreakpoints(fCommandControl.getGDBDMContext(), requestMonitor); - } - }); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - new MIRegisters(fSession).initialize(requestMonitor); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - new MIDisassembly(fSession).initialize(requestMonitor); - }}, - /* - * If needed, insert breakpoint at main and run to it. - */ - new Step() { - private boolean fStopInMain = false; - private String fStopSymbol = null; - - /** - * @return The return value actually indicates whether the get operation succeeded, - * not whether to stop. - */ - private boolean readStopAtMain(RequestMonitor requestMonitor) { - try { - fStopInMain = fLaunch.getLaunchConfiguration().getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN, false ); - } catch (CoreException e) { - requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Cannot retrieve the entry point symbol", e)); //$NON-NLS-1$ - requestMonitor.done(); - return false; - } - return true; - } - - private boolean readStopSymbol(RequestMonitor requestMonitor) { - try { - fStopSymbol = fLaunch.getLaunchConfiguration().getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN_SYMBOL, ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_SYMBOL_DEFAULT ); - } catch (CoreException e) { - requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.CONFIGURATION_INVALID, "Cannot retrieve the entry point symbol", e)); //$NON-NLS-1$ - requestMonitor.done(); - return false; - } - return true; - } - - @Override - public void execute(final RequestMonitor requestMonitor) { - if (!readStopAtMain(requestMonitor)) return; - if (!fStopInMain) { - // Just start the program. - fCommandControl.queueCommand( - new MIExecRun((IContainerDMContext)fCommandControl.getControlDMContext(), new String[0]), - new DataRequestMonitor(getExecutor(), requestMonitor) { - @Override - protected void handleOK() { - requestMonitor.done(); - } - } - ); - } else { - if (!readStopSymbol(requestMonitor)) return; - - // Insert a breakpoint at the requested stop symbol. - fCommandControl.queueCommand( - new MIBreakInsert( - (IBreakpointsTargetDMContext)fCommandControl.getControlDMContext(), - true, false, null, 0, fStopSymbol, 0), - new DataRequestMonitor(getExecutor(), requestMonitor) { - @Override - protected void handleOK() { - - // After the break-insert is done, execute the -exec-run command. - fCommandControl.queueCommand( - new MIExecRun((IContainerDMContext)fCommandControl.getControlDMContext(), new String[0]), - new DataRequestMonitor(getExecutor(), requestMonitor) { - @Override - protected void handleOK() { - requestMonitor.done(); - } - } - ); - } - }); - } - } - }, - }; - - DsfSession fSession; - GdbLaunch fLaunch; - IPath fExecPath; - - GDBControl fCommandControl; - CSourceLookup fSourceLookup; - - public LaunchSequence(DsfSession session, GdbLaunch launch, IPath execPath) { - super(session.getExecutor()); - fSession = session; - fLaunch = launch; - fExecPath = execPath; - } - - @Override - public Step[] getSteps() { - return fSteps; - } - - private IPath getGDBPath() { - IPath retVal = new Path("gdb.exe"); //$NON-NLS-1$ - try { - retVal = new Path( fLaunch.getLaunchConfiguration().getAttribute( IMILaunchConfigurationConstants.ATTR_DEBUG_NAME, IMILaunchConfigurationConstants.DEBUGGER_DEBUG_NAME_DEFAULT ) ); - } catch (CoreException e) { - } - return retVal; - } - -} diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/ShutdownSequence.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/ShutdownSequence.java deleted file mode 100644 index e0dbd93c59a..00000000000 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/ShutdownSequence.java +++ /dev/null @@ -1,179 +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.gdb.launching; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.concurrent.DsfExecutor; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.concurrent.Sequence; -import org.eclipse.dd.dsf.service.DsfServicesTracker; -import org.eclipse.dd.dsf.service.IDsfService; -import org.eclipse.dd.gdb.internal.GdbPlugin; -import org.eclipse.dd.gdb.service.GDBRunControl; -import org.eclipse.dd.gdb.service.command.GDBControl; -import org.eclipse.dd.mi.service.CSourceLookup; -import org.eclipse.dd.mi.service.ExpressionService; -import org.eclipse.dd.mi.service.MIBreakpoints; -import org.eclipse.dd.mi.service.MIBreakpointsManager; -import org.eclipse.dd.mi.service.MIDisassembly; -import org.eclipse.dd.mi.service.MIMemory; -import org.eclipse.dd.mi.service.MIModules; -import org.eclipse.dd.mi.service.MIRegisters; -import org.eclipse.dd.mi.service.MIStack; - -public class ShutdownSequence extends Sequence { - - String fSessionId; - - String fApplicationName; - - String fDebugModelId; - - DsfServicesTracker fTracker; - - public ShutdownSequence(DsfExecutor executor, String sessionId, RequestMonitor requestMonitor) { - super(executor, requestMonitor); - fSessionId = sessionId; - } - - @Override - public Step[] getSteps() { - return fSteps; - } - - private final Step[] fSteps = new Step[] { new Step() { - @Override - public void execute(RequestMonitor requestMonitor) { - assert GdbPlugin.getBundleContext() != null; - fTracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), fSessionId); - requestMonitor.done(); - } - - @Override - public void rollBack(RequestMonitor requestMonitor) { - fTracker.dispose(); - fTracker = null; - requestMonitor.done(); - } - }, new Step() { - @Override - public void execute(RequestMonitor requestMonitor) { - shutdownService(MIDisassembly.class, requestMonitor); - } - }, new Step() { - @Override - public void execute(RequestMonitor requestMonitor) { - shutdownService(MIRegisters.class, requestMonitor); - } -// TODO: As Pawel about the necessity of this step -// Not clear on the purpose of this step since the next one does it also -// (stopTrackingBreakpoints() is called as part of the shutdown method) -// Besides, the run control is already gone so removing breakpoints from -// the back-end is bound to fail... -// }, new Step() { -// @Override -// public void execute(final RequestMonitor requestMonitor) { -// MIBreakpointsManager bpm = fTracker.getService(MIBreakpointsManager.class); -// GDBControl commandControl = fTracker.getService(GDBControl.class); -// if (bpm != null && commandControl != null) { -// bpm.stopTrackingBreakpoints( -// commandControl.getGDBDMContext(), -// new RequestMonitor(getExecutor(), requestMonitor) { -// @Override -// protected void handleCompleted() { -// // If un-installing breakpoints fails, log the error but continue shutting down. -// if (!getStatus().isOK()) { -// DsfGdbPlugin.getDefault().getLog().log(getStatus()); -// } -// requestMonitor.done(); -// } -// }); -// } else { -// requestMonitor.setStatus(new Status(IStatus.ERROR, DsfGdbPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, -// "Needed services not found.", null)); //$NON-NLS-1$ -// requestMonitor.done(); -// } -// } - }, new Step() { - @Override - public void execute(RequestMonitor requestMonitor) { - shutdownService(MIBreakpointsManager.class, requestMonitor); - } - }, new Step() { - @Override - public void execute(RequestMonitor requestMonitor) { - shutdownService(MIBreakpoints.class, requestMonitor); - } - }, new Step() { - @Override - public void execute(RequestMonitor requestMonitor) { - shutdownService(CSourceLookup.class, requestMonitor); - } - }, new Step() { - @Override - public void execute(RequestMonitor requestMonitor) { - shutdownService(ExpressionService.class, requestMonitor); - } - }, new Step() { - @Override - public void execute(RequestMonitor requestMonitor) { - shutdownService(MIStack.class, requestMonitor); - } - }, new Step() { - @Override - public void execute(RequestMonitor requestMonitor) { - shutdownService(MIModules.class, requestMonitor); - } - }, new Step() { - @Override - public void execute(RequestMonitor requestMonitor) { - shutdownService(MIMemory.class, requestMonitor); - } - }, new Step() { - @Override - public void execute(RequestMonitor requestMonitor) { - shutdownService(GDBRunControl.class, requestMonitor); - } - }, new Step() { - @Override - public void execute(RequestMonitor requestMonitor) { - shutdownService(GDBControl.class, requestMonitor); - } - }, new Step() { - @Override - public void execute(RequestMonitor requestMonitor) { - fTracker.dispose(); - fTracker = null; - requestMonitor.done(); - } - } }; - - @SuppressWarnings("unchecked") - private void shutdownService(Class clazz, final RequestMonitor requestMonitor) { - IDsfService service = fTracker.getService(clazz); - if (service != null) { - service.shutdown(new RequestMonitor(getExecutor(), requestMonitor) { - @Override - protected void handleCompleted() { - if (!getStatus().isOK()) { - GdbPlugin.getDefault().getLog().log(getStatus()); - } - requestMonitor.done(); - } - }); - } else { - requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, - "Service '" + clazz.getName() + "' not found.", null)); //$NON-NLS-1$//$NON-NLS-2$ - requestMonitor.done(); - } - } -} diff --git a/plugins/org.eclipse.dd.mi/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.mi/META-INF/MANIFEST.MF index 0378107a447..eedb716dfe6 100644 --- a/plugins/org.eclipse.dd.mi/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.mi/META-INF/MANIFEST.MF @@ -8,8 +8,6 @@ Bundle-Activator: org.eclipse.dd.mi.internal.MIPlugin Bundle-Localization: plugin Require-Bundle: org.eclipse.core.runtime, org.eclipse.debug.core, - org.eclipse.core.resources, - org.eclipse.core.variables, org.eclipse.dd.dsf, org.eclipse.dd.dsf.debug, org.eclipse.cdt.debug.core, diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MITargetSelect.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MITargetSelect.java new file mode 100644 index 00000000000..80b5bc84c37 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MITargetSelect.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2008 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; + +/** + * This command connects to a remote target using TCP/IP. + */ +public class MITargetSelect extends MICommand { + + public MITargetSelect(IDMContext ctx, String host, String port) { + super(ctx, "-target-select extended-remote " + host + ":" + port); //$NON-NLS-1$ //$NON-NLS-2$ + } +} diff --git a/plugins/org.eclipse.dd.tests.gdb/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.tests.gdb/META-INF/MANIFEST.MF index 326dfb185e7..f244648c223 100644 --- a/plugins/org.eclipse.dd.tests.gdb/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.tests.gdb/META-INF/MANIFEST.MF @@ -17,7 +17,8 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.debug.core, org.eclipse.cdt.debug.mi.core, org.eclipse.swt, - org.eclipse.dd.gdb + org.eclipse.dd.gdb, + org.eclipse.dd.gdb.launch Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: J2SE-1.5 Bundle-ClassPath: . diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java index 7e86c586dec..15b239a6185 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java @@ -15,7 +15,7 @@ import java.util.Map; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.dd.gdb.launching.GdbLaunch; +import org.eclipse.dd.gdb.launch.launching.GdbLaunch; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationType; diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/LaunchSequence.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/LaunchSequence.java index 52cd80c287c..378d6e913fe 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/LaunchSequence.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/LaunchSequence.java @@ -27,7 +27,7 @@ import org.eclipse.dd.dsf.concurrent.Sequence; import org.eclipse.dd.dsf.debug.service.StepQueueManager; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.gdb.launching.GdbLaunch; +import org.eclipse.dd.gdb.launch.launching.GdbLaunch; import org.eclipse.dd.gdb.service.GDBRunControl; import org.eclipse.dd.gdb.service.command.GDBControl; import org.eclipse.dd.mi.service.CSourceLookup; diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java index 114ee8324c7..eb011ac3cf2 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java @@ -35,7 +35,7 @@ import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.debug.model.DsfMemoryBlockRetrieval; import org.eclipse.dd.dsf.service.DsfServicesTracker; -import org.eclipse.dd.gdb.launching.GdbLaunch; +import org.eclipse.dd.gdb.launch.launching.GdbLaunch; import org.eclipse.dd.gdb.service.command.GDBControl; import org.eclipse.dd.mi.service.command.AbstractCLIProcess; import org.eclipse.dd.mi.service.command.MIInferiorProcess; From 681323f895a60d95d9e9a59b435d973e9781d5c2 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Wed, 12 Mar 2008 17:58:17 +0000 Subject: [PATCH 292/834] Bug 202339. GDB Remote Launch connecting to a GDB Server works on Linux. Serial connection has not been tested yet. --- plugins/org.eclipse.dd.gdb.launch/plugin.xml | 2 +- .../launching/GdbRemoteLaunchDelegate.java | 9 - .../gdb/launch/launching/LaunchSequence.java | 183 +++++++++++++----- .../dd/gdb/service/command/GDBControl.java | 2 +- .../command/commands/MITargetSelect.java | 7 +- 5 files changed, 147 insertions(+), 56 deletions(-) diff --git a/plugins/org.eclipse.dd.gdb.launch/plugin.xml b/plugins/org.eclipse.dd.gdb.launch/plugin.xml index 4b4a09485e8..cc2a0d580d0 100644 --- a/plugins/org.eclipse.dd.gdb.launch/plugin.xml +++ b/plugins/org.eclipse.dd.gdb.launch/plugin.xml @@ -12,7 +12,7 @@ modes="debug"> (getExecutor(), requestMonitor)); + } else { + if (!getSerialDevice(requestMonitor)) return; + + fCommandControl.queueCommand( + new MITargetSelect((IContainerDMContext)fCommandControl.getControlDMContext(), + fSerialDevice), + new DataRequestMonitor(getExecutor(), requestMonitor)); + } + } else { + requestMonitor.done(); + } + + } + }, + /* Start tracking the breakpoints once we know we are connected to the target (necessary for remote debugging) */ + new Step() { @Override + public void execute(final RequestMonitor requestMonitor) { + fBpmService.startTrackingBreakpoints(fCommandControl.getGDBDMContext(), requestMonitor); + }}, /* * If needed, insert breakpoint at main and run to it. */ @@ -161,18 +262,18 @@ public class LaunchSequence extends Sequence { @Override public void execute(final RequestMonitor requestMonitor) { + final MICommand execCommand; + if (fSessionType == SessionType.REMOTE) { + // When doing remote debugging, we use -exec-continue instead of -exec-run + execCommand = new MIExecContinue((IContainerDMContext)fCommandControl.getControlDMContext()); + } else { + execCommand = new MIExecRun((IContainerDMContext)fCommandControl.getControlDMContext(), new String[0]); + } + if (!readStopAtMain(requestMonitor)) return; if (!fStopInMain) { // Just start the program. - fCommandControl.queueCommand( - new MIExecRun((IContainerDMContext)fCommandControl.getControlDMContext(), new String[0]), - new DataRequestMonitor(getExecutor(), requestMonitor) { - @Override - protected void handleOK() { - requestMonitor.done(); - } - } - ); + fCommandControl.queueCommand(execCommand, new DataRequestMonitor(getExecutor(), requestMonitor)); } else { if (!readStopSymbol(requestMonitor)) return; @@ -185,16 +286,8 @@ public class LaunchSequence extends Sequence { @Override protected void handleOK() { - // After the break-insert is done, execute the -exec-run command. - fCommandControl.queueCommand( - new MIExecRun((IContainerDMContext)fCommandControl.getControlDMContext(), new String[0]), - new DataRequestMonitor(getExecutor(), requestMonitor) { - @Override - protected void handleOK() { - requestMonitor.done(); - } - } - ); + // After the break-insert is done, execute the -exec-run or -exec-continue command. + fCommandControl.queueCommand(execCommand, new DataRequestMonitor(getExecutor(), requestMonitor)); } }); } @@ -205,9 +298,11 @@ public class LaunchSequence extends Sequence { DsfSession fSession; GdbLaunch fLaunch; IPath fExecPath; + SessionType fSessionType; GDBControl fCommandControl; CSourceLookup fSourceLookup; + MIBreakpointsManager fBpmService; public LaunchSequence(DsfSession session, GdbLaunch launch, IPath execPath) { super(session.getExecutor()); diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControl.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControl.java index ea79486a158..0e33727fc38 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControl.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControl.java @@ -86,7 +86,7 @@ public class GDBControl extends AbstractMIControl { private static int fgInstanceCounter = 0; private final GDBControlDMContext fControlDmc; - public enum SessionType { RUN, ATTACH, CORE } + public enum SessionType { RUN, ATTACH, CORE, REMOTE } private SessionType fSessionType; private boolean fConnected = false; diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MITargetSelect.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MITargetSelect.java index 80b5bc84c37..e0071c19626 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MITargetSelect.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MITargetSelect.java @@ -14,11 +14,16 @@ import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.mi.service.command.output.MIInfo; /** - * This command connects to a remote target using TCP/IP. + * This command connects to a remote target. */ public class MITargetSelect extends MICommand { public MITargetSelect(IDMContext ctx, String host, String port) { super(ctx, "-target-select extended-remote " + host + ":" + port); //$NON-NLS-1$ //$NON-NLS-2$ } + + public MITargetSelect(IDMContext ctx, String serialDevice) { + super(ctx, "-target-select extended-remote " + serialDevice); //$NON-NLS-1$ + } + } From b36441f7f901dcda1904c19c2a243089d82f17e9 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 12 Mar 2008 19:16:54 +0000 Subject: [PATCH 293/834] [220446] Updated Excercise 4 comments. --- .../dataviewer/DataGeneratorWithExecutor.java | 66 ++++++++++++------- .../dsf/dataviewer/IDataGenerator.java | 3 +- 2 files changed, 46 insertions(+), 23 deletions(-) diff --git a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithExecutor.java b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithExecutor.java index d667b2810d4..d3c392c8e2c 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithExecutor.java +++ b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithExecutor.java @@ -50,7 +50,8 @@ import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; *

      */ //#ifdef excercises -// TODO Excercise 4 - Add an annotationindicating allowed concurrency access +//TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) +//indicating allowed thread access to this class/method/member //#else //#@ThreadSafe //#endif @@ -73,7 +74,8 @@ public class DataGeneratorWithExecutor implements IDataGenerator { } //#ifdef excercises - // TODO Excercise 4 - Add an annotationindicating allowed concurrency access + // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) + // indicating allowed thread access to this class/method/member //#else //# @Immutable //#endif @@ -84,7 +86,8 @@ public class DataGeneratorWithExecutor implements IDataGenerator { } //#ifdef excercises - // TODO Excercise 4 - Add an annotationindicating allowed concurrency access + // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) + // indicating allowed thread access to this class/method/member //#else //# @Immutable //#endif @@ -98,7 +101,8 @@ public class DataGeneratorWithExecutor implements IDataGenerator { // The executor used to access all internal data of the generator. //#ifdef excercises - // TODO Excercise 4 - Add an annotation indicating allowed concurrency access + // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) + // indicating allowed thread access to this class/method/member // Hint: If a member does not have an annotation, the programmer can assume // that the concurrency rule that applies to the class also applies to this // member. @@ -110,7 +114,8 @@ public class DataGeneratorWithExecutor implements IDataGenerator { // method reads from it. // The executor used to access all internal data of the generator. //#ifdef excercises - // TODO Excercise 4 - Add an annotationindicating allowed concurrency access + // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) + // indicating allowed thread access to this class/method/member //#else //# @ConfinedToDsfExecutor("fExecutor") //#endif @@ -119,7 +124,8 @@ public class DataGeneratorWithExecutor implements IDataGenerator { // List of listeners is not synchronized, it also has to be accessed // using the executor. //#ifdef excercises - // TODO Excercise 4 - Add an annotationindicating allowed concurrency access + // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) + // indicating allowed thread access to this class/method/member //#else //# @ConfinedToDsfExecutor("fExecutor") //#endif @@ -127,7 +133,8 @@ public class DataGeneratorWithExecutor implements IDataGenerator { // Current number of elements in this generator. //#ifdef excercises - // TODO Excercise 4 - Add an annotationindicating allowed concurrency access + // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) + // indicating allowed thread access to this class/method/member //#else //# @ConfinedToDsfExecutor("fExecutor") //#endif @@ -135,7 +142,8 @@ public class DataGeneratorWithExecutor implements IDataGenerator { // Counter used to determine when to reset the element count. //#ifdef excercises - // TODO Excercise 4 - Add an annotationindicating allowed concurrency access + // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) + // indicating allowed thread access to this class/method/member //#else //# @ConfinedToDsfExecutor("fExecutor") //#endif @@ -143,7 +151,8 @@ public class DataGeneratorWithExecutor implements IDataGenerator { // Elements which were modified since the last reset. //#ifdef excercises - // TODO Excercise 4 - Add an annotationindicating allowed concurrency access + // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) + // indicating allowed thread access to this class/method/member //#else //# @ConfinedToDsfExecutor("fExecutor") //#endif @@ -151,14 +160,16 @@ public class DataGeneratorWithExecutor implements IDataGenerator { // Flag used to ensure that requests are processed sequentially. //#ifdef excercises - // TODO Excercise 4 - Add an annotationindicating allowed concurrency access + // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) + // indicating allowed thread access to this class/method/member //#else //# @ConfinedToDsfExecutor("fExecutor") //#endif private boolean fServiceQueueInProgress = false; //#ifdef excercises - // TODO Excercise 4 - Add an annotation indicating allowed concurrency access + // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) + // indicating allowed thread access to this class/method/member //#endif public DataGeneratorWithExecutor() { // Create the executor @@ -177,7 +188,8 @@ public class DataGeneratorWithExecutor implements IDataGenerator { } //#ifdef excercises - // TODO Excercise 4 - Add an annotation indicating allowed concurrency access + // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) + // indicating allowed thread access to this class/method/member //#endif public void shutdown(final RequestMonitor rm) { try { @@ -203,7 +215,8 @@ public class DataGeneratorWithExecutor implements IDataGenerator { } //#ifdef excercises - // TODO Excercise 4 - Add an annotation indicating allowed concurrency access + // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) + // indicating allowed thread access to this class/method/member //#endif public void getCount(final DataRequestMonitor rm) { try { @@ -220,7 +233,8 @@ public class DataGeneratorWithExecutor implements IDataGenerator { } //#ifdef excercises - // TODO Excercise 4 - Add an annotation indicating allowed concurrency access + // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) + // indicating allowed thread access to this class/method/member //#endif public void getValue(final int index, final DataRequestMonitor rm) { try { @@ -237,7 +251,8 @@ public class DataGeneratorWithExecutor implements IDataGenerator { } //#ifdef excercises - // TODO Excercise 4 - Add an annotation indicating allowed concurrency access + // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) + // indicating allowed thread access to this class/method/member //#endif public void addListener(final Listener listener) { try { @@ -250,7 +265,8 @@ public class DataGeneratorWithExecutor implements IDataGenerator { } //#ifdef excercises - // TODO Excercise 4 - Add an annotation indicating allowed concurrency access + // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) + // indicating allowed thread access to this class/method/member //#endif public void removeListener(final Listener listener) { try { @@ -264,7 +280,8 @@ public class DataGeneratorWithExecutor implements IDataGenerator { // Main processing function of this generator. //#ifdef excercises - // TODO Excercise 4 - Add an annotationindicating allowed concurrency access + // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) + // indicating allowed thread access to this class/method/member //#else //# @ConfinedToDsfExecutor("fExecutor") //#endif @@ -319,7 +336,8 @@ public class DataGeneratorWithExecutor implements IDataGenerator { } //#ifdef excercises - // TODO Excercise 4 - Add an annotationindicating allowed concurrency access + // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) + // indicating allowed thread access to this class/method/member //#else //# @ConfinedToDsfExecutor("fExecutor") //#endif @@ -332,7 +350,8 @@ public class DataGeneratorWithExecutor implements IDataGenerator { } //#ifdef excercises - // TODO Excercise 4 - Add an annotationindicating allowed concurrency access + // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) + // indicating allowed thread access to this class/method/member //#else //# @ConfinedToDsfExecutor("fExecutor") //#endif @@ -352,7 +371,8 @@ public class DataGeneratorWithExecutor implements IDataGenerator { * This method simulates changes in the supplier's data set. */ //#ifdef excercises - // TODO Excercise 4 - Add an annotationindicating allowed concurrency access + // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) + // indicating allowed thread access to this class/method/member //#else //# @ConfinedToDsfExecutor("fExecutor") //#endif @@ -370,7 +390,8 @@ public class DataGeneratorWithExecutor implements IDataGenerator { * Calculates new size for provider's data set. */ //#ifdef excercises - // TODO Excercise 4 - Add an annotationindicating allowed concurrency access + // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) + // indicating allowed thread access to this class/method/member //#else //# @ConfinedToDsfExecutor("fExecutor") //#endif @@ -392,7 +413,8 @@ public class DataGeneratorWithExecutor implements IDataGenerator { * Invalidates a random range of indexes. */ //#ifdef excercises - // TODO Excercise 4 - Add an annotationindicating allowed concurrency access + // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) + // indicating allowed thread access to this class/method/member //#else //# @ConfinedToDsfExecutor("fExecutor") //#endif diff --git a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/IDataGenerator.java b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/IDataGenerator.java index e3eb61bc6b1..8e54e8648b2 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/IDataGenerator.java +++ b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/IDataGenerator.java @@ -30,7 +30,8 @@ import org.eclipse.dd.dsf.concurrent.RequestMonitor; * is changed. */ //#ifdef excercises -//TODO Excercise 4 - Add an annotationindicating allowed concurrency access +// TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) +// indicating allowed thread access to this class/method/member //#else //#@ThreadSafe //#endif From 1b7b4b9e158d7f37ac90647be7ea9e71086df96b Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 12 Mar 2008 19:20:51 +0000 Subject: [PATCH 294/834] [220446] Updated the "PDA Debugger Introduction" document. --- .../docs/pda/breakpoints_1.dia | Bin 0 -> 2012 bytes .../docs/pda/breakpoints_1.png | Bin 0 -> 26313 bytes .../docs/pda/connecting_1.dia | Bin 0 -> 2441 bytes .../docs/pda/connecting_1.png | Bin 0 -> 21993 bytes .../docs/pda/launch_1.png | Bin 0 -> 7540 bytes .../docs/pda/launch_2.dia | Bin 0 -> 771 bytes .../org.eclipse.dd.doc.dsf/docs/pda/pda.gif | Bin 0 -> 182 bytes .../docs/pda/pda_tutorial_outline.html | 2204 ++++++++++++++++- 8 files changed, 2152 insertions(+), 52 deletions(-) create mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/pda/breakpoints_1.dia create mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/pda/breakpoints_1.png create mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/pda/connecting_1.dia create mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/pda/connecting_1.png create mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/pda/launch_1.png create mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/pda/launch_2.dia create mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/pda/pda.gif diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/pda/breakpoints_1.dia b/plugins/org.eclipse.dd.doc.dsf/docs/pda/breakpoints_1.dia new file mode 100644 index 0000000000000000000000000000000000000000..e07bbeef391a45bdc2419101a8f8fa12956dfe53 GIT binary patch literal 2012 zcmV<22P60&iwFP!000001MQtlZ{s!)fbaelg7@mse2Jnqn=E$G7A??451XD1+F~4a zWyz4}JbLJFFDc3KLy}*z;s`4PNnm+AL((&&k3*XI^!a%fSdTJJ{3yKXBLMrB3@4H2 zhtr$>-*>-V@&4!A-Y3r&AN9{P7Bfq~BTUS*oBo4R^N+*f)6)|OUJ{|A7zF+TBy#wl z2m&$GLc{)T&$8APctQztEx#(1iv96INh=gHdD9<@$&YCqEkduKN#$~rD2QU~Q3N;r z5BKS#Kg`t(H}ve#Jr`3sj-~ifts3fw>z<-|F5_*rvw4*GT136f3nCSI%;y7y2P|1@37EWgusx zNfd`gFgQ<-QUht~DE4ZZHtZUzAEZBhP}RB-0^Ejc4|JL_Kh#4s+6>E*z%*egPwY?f z5Iv1b=yU(A^%yJJhdqjg=P!~S;|7ppQ3g3ZRC zy9z%<0dG9|YV_xj=%c{t0`TVyz&rV@)*=w)5r}I?AO^(IF~Wh1?FJ(eY2bupfE>UH z=O!9$>I^Uh5SWb!@*iF78P zD4lVVLYysMu^x1e%KcGADHK?%S8w{fIG@;3dY(*3YR?69N@_k2Vhk`s{526`1{}_D zdotl#^0Rv1q<%?7ahC?qn+BJ@*d@W1CPCP65-gvO(YiU1=ow3*8dg4kRmi4ID{p+*u6 z9M%RT`LcXR(z}Z_8w4GaoF7S6-iTQTC9Q-KdJ!mLb@L!428Np~6Ke}}Stq70Acjbo z-6WFK>eE3BHI0{w8SF~MZQ>E9b{w*0ZH_k?ixfc4(gF!agkMt*7$a$cgmBgZ8u{aw zUpGp`R_~h##Z-1ga%Lh~`lAE5i#j4{BayJCiA4VE%lJ<}lqF!o+mR44GYQZgAd?u8 zb8XN8V=_PtaO|8|2N=tLM_GD0wtppJ*s#ndaFmoZ9pD@yR<{bD--wMXB-Kt03vDQU z?I>;vy^)CH=xIkN;hL&Pfefd+un(SG<9ao*2P_Y^aOQ+i{a*4$HP;HRa%d;TsI{MXfu9Ibo%0i z81Qgy-XI8-_O7(pgVWZb-Ew+f>KuSeXW+|@gxX9(um%ay3z1Om4ao$ii(rkW5e_IZ zbs?75g%Gg0sSCL+sS7RUp3vgGaRGxm_Gz4b3jW!FPkX_KwqrGn7%PMt7I19Lv(>O{ zv!d%j_6}CV4&fO`Q6yX-CXLsAI58=Myw-jYXYK&oz-a~a zXb1GH-d6ReEBm}5`V_siL!b7d4{OW%m-(_NX6ar?OzgDmgKdfoN)SZwyI24-8=F%& z+gTst=`tAt-Cm%Mf0|hSy3k%ARC|*(P8SsP&86wO55zc49Lu^7b*V-mX7(7i27xM0 z<>*-GEm^44V>=vbFAni`EPFLUF%#1&A}QvwLyyB!5SDg<A1)L^zIH<~?cfH*hb!2~YV1f=I89GmAln~*jTkRK*8 zR{0L-;c^{porpRhx(pDNxNnC;t;Hb>TXV!B1rD)Ux_D0^H$a3axASv7oCb-gqK74d z%(Q0DrXW)mGM(VvH^n+KI^meXcUv98=qzNkSvEa?8essXC$nZ;q;H_qL1up64lb%X uskN7XN6hNJBldY$*~V!9&{O4~GE zs<+VAVjF$M9(wl_8Lc8%gOIR7i%?qM9y9x6;&G{{YqhAA?F&0SgXe|ByxO-58Q8+! zvm@!;xq>Cn(Jc01_)x|9GV-FL=$4p^lbO?U?_%#_TUwm61@>cPB)A#`ViWhe>-nEn zNuy-1yAmSEG-%x6a?@$w5|c;C<_wm;cyWjAn-3QiOf}SWd_Pl#XcHJy8Fi=Waxwj{glTZ@*5e*N|(Ae16hYuVgBKmA3ao0=B z%3R&t#9UShKCp|4Wp?y)sz(!V9<_CO;KIB(r?5?hAS&6De30MUtw*Wm75#X zXEyQqGb#qgr;(9a?L|2Yo$`C>A|9`zqAsNNiMnol_WwYMV7w5(gg^|`U%GaCvcaRW zd24-rUC3$i-QL=8SbT9YD@WqBXNrW9b#--aUnl3B>gZzMef-FG^ClH7F(F~=oI|^D zg)ZB{?yi!G%GGJFxwnt6Dka3n$J884Fw67eCk?VtbZ&$yGQKb#C9bn{G(%S(?8sk|v)s*cnAZN=20( z7bi6xp~YJL>Xjs>LY{_~mlx&S{@xz*RSil~-=cV31A|8Al@Aj&_7f8mSA<-cd3c-% z%!v`2sC}*o#B;ZwyJA1Dn}0|hA7VQBiTKYpAS@3$=Xz{{4rHn|kW%;vXbv2xcF5cFK~Hk_HjPbu%#WB=?>rT&Csq zIogApR#Q`R<)$Yu3yUQ}5Mea`YYX|nM|$z%1>CF;@b&)v`qsqNi`|1ca$Qjr1+KQn z#>U>>-cnM5TCDI>9b)g}TM@>2@zUB`bfN$w6Hsmj;T@;=GC?_E1DTe*NJe z-#Xuus}$T{UL>pqjt$jTu@pGQbm)IzAbb1kK?Ke_)h%?z@Vl}cnQ<(kwrv0Y*Q0|8 z`$P@{s|}64KK=Jt{&VN`=%ve_<%CjgW@31_(slE$oSYmy{BQ9NR>P(|cVuPJsb2^) zGNP-!FJTF}rc*ZiJV-W&O2DC|tu0Ws!1_J>4K`!r!MHUC2M4^(`<@<(8&>fV5k22$ z{9>HHeEk|76JriV2%VmmHmkn=`0VspR8+K`v*;4`b6_q~!9=PkrYXzCn)HgjB z-^CsuY_?e|DJp)pc^ws{;^4sbL4PBGKTE_~%80 zhR!+&xF_(7i8YUmXa%Xm!}s#4S7&bU`*{{c!5&xvA+*uLEUf;*TREP#1{`bdE0~8!5}C zQ=%gf%00i!)C+ZHT{e=;{;n|hk9rNId{e{2yRCs30u?V_M0J~3jelG0j@xSdPOU19 zSzT2{P=7lWOLBE>xB&Zcc71(ngN>=_;~E!d=Y<`2_rtli5IZ|N_|D6hTtY(ROupN# z7&0<4#PzF{X{8APzYx=QnbEM2ugAkK>4tU~v~g$n|){VV^vJZUa@Mnuby z_P;CGMRrrCx-`{-?|XZ?cka*z`2@=C##WzthBP<9?m&Mhp^6JW|ll4V(v`Xt1u7Pz^&ExeW) zefq?(_$FMW@I_5(|F^wtMl?wa1 ztmbh2#3~3JJgZG7aS(eE71tsTxeu7kE^-()!97ta7;bE62#<)^v5b{xxZ?XGtFiGk ziTlC9#+X#vwdysVWHx^OPs78*Hl zmKA8Xm6er-jh@c{A6&j{>3(fRN2KhAMq0;XF85&{?T z$9I!>la&)dhsIdvTqhnF9-CQ8P+*<%*oe9X-7s!JB+wIy}Sq|dC8-G?A^S1 z6VUaH&vyfSeEbJgj03c_MC(|N6G5|K*xvO?RJEoS_{BAKEpf|qLC|jXISK|X)G|f) zzkRc^v4J}UeFXWD5kLZ~n)aVh#Z2d~3O2rZWM@v140I_1IZ>Ge@=hjFe8HM`K zVnI#5`zM}>3Ja6Ke4$tKHG;EAz;V9)&BHH+H6td!VT!w;kkFg5vaj&Ooa*!$2NUV(>CnLL-@iYiX9b%-|H+dl zKTl_VYBLjWHSB))w$$@;zuZqHO<)JWxThEcqL*^dBO5tgvKOyv&l?hzv~oAxX@b;VpMkD(WaHUKE~#3S=X* z*-x&4rb%b7XMB%0hw_vzyrgGOzUzVD;>;&0x6q{iVT*)7b^pez+pZFlZ+D=QYuBlw z66Z$!Z)7m+D`w6lx%&RuH33~(d)Zj+d-tZT%Nv*H=bhGu@){Z%Zso|<)z*6dJpC?E z1D)r`4|nvyRwJ&97ccsr9j^HHT`$(6Rxzjl4_fmNl#&<_fIM&TCy)VNbS)i8r32Bz zySAl>-^Q<14Dj9aC}#Q>KyinMl)1%*3|xnsJ#cKi6B z@#VZzWVm?K+u$!CxenPQnPaq^Dq{NeBBZ=rR{*6=eu0LPn zLgErJ=pYcnwMJJcM@qP-gy&z;BA}*Kbr~~6HicPnb0f9*x}8-@LuFoG$LOdwi(b%x z;n}xD0Ak+zqdEfV4axbX8L(WTpaMWV0#HFU_~ zu1C*BtuZ=1hK5?`5I7-~FdT83weo12>*#uW#f|H+*k0)9A*XPAgS51^>a6be*wAlE>ZEk)(z?q)u zqModb%vB~P{u?*Cm%e@YpgNkm=3gL;CQjk=n)hVSL zs_};p-@bi=dlY&3x~%Q;X$nTXe(uP~$iabYg>LVh0~Eg4kGqkq&zQKlUIM8oDJiL| z6XfQOZAgrdC!UN7Ynv<8ue(S~Ohgp-^r_@V;%5!I*w64aF@f{=ZBP(u-gU0oHdJwT z+ol(^cZY~D3t9#ct#Q+Hm-(rvsA_D+0?a2TUzsXdSgby z)<%3ZX2|2}WdC)m`R5r>2?}y@&@kLKKHt*U zS0=W6BDj#_4jAi|X-}l+6MpYIcZo+i*+Y~4k<>9XI$1AqIi8m-ahlM`NEcVv*Oiqx z`1qs|9hkJ_QLeKsNYFQh(xVBU$}?DhEOm5oadC8HVPOJ>aRhjs{uC3jvcV(|2O)Gpus)8{;JNpt4a&Ry@o!&Rv!aljp3ZmkY z5?Ds~R6;?{J^lUWJjqaHpy7X6Ta&xUSRB#Cj(PcDx#F+QMWZT-kMd~ z+SmjH2JX;vuWO?AqO~ixxDs9!aho+lFGMP*)K}ZIHvvV*|X8AFcD(|vdP!V{qm_?M@vh@?@WY;hlhg$@AN<)yUDbV6h4rN z1Tk7+>mHj{RaZO!Vh>d8(LVaa<}Nht!@gDNl>&TH3p4-RB8Z}9T|I64A8!k6l^ z^!}2cpI^`uc?N7;TpMfaoK@SY$;k$v;{(88iVROdI3gt`uC1$!Rhs|$_1@jP>kA8k z1oJ!YM2yMh0D20IEJ5*+o0cy9m>7Ifd91@z*0TYz6QQ!SpIjSX&M zScfqnU1$Y#LF-?>v_aKRO$}=U`~j5(mc!fR>tvDB)Ay>)GtlEMTJ(huR~EWj@_1hc zy>yqno$_mtr{p9bt$X&+%xuxCS5CXjefk`vH70`=ymk6zduVC}!(N`ArKP0=k{U%L zp;p+UNBO}{8Cq)C)MZY;b>5GL)k@wp;`lrteAf$kZZ zjIC%&w9jO%Bj`MWf`W^U@_8EBHlPxnHwd)Ou*F%0HLXGwIftHA{2Wv@#h4V_I%|Z> zTQ*6*e}P6bVFTdTimIx1R#s1YmHV7rbZvFj!rq=q2>mJ}V`oA-%*kHC@<^hYS}V zKL+?_f69%X@o{q6D$|~Xfq{X;-4$U0f%eW$pp2BXRll$)LAA~U4GoRkw?Bpw(l<0V zZcWvH2jPp=cKdK86X5gs@bGmS8X7h>T&Ciwh>PB*K+aBjldt=oelZ-ShAqh)J=NFu zqN-{S_#3F=?JQYYSx87o_wL;TK?&4u%&fFDO2Ezw3kzSqfSjaiqYyPujFc1j5=$4^ zoxn8tc|Xx5A2)0dU^+nR!_02rNDLC*V@jq6dN^pf&ljOei&zZ|)ABuECwm?|`5+0M z9nbuB7>*|OYxa>ZT%0^kWbO#eNBhu(?5LO(c%D4S}Dp2=;;zk-!B3uw} z84;L@H?wJi$UUErMTZk&yhTDm!7r&UXj{L4LVyr&-L~~`U>YHsf33jps(?V4;llqo zl8#ggF`P%Mz1K?)P~88K|4S@?-$w*i%#TFXNH9{STW2K}QCnKXW4>h}1u*UAyNuq_ z4??LIohwE!HhS)WK*y3~cE)Ip%k$?Hd`@JwqKgW2GDv+HCxEGvmH?BEo*tI^=Ela` zwl=`AO}(LCRQ8u1p^;XO-=c^Y}8AOl)kS)n3JfWCULIdNn2){VBw$w_#?4t4sm@+Q{S zsTmp31a})fAG*38Kox-h0C?%4-(m}D3knlr4_lIX7a3?L_n2b_D7~L;_Ao8Q`sA-EVO4GJBU zpNx!*qN1X$rsJ}ZkdWz^22QRwVFy|zHTjrWbW8|b%k2fp)^v3>BTtfD%{zB4lasG6 zE&|)8q@ofQ5<2q6ArxfU`S$HC&O&DtQJD02Viq7fF0Lo41$uYx0F4RlFb+E39_5D3 zqPF9_uzQpeIV>|NxNryrk&KMCiQn%@Y@6_9XJPAIIx(7lP z^zBxF$_8|?vr7ePnZ-Uia5L1I;}!Fu)MTl@TXG5-0J_I%*fcpk?Yp-+n46o6l!%=~ z6PkwLA{ixkANm+ck;a{e;$j$V&rYc1%*2cg472UO>kH8YbK?lZd4)*-T_M`T;I^Ql zp&1w$fUFW07G`x_Sy?$UCdS^v;)!Bjb#*m2H#cV1pDKHP$pV_J^zns&uX6~pXG4@8 zo$RS1meMmd}sApf)=KziwY-hz^=>2A|^n!M|BauyQU^;9!O zUo5nt2WP(?7ypdv&*Co_ta8DHtibpcRp%qd0Tm4|#Zd~7gOxKA*w@ZC;VKs%h~;&s zcnBkxfgp3bbNIODLmy0ljUYl&anDD<4~x${pAbOgqj<(rP)&VC1A%}!Gy%b7>Q4D! zPwxbkw3HUKa{oMv6NgR&B8O% zMJZ|?IdE=UvVms?%hJ;p;BW4vk5Z?P@50OHsil#9Uhc9w+a)1{|NFb>a zW1_~!#)3}d>gqZ-H)mXt^e*Tf2ppy+Ccuq4TU%)v8J7Wr1PeejW{#ci>#hwWdf{M>@z7*JN;2X~` zF+-07!DQtX&D{DIi~@xPJTOdJH@ELYLmG5GQ1cbhKrJ?|9Q!dxgvnO2qZ3{{}rh^YH;>XMvDg#sLJDHCmw-%!3WCh?oSo-K)}JIEz+|3 zC2vO%WDl=_)+PN0_LXE-;lHVFN0j3)EAX0WL`^$J=%@EfPAFGc5S_?wk~eAXQU`1b z9w_#yC46M%moF~Bxw{ukEtJj?E5H41xIit;1te}#ataCqKqRjKWeQSpO8-e|t3M_F zZxO-mQu7p|MEIitA)y)ZO)R;PimO{lE2Bwl+D?aLfQ5_82CDA*x|N-ssYKC z@&VFO@4`Tk9nrY2^H)nrNPf;`+UVwi1^GJ*uuWsND(HLi1JnXC+)e-lGoD}A>2C7! z^3u?>^z`&}bX*k{reHePf&lUy?Cs$~m;eW-E$nX&>NuaTk_rZQ=$nfFL@AR-7?=pM zZ|4x9I$hEzL7#rz`H0kF?Ndg@kw_7mls@uvsoxzNE70Vie}MYq(B7P;3bhlFswnI? zl)%}dE4(+I1Iisx=tI;;#Jpe+8?nKC!QoP z?_S5ua6xH$djVgvFbh>w81@w$vD*r*~Tn#tvQX%wW^xZ71Hw}YEAqR>8wK(!*3lj{Qh z$=Q4|^cn3kAeSSFLDC1L1KF)|Mj9^1!~_{E$XpDKJDn7;@;W&>#Kkk2UbNKkAk3nU zbf~sd@ez^6@ccOMHP93k9$e<{yQh9ml7mGJJvP{&qzdHL0^Upws?VlMoXI|7Udy<#J|K!ZR(06F6L z_?V)e7;Xg-#4!Fs8IH!<+Lsc0o+;*GX8lLCh$aaC?Gru~{;j{!wc(I*u-$nDt<(hC zdWvgoa`M>F(A$+=50MOY=E>K#saCCji{vNj*hjt4(V=mIO&Jj#&F3nCj+}3vWvsEQ zgRpJMMI9fu-p?Pj_*-JL_%|J#4*n&cqy3y>`6ZoCjE}!dc6s=)V$7yOS2<@8!~o~* z*;cUrFfcGQHv;}9ZVsk2o;L<9ssP%9ggSR}8CTZco^#IwSt>GY66+aycY6;|Cc4-{ z;4Lp-I&?-}UUbZOH<8LX{~D{6=n}M==&(ti-hie+CMZzg4H7`T0-jaO9S*MD&WIdG z;_x}Ey9dC=W7mu$F+y+0fi6lG`~!Uu7*tj9_BmEvJk``^L5@iic!=kQpvj4mfMyRc=hjrq=;;2(7kZ%iF18mI7B+f) z=g_Zx(rVP;z7x=DG`k1aEq1mO1BNj>dz3M$GGkoYI}@ILS8s&B=#vF%TVtBI@VG*W zOt60M!Lyq!Q=-H(UwZ$nn1bOCdNrPuL>Bbq&vMn?32zHLi%B)@T~ANWXBqfJR#sMC zUc#y)uY@~*!T>wQ@M=LIBC;q&DtNCe9%4GxopAac_J9V?q?|OnwszP_VGr-CrK3aC zk?&qUh=U&)sviRN-MlZQ+PpslLJ4c$oQ$cd6+s}OprX2acmP5)F*h%Cbv9f8Q@dSXNp9cIQJ*lt!6 zD@BcsKA;nUr=^*%te~a_K_WVyw}IuLf&i@|VLG>{mV1){o&(1Q9hG73gP zdok$fRKl(&M_?#Th3Mwi~JMORmnc3J* zfQClp%Ok5TjG78=INwcXo0J2_;KbU}QS@)FQh2`jZ0#>bknRT3RFK zNdAujrJpnD#W*z*4t;qBR&AqoMM+0mBM@fwE6w`gW8W^n7o`b?F8o*|X9$GL^cy`d z6=aI}HNAYfJ&+|;n@ug^z73SwD#AcZD;@;ng&nxkw6rv^ts{rEInzKPfh7rnncc$^ z$WnpjC&RST$J_b3QG(t)G(k^C z2R|t7a^n=D6@(NN6Xr-GJl|a};N-p@Q?;Z3%x2$wnouaHcuDtIG24Zfm!Cfqk`xdk z0$Ce^2n+|l%e|MKY$w49@CHx&;g^rG{ERC(uS3bokf5|epJ|`5(kOC)R-Wm5#9~Kz zi?xNqzCofP4OVyyHX;~z9*-`rn_A2_4aE1vM7U_tv_h>%EUZ}jk6%JfN#(b{SL@IU zv7!^#ym4I}osdKjL!jWul%{|N4ewq2`ow*NF0$3A(Dqt8Jo-k9!E8_v)xg<2x9}Hq zyo@Y{i6fp2J2HzG3=a`IwQ}zBx_^z;K6lBdCkwyvuNh89uOSm^?&YR z3%LGVd-X|t{Nn1W``L+yXy(l1P`T{U(>8P-y#;uQRc+ZG4@oU(`0SngM2fo_Vkt;}J3K0YOdyn1W>`p4CfDCb8$S~GDnX-Ibq}BP1n1XTivRF zVm;r?1j<`RMO{C#g%FDTQZg5pY4Lutet*aXiskin@+((jCZ>3`jZ~gV_uyn@XM+a$ z0NTBP&-brW(9>OnreI6=`<-3)kZWhZT0@0>Yzp9Je(B}eBt?3Ra7{_yW-$n zjo_*3;7iLjm%D@h9AK7l7x^c&tz{F)@MXCKEvd(b_!Qcx<%>t@n4X zJpMEq^{I5V;)LV(ba$^o zIg$2+o*>g2-{5`d1ghGPDDY42SLiO5LNEAN9N2yAcN%!&|`w zka@x11vx~jse^F43{0G~^mK5oKwX12Uo9x3Sb(!HD4(wiZQZCX_yPm~Jl`9Z&#uUu zg_s#Pb8~;3O&;g6+lRZl7fUY(?wd5-AjE}Yu864~`w%Tcj1c;xd2iAnMDjqrkC4uW z#Xamh6PDC)b4TNbc{=IzNOAHb%RA0s2ZE*SaeQFw<#h~YK}J^guAUxI>!V*8ogaqP zcW!xqgi8aJv6fI}ctU#@LS?Wv>)m(g&P3^&Z`rmINJ3|TzP9XCS4$hiybb9|FwntU z4mAMlXVOc9_1XBu#6mREuLOY{OZw;XeC){;LQAP*R>dYcC=S8F!NBt1lgx|ZL3SU^ zRakWtWMuLM!-SIX;lZ?kRl${Q-#8#>oU?nlCWt_~m1}-ixg0Z!|?eI(C#lgmgZ-HO@^RV9!+!@=k zS4*&DWmuc#GI%XDz_w6VSBG{6DN9gz!-$x)V(@5r;buYmE7Prb`{6^`>({SqYsvVT zt<_2hJ24{L=Ad^(QVAz?Ex<*y>%HE{i4h&Te}<0I8aKvWZGQtZgLh|dPgzC9=lhgf z*lU^at;m0yjMZ2fTFxH@HA~FUKhC5$@2`(S>8yVJ+SA>A^3B5@APWtyh}L09ecFSy zHun}Syr!gY1z;O^eso9Fglkqf!35;caiDfW_VJw&*S!XJNZ}A;qeaPj0WrA(;jy5g zAmArymmq=K91hqO`g>b54{Q_Ym(rd9NugC>p{psfa3$e9_Ko41<^=Eu8pqDT!97UM z1fb!}FD&d=kRtpKg#gz=Q!7wOU7nkBTpPMNdV%%YH7O}6a561;Q*v@1$jOD2IiUv= zQc)S`=zNE?V4Z$+$btNy;`EOYdwSW(!t(M@j8b*_)8pfwVE$}uY`}9mOOT_B1q|r| zpSQSVgao&_;~#=J!2~qP#Anaa1sv(lx7{!PcH_!*XysF#TW)4uYY=Y~b6$>IAMj7X4kq}+3k)rwPx>Dgy1jMwmx#Z^ z_a`Sc=rP2!@{rs^LU&&4Qr+=$h|s}F+3byeTvM z2uzazgn~59?1i)K5HU(IUvEg@v9q(ozz5t+h`TM?f~*G!>@^sT@Gp6}xoI#DawWp* zgAixKW1Z`@+^mBNQmJ+qO8bcb<5qq$^rNcrE-H(Pj8s-r%M^6Zx4I2YNQ4?cW-)+( zm6J0jI=a)o>+l3xKcEDFTM($jt8fc9tA~nEGwm6nTkW=Wue#4w@hU?>ZGF9%$2VzP zmwhNKkd`)H#b#ft8N)*$3X4P&)Q@(mcpk5W&m7^;XT(Li z3CUd6ZH$DmifuXMQ{+*v7Pf{IiN0ILU)3@~mjLZ?Co79cya)_L8QP9Z1X#2+Q3D;q z%c)L;nVFe|#S#c0CM_7rv9XUr(11jot>(l)TH>&q$hRKyAn*Yo9IvVh>1-g5qE3tQ z&d!yosT3h?hqHnBp;UnTvCEy@+zgw2Zw@9aA2X?)hx5C;Ev>CJnTf&l;kTP)=HO`Z z`d$_l)%T^mIRi|@&CM743a3BS5@~~3xvU*xxP(d0UVP+KZ^Y<*TXK1Xa@d?hdnDd3 zru3Hw0s<*+P|7S;J{D>M4usr%Bu z&#XU*d%@oCnBp)BJ`{ky{ey!H9#ch6&o|>)Vu#*m5aikZY|2LR1@<2(51s76fLQ76 zJ&yL)?o^t2czVJ>%<(U!;Bf09NyI}~nvm`Ggp^;J05?pnkcs2l%knDD8P z4dq{=1V%rhyergc035I}%%Lv`Z3VphBt&g>m8$#WEsr=<{-lX)ez;dO)Z$V=tNmo@< zP+(zWW6;36BH92^bbzFEkF(!Gym}uRXh%m!Z8*uLOP1rY<6k7Jed*p?mAhQU>uoW! z-Xg_((EyBb0Byt7; z?aj{3NfZn}J4njR>^I?on*8a79;DQBisThN-v1>>V+FIk$L)Q5G#fT~-+Q{j1BM+S z3`PGDCWQQevbYDB2C2i%02%|LkI91v3tL-;T3T8#7G>iNtD~@x8Bi%>TpcuWFp{Gi za$w<{`x8J?u6kgn0=kFN3NYxLbAu=ZA6tM*je+>$MPplANb3Q$|K34rSjhepAWObl zrk$5<<->>)zt|`9=tT}2!~xG;<<-Oy9e+L&!TA6-ptcN{P1u$m=}dya|r`^l|gqKBus-@CigCm0{Y!@aGY!qy_YHP*@hV zK_QBYijp^d$0p)jJx;Gdu1yE?fFNOkl9wU$a2?kAv+>(T0z{Qk6z!{w(o?nGhu@&> z!83dk8%ucc;w$40>~D9&v0?VYKu=GpEE^)^#ShwV8ImeK{-m|3UEYpF$;soo|B*+M zr`p0%}|;G%v*=A`Ddn zKQuXwE{y{hf8Pf1S($aqmB4BDV zl&A1oK22C+Dm<$rA|L?GNJ~S*X>%O#D?$=f3FzNo3fX*q`RGRx>Z9zpz>rx+?^UPX z(kCt6*JK)5JqWN>cr&u%|?9_H5!+C!35y9`t=FOO> z$PELZKd;WuOWtDOfd}xfVaH_2tQJ4UeGfk6gh32vZYm$tU$9%geWbq6OFxSOGM+^GqElTD73&N>Tg^4Q}Rhboo`25)VV|Req8Dq6iTY5tv<& z0L|5asX|+jMjs}#BuS=!nla)qE7-zYfGMsFKwZARP5Eq~ipM>BR_*oO&d={B2u!EP z-^=e*qL;%ME@om6l$c`B1V9FZ=~?X=YBDmY+a1~2bn^uY01aSyd_Oo)Ra6`YTJ`j* zlEV=Mvmu3Cb-xWABGVUOKYo5GQLT`t28szdJCwq%Y`&efuAAc!KLqNDhJj%S&>fHu z2qe1X;n>Y4-B00vL55_GH6<;rln*2Pi)4{69hLTR7E(6z?*5;kRBh>B36Lw35F;BN z8Uj@rwmHAsSN$~k>1B9bKqJOnWas+Lmlrk6PKfRE4h@Y~XeX}yjqhTNrPsJZIS}L_0;EVyNavEv^~2$3vlveXLVStM1&J$T#>@ zGHXEYQpd~(sPyNvh@m_B5Nn%uUx?mLKCg1o%M<-o&WXub9LZiTUoq$Dyo-qQby_47Ukbxv2AndL*w z5wWbz5^|wPMu<>hw8_#(jEf`}jFDJz$)1K{D4|RnaRCPtJzR_fZUO04Vp38+kTezh zACBO4NS1cA-82HL*CI8?{oCf(u776%bPNop0D-DDMEs9@{#|uiM_jz+Ilc~k98Lz? zL5$#YEJu3vH&iV;^y)IWRZ=H7`>42AePm_O3%8+eUcGwNor`qzjueQnj4CNEAXW48 z^FzNb(pq0zQz#wP@?Cec48VwnkhE6)?Q&QZ`r9S}@2>DohDJ$lUeQ3eD?&0um1O3M zxA;lc&9$FK)@$0IakDtE4q9Tms1JEeTYy$D^H9*d0X*{JvNB&77uiwzmbBqMo0NRr z9PfuNy7Gi$1_E7dlbeK{>4-~Q!M~2?CoevSp3yyKU$p|)_bH+)6@%>It@=ll+4Ah+ zZa#a1a=>;V^^&NV2fs4mBS~>PL^id?6*RG2XeqDqpN+XI#cih~#-#}nGAD~SCn~!{ zTc7&Ej|i045iyj4z%scXu4@H7fk|3WzWH{DI_iNj9c2DISpgNn%GMUb*)cIOT~abM zLoM9UTH<<^05qUexQs0N+L~)H`)V1N&dBS%5~XJ{*%1p|CsjJ`i^n_ez2ko4dTh!A z|K@mfzsNuqhW+UxKZWZ-C98oL_)t95@7}eFZ?qP!p&F3hWYF&~P7H(&)qrvQf)noE0E7e&1^B<6`95(AjIfN6>iq-TwDh3?ABHP z);l~xU~1w~%N3Dts}N<0R|x>FvGmPp}YeU#>d^gs2f4 z;qn;?LITjzDu-D+ILt`dnT-VDBGY58x^1C&DM+Pd2$Fi#%yzQGHBN1lOLMYV!RVXT zJnd?zn5q7z5bE5pe51FvaE9k5i$I{?Cwgf@Aadc311AcC3^8eSo*RNln|L#PAht2C z2c!^#G2tb@AOuH!_#d1{>uC1$FlD%09eXDLi=F)X0x606U8ycx!ni3+RsKrSX-=F; zYTo}5kX#OY<|xMRWB~?G9>V0O(;JPw2QQ5FFd*Qz!er$@@oqT;4@BRN!_>;^#s)CD<ajd}k%#+W!Ps3Fc>5BK+b3Is{-Px*)jJJ8UF}3QvcWN+E>-R0*U| zmp3WL&W@0QxHSlM`U;TTv@}qyfV`<1P>-HM5I#RQcVnW4lZ`F1e}##G;e22d4$r{M z0t*B5LlRQbiLtTKk00R=&AT6jQG_laa7`g>h)cq|gnJ>F()J-{T(=2KU#e(n5&Iq% zh@GwhmVyZBG3CM5j2I+St7C~InK?P_VaOSnILziuRa@&g!ig=|cXV}Y{eGT-x<2;# zGXPbv2rdy5&uah0N(O+7qCXKsNKwNARjjTrvukeq{~D4(4rX94xQ%K8vSw>*YkA`V zx$hwissXqF3C=Q83TBEr#`&k+19idamxU&P!1nlUpAug1fDw(N^75{de|eb@EP_WR z;dTwd3xP&y7T=sI8^ph6Y8;zEVs|C*8<*Veds1*j7`MQLnN{To&jMCi%4EeFG#5rU z)^)&Bqq7kbKGl%4qmKEc4EiQf11m5H5COmo0!73fe0vyj;r;Oz!L@fDZG{B$p8+OW zOvv8+KB;9kqLNKVhjPRDD#sg@{ZPg8pPKv`-;^4@ z=i>FFg^SlGv5lVD78KF@tpR9&ITqVNhHeH}1k-xbm|#CmH~FLrBr9@OSNxCP2LusI8?{dbb+;T!#-y!Uf=y;-q>kdrg2>2czMwWff52kbC7Zt_y6;+JL+R4BLr%%fc%e6*Ci?Et24LvvcIu@{n=Vh>VRm}zJx0wM#jvmE~la_MaH!MuYB7a7!+ z^J5yohJ}Qkq{V*=yIa7HqNSy^YTg9^3%d}mWDd@UfW86YP7TYzezBk4U{Hdb4YM(j zTo$;sd9P&vJ?1%_FaRgY+~WR{e+n)k$GwImi`$h114HFEr*7LvtYezajrNw>N0PjK zTT*x?o>@R^4Qt?hQ$g+!f-EpS5@kSX#4^i5jA(HZ-{u|pZ>Jxy;RLB85K7N|zbY6t z!9IM}*@e>50wxh5-yE6++;ZHj=aKj4UW)XFE%eNg`9@ZQ^K6a+7MP4VWO#G0NX%vA zTCG*jl&wEsL?C=1sUCo9M52K}@0XNhc0zp+fE0yAf`!;c>vPSIIH34FS*hL|VE6JH zt`mw;cd)pj)BICjR|y0{7QHo2p>2jAAORR3$%9=R)KArL{2#GA4C09pH+jNM6w&bp zruu>P!ZrraF@k7Er0I_U8ebETWtakl11})t1*2Nqduy5v;r%QBA?A)x74==_XL;ot zSR(@27}&2Okn`)$@PTmAIx@<2W0J&Yb?|9$A@N#j*bJ))sToeH0eKZpih4f0hDrP9 zK@VgiwlDuB=a1QidqmYb-1^NWWlB2LBvy z1?!IJ(j{otJtjPEo8$Xn@e-D7cl@c@cCGydj-KQ^LtC`l-BpCT@ItAB z-QO`|UAEhnmVlc$B@3IHL}B!^t}c1iUNvVBPKE>Y@%TC%#RS^b>UXN4KTh8`&B&h# zRKTh-*NC$z6rJT>GTyt>_pY%Le04BDUzC=HR)e?>@-ARG(B^oOacOxW;cyZe(qRl( z1LSxUXktE~LH%#&O!^CjhvA4|9F7Pi?%uqCklim?7qI2RSeh12sizAu69yU1E!)sX zAK{1&XRezO9xZ+wt`8r=`g@W|O$b=E@XtA`S&}zk8bS~fq9Ei^%d4xO2L~VVbFi=+ zLLw>b9oFvu&S+uM#>(^BO$wx~f~z&M9zyUIUhZ9ME0P#O)9G&oHBbPfg|5)H=lbW& z!Qy&~US~#a#YgfQ8c$*P2*$b&y?vdXcVP};(Mhn5%j!A^Q;=1y3JHND&iJQ&k8LM6 z%7TPekVxIRo+mcme?rf+kkBp(_z@ij1mI*a&{jsv0II-|S8(FQubEWu^2k4jRoj<9 z#B~MC3Wr)a;hmpiz{|(?rnZ(QC`p-7Ft*#|pr#k%7|oDWfy@OQuLfrb938tFC2L8M zkcZiQ&toy43RbZKEC&b*j4Fr%(*?o6U)~Z01Vo^#K=Xo7P(Gh~_PaZlxlh4)ePYi7 zs}JN1^3QXHc`kNy6b9w9A{2n^&BTA1=<)8vxeWjAlXE|8%G7~FS2$J;_P>w z!1S{YIq(u2vG@Vd$KSjW>zrF*Uub#2E@Es~=R=NFUo$Bl_zb}b2)aXk zS~@y*C1%je5=%zRf5=i|62^uAJ1C2)Yb7^tYB)K~;OhCf3hfBg0&rLv(&YE;3*zJk zX6NNyLRrJN9jH`pRru(T2cfDPd=|e+-rJd720J@o0sMz|TPJXHe?~>EO{Mw||2}me zdV;#=Tof9w!=3IMtJj(B3l1is`p*uQUBna^%n4y1;?SHwa9_BjN?Ke6ynyB=IyucT#X!_*3jOi9(%= zyChN?mP)Q!WlN$sQaX^KG_AS#?Wp0GC6<`jkA#cvW(}Dnz}gs<+FQrF07KDvC&H{! zOQEs9m(^Qwko-;l!IpZ_?qGtcSR#x2rND!`7R5pRYa6HP*`6 ziT8eUdi!qB^+pzRWCj>Fplr-FSa<<>Wix{VhW}YXr~}4mxCm(V(1an{2__9hT`k~P zWv@)zmzd?n?dR6Av=oYOML}qX31MT$_tjM}@5{*Vz<5sxfNXBUzfGq{{}7)bMt{}`D^HC z+76JWB3cS_a%72I*~cPG#=@B;C2vMXQk^Qw%fA6f%K;s!h9Yl)i3$4`Fr!#*P|^?Pa#?}ysty>E4J-G1(J@+O18ta9m`w9_$WmsxLX|Rl90F1NorF;aGZ}$7u85fN=AoS57q1HinhY31;==io5TO%3)y+U(x z#FE-Yof!NDn+v}0a${)y+4S^c*p3uaworEG?oT^OCz$JE-5^9;!5(6;$FkIs7_||F z2xU5yc!z&fgJfmAp*oYG^5C4#0bcE_EM)b#LVK<(!|R9W`$;TLdqk!%#Di^$U>Ldx(dHud=x*^1zBuzBi{ zO?{2PCO^2FPKiQc-|foJs)POh1RPDdW7zlaR&Z|^8uIPQHNalJ3h_C@)3q)mbVg^T} zwE~ugl#s|91QXD~aNmAX6B2p(CQF31mOoN2!pYke&=I)=giAwRx&>wDR-v zkQv4I33l_s%t0H!=i$-z~ z$}9K{k&^}UEz;9uuU;XQHXi%C^%!;NYv>_TK$`Hi9cM6>32<_be*OA&bTm3H&i?Zx z$uYuhF5a!Ja)ir)L^|=J_`c{hMdzzT8sGG=;^R3NYM^rSfz~j#kQ-hGFY1bSL7fyJ zO*9ColnAdkNg$;-T3LW`^TQ{^hjgNm7i|L3<#(I zTyCsjbx+nLT(+B8k{S2Tmte_P>k`UNt|!gjiHVtq+aOKf%-Y)8++52 z@Hla7(E?*MVXg?jnfPGqz}3VA14AbLXuEV}U(d@;_kWo#*q`Mg2FDKO$zOkko7&DU zqo$_DQre*{u&Y>D9mpD2DWW*g7a_MfcMdD?BwHN;qpa2T(jA>r#1ZJ;bs8ZnOS_d|FZlYlB%`qK)($S9D^T6y43K7EnuY~Cm=g|1XJ@JSR@#PP zRGOZFa?I}AMv}<&Rz`?3xHHTpX>Yl|SgTE0i1NQ{pR03R-8`pvB}gP?ySB52Aj?E} znQ3;b0kYe)nZ}YmU|~S(gOMbwC6Z=1Sj7yr9}Zc7pA1z>+`Q7`BUs)BTQ>`foyy|j zvfEnTyeUab3!E2$7ArqD7eg?2L?bFkvYdUm;ZIG*;!UPoNS%oNAa!yy73|+n7Z}hy z2K5;O0|QKK$l6TIeHEy!rNzX;V%PRWM^h6~jjkRZP+dF&IqEgyn`0b^mwXLJW65r-f0p~6Kvx19wzeOzs)4@8 z2npx5wvj_ZGJH!$>Q24~k=cPLTPgEL<4}i(d&(blIvtP9@Zg&_VL;>IJQQH3f4c(xhYw@Smn z&(A6=r{l9ZnEy9aJ6x2>0eA?=nNavz<@;xlZ9>!L=+q$Xl2v>at7MGVJG97`VlKe(-K)@hbbT#yN_w3m- zQ`_H<7*a0PlOi$TBTS~JrgG$GG}1)G2oSVunU%GT7w29;(nzO)q*RTiqZRQU0d6x# zS5#f8>I5T&8XA~FEKK(7u|`nI-xf_1lf6&?83{->HZPCVn$82 zCC7yHu!BUi1xkSo&A8F}g4tA9;pph7zNMuPv04LgL~*;ar>jzB2Y`$4u0o#9gOids22kJF5J#?D6A8 ztcAdPRQRnansiLz@GrvCcY+Z)W*F%)RVwX1h~&Z633v*XWMt+btvp0+0~In<<6i^2 zsDwni^fl;cpy^3I?gb6V?>)Wf^tj%eZA(z~{s;=Xa^(t?f9nu%*4L|6SRxFg1rG>j z4{^OWR!?1t^vh+Wx9n2%n8u`;eU)qXxTF=!SE5$0**9}V3Er`k)|ks=QrQO`xPLxd zs9%uS>RVpJWcjJ1Tw6~E1#zf%bEGhS5DWUJ<~9G!wum*}PS#W|YIA)}FGB<8=@e{o zu&O2WBTxgSFYK}dW;l3hU+gQaluwD`{0*1bX;@k9IvlRS_sC2VjZGyrl{m2y$RKNJ z2|tio1lir}tV@=vr`Fe*7I>U(>xNkOL{hnw0)MkX5u9c-Os?hL>rO}X+M}9obR?3h zao>4*BkJc4Tfe36Pw@N5y+Tx1rDe%k+<>0mEw~HI%9ihl8$I7x_l8a0(D1|5R5SH4 zvKIA{kNvj3k-FR?4oVW>4)#}L8y6SpxPtQQ%TAb-5O2w?<>ONYpom)OA z-$~3f`u=@g=lr8Dzn7h_to9_mpx2R(w>x`}!QDqcap#i5mwTq)j?ltHfly9O`3HBL z$~zu7U=wRI??57-@DC9VaG@IZ*fT6y7?ppb-yELJm>b9swgYa|Dve&`VC=rVq^;AG zzn=TFt@^{Y{Fy(NPui2u%quPx3G}xd{68b)kK`@e<~K#TbZucPDZ8d~qeBssVMQ z_wqpx5Pajtn<4T?4Nv&B5UPMgPfIJSLx&F0>IuI|h5L=>vFdNb-mvg(8T$!JJNy`= zgLV!MZ`s)SST=Ng{2Exlz~A^%H^G>SVbf01N^o!Fzh~l^%DH37@!fpvpozE zGHQtq3k&}c0uFeSqc=Lnqr$@#p<9n=gvpGBoxP*Ieg9zlIN$$MXxt6s%c(5eNt(&MP^Ea5;2^_r|D1U%d%t-*`U!xh| z!lmPBBEUNXiC85O|8M4M*OG|p4mAJYL~Z)bSY{H1gxkQE|AqRbfGxzIB#~rD_)FF+}gC6UyHf-J778QWv(5QhM9K78i_^5v`VG1|~rs*kh}sL7u1KXpw6#4rcncKMKZQrfIT>C;g?=N^YD) zN$NcY(QW_TeevnvteUymXs4#_c`((ZR0m(Gn}+72)G1BRb-LZ`Y@TGH5y_wDJ0cbB z*xxT?R#KS}il=w){zBg^FKKmP-B#I!Rw~J7K{^fNT|H)OqUAtfATh>fFqo1G3M$a| zF*#n{=(6gf%c@H+t1irj^CZpFAk24Fj*=wOLA=zOrwe_$o@^XMW{TByt3faB!#q#+ zT>pI#WruWNdH9F59c#JMG@R5M?uJA~D^KAhe;9tP8!iYiJAK5K3ZC65cnq^}6zQ@) zgmJ#qK$|!Je4ggF?@@u_>(d*~iDhe*i^N1~rrGg}#B>o(bhc-*ZOT-%^so}U**EIj za)%Dg^3c|jU8snHXPvH^|8>1sd#f9~!krhRkc|GT$N8#zpYkA{1nI>Ybu#8)zzHHxM>cWSrh5*9$3!jPE=0=R@AOf63qfU*G=mH`;v zOc-%V0-E&cko6xoV;B3@e*!RJSW$!orvfs0q8}55vEJ7e2oT)-pa#mU-7jjX$2J-q zqvAe{q61WH#-Xo~-4tV0EHKpo0(YVar3=KhuHbKM$%a5~nGtoph+__jU=~i%2AuvG z7IJjCh5SAW=fj624ZoQQ6-2cbzZLsFT8&w~?R0Fe5!64?OggekPxG>DeY$L$! z!i8BW84w5<;n+8SrINyF9HC*?4hkbk00~E2NWqolNI2va3~(w1rjk?4pn|84-W%l< z*B>!?1DxVFJz7ksI`w{!r>3`ERN%~n0s~{I+{Y3ShG@qqIz~~QlF;8mo&LjEVF|Bb zjbjpYNo|Gw<1#csfWX)&l0Z<12WGuj1Pb3!Ye~?FA&QayHZ1ybLJvy?t(>ZrDVWNh zc95Y?OXG%&h(=L)I~%fNR+-Z8j-oj6WEiAr@>H!A6YF)nz+t@Aq%K2VmM&~v&^hshH^vj< zzlZLzgm8#_2#jYU2NptvKsF936c#R_WVdr=FyfQi?>RsQM#y%pQhChb- zOCGh?8!ro1GOx>fIY-3px!K|2)m5(iO(!#L&Kg^cN`txnmV{*)DAgFKP!S$+SyygU z7^D(DDr(EI08l7mLq^hR2}`4n9g=-&nA>t!#M+gubSb8{7EiAratO92ly2-@5@`?% zNW^FnN|&U-Ne(%0P06v>`=rh9zbB)P$vJ0oRY{PJ&$YzARgV4J+Oz;_yaVcc2^|FD zpnN0)`=pw#I$f%u&8dQ|a6dXG zRiIucXoec^=)%UpiQ}*t2aFS8_1L(X-Revkp+2HT-0b>k*5}}h_I^amdft7S%)BC& z)`ia86Rw>J+HtL`i=7>SRLwVi3BYVs5s*&7iUG!} z`+4H^CaW6M4y@eA`Ag<#hga8(SM}~1Jwvd+c@5*C6&YAiWusR_P&B|8D8Z;Lv!v#@ zONXthk7c5^P<3C`XHh-cd25}wR^zQzS9e~ox7NJK90SCB?7GeY8qTAL)l)cZm;jE6 zv2O}QD>%?c9jrM}FV)%H+)15v{O1DOadzit$A8+(e|T$hc?dwoZ7I8?oN{bI3mQIT zsVLW*;RISm7RZah+Vbx%JU z?%##Mox6o)v$AsxTUfP(o4>H4`MP{4(_xC^qC8tDIxq^2pD2sHECRM5XZO3sCa?Ef zn9YNH{Lt%mvs?nGRM_7ejKCMB%=5`j0&xMapV`j$NQ^bdW8AU(&PT?-*xx_+D| z=f%r4uuuamfnoyL8HkWV?RlC(x3lhYFJsxAl^sOADnu>+FW!uN*V}k?@?G!$cj<2# HWPtzxg1*PT literal 0 HcmV?d00001 diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/pda/connecting_1.png b/plugins/org.eclipse.dd.doc.dsf/docs/pda/connecting_1.png new file mode 100644 index 0000000000000000000000000000000000000000..b07c13701a92e69b8a1613e18e3afccfb29dda01 GIT binary patch literal 21993 zcmb5W2RzmP`#!E?hX|QjS;-OEBReZQ;gFqCNV2j=W@JS64B6w@ds9Torj(hTy@lWH z{r!Kxzwh|`{{P?q_2}`S$>jqT0>2N=rYY^3=9k+CB=IWFfcAfVPGI4 z@euGzUloBO{J?aSQF@4nhxcPfeHsIU5ku*o^h4K_KR?|J$erhKH@W?8=3l=RUx+}2 zQa&)FdJ=3&|C@}?GU@|$^rHXkS1)hfq)(KX*)k7~ZLZ8!_>yj@|60M78R2&6*3GDt zG>)8?$QONlo1lU2+o5biZ=tiW%i4DV%$eVZoiL zP2`Nl7%0+HlNY2f_Xjm~bl6<3Vz8)Y4TKnC4WlunBuG#gjI?-2j3^>33XEH!KHNZRW-Rpcq&8LpJTb34`<&8(}%u(J@eS8&#laUrkzSqK*L|z+B2ZuND zyTkmKQu)IoR`#@ii$~B)cnS*$?EQG&@@%9a_H1)+bxb{35T4w=!8?JSik$pia`KOQ zXPYaFc>7sue6wsg)+i}FrgX3U3Ai!B!B7(3XW#k#nQ&sW(!GzDC#=%<4h|T2Oj>n~ zy*@~O7n<_qvmHnK`uaviMI9arSXxwwaki3v;`LiD~? z@D;kGJC8s1CGrtmzASONJG8sIdwOy(v|%@nW)cvn%E(~knTB%nH}#gbGQ86hOvCPKI!)7yFi?yin_XSz0-167-jG0&+-x1>z@4(JngajS?}B# za&>)u9j8Lfe!8{MZD-+2a(sGvi`U7%vCnDjmqsb_T9!^$CZ>SHqa(vQhpwKU-N@)A znaWoj@PeW!ws|UTtC@e zmTkF$kH7rAYV}u>hq3!It4#OHDX+0A8{J#Qgej6f61Q%B{{8_|lM(GpB17*s|CWqh z?ag(O!2)#wAt6d~@&p^Y#TB8ol$4a{=;%Biv$QNY&eET^obDg*t>(8LAI?RRk&+fA zaqqy03O~kR3TWILeY84STv%EvMAdBCffJ-27!A#gi)iQ>KxT zk%vEGv>iS7C#(t!3oFVm4wyI#&jE$ypA83Pk3YQ${?X{v%78^dBGWyjE-7x_9ksNy z^ybYQkAwA*v9ZPZd6gvor$^hr3Dc7VY;^A5|D4EYMMFbFf7dlCG4bdl?Q?WuYH8`l z*4(Er7Nc=ok6?iu^>Vk|b=}NpZay2%*NS0NrIGY*ta5a6a=I?*{r3}t&)=<23@z{s z3%8d@Nl6#Jrh4oy4Sf9gady_M{)Xkw;3c1LOA+!1=RMus+9Rz-qtDBcU~Rk5)_O(yUckaLMpR9Sx0vD>df@C{mO7YESe-FA(Q#} z*(rnPrnI+rb7W*c>}w;BKLQJG`7z`)Kd+)7?CE5aplVsL{(pqJ|I3K@fAzLjZrJy| z{TQt{-bZ@oA+{KC_aspo9SGTnv0CL~L7ic^jSi#@7>xYO1_&|XX;1voHrDs`Xcf*& z4gt4bI}MVVU-J8K+csJeT}k@#GNS?>a%5oHY1SxYB2l0=^dTQs-2KEbuI4!m0cJEV zLixk>>(>MNuh=bytZ6Y}#nB{+4Z9T^y-47$z4ed_D{kdmo2mVHSgcOo%}XA5$ZG>F zgyiMX?ZzxjYr{BxA1IDBEmCy;{-#tvNFBKM?BI4F`Uqh+Ed zv~W1yF$4shiN8}ya^_5{FP9aR;&F?($HsMQata-q9^ z{d@JZlRmzFgIarO-@0BJgmQ`bfD`Lo8%{lTwUm&su#?RWVn}MqX=(Hfuqh5-NDwIE zF->_L{M_l6RBy^zUx|y0lh_;9Ds4FvovMfvr|XV+BbeSQS7q(O-MHCqmF^{fezcsM z-n`jPuQ>mCe}Xq(RUtB?fC$Im=cU(yQILW~C_KoKD<*7gAT&x#xP_Vg#Mo$G>kO zW?NZUSXf!B2v;d>+z#~?;h+<9LEgG$mL{jF8m^WL&p+g&N?H5(Qv^0P_VB85{B7s8@jK$; z;%sa|G~3^8N}r9R{Y;O`86#8apKRafOwIG_vTUXkb;`@j%Q!E}%X>1_EG~Z4|LFs6 z2=UkHE)E9wB_^2=e}DhFx2h3G+r8Y+C(7k~Dgo-Wx3@!d`}4CQ{x?#kd6anS<41XR z_S|Hl=k;}UBg4ZFb#)sW8m8)$})O`Ju_w+_twVL&CTbDCI3pDADtddDagrb zmZqkpSlig-j|m6}>C58zFv~;? z5{+myx~y#LVm<`od)|hB`ujWH_{NPJy9D{h3Gqhm%UO{Uyg~$K`9ZM>3BuOHd7nRj zhE+1t5!|07pqxAO=SNNHOV~vo2WRlXrO1SoW@NYRhAy8-+T%_xp58i09W}b8Mz9V7 zqR!6_T6QVmNTK}rFWU91T!gr6l8GUy5+uB_6bsx zrpnVt_CIMbKcN$;l`&{OfV$PHDXkim2JjKQXvhd ziF*tV4t}qBzA-nq18AY_`un`Ro1&ui&wf-F>sQg-F}r7B!Md04bAB=fqXJPTQsVfD zkrBOsgO}IoqvuT{0GnY&j1=l>VP2pBm^Lvnv6GXN=f4^!erdC@;vsw9PItX)A4l6! zavOOh{jgUNF^52|4w+y0Kef%u5YE=gqmf?0fkuE7tBAF)?I&`dI_y6ci6i zcXoF2Syu)>^uoRLtguxySsuWo7++xHWhC z_H735LsKWGO2a~>`}RsVnH)sEUJFuv90w2#M)jXt?$UOXkE9oOUKxhTf|w%qa-C;` z7$U%NSBBB<#*_~{It&Se*Y3c4PfXpd1ad}nHsYW-AouZ43`xLOkksPi;(j%Ii7_$x zk&u#+@j*^0C@6q|h7nIlpenhq{pisu%*^cU0|SHW3=I8u9c*pa03|J%X<$A!GrMh2 z`wb4r6vM-v+HEY-hlLtEN_UcFT^cBo5kma@EG#UQHe+8qIv)S|UM0$xs=kcc)wg&N z0NWS`2S-#y1RD#>cCz;E-)luU7CA=4qoWZFlD{B?_4e9~6lf1`LX>ve`1KR^Fl_$a z=PNfczoS{Cm5dvs=K_nPM_bBgqBUgfD?{Wy9e*e33~VJ$zh21l*}pFu8!N8c-c=Eo zSNWI(745qcdylb#<%%CG+i$vSmunm4ES0Dc%AVyCjo0uKS@rOc1Jfo^yykKIOz3+- zE3xKG6)dnjuUyA0_w9?O!HP>D*J*kn71nUaJT99Neb3j>*eFVG(65y=yxsc7=b*l5 zJgm5H=uf@mYCI2oTS;;Ey+sC3M=bKju{F7|DC}k5a;+~gR&>5`iY{VNpb)aSMs6g{MeRjk0_9iO{iueyy_vYSkDivL;)~TkJ;jyhL1j z2q}{-nP(owvyRj(2){1o>mM;DWlS#FdA-zJ}quyX+(ya1En7NG;bf(f;%if&xdh&JyZey{I&xquo#=4*?I%G^BNB=A0A%KHgy;gi~<}W@Y zOHS+m3$bvu$lk$kRT{%oIMHKnbEZQQ%Iumc?;i!)oYsm{&0azf)VxpK-+#uz*c7s~ zLH$1j!BS-=)ZO9kWe_yGyA>hl08)S~HpKjdKj~+~%gE~@ygWQSH*Y?Hq6i|@U5EK@ zD5wB|!|@kj=GgEsN`UP{L4ozJMmIk{KR`V_Jw3$qcQe?wfk+{w6+|*JGQtj%kT5!D z4u}Hum~?v)>Y6p9$LId5(k7TE_`!WRIxa5zP$c&?H9!sndH~SFCJ-ab%gg7-V=c`` z3$({SiD(5I4}N)E+=bV%(^!e2vD@$1ckkY1XJ_v$_NR+F7sv)*fs2nuDB)4xG3#WG zyz4O29+>WPR@dC@JyCA4d+&jk79c%dKE5B7Ph;M_yXP~1Q2>s$oK?M;lP^f26|_aW zsV2g0@!+1|ES`A^54nCh{tv!DU@qh;vn3=R*G-d^en1rhHlv>Brw0Kf;qozW-wrf+ zyj&@6c)78^G%yE15THp`@GhiuG&<@u;Ujjf&-q!aA0~XhaNx-mI#KfL*HwsG92eDG zU4>8IYG%oQNfKD?VNcIKgL-v(yzFt^_wa`&fjA?#Yl+Y$!qUYb&%Is@CjbV9iTP1w zW3~PB@87>LYsdW;PchpSwwvxWt1-kB@Xb$#=zYmT5luyXy(kyg1(5+UR#jCsAS#&t zxWXN1qkBG`U%rH&;W5p(2NGPpdUZFQ&{-ZMN}?h@AoA{ZH{<}@ z`2Y842NQwNueMdf6LDFiN><-no7jO9@1_eX@L(wVO|-fnFXsjmQj^lrrM`Xp0ulqD zHh`&0F>GAM%_$_?u-y8Sg}BAU9u`<)6;{@o1>b%KO4rqt^W!oX|27kkhMP&g=T@+zY870Pr!`7G0Jr_QESsGFzLw)9jb3rG&29wqQqW|O^qjkAOiT?FeAP3A)H z0aT`Nkm4)^H7Vh4UNI(gk#8KH34U8AnaJMq?YE7s&3M&qX^$nPPn_ZvXEE?FwmNZl zm%maBQb;*9?k?Mv$2hO}j{Oa!cRN`B*)M)zU~g}~_%$^#7l|$W4B>I?L9l;aZF3~I z;RXBZFb?Mlfw+Ua`|;ohWp1NJ)Po0RFFrHg_9PAV7dNNUGkKli;L^- z-A1`EiVL8num7Dr-BYHe;ptEg0PUJ51DUWrf#Rfh6g&N1WplE(s_>G&|E@*Zv^$Bd zY_bSAH;z^ju|@plWqXpo4rPOAYJ}VM8ILerlbnIan{g3ZYm0^YulASMS64lts9oqI zZLV<*`!-ml|IxJV`W+Xu1YxtV8}L~OA?JXJ^^A;4hL-#2&f55Lw#$l``2M11N!E+zO5k}&hr;-1{sIvr$8>_vN*@3c4D~H{)DiG(Ai%jkhvt ztd$lszemCRjfaWYZ8}R{nYqpMA28(KpI+ms$$L6-sfdR(D2(>jgP6KN03UQK+du^Q zUDGf|GmO3$CqcD_cCO+9D||t#o}QlK646vbN+}C_Tm=b=NjB*4p}k)eh+R?V%f*xA@}va`v_$+L5E*jQOpMI7bVWR%De z1m@i0;$9GM)y4N7hEZ@q-We@1R3<7dElr0&toYCI;K2hgFL9=OSp(U*xd&?#d`P4% zAP>mlKuKLDAQ1CBkDI+5TN^*$3)bT#2$9n+%U%z?dNO8jp$^sj+s!R3#9weXfGu7vZHasLuE?M+n#Rb` zFcsihN(umrT}UBAx$5lf?A(U+56>(5=H4(!NogEK`j$u3DkLW_=#?Ls%gI6xhHaL zwJx*rRJxa0-pZ1k$%K6QYB3Nxa&mGI+Hg89Dk8%M7brbQWJ(O`c-?oG*4Avpx*&htfBD@B%yrba_V56M~`T)UVR%MpF8m6YpNJf)Y3$R`1k|XRl~vx zk@TSZum>14xjTQ$kj7d4mhl(xz@_Bj!wM@dOZ&GRX{sph7(O&BjwJ2Xm9|NgbMw$2*^5hj4d z%F60=3@&h-Zb8ouRW(RhfJU=Q&`V#@d6hQ;YHMr1J^j73G+yUuwIX0h?`3Ca2VCXK zxA&NPi?9?73=OH{Y8o3om%hCZAW2mNhOck(TD&&1aykt+zO?D_!AAPqx2AU+;U-yG zS%+5vW(~bIX#oif$p3T^$DGQ_UC3B{Kf~SK+?FXjTmv>Y?N7HEgzYl`h7H>Qj|JFh zWe={kgr5e}2IL-`2u1-Yp@on9Lgk)JXsP`iwbXhbBRhhLg#-nSK$!XYa_U16)bo%E zYjbjP>g(MHGUWya1`NKG!Jt6y1M1-x2Zz%A`)2eSnwpwGp6%}KRV5(TiVYhC;aOm*_9fhj zlspseNPy?6u>4{@)qMImQd|&p6`)FDej8U=kG#SrKwx6R`bbSmx<7{2DK%;Wb_vu# z0Hg!G0?)ozhJ=KGdIy*XWKOU7?zjIoI`0SQ#xpnGJsv4D{b5HzNjU}!0&4Xgt($e3 zv_G|VJKFuP3d*YCo51)0V^~sDMBczi`eCpkKzQF*S1_Hj!D)FLWX%_ks8}@(i3p^4 zgt;C5bLfAK`Rx31(2s9_rA^8n0Bys-Fa?1Ml**;0C%Y&t#>>vwabI$q0UcuF;Lrn4 zDk%3%wykHM&?y;Fz(3X0Vp~`j?#iu_QQt1eQTZMAiars zd*3av)r^&&e;0^KAyB4|t+7atFUBg)L2 zRZ?Qt9mPaId3$$%UvO+F>P3qplq0YNr+{*y5|xW4$gjFdyNk&xnqSOdp|O!AQoXgc zr3W(r>Jc%6#3a1!` z7KC&O%_gn&y0ovMX)-ZX%L7yja5BLG0r%wP({{C6+F-s+UwVyd{uKF?nbgq^Xk1Qtbz zf4$cQ++W!POzq|6rRR;#&JHLrRa)G~F2N0apDBopLRd^Sx9%}QNpC`s%t`*w?I~x8 zc}w}pJ~0&ZZ3=sS>oiAfpM9Em|MsOkPIN%$StkCUs`8*O>@0vba5b7paS*+mbx}n{ zMNs&pswp%T4lUn+eGn|8A|Y+Iy>)e^2&$_*O5ouAaf$bLcEUnJGU(;sQ@_zOHkS0* zUxSqm2h@zm$L`W&*eLuFPCq6zVLHLlLh^GENj!j1U-=0u4R}XQV@lowtk+v}%)>|3 zMMZDi-@-=|5`grt1w|4>htoRRH+5!Rp}>{`(+4@BDm&X81poG8JoL2!-B;2kZ!Z{p zz4Fenu^Px?ph};BL~QKwrwWQ}tqq8vr&VJ{d_rsjp71fC#URmuMhPn-WeaIwU;wkG zsjdBC;0f%@FB%EwCoSiX>Ybi~qJCFgTuVy}(rm|ac>!I`wHpsh1A<$52Z~34>U9F@ z5qL+S=2xK*1^Yo}-JSfIkCBm7$P-HS>UPxf})hVsS zaHaqSM-@rR?O`qTKa+J@xkE(MyqzN>v8F15PykAt|8j`O%Mpg#|S#*5l7Wu$BchprhQoG zrocw@?m9B5-`(njA{q$J((}z=ZS^P>NC99V7{Jh!^Kx)l{4XhcIp ze79~{!=SL`NG}Hb1&~ZYLPs@vX#Afr#Jk^kbDtt3L9+kn03(G_xjDYT zow9!oznpuq4G1!Jr$YfGdQ}>KljXC%tqf%2L3mijK)|~Rs66@!6TlJ6pTCtYT z{Owc0E9Td_pfNwvz@_zCf}~3Q&?m0}ci6^mgTC|Ar$`3LGXRy4JRzWEw#?d)`m~(3 zX-_8DMrZw=p9dOb12}rt1&`+3GFzp}7U}_mvf>s0^qC*SgaBgwAaZb{(9<8oX(4`n zIL@2hSeG_5Gz6@vUuCTgMQ2%fD|;zkofD<S~4FU`c>LC>}Lq-ZI|6@6l@tG>T`N4^rqxY2yF4(j3R>MA7?wfU!Jid05E zoF+CY>3g|_^7er;Q%osW#3rbnExrjKo?2)=we@D1>B+Fv+rO< z;1CcP`Re6cNY^vZ`rbQc5^|};(R>V8gc{Y;C59Uo-2Zvn`D*I7C~GDDu{VdHdxDZN zRFjM>xh)d{Xv)Mde7Nqu2r+Vwt!{AeLAdH zva@+SMc(FBOCoVDH^1%U)Gij1;Qek8bCHJj*MAmHEj``}_V_Rn{iKBY?XlnEQ_nF4G{fcbiNr+Rvb22JgsI)vXM7G6RZ-! zL&^$YX=6#deQ{IC(b1&Wuiv%oO8|Px;GFCE^9^8V)}i(X=pWE^5JyHv20#XUFo~Bi zaWsq8c>MKq!N(>bbWv0=ywwK1;96tm{Io?d_G7k%56wa8`Y6HxHg6AVKT?O~^g25OdpR ziL?n|F0lT1L0X5?{6O1|j}Wdm((D>`HG3d~-a0xs>~Bn|8~#}BkBE_@2%@I*M{BI+&a#(Ru|_xtn9vD42aheZ4^Rv8``g>R zB4XZ@DqjQCZ*!QlYHT8z$QHbdicbBU!n$`AG;W?|%DiSlM+aBzlpA`mc4Mi_qXf;DQs=$=pRh49Behhpn zL~(pPyab?@fnan?dYd|YScO9pcxH$l^OAo2Tqan_#XBW&DYu?h$PNNPWbSJy3;t(` z8I`1cM-p#3d`zN>+;ZauVo6xvp;%SuyJYllnvx4GcE^h8IpL*X+ zpQ(=dPjxrIu2ht3=+1tqqmY{pI-*H=PJN)`_ zWu)-n&ksscQeM#gU~T%pUYa`KIeLMe)naM8jth>fgP*~`NP-6Jy*Yj9v>uKAHa`sd zp{$Qp6v-fLJ4nuaeLpAT)Bi9eiu2cF;=Zd1nz-w8OXZG=i-N@?1zjAVz#KQHrR)0> zp}@*ba}RYF?3ni=j-hi%TooNK+b|q0!F?tFayo8%y;)iCmB{kat-E&(&N)BhUb&vZ zP{uRy=1DpJpn-o@*RKX!kS(q#?zdKl@5aQ(M3g{PlN1-{vNm1@qC4!LV({91e#bHV zh%Nc5s-Sd|jeX^c&Bz)PkR34&mmLQOw4w4S&@QAvqDZKygrO7#@xMOEqMUlboGiNz zN1?D;=L`LJv@c(%UVo?_$^Pu@?D75|sDYiz2+WdTXJs4r<8o-2>R*+CfL;miJV-(C zC%;<=hCF2-X3-FL6L2dogy>E*MN^yX%lFf@&ra%zX2D@M01O>++ z+WF_b)GvRwL31+7h{pB==IoQXzN~cnX9R-a@Wv;+sHfixa4$a4LGKE0qVM?-9k}39 z2k+yy-^64fL1nl&MKxMQ<6&A(5+<@NS{g_&GaQ7>H1VJ{& zdkmKch9*ioyCw94wtX_up94b?1Y#eu6`3mX3=v{MZ-h0@m0XgQOlvIJCbZctb}cQ8 zJjRcu-tS|js4BY&V|zPVYUmP^)vXDK2q41U?VTb!I( z5ia5K9UAIwqqts!#il(=ldM^p_b{&%yZtgP%{V~RaMSXlV)$<+D&!NE%x z7w_Exh5S4DE7yYe1WfSvkS4OBeilFQFW?@)N1(g1&-%K%H#ax&h=^DNE}XPr;t>;T z$jrj%QHxR%YTjqn!-nRBD}$O2t*TQ4T1t*|U4W^XO& zyRKua(MC`d@I>o}^Ri~GO4C$JOf5CZIQVsW`v|DTfp`K$4v;U}xkKRGxpwVZ z-39W}uY4k{o0^oI45!TV*^^W|fBMMe>ROdS)MI^3^q!mC1{Lq&?9B^>q9ce1Y`%qR zxwIkY`X9Dw>37Z-o<*i>4KD>aXBzAEM>cN;?!CY3pf{)A8tex$jjC1Fsx z+z+Af1okuya`cqXc@qE-;K{8L7J%?-@8~!OXHFu$2*zc$_ku{hbd#q~deKDH5wiP{-3`k7mszf&$h%Tf$txITqL=UUc~8pZ5Zs`g#f>xgDkpgN3Rk=w+1noNN>~bD zoXLji1|)wDzNJ9!YwYN~BSvo%&4hmChX?o&X}&$-fBf+ctcL-guo#5>4{=Pj3Y`IC zL-4#M@R+uTUgKN`>nWJ$zNuIA;#Eud+`EF@w_-|F(=|5sfe`EmtP1_zLqN8>_P_3b zx|Cu`onRpH^q&K!#L>m&3L)WSxdnkhBai~Kov(q%f&;33NMHdZxVXWUm6c#+J32gE zo2X#t;wpx;DsCZqM>L7tz}mnFbhYhW&_sHlKN3+Cti8l4h@ zxkpD3BRJ;F$xt75S*z7WN9PVW_l>t8Mkn%reic5{x!jqU1VsG>W~!4(;oc`iIc|wIrjGUfO-AM z%pmG?Q&>2GBsx7^5`@_Da$dMHfKB))n2>9%M?$?}P;H8Jl)a+92vPdHkmQ_{x4~;P2~e^*uWU<=CLnbzo>{$fVXg zYCz2QOsC>#?>|gC%Oy{!-5Gdq;{0@ct2BOW@b(}}1O^vE2o5Hg*4?0p1?!me^5DfB z4YvY`ydno+o%7bMyfN4nuCuS%VG8D^r@z6%0eg|Z($Cr#Ss?g+-1z|A1lwQ}rA<%q zBLl_}GLTs=(5)T(GJ8D`KGvEL}UaFA@})YZ5a#%6b0Pi z51Rg&kdOd`9zPsHLP7!pnwVC73DN>NY%DB|XUD6Xv}@2}1A!v~zq|CoO^BfaZ1G8_^Yd_I(&EA2Qv*wx6swYyf3l45~d` zH;vaKR4o_w?gRwAJUcWEEiJsLx@S-i$}BaXB}tYGf1&#W`A0z#7P~AR^wrI$_w1Y~ zE#s@|Ub=iWjUNFhZS#6!sigWeHiJu+xLRUdR_z%IBf~)kH!g}DrIh;dMG|X4kr5=W zx>q#dstL;Q3*;lz+`1q2_0^AWe7L%)Zi-f{-S6-OkgpA{+W$x=q$Sm}e=&h3g<=j& zVt;041^{G2$n`$?Qoi*{Na{R8e0Sk8I? z93g;+AQLtp*1|q>B2xanNR4bJ0z1gcFx2DV51azmew#loB&*2(2|b1#dplJmb=Jhn zcqdjVy3BRubTp4f7XzgHSZDPD#|*z&7KncNUWbNa!vnLA6+ZY+5Gyb*96QZzSrXfkWiqUVYhU@R6hRtT2oEJnsXR>wIGDG>Y0}s-tm(wUJ_SX z(OBcy&u-H0$q;#P1wU#5wE=7)kkt|s6P*+uf@r?dTu@h+nBX=)WX7(uP~R}P;i6hN zLPK2RS5PgXd(V|$p@`rxH1u-4V_|EnRKX{^(4JrASQ+irglZHMpFUYZQ^rGu(*NY_ zef=33L|nen8Tx*VE5`8JgjC?8blK16vw0W|jGHUaK_%&VXb%jJv-2J-NMIH5n1J|9 z5`HlY9_=dqKahby;-JoHZ6@OkGOAH=(Z)i|iKFlN(8wk=WZX|1nKoZl2i6W8KA<=O zvJ?>!0fmJz;6mDb&7S7EkZ45@rVx-@ns*143AIetI|~3i0$v!lffJ@dq=O6!jZ2^z zA&nZx(^wz$j4ons#1Ca+=>VD6&>-e4i-xQYFaVfc0jBv8U1L>s^<4KZ-mynj?u*^sql5PKc%4Iz1?icAbQs{c3-j>j|tKX#Pc7p z9>ME`l~z?=BT=*D)uXf)y=ex2*d?|{@ML%l;pk151+j*a6)nAUPwE=AlFfgV?znxH z$c>@F-i#n%N5zr5b>KZpXO*+_GJ;A3qr6SoWCqLTT41VW*S2>GjGA{l z;>hc?(U}8J#%-?-6zV>_gx={6l!4+UW%wO9;ppWv?%uCuxu>s0k*dd5bCr~+i1mbq zV(_xCADt4#JRNGh$6R`Lgmd{F7Bc#U2~)AT-!GMJY;?K-Cc#ryuibE&IULvgK+5%N zp97JY%IDeP4Vr@ip|P98B(>#)NJo*t$Fev2K3v<&H33JT|c zcluv_(Qh`VMiC}#Wcg!g)R;XT%vOSR^C^O^x4$1`?0rbbOfIj@rSSbMqEv;|?wQ{y z&TetW5*q=bLy(E7t)ru3VnPInV89vwL=wPuU@UEIZ3QSH;kxO2dj!ZP<{LMFg9{>} zb=jJglTnnF?P%C&rUgwM*y^W4Y^I@Hw^^|$rrZU+TQ?FT1Qyia^(&j3TsKC@OYCTLs)tjm_9? zA0Ho?Za5Ek3s_cT`=w?iwTaucr1S>@meaan?}KkGAPOQP2+=J&UqN$Q(b^YtAhOUw4;VGI z8BBH{dbi`iJKz=wMb@YGHMDQ{VqaK?wmU#1zJR_!Hbbim zNIQH?VCwdUhiCfd0I32%?QjB3IGeb56Qp}nQ`3|EKg#Or7yfJ%Y8)CD^djsbw?Tyf zNtKI{(FCA9bn11gd_r}qOridZjCTAZQ!|&Le#*;HnMnW-X(AU$>Cb;!@EbH~aHzwI z^_lI&w|-WHD$9ff!^gKXX6(bo!J${@z$)$l^^lH^j)TKC@VC&%0=Eo3A&pMU58{~r zmBGS(E}|?XvAGPU13cdZ1Oyj0yX54;77eGDBNXv659UvwL?lJtV9KBWnxTYqf&zvL zE_Wf7xCbaOcwP8I!QBuL1z_n7y|}2DSn}~SfHJf+2I%Zz|78k=Z_qsP zZ^j9$^2bP-ke=o;dXKd-2p`bcn$VaswjuXv@_`~2{g+FH`8>sMV42eF-qkiVR3!$2 zzA!)k{glJYmq1{MiLJKSSzDWl$biEJR5&nr77aXsI>7E%<3%Y%6_&6}YXce}WL-dt zpgx^9d!10lg_&}&00ByoS6uwlw~eyAv9Xb`KoT6mH#s=o8yUBFH-XE+;ESk)gf}R? zus1lkxSE`nqt$XBQzfp@hTX>5yMaWmfpT#Uss@yO(4A@!6uDDFe&K}X%rnvibk$_i z_6m5|$tI8Zl~=b!Mcub%yPR?#{$pJz{2$hZ3G*qGR*nh>7=LYThnJm>1;j$ZcnWe$ z-q>F*>>5~%w@MM4mx}}DH)4xAJ3FVRr>)Z5EL(jq4YQ&g9LjTZtsXuch5`nZU@kTS z4=5m1m6Y(WT%m_P7T~hK-Yti5hA0Wv0q8r0hL>&V6Z4M*AuiGG*X(nSTGkEum#>&Z z)vfJpgnWOh7(8*pt+szhdRPA@H6D_O2$x-v1VNCH;ckH;a{D&Kkd+nB)?@ylwSNN2 zCT{ReMIrpL=q}1c+Kh4|6RDj1DO4S!&Dv~*PhF`m@w(tl|N?%DA zz`(fn`r>;5CfDX;b&lfo<4b_wbe{Di$F?Lt`1RaxpP6`2$9-Gl3w;YykfOiZYaTIg)k` z!X0bom!T~m?6W2CeAZCjLIwm{2%nJffIz#q^IJfsKkH$ggMu`T&Z+LBLf}MCd`O+waIwc_}~eIY}@ud}&2f*O?Zk zT5vF;5V!KLlT)CE=Ta{}x@j~(+-de<0^=mP_1#bq_I@i9Zh1yu>)=KeCI-3eQ@_9@ z1RgQFV%tqFG)6!GS#~Qq70TzAYO7Ktb|tlc<4qpGlKJnbQF-P)SF0&e*?q0$i5_|~fU`$c)&gdoA+Yjf6#sLt7ei3` z73>TSNwjUD0?4{n(7Xc~aX9_IRdlR-WNff@Bp`}HAcy^#KlOrFgyzG)BA+b|Lk!S* zx>@q!_Z1a^y@LaYK2VAI@GlHPMFj=7Zr}d;<;$1uZW2dosoPGWmVbCxN)w?SmEzhp z%?@zQ!PZx30(;@X{{HB)6R-uJ`}@bvYkLNk5MZSI)Y+*~dSMuWK$LJ2!m~DcsYqY< z7_`8R<>maLWquk}Q&T1Z9!W{#W{)hIE3B_I4)v><&`zR;03%IJXELPyLF82?dI_R1 z43CqO=hFLNJf?rV(q9J#fPU9JpJP+VBCy|CPzCN|C3t1>=TF$57VFIIXi2nF(bx!h z>Hz!=1M6j-vwL|M9EG{SAN=;{E1ciu#{O*FrSnJW_%V=ztn z+A*|BM2_Sa;4YjmXtS}B@bGXLH6CGn3Jl>^C%VS7MRx zZ?+KiS{l|nxj_L8RlFKrA{hEXz~?q@E*i1!PnTq%rB%kGhMWeFLRncErYAKj%EXS} zi;PX>a6U%;;;SYA*l5Tiz3)*VOA5b#*9QTTk}@8c$iqX|6)kvn$VPbpNQ;WHbr^lI z&De8D#<}y`o&ZV$J6F0|u8p;|KC~voSA9Ss4^=8qhvzF!^e4VNP%s#`E+hGyI0*$mT+Y9V&c^se&Q%^*O6h_D3R zdkYH`3=GD)x(ezSR5r-oKxG5mSAwQY@PdLk5ByxG16Itbd7^;_)~S`>Wy~-O*4_-Q zT%gO6*S>sqRjHRP1Ww)D((=A!`b~CcX*ZIRUW&e66z3 zVbKD8Oc9jPS9fM<4|XiRy@>7kD{%CE7LVhgLg>3Z$+^h3P=FMY$IH+^?d(@TU1!AERZ6`+$@0>%H*;2IfO$4H~fevHMH<9@`Rj#=WE zZ;x8)8;=TJA+|e?nla$8$x)?U=?Br`f44~jz*&5HN7d}t?#EM4a4mi8>Vo772mAv6 z9UK}+&)KpGV@_E6_i?@@nS_-UdWP=Pe8wOT-GXN(v6p2(#0MO2ia)@p({MJ)|LYl& zjWeO?Y;v_q0?MOooTCRGCIiE9dKeA?tuoG-7heDrkhj-PBIQDY^6~FOKo7%c`VxVx zIfbt|6Z#A{T#p>Mei&Zh$Ke}dUMDPX_SW)o!)t(i-90?OROSv68x&QYDhm2QlkukI zbm@gvypp<$SJa~U=y6;fEA+ZPbaAQHDP*-2{mVO%I0jP%hzJ%dnEA?}@-%B^=8E}g zNUc6JTXbY7#wa~|_bQ9&iXPtrMGVO{@PI=;No)UHS0=>UN}DEJ-YSQg%PgmXbM9$* zO4ZVEMSsYZ!f~wFH6KF159hf(S6beP?c4~UI!LrAhc_-vSk67wPZ5YO?6_h*{)h!( zGr=#g_6mtv_-`?Jfo&TEFDP%8-dLj`-3%@}!OZZNxFixFFFsf`VL=v0vrq9_iZ<@4 zXsm$c9iEAq_@1wgPz6ixeNBss+B{w@CF2wu{O9R+nl~8*AaFWycwb9=B;Gz3CzOmR$QF*y5^T$AfwO*=hpz zdNG$O&3&~S0<|pWnL&mm@l7cj9VIug@sI>gpP%)$-@z&OZ#7eXo7lzV{E@+3o`MR| z%j^E~p5>(w0>7@yyaaDdtw`t*VO$SS+E~`8WMoYAq}zx#FFHcX1KW8o1V}>unlOZ) z1zn(k<%}z)o3x3Zs%av&U~3K~0iu_p8!6CHA$&u|WJ2*yVxSm)wY2_gc(+)WIR!en z+T{fkdhJ!;gKM@H;O<%bkkA+HafI!^5*q@oq){H0GkE5hl>X3HI~z2~M<7K(f=bbp zvh1mu_k`}%8zd-$%=%Qe3zfTjb^6o$ZYiVW2k-?SlUh>R1Wyi=^0M=GgE6rf$0NQz zLz?+~3$BEQUW&-wtj@DNq@9;);0gZV{a4TmTjA1D!;}E1y67}Si6;DG!Pd3L9me8p zd_PvKpn^EuMJDB;b>uN8^nw5Q5?aOs-XUjSC-!Vc z&y~PS!dMi>eR8pg+1GwWF&A_j9&(-fUTitp=j%_|;{E+6=;)ua65t{25{lIG`3eXX zZ`G;bP}EFGTrz?dS(6l%^aPn>K4s-zxY1LPN9vkYkwTYjz=u-lnuq=- zmS79Hj<5RBp8Zl3%65&2Ydc+63`q5T#rzR-o8@?q!ap|ZSdb&~O#K2-$vPn{afCYW z+T7y?_L!|vD&HorgtF&f=>@Y1^n@|y5l!_wf5$hzj_rHS!O2OsZHj5bgzk%;9z~Gg z1QXNR6T}Bt&bX8K?pO`{$^Jz{k+y-tO6Rf;IxF#cXQ3N zGKQ@DXg2R1!zD}%Q$=>bWx^=k@i;Jelxk@x9MzbzG3I4D?^A3DAY()VT@e_xn^dTent>?@43AAx6wW`t zso7sgh1|lJCbsem%tK%_zaT>$KfU-Z&7K6cba)*j!1TEfN|6(T=s7cUJjT^COb#P!gjRH6Cjw zhFs!0$x4rqyVJ2U{Sdp?9(RA-_yFI@9?(^XFe!ZWsSNaViVdc>WFKi#`;`Jmm z~Gm>7f~uQ6}t$}Kt?8m3(Ka9OSQBzazwJy*TV<1mC{ z?EwK5))=#o&DKz{Z4`3*Qi`Pe`VOy&P$IVSV6EO%*S6e-CWIn~xBKH>%PXyvPPcrc zeRr$g2FJ2%@K=6qWY3Urzqb1bc!|V+^HZedQ;?*;XNxh0AtZrBG&X!lE$>k~yeOrm zcFeqbqM7yoNlN1yA-9W3#XOB&Z&}h`P4GdWV?#t@AbYSUP1bW59v&XZM`5Yy=cjj0 zx?FsqP^VQ_Yk#;ZGhLEbjdTT&ik-Fk=9@IA0t&65JGe-~VlRmQk(KR3FeYKdLiLJK zc!Im0!y=1Qp+*t~Z7=)48QsujpA zhbi1FEl;Glvm|Mls_Kg7)0dE8(m8*i&HYA-b}rCZpxtXDHmZRu^wuhdhE{Ao#`^cG zo?W{!w_`T4CFTjk9v;iYuhnFgrc?y%Ii6;`f8Ts^Zj+TJPf9Dw2hR3WjEH!4o28Lm z@vBOMHD^La_$>61Sit3?r$YFn+pNg!y(YQ*C(!TdiO2c#eQj-{H~`aS{VIc>k);7c zSfTDuy+36fOMNGyFQ56r@#Zx0zjI+pf)3^B#M%--3y@$qrm?`z@kCIeM0Di>DhKue z1Lx4egFp{FLF$`Di#<~{;d+=t@Uv}fBH>MAQ+Dy0>AHh-_$&9%ZNLu*;sH|g_gha9 z%K%#ir4H^HxCKx<;cq zF$=>EB_)lBG$4454?*}&o^R7P>5niq2tkk?kP5y&KF83gG=2;Ctt*gPpeJH%{s1|_ zGAvqu#8mZY%e*ohfJO_}0XUoE{a5-hxFNaE(HxFCrf;%wf}(o3L2wU`#nxB8?KH5^ z=dGoc_%v>hNb9l)Y`aBW&}ccJ%3@y3k}4gytZE=^lx^e4?aE0p>Yb{C8QQ~wqa69B z?BTqld7Pk=j!v(qvj$InuM9$`^UXqrE5X8A%Zz~(6Nx0Aq7nWU~ zIpadp(!I7N^1vUvk3Vna58lx6qpxTSZq(Ali-%gumY(;LF%Mh2EHR|s6*(9X|BP;k zRLFBh&!uBauppp2&8;BI92RGSO-dHW?~AG{d>7zNUpN{hvNB|lI9)Co-q=0j0+a6G4UAr9wCV{=RnV0_T-GUr*yrbpz zqAzwvkx;t1CP>@(y6%FJ^m7)0XU#tpgn5RJ$DZ_^?EJoTq&H+C?Lp-C6HZ@e3C(LP z`zW77gR{a4^aa7nfeYR2;$2^j^1O3)yRhq5`8}Ui2wbDgJCy^$Nh|}lfaIJo&z}na z;@NGZMLchvl*&CBj7J8A(KS_3A$Bjc_^}!P5weYMsEU;ke8RX6Z6n;wq^qN8 z3;@tXQ@`UF>8YP*(z|%67y9RV+L{2$pLan=*$1lRoTttc9{}J2+n+%L$jZ4&6*Bnh z>OWxkNq2#cjwj#y6&3*CrP0+?H+_X7&V>fEue|Bo_PG6XORs>|_-J``%8JIiV#=gi zhK8M0P4H^;Ew1a4VP@ahE~-{LO7}9#>sAQ71-=`9E^uNjQ4p?c9hWy*$>3-v!jXto z6HsTR1GbU0f7<&?wkg)n%&mh}H<2#3KZe(bm5v7ocXA!T{z4l%Q|fI1z}D#SJX<2) z;m3Vqz{f0F0PUv$iDHBApGt>?t?LI5Ln)$A;}P5WVq-vqu9sF>2G61=nwUA6%uKMm z4ZIEbW}qh5{md2BF`0Ol`=JF3I{@WQl?d9OymbCcjT^~vnH7L~dm&y6Mf8JxW%8fJ z`UF-pzv!JS3JJoPtqj*F1pcyfeHL~upS)ba@e9XoV4a)~Go*M)6c2=MMle4)N2Yx~ zpXV>FApO;W?o}(Ii@2TOZy<10DRQjh8dq*sA=S=JAb@T0v5if2YU=jT{paeh5yr;7 zRn5(EF9o+T4E&Ylj+aEcA2D}Ze6>K>XLAh)SNs-3+t4lp3m5F0_nLIyo>|cL+V)<- zV%JVd^A->LUk!!qp5s;Ydg#L+a$i_@d5?U&DJm;#(bF>kS^rj15cTy7KWXCEkCtji zI${>X+acn1L7PcQV1>E^WdBhI$}X=!n{to{6b`~m_Ginq&A8kbR6!K25eVH@^4r_I zxs;$gXrz<{JifzP+{3a5a_&nUeu82m>7Y{n?!pCAbMw;b>f6dYgCANc z9}&b-hn|ZBi6WgW@CwS(_}7h{O6o9`Oz2AIK?UFGvZAxj&)u0pfwAHE4wi|L87$A}uSca<0wa zWwD#qLGDq$3dp2Pr2x~>%FrIK5tX!7QHFEejLLtQ;@5EsHQ@Vh7G*HE+b?<}^@B+z z3Z=C2D^)~X+~miPA0oG{?42=Y{B9F_Y@(@h6;9X6y|GT~v+Zn~oHkUK^ZI zn3@bJta4DT34gM4Qx{o$vjP;%dAb63VZ!a0=gL#Mrnv$=gwx z-U(ciM%FSlr9w1U56C1$&EVjpp-f4=mX-@rZYU{x2M3qooG1N*gOj9Ak{ixPRn@Yj zyG4vB_C; z?vx7AfBtJ#5w8oN-w*ZE(M!MW75O!UG*?EA)!zQ}K2CpK}MA4SDSW;x#x2)q>27S(i9A8fVraE{qt zCjFdrL;eOA%1|RzQqKvd8)o-$`tgJX~%(kG~1M2JQPAF$a`_n|z6jq+3 zrQd-h`kd+z3S400{`3wmd$4S-bs`#hOA+?iC7p0uQ3<>BHjrOV zz|2CCAtJ0cfEN{dO6ceJtJ$#GN=yuSQnGBvJ2moJPN!<#vJA$xW?!#+wjN6mud-7h zoidV;LD`)z+JTUb@hLaYTr2_d=8>eNFLfpXT=zR}acT;SEH-j_dqzN5R8;Q|qV>c( zOiM~i0#826TQxeTrF{6%=sI&xKUcwwfP^6@D@^`OZwd*yOjVi%p4_F(gKmjr6>a;- z3X3b6e2p?p2I}YKRJ~E%K;8!OjE|RAxE|hkXec{B+Up-L}!vC6$8e%$ESv&wT0#zD_y~>^jS~USQ*1#!Mk?LGFZ!IOH^Ubt*xhB$=ts7zlZv5Wo%;W^zr#!^53kiW|7twQb8w6v0?rRVlwu=9_Un^c0EK6_SJS68>YppleuKIZpt zZ+i#MH7b=GpFenK8yXVt?Ja{(v(Q>C&6dIcdSgR8a*q5%wEfoy6*BI(>)0>h+E|d+ z5;rC>&^?$mh!ji>SFEzgh{TR>thxD+i_&b1w)#Y!9`bmYg_xyP9_^dK4|X~V{OHA? zi*cgqHQw3#jjt-6nwpdVFOf4xkbyD>P-lbS#bD4-jCimCNoHsVA}xe?jNDK@F_7fG zsI}tT<~i4$G=E9YV5(}x{_PphJ3PHf{IEtBq==-XNgRimv6faOhnQ9IHA!%JZSCXb zz9iWzteGD+&7X~lP~&sPv`aDZDuC+CE{>gq*Psws^Ty7XkvqHNVXr?rtEm#^%Qxm^ zb;VUwMh}}eS9FId$WFhyo-R)WgI7|XFsAJHM+>KK8Nyj1hM{`{uq_1@mXJ2c2k;~1 zd2$Om%Z1tww#wsWOe9-35NDf_m>-zuj+rZQ%NKdI8w zQEZ6z`D*Rm$%mroZD*5MHumV14|bCjq$!xn zAhWY|du-{$*AkF+pJZvm!qj|XG(6q|&DLMd$S2kU)YQHRKl^?QM@dtJvv2^q`B_+L zE+0O-JAU(ald&M6`wC0+bS)t4X=|7W0ARVMzT5r_J$VT*8UX-=g#iGXzG_M)W$~Ma zzGP-V^j_GjQm8P``LfmYvoGc}y6*x2&u)}BxX=!Qh_zk!6>gru|(08i0%7H|uO-u()Hh$J>#>d4huNLvd@Va>;`1`vTGl}#) z5Js)93od!&biBM+vVBH?VWPJsUjJ;>>-&v)hs36E2XqHINPHW@{|Zh_OWuM{yrR#57pa9N(PehRR_N~yIp$%w_=`Hh z9|;6$@PG?8dg4(8YrNLjywd%-+IOFxdEob7Hsof{q<`%g5{NapdlLwx-u$DAiV6`? zQIq@k!>N}!zT*o~)*SIuKRyWE)HNK|op_-@aVdrhE++2}NZBjNKe$+`j!l5lV;Va18AM;KrYFzdn15CX^>IVl_3}9puY_C^_u2Y$@DEVLt_S#;72Ur30 zX|c^~>43pn`Wp$-xtg3tX&eh6wkymJU^f<;~0i{gBxyWQ%QU{qKNQ z0poslXylEnNC72yRnzS1XUZ32HM#qrpwMAsx#mdC%_MO@#g1RZfD~UmBA>qIZuCkK z=g5VI_vWRJCqTDiuxeS8La=XD!Ivx%hyW>uhc3CexX5maIef2jxxY zLI;?4zw{z^Lc~T~pH#aJEY5;iO3E^<*jf3MV_tAq`Sx6~Xnq$F0rQkVttz#3lMT+k zN~~`cq;?yyZAAY9A=GZO3zCJit1r`v$Bw0to;PlUdvSdoJgIKyuSe(3tYjY+Cr@pI zrz_wjXFp}_ewhgK^=jmdYIffRXXP1`Q2BK!E!6;|vukTTn-TWpQ@T{hCP>y%{Mm>=5Sud1v$ ztp8c_Stb0?+HlOq;Z1sOK5tSx!DHX^Ls@iXP>Wt|dnD3fT;jyQ_^ByoH(;)`Q5lIHEy{d2eQJS*CZ3N>iQE2vQS8 zzB(TEhY3%F6R8z@{C9g?X$gL7%;4dp^{Q?rWhwXWW0BcWjhL7a$bq9!epz<)?CWv# zc@KQ-uB**`&|mekSvo*F`u1mWq-x#5nvvTn3ta`v21&ALB%x&oH}lSINK@M(Wa zrq}$Fv?3ytMcT|%ZZw-k6AskepS2P@k{a*8t9%#2Y(a1h0@<|C0!d81#53AD3q|c? z`qa?{H{7(DwdAhx(gY~p`|U4vCHC+dZ*JpmM~0Y1t-;ymyw)AaO9HVY(p&kAi+ECQHfeW*gcN$)-o>nZrqOa5Nd>nhVpBE3y$T;-Z6UdHVV9?R>K^yr zLo328Y$nhVAGl@4iNNAvmx}Pa97z4^5&}vZOK%wXMwfcx#NK_SwEN{F4shHl#i2Z> zg|G8G6D|>5T0d&ywJn@|t(rJqLed(nuP_v=D7#1pI5~ZnZP01She!;tZy+1fCJYOk zS6rp0-=#4FuD)x4A0D*o*K`t9XOA5lW^pRdX}hI?tZZyz`R0|VP7T?)dJ{kE8cgno zYVk`msjrZPI<#}+Qp{acXtR1QaLCHMi0VZ@|G865ZvUXs6N!OI6t_z;pBH_b&70td zLulo^ub})zD{aKuccgI3)7kksYeO;iW03W^nA+Ea(t?8O5C~*#v@oIsDV^h#dislR zW{tW0b606^y$rl>es$Jp;-hq~`Mn7rNBqMJJ;UrV_U9kSJ$NX8qr%2q70eT>C6vNd zr^aOwN*F;a$rIVtX#{_G%jpn*2g6Pa6#N>^L_t&2WiY)^0MCl#$CobNP7!lT1%zr%r2a z6c@Lfdy-p1Q?g%UP0n>jWJU7h^dIOtTIIftn%fAKen*Hrcwjw1q3kAMsGerq%-wEf z3o@pZO6al!We5k|g4^5i7fT$Y()SHcrW#>!CpBIG_IjFUF131``>8KKa1rZd^Fm$W zPv$?<5y1@0L1)a{TExUYz>)~pr0Kf?DOx+sQzzAv`I+ADmZTEk-e>Cc-+jW+)_i?R zv_te`Qd${(5nYuZ9myL;lV>zX5E>1B&ticU12b#i_k9hD#m6fv^jrcGy2?Zef-JN+N0g-INZ&;^XbK&U2^|O2;JXs z`Ugyf3wzfgGgU;j77>gW;Unwl4&)AE38gFLSL&_U~*{6?_f0@Yp6QaGZq(G9zK(by4F=J1Z`m*K2Nys<}kthey)eadHVW3=H zrtMe8#nHpd_XGq^WDdB)6;$oY9$Ll0COAG@COV2a)b?MA zLEmDGj%FX+RM%X(oH>S%x4fg>kS=Mt@(Br`?GAqmig?{=usaQplU zNq`pL8+80D1}9`UIE-F}Ag~T#dGHqHo2zV`oI=MfvbdwrTOX08`HR+I z;M83;wT8>)p&N>h2`>J8At(}q?{T)`PM`qH(-3PA{Q&N6JzT#xo|*u@XETBU{{0; zROuTG+J*q#u%}OQ^JfBU>s%%Ga4jl~v@9$}1&vVk1LyA@(m-&cLWCE)vy`f2S*cR~ zGU{=lXjv!eWuyCv^nsXsKgj|tD#%3D5MW0N$R)6~dpBW^FYMQa?6t0%g@r|{{n_L5 zi>=Tx)PSqrN`vv8KyK>2TLMFwyI0w@t!=>8A`T6c{Ay|$EEnb@)Se~;)dpQ0+rRu& z084kB8i$g2e_-DI+Ws9AsW%8rf1hxO*aXB%fHPPbx8fE6#u96CFj&s--h+R3aj?2x zZC+MQ?X8gnOg&?+OF17$_zX{~ILhXzBrST7wd~=)xk8sur}QOo4kdiF!klly9D9=X z8ZYN*SLUFoY4>G(Oe}n!jqXoRK~38~Jk=Z6%0;1=_YNacWzTMsH-162P7viVPxn*4|Jm|O{3jgN%Ln#8J1#qM? zaq1QOE3WsOtK$N5y z8S3uK@yeSoUuJ1a-sQM{D#g@s2GGSW-PzMXdeykkS2dmYLb`P$>SLug=~8QUZro~ww8e12_g@DUH9ouKmw`{|08#*GLRR-&w8EhX)pBR)9wWkX!zYtB;Yzv8XA~Zpc z*6TweM^3v)$Ms+u0S?-wFYQA^y$O%FI7i#>d+qW-1H6AR3*|KR^0^M9TQ{BO^V_`8>w0|2p##*k41X#haUEA|}V=_-Y$Qjo*J<@sbPfcnyX MV4w-T|1|vn0N4VR#{d8T literal 0 HcmV?d00001 diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/pda/launch_2.dia b/plugins/org.eclipse.dd.doc.dsf/docs/pda/launch_2.dia new file mode 100644 index 0000000000000000000000000000000000000000..f0d4b4876b243e51858d6f48586591150e611cc3 GIT binary patch literal 771 zcmV+e1N{6SiwFP!000001HD&WZ<{a_eebV8^tCl#A%wO`wLVOmG-(gpo{LZ+?(oAZdUc&h*Y_4Rh5 zKhCZmB7*PKHx@Y2)Eg|@JWchblvAWCwSf$}n&ilr1J%q3_HCot7RJb#V_&sn4ws1i5llndW_+NXbvke}QTC9s|YjF5CKMZY)UDow!Gc7M2x>A^@Z49 zNJc^mO|vIVei;4wW9X}^v#s9y*U#Jy1zT%-h$i5I+rK@;If)=UvCWP#ElkT2W}J$8 z75Co26hoC}y_KMN4Wguf+P7(~T;Q_e97KVKe_$?4dp{*+5f+hlt9?sUBi8rl4t44v z(NzCo9tWsuNztj=SBp@}ciU)$9QS67oT}@3&1mBf!z#T{7BGt`>?D+e?cUoivfLYM zf?Ut@h6w_NB$#u->gR$FGqu&&){nZeU4Jr>=bk~o1QIW0JHKTk+xEtu<2t76O~%$h zFCiBZh~PL!8?w|}Y(B#@B7s*yAyk#<=&pSfo&nMTXQ|p(7gAUd3RUX2BP7K+n=btpTd$hK zq5uoQSM92{eI|84fyG@l(;T`H_7W$m@@a)?Ru<3OHm&}&ANKLt)qmR5nH1{}002EP BbZr0t literal 0 HcmV?d00001 diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/pda/pda.gif b/plugins/org.eclipse.dd.doc.dsf/docs/pda/pda.gif new file mode 100644 index 0000000000000000000000000000000000000000..9a6adbfc87e48e9c48ea6318945d0f7fed0784d9 GIT binary patch literal 182 zcmZ?wbhEHb6krfwc+A591WgP+2};o(9v-Qwskb%H6c-mW+z^>CVZ!|R^VhCj`@j9` zeHow to write a DSF-based debugger -

      How to write a DSF-based debugger
      -

      +

      How to write a DSF-based debugger
      +

      Summary

      DSF

      • Customizing, componentization, performance.
      • GDB Reference Implementation
      -

      Debug Services

      +

      Push Down Automata (PDA)
      +

      +The Push Down Automata (PDA) debugger example is used as the basis for +this tutorial.  Before starting the tutorial it is best to +familiarize with the features of the debugger.
      +

      Running the Example

      +Launch the PDA debugger with these twelve "easy" steps:
      +
        +
      1. Download and install Eclipse development environment, either the Eclipse Classic 3.4 or Eclipse IDE for C/C++ Developers
        +
      2. +
      3. Install the DSF SDK feature to build against, by performing +either:
        +
      4. +
          +
        1. Using update manager, install the Debugger Services Framework end-user and +extender SDK, found in the Ganymede +Discovery Site under Remote +Access and Device Development.
        2. +
        3. Check out org.eclipse.dd.dsf +and org.eclipse.dd.dsf.ui plugins, found in the /cvsroot/dsdp repository under org.eclipse.dd.dsf/plugins +directory.
        4. +
        +
      5. Check out the org.eclipse.dd.examples.pda +and org.eclipse.dd.examples.pda.ui plugins, +found /cvsroot/dsdp in the org.eclipse.dd.dsf/plugins +directory.
      6. +
      7. Build the PDA plugins.
      8. +
      9. Create an instance of an Eclipse +Application launch configuration and launch it in Debug mode.
        +
      10. +
      11. Switch to the new Eclipse IDE Application
      12. +
      13. Create a new empty project:
        +
      14. +
          +
        1. Select the File->New->Project... +action
        2. +
        3. Select General->Project +in the New Project dialog.
        4. +
        5. Enter a name for the new project (e.g. "PDA")
        6. +
        +
      15. Link in the folder with PDA examples from the org.eclipse.dd.examples.pda plugin.
      16. +
          +
        1. Right-click on the new Project and select New->Folder
          +
        2. +
        3. Click on the Advanced +>> button at the bottom of the New Folder dialog.
        4. +
        5. Select the Link to folder in +the filesystem check box.
        6. +
        7. Type in or browse to the samples +directory found in the org.eclipse.dd.examples.pda +plugin.
        8. +
        +
      17. Open the PDA editor by double-clicking on the PDA file (e.g. fibonacci.pda).  See note +below.
        +
      18. +
      19. Set a breakpoint in the program by double-clicking in the editor +gutter.
      20. +
      21. Launch the PDA debugger
      22. +
          +
        1. Set the dsfPerlDebugger +variable to point to the Perl executable in your system.  +Variables can be set in the Windows->Preferences->Run/Debug->String +Substitution preference page.
        2. +
        3. Create a new launch configuration of type DSF PDA Application
        4. +
        5. In the Main tab, enter the workspace path to the program name +(e.g. /PDA/samples/fibonacci.pda).
        6. +
        7. Select Debug to +launch the PDA debugger.
        8. +
        +
      23. Step, select stack frames, debug...
      24. +
      + + + + + + +
      Note: If the Debug Platform example +plugins (org.eclipse.debug.examples.*) were previously installed in the +same workspace as the DSF PDA example, the two examples will both have +an editor registered for the ".pda" file type.  To ensure that the +right editor is opened, right click on the PDA file in the Navigator, +and select Open With->PDA(DSF) Editor.  The editor that is +opened should have the DSF-PDA icon:
      +
      + + + + + + +
      Note: A Perl +interpreter is required for PDA. Linux®™ comes with Perl. For +Microsoft® +Windows®, we use either ActivePerl (http://www.activeperl.com/) or +Indigo Perl (http://www.indigostar.com/).
      +
      +

      Language

      +

      To demonstrate how to write a debugger for Eclipse, we need a +language and a run time to debug. For this example, we chose an +enhanced push down automata (PDA) assembly language and a simple +interpreter implemented in Perl. Each line contains a single operation +and any number of arguments. Our language differs from a standard PDA +in two major ways:

      +
        +
      • Our language has a control stack and thus has call-return +subroutines.
      • +
      • Our language allows data to be stored either on the data stack or +in named variables on the control stack.
      • +
      +

      Here is an annotated example of the Fibonacci computation (note that +the annotations themselves are not valid syntax in this language – in +this language, all comments must start at column 1 and be the entire +line):

      +
      +
      + + + + + + + + + + +
      samples/fibonacci.pda
      +

      +
      +
      push 6
      call Fibonacci function call with one argument on the data stack
      output print result to stdout
      halt
      #
      # f(n) = f(n-1) + f(n-2)
      # f(0) = 1
      # f(1) = 1
      #
      :fibonacci
      var n define variable n on control stack
      pop $n get n from data stack
      push $n
      branch_not_zero gt0
      push 1 f(0) = 1

      return return with one value on data stack
      :gt0
      push $n
      dec
      branch_not_zero gt1
      push 1 f(1) = 1
      return return with one value on data stack
      :gt1
      push $n stack: n
      dec stack: n-1
      call fibonacci stack: f(n-1)

      push $n stack: f(n-1) n
      dec stack: f(n-1) n-1
      dec stack: f(n-1) n-2
      call Fibonacci stack: f(n-1) f(n-2)
      add stack: f(n-1)+f(n-2)
      return return with one value on data stack
      +
      +
      +

      Debug Protocol

      +

      Our PDA assembly language interpreter can be started in either run +mode or debug mode. When started in debug mode, the interpreter listens +for debug commands on a specified local TCP socket and sends debug +events to a separate local TCP socket.  A detailed description of +the protocol can be found in org.eclipse.dd.examples.pda/pdavm/docs/protocol.html, +but the lists below show a quick overview.
      +

      +

      The commands include:

      +
        +
      • clear N – clear the breakpoint on line N
      • +
      • data – return the contents of the data stack; the +data is returned from oldest to newest as a single string +“value|value|value|…|value|”
      • +
      • exit – end the interpreter
      • +
      • resume – resume full speed execution of the program
      • +
      • set N – set a breakpoint on line N
      • +
      • stack – return the contents of the control stack +(program counters, function and variable names); the stack is returned +from oldest to newest as a single string “frame#frame#frame#…#frame”. +Each frame is a string “filename|pc|function name|variable +name|variable name| …|variable name”
      • +
      • step – single step forward
      • +
      • suspend – end full speed execution and listen for +debug commands
      • +
      • var N M – return the contents of a variable M from +the control stack frame N (stack frames are indexed from 0).
      • +
      +

      The debug events that are reported asynchronously to the second +socket include:

      +
        +
      • started – the interpreter has started (guaranteed to +be the first event sent)
      • +
      • terminated – the interpreter has terminated +(guaranteed to be the last event sent)
      • +
      • suspended X – the interpreter has suspended and +entered debug mode; X is the cause of the suspension, either step or +client or breakpoint N
      • +
      • resumed X – the interpreter has resumed execution in +run mode; X is the cause of the resume, either step or client
      • +
      • unimplemented instruction X – an unimplemented +instruction was encountered
      • +
      • no such label X – a branch or call to an unknown +label was encountered
      • +
      +

      Debug Services

      +

      TODO: remove this sesion?

      Use of services is intended to allow for maximum level of extendability and customization.  To achieve this, service interfaces should encapsulate functionality that logically belongs together and at the @@ -63,86 +261,1970 @@ for reading stack information.
      Service for reading symbol information about the loaded modules.
      -


      -

      +

      Step 1 - Launching
      +

      +The first task in integrating a debugger in Eclipse is creating and +managing the debugger process.  The Eclipse Platform provides an +extensive API for this purpose, which is nicely presented in the We +Have Lift-off: The Launching Framework in Eclipse article.  +This section (as this tutorial) concentrates on the DSF-specific tasks +of launching the PDA debugger.
      +

      Launch Delegate

      +At first glance, there's nothing unusual about the PDA debugger launch +delegate.  Just like the Debug Platform version it:
      +
        +
      1. finds the Perl executable,
      2. +
      3. finds free socket ports for debugger communication,
      4. +
      5. finds the PDA program
      6. +
      7. launches Perl to run the interpreter
      8. +
      +The major difference is that it does not create an instance of the +standard debug model IDebugTerget +object.  Instead it implements the getLaunch() method in the ILaunchConfigurationDelegate2 +extension interface, in order to create a custom launch object:

      +
      + + + + + + + + + + +
      org.eclipse.dd.examples.pda.launch.PDALaunchDelegate +- getLaunch()

      +
      +
       51:  public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) throws CoreException {

      52: // Need to configure the source locator before creating the launch
      53: // because once the launch is created and added to launch manager,
      54: // the adapters will be created for the whole session, including
      55: // the source lookup adapter.
      56: ISourceLocator locator = getSourceLocator(configuration);

      58: return new PDALaunch(configuration, mode, locator);
      59: }
      +
      +
      +
        +
      +

      PDALaunch

      +The PDALaunch object plays two main roles:
      +
        +
      1. Serve as the root element of the PDA View Model hierarchy
      2. +
      3. Manage the lifecycle of the DSF session, its services, and the +executor that belongs to the session. 
        +
      4. +
      +The first task will be described in the View Model section, the second +task is described here. 

      -

      Push Down Automata (PDA)
      +Even though the PDALaunch constructor is called +long before the debugging services are created, the session and the +executor need to be available to the UI clients that present the launch +object in the Debug view.
      +
      +
      + + + + + + + + + + +
      org.eclipse.dd.examples.pda.launch.PDALaunch +- <<constructor>>

      +
      +
       65:     public PDALaunch(ILaunchConfiguration launchConfiguration, String mode, ISourceLocator locator) {
      66: super(launchConfiguration, mode, locator);

      68: // Create the dispatch queue to be used by debugger control and services
      69: // that belong to this launch
      70: final DefaultDsfExecutor dsfExecutor = new DefaultDsfExecutor(PDAPlugin.ID_PDA_DEBUG_MODEL);
      71: dsfExecutor.prestartCoreThread();
      72: fExecutor = dsfExecutor;
      73: fSession = DsfSession.startSession(fExecutor, PDAPlugin.ID_PDA_DEBUG_MODEL);
      74: }
      +
      +
      +
        +
      • Lines 70 and 73 create the executor and the session +respectively.
        +
      • +
      +As the last step of the launch process, after the Perl process is +started, the launch delegate calls the launch to initialize the DSF +services.  There is an expected race condition between +initializeServices() and shutdownServices() routines in that the PDA +process may run to completion and exit while the initialize services +routine is still running.  Also, the user may terminate the +program while the initialization sequene is still running.  The +use of fInitializationSequence variable and other flags protects deals +with this race condition.
      +
      +
      + + + + + + + + + + +
      org.eclipse.dd.examples.pda.launch.PDALaunch +- intializeServices()

      +
      +
       90:     @ConfinedToDsfExecutor("getSession().getExecutor()")
      91: public void initializeServices(String program, int requestPort, int eventPort, final RequestMonitor rm)
      92: {
      93: // Double-check that we're being called in the correct thread.
      94: assert fExecutor.isInExecutorThread();

      96: // Check if shutdownServices() was called already, which would be
      97: // highly unusual, but if so we don't need to do anything except set
      98: // the initialized flag.
      99: synchronized(this) {
      100: if (fShutDown) {
      101: fInitialized = true;
      102: return;
      103: }
      104: }

      106: // Register the launch as listener for services events.
      107: fSession.addServiceEventListener(PDALaunch.this, null);

      109: // The initialization sequence is stored in a field to allow it to be
      110: // canceled if shutdownServices() is called before the sequence
      111: // completes.
      112: fInitializationSequence = new PDAServicesInitSequence(
      113: getSession(), program, requestPort, eventPort,
      114: new RequestMonitor(ImmediateExecutor.getInstance(), rm) {
      115: @Override
      116: protected void handleCompleted() {
      117: // Set the initialized flag and check whether the
      118: // shutdown flag is set. Access the flags in a
      119: // synchronized section as these flags can be accessed
      120: // on any thread.
      121: boolean doShutdown = false;
      122: synchronized (this) {
      123: fInitialized = true;
      124: fInitializationSequence = null;
      125: if (fShutDown) {
      126: doShutdown = true;
      127: }
      128: }

      130: if (doShutdown) {
      131: // If shutdownServices() was already called, start the
      132: // shutdown sequence now.
      133: doShutdown(rm);
      134: } else {
      135: // If there was an error in the startup sequence,
      136: // report the error to the client.
      137: if (getStatus().getSeverity() == IStatus.ERROR) {
      138: rm.setStatus(getStatus());
      139: }
      140: rm.done();
      141: }
      142: fireChanged();
      143: }
      144: });

      146: // Finally, execute the sequence.
      147: getSession().getExecutor().execute(fInitializationSequence);
      148: }
      +
      +
      +
        +
      • Line 88 declares the initializeServices() to be invoked only +within the session executor thread.  This is to protect access to +the fInitializationSequence variable and to allow the call on line 107 +to be made without use of another runnable.
      • +
      +Due to race conditions between debugger events and user commands, the shutdownServices() routine may be +invoked more than once.  The shutdown logic must protect against +these race conditions.
      +
      +
      + + + + + + + + + + +
      org.eclipse.dd.examples.pda.launch.PDALaunch +- shutdownServices()
      +
      202:     @ConfinedToDsfExecutor("getSession().getExecutor()")
      203: public void shutdownServices(final RequestMonitor rm) {
      204: // Check initialize and shutdown flags to determine if the shutdown
      205: // sequence can be called yet.
      206: boolean doShutdown = false;
      207: synchronized (this) {
      208: if (!fInitialized && fInitializationSequence != null) {
      209: // Launch has not yet initialized, try to cancel the
      210: // shutdown sequence.
      211: fInitializationSequence.cancel(false);
      212: } else {
      213: doShutdown = !fShutDown && fInitialized;
      214: }
      215: fShutDown = true;
      216: }

      218: if (doShutdown) {
      219: doShutdown(rm);
      220: } else {
      221: rm.done();
      222: }
      223: }

      225: @ConfinedToDsfExecutor("getSession().getExecutor()")
      226: private void doShutdown(final RequestMonitor rm) {
      227: fExecutor.execute( new PDAServicesShutdownSequence(
      228: fExecutor, fSession.getId(),
      229: new RequestMonitor(fSession.getExecutor(), rm) {
      230: @Override
      231: public void handleCompleted() {
      232: fSession.removeServiceEventListener(PDALaunch.this);
      233: if (!getStatus().isOK()) {
      234: PDAPlugin.getDefault().getLog().log(new MultiStatus(
      235: PDAPlugin.PLUGIN_ID, -1, new IStatus[]{getStatus()}, "Session shutdown failed", null)); //$NON-NLS-1$
      236: }
      237: // Last order of business, shutdown the dispatch queue.
      238: DsfSession.endSession(fSession);
      239: // endSession takes a full dispatch to distribute the
      240: // session-ended event, finish step only after the dispatch.
      241: fExecutor.shutdown();
      242: fireTerminate();

      244: rm.setStatus(getStatus());
      245: rm.done();
      246: }
      247: }) );
      248: }

      +

      +
      +
      +

      Launch/Shutdown Sequence

      +The actual task of calling the asynchronous IDsfService's initialize() and shutdown() methods is implemented +using the Sequence +object.  The following listing shows part of the declaration of +the +Sequence.Step objects which +perform the service initialization:
      +
      +
      + + + + + + + + + + +
      org.eclipse.dd.examples.pda.launch.PDAServicesInitSequence +- fSteps

      +
      +
       38:     Step[] fSteps = new Step[] {
      39: new Step()
      40: {
      41: @Override
      42: public void execute(RequestMonitor requestMonitor) {
      43: // Create the connection to PDA debugger.
      44: fCommandControl = new PDACommandControl(fSession, fProgram, fRequestPort, fEventPort);
      45: fCommandControl.initialize(requestMonitor);
      46: }
      47: },
      48: new Step() {
      49: @Override
      50: public void execute(RequestMonitor requestMonitor) {
      51: // Start the run control service.
      52: fRunControl = new PDARunControl(fSession);
      53: fRunControl.initialize(requestMonitor);
      54: }
      55: },
      56: new Step() {
      57: @Override
      58: public void execute(RequestMonitor requestMonitor) {
      59: // Start the service to manage step actions.
      60: new StepQueueManager(fSession).initialize(requestMonitor);
      61: }
      62: },
      ...
      +
      +
      +

      Step 2 - Connecting 

      +With the launch framework in place, the debugger back end is running +and the DSF session and executor are started.  The next step is to +create the first service and to connect to the debugger.  DSF +defines a debug interface: ICommandControl +which abstracts a debugger connection as a facility that processes +commands and generates events.  The ICommandControl method allow +for three major functions:
      +
        +
      1. Queue/Remove/Cancel +commands - It is assumed that the command control service uses a +queue to hold commands that are to be sent to the debugger.  As +long as commands are still in the queue, clients can remove the +commands so they are never sent.  Even after the commands are +sent, the clients may request to cancel a running command, although +there is no guarantee that the debugger supports that.
      2. +
      3. Listening to Commands +Queued/Sent/Completed - Clients can listen to all command +traffic in order to implement custom processing.
      4. +
      5. Listening to Events +- Events are messages from the debugger which are not direct responses +to any commands.  Many clients need to listen to events such as +target state change events.
        +
      6. +
      + + + + + + + + + + +

      +
      Image 1: PDA Command Control Diagram
      +
      +

      Synchronization

      +Since there are several threads being used by the PDA Command Control +protecting state data becomes very important.
      +
      +Most of the state data in the command control service is protected +using the session thread, i.e. they can only be accessed while +executing in the session executor's thread:
      +
      +
      + + + + + + + + + + +
      org.eclipse.dd.examples.pda.service.PDACommandControl +- members declaration
      +
       56:     // Parameters that the command control is created with.
      57: final private String fProgram;
      58: final private int fRequestPort;
      59: final private int fEventPort;

      61: // Queue of commands waiting to be sent to the debugger. As long as commands
      62: // are in this queue, they can still be removed by clients.
      63: private final List<CommandHandle> fCommandQueue = new LinkedList<CommandHandle>();
      64:
      65: // Queue of commands that are being sent to the debugger. This queue is read
      66: // by the send job, so as soon as commands are inserted into this queue, they can
      67: // be considered as sent.
      68: @ThreadSafe
      69: private final BlockingQueue<CommandHandle> fTxCommands = new LinkedBlockingQueue<CommandHandle>();
      70:
      71: // Flag indicating that the PDA debugger started
      72: private boolean fStarted = false;
      73:
      74: // Flag indicating that the PDA debugger has been disconnected
      75: @ThreadSafe
      76: private boolean fTerminated = false;
      77:
      78: // Data Model context of this command control.
      79: private PDAProgramDMContext fDMContext;

      81: // Synchronous listeners for commands and events.
      82: private final List<ICommandListener> fCommandListeners = new ArrayList<ICommandListener>();
      83: private final List<IEventListener> fEventListeners = new ArrayList<IEventListener>();
      84:
      85: // Sockets for communicating with PDA debugger
      86: @ThreadSafe
      87: private Socket fRequestSocket;
      88: @ThreadSafe
      89: private PrintWriter fRequestWriter;
      90: @ThreadSafe
      91: private BufferedReader fRequestReader;
      92: @ThreadSafe
      93: private Socket fEventSocket;
      94: @ThreadSafe
      95: private BufferedReader fEventReader;

      97: // Jobs servicing the sockets.
      98: private EventDispatchJob fEventDispatchJob;
      99: private CommandSendJob fCommandSendJob;
      +

      +
      +
      +
        +
      +
        +
      • Line 63 declares the main command queue fCommandQueue.  Commands sit +in this queue until the command channel is free to send.
      • +
      • Line 69 declares a second command queue fTxCommands.  This queue is +used only as a means of synchronization with the send job.
      • +
      • Line 76 declares the fTerminated +flag.  It needs to be thread safe to allow the command and event +processing jobs to access it.
        +
      • +
      • Lines 86-95 declare the commuication sockets.  They are +marked as thread-safe though only used by dedicated threads after being +created.
      • +
      +Following is an example of how the access to session-thread protected +variables is implemented.
      +
      +
      + + + + + + + + + + +
      org.eclipse.dd.examples.pda.service.PDACommandControl.EventDispatchJob +- run()

      +
      +
      300:         protected IStatus run(IProgressMonitor monitor) {
      301: while (!isTerminated()) {
      302: try {
      303: // Wait for an event.
      304: final String event = fEventReader.readLine();
      305: if (event != null) {
      306: try {
      307: // Process the event in executor thread.
      308: getExecutor().execute(new DsfRunnable() {
      309: public void run() {
      310: processEventReceived(event);
      311: }
      312: });
      313: } catch (RejectedExecutionException e) {}
      314: } else {
      315: break;
      316: }
      317: } catch (IOException e) {
      318: break;
      319: }
      320: }
      321: if (!isTerminated()) {
      322: // Exception from the event socket is an indicator that the PDA debugger
      323: // has exited. Call setTerminated() in executor thread.
      324: try {
      325: getExecutor().execute(new DsfRunnable() {
      326: public void run() {
      327: setTerminated();
      328: }
      329: });
      330: } catch (RejectedExecutionException e) {}
      331: }
      332: return Status.OK_STATUS;
      333: }
      334:
      335: }
      +
      +
        +
      • Line 300 declares the run() +command of the event dispatch job.  It executes this loop reading +the events socket until the socket is closed or the PDA debugger is +terminated
      • +
      • Line 308 submits a runnable to switch to the session executor +thread.
      • +
      • Line 310 calls a method to process the event.
        +
      • +
      +
      +

      Command/Event Listeners

      +As mentioned before there are two types of listeners that can be +registered with the comands control: event +listners and command listeners.  The most important +feature of these listeners, is that they are called by the command +control synchronously.  +As a result of this, the command listeners can expect to see the state +of the command queue that is consistent with the event they just +received.  However, if clients need to modify the queue as a +result of the event, they should only do it in a separate runnable, +otherwise other command listeners may encounter the command control in +an inconsistent state.
      +
      +
      + + + + + + + + + + +
      org.eclipse.dd.examples.pda.service.PDACommandControl +- queueCommand()
      +
      337:     public <V extends ICommandResult> void queueCommand(ICommand<V> command, DataRequestMonitor<V> rm) {
      338: if (command instanceof AbstractPDACommand<?>) {
      339: // Cast from command with "<V extends ICommandResult>" to a more concrete
      340: // type to use internally in the command control.
      341: @SuppressWarnings("unchecked")
      342: AbstractPDACommand<PDACommandResult> pdaCommand = (AbstractPDACommand<PDACommandResult>)command;
      343:
      344: // Similarly, cast the request monitor to a more concrete type.
      345: @SuppressWarnings("unchecked")
      346: DataRequestMonitor<PDACommandResult> pdaRM = (DataRequestMonitor<PDACommandResult>)rm;

      348: // Add the command to the queue and notify command listeners.
      349: fCommandQueue.add( new CommandHandle(pdaCommand, pdaRM) );
      350: for (ICommandListener listener : fCommandListeners) {
      351: listener.commandQueued(command);
      352: }
      353:
      354: // In a separate dispatch cycle. This allows command listeners to repond to the
      355: // command queued event.
      356: getExecutor().execute(new DsfRunnable() {
      357: public void run() {
      358: processQueues();
      359: }
      360: });
      361:
      362: } else {
      363: PDAPlugin.failRequest(rm, INTERNAL_ERROR, "Unrecognized command: " + command);
      364: }
      365: }
      +

      +
      +
      +
        +
      • Line 349 adds the new command to the queue.
      • +
      • Lines 350-352 call the command listeners to notify them of the +new command.
      • +
      • Lines 356-360 submit a separate runnable to read the queue and to +send commands to the debugger.  The separate runnable is used to +allow the command listeners to modify the queue as well.
      • +
      +

      PDAProgramDMContext

      +Finally the command control also declares a Data Model context, which +is a parent to all other contexts for a given PDA debugger +session.  Each command used with the command control has to +implement the ICommand.getContext() method, which returns the context +that the command is acting on.  In PDA debugger, this context is +always the PDAProgramDMContext +instance returned by PDACommandControl.getProgramDMContext(). +However in other debuggers this context can have two other functions:
      +
        +
      1. To identify the command +control instnace - In debugger sessions that connect to multiple +back ends, the context can be used to identify which command control +should process a given command.
      2. +
      3. To help control +debugger command protocol state - The PDA debug protocol is +stateless, which means that any command acts independently of any +commands that came before it.  For debuggers which do have +protocol state, e.g. GDB/MI, the command control needs to check the +context of each command and set the protocol by preceeding the command +being processed with other commands.
        +
      4. +
      + +

      PDA Commands

      +To increase type safetly and make the code more readable the plain text +PDA commands are abstracted using specific command objects.  Below +is an example of a command class:
      +
      +
      + + + + + + + + + + +
      org.eclipse.dd.examples.pda.service.commands.PDADataCommand +

      +
      +
       15: /**
      16: * Retrieves data stack information
      17: *
      18: * <pre>
      19: * C: data
      20: * R: {value 1}|{value 2}|{value 3}|...|
      21: * </pre>
      22: */
      23: @Immutable
      24:
      public class PDADataCommand extends AbstractPDACommand<PDADataCommandResult> {
      25:
      26: public PDADataCommand(PDAProgramDMContext context) {
      27: super(context, "data");
      28: }
      29:
      30: @Override
      31: public PDADataCommandResult createResult(String resultText) {
      32: return new PDADataCommandResult(resultText);
      33: }
      34: }
      +
      +
      +
        +
      • Line 23 declares the class, using the PDADataCommandResult class as the +type for the result which has to be generated by this command.
      • +
      • Line 31 creates and returns the PDADataCommandResult object, +which parses the command result string.
      • +
      +Here is the corresponding data result class:
      +
      +
      + + + + + + + + + + +
      org.eclipse.dd.examples.pda.service.commands.PDADataCommandResult +

      +
      +
       20: @Immutable
      21:
      public class PDADataCommandResult extends PDACommandResult {
      22:
      23: final public String[] fValues;
      24:
      25: PDADataCommandResult(String response) {
      26: super(response);
      27: StringTokenizer st = new StringTokenizer(response, "|");
      28: List<String> valuesList = new ArrayList<String>();
      29:
      30: while (st.hasMoreTokens()) {
      31: String token = st.nextToken();
      32: if (token.length() != 0) {
      33: valuesList.add(st.nextToken());
      34: }
      35: }
      36:
      37: fValues = new String[valuesList.size()];
      38: for (int i = 0; i < valuesList.size(); i++) {
      39: fValues[i] = valuesList.get(i);
      40: }
      41: }
      42: }
      +
      +
      +
        +
      • Line 23 declares the parsed result.  It is declared public +but also final, protecting it from being modified by clients.
        +
      • +
      +
      + + + + + + +
      Note: Command and command results +can be stored in a cache as keys and values.  Making them +immutable helps guard the integrity of these caches.
      +

      +

      Step 3 - View Model

      +

      Adapter Glue

      + + + + + + +
      The adapter mechanism is something +like the glue of Eclipse APIs, since it allows object to be associated +with each without having any +explicit dependencies.  Just like glue it works best when the +mating +parts are clean and closely fitted together, where just a little glue +does the job.  If too much glue is used to put together many +odd +parts, the whole thing can turn into a big sticky mess that falls apart +at the lightest touch.
      +
      +After connecting to the debugger, the next step is to get something to +display in the debugger views.  Flexible Hierarchy viewers depend +heavily on the adapter mechanism to associate the presentation classes +with the objects being presented.  The first step to connect the +DSF +View Model for the debugger views is to register an adapter factory for +the custom PDALaunch object:
      +
      +
      + + + + + + + + + + +
      org.eclipse.dd.examples.pda.ui/plugin.xml +- PDA adapter factory declaration
      +
         <extension
      point="org.eclipse.core.runtime.adapters">
      <factory
      class="org.eclipse.dd.examples.pda.ui.PDAAdapterFactory"
      adaptableType="org.eclipse.dd.examples.pda.launch.PDALaunch">
      <adapter type="org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider"/>
      <adapter type="org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory"/>
      </factory>
      </extension>
      +

      +
      +
      +
      +The adapter factory has two jobs:
      +
        +
      1. Return the PDAVMAdapter instance as the content provider for the +PDALaunch element.
      2. +
      3. Register and manage the life-cycle of all other adapters required +for a functioning debugger.
      4. +
      +The first job is performed by the IAdapterFactory.getAdapter() method +listed below:
      +
      +
      + + + + + + + + + + +
      org.eclipse.dd.examples.pda.ui.PDAAdapterFactory +- getAdapter()

      +
      +
      157:     public Object getAdapter(Object adaptableObject, Class adapterType) {
      158: if (!(adaptableObject instanceof PDALaunch)) return null;

      160: PDALaunch launch = (PDALaunch)adaptableObject;

      162: // Find the correct set of adapters based on the launch. If not found
      163: // it means that we have a new launch, and we have to create a
      164: // new set of adapters.
      165: LaunchAdapterSet adapterSet;
      166: synchronized(fLaunchAdapterSets) {
      167: adapterSet = fLaunchAdapterSets.get(launch);
      168: if (adapterSet == null) {
      169: adapterSet = new LaunchAdapterSet(launch);
      170: fLaunchAdapterSets.put(launch, adapterSet);
      171: }
      172: }
      173:
      174: // Returns the adapter type for the launch object.
      175: if (adapterType.equals(IElementContentProvider.class)) return adapterSet.fViewModelAdapter;
      176: else if (adapterType.equals(IModelProxyFactory.class)) return adapterSet.fViewModelAdapter;
      177: else return null;
      178: }
      +
      +
        -
      • Cut and Paste
        +
      • Lines 158-160 verify that the adaptable object is of correct type.
      • +
      • Lines 165-172 check if the given launch has been seen +before.  It if is a new launch, it means that new adapters need to +be created and registered for this debug session.
      • +
      • Lines 175-176 Return the requested adapters for the PDALaunch +object.
      -

      PDA debugger
      +The LaunchAdapterSet constructor is responsible for creating and +registering all other adapters for the new debug session.  +However, instead of using the platform adapter factory mechanism, the +adapters are registered with the DSF session object and are returned as +adapters to the Data Model's IDMContext +object.
      +
      +
      + + + + + + + + + + +
      org.eclipse.dd.examples.pda.ui.PDAAdapterFactory.LaunchAdapterSet +- <<constructor>>
      +
       85:         LaunchAdapterSet(PDALaunch launch) {
      86: // Initialize launch and session.
      87: fLaunch = launch;
      88: DsfSession session = launch.getSession();
      89:
      90: // Initialize VM
      91: fViewModelAdapter = new PDAVMAdapter(session);

      93: // Initialize source lookup
      94: fSourceDisplayAdapter = new MISourceDisplayAdapter(session, (ISourceLookupDirector)launch.getSourceLocator());
      95: session.registerModelAdapter(ISourceDisplay.class, fSourceDisplayAdapter);
      96:
      97: // Initialize retargetable command handler.
      98: fStepIntoCommand = new DsfStepIntoCommand(session);
      99: fStepOverCommand = new DsfStepOverCommand(session);
      100: fStepReturnCommand = new DsfStepReturnCommand(session);
      101: fSuspendCommand = new DsfSuspendCommand(session);
      102: fResumeCommand = new DsfResumeCommand(session);
      103: fTerminateCommand = new PDATerminateCommand(session);
      104: session.registerModelAdapter(IStepIntoHandler.class, fStepIntoCommand);
      105: session.registerModelAdapter(IStepOverHandler.class, fStepOverCommand);
      106: session.registerModelAdapter(IStepReturnHandler.class, fStepReturnCommand);
      107: session.registerModelAdapter(ISuspendHandler.class, fSuspendCommand);
      108: session.registerModelAdapter(IResumeHandler.class, fResumeCommand);
      109: session.registerModelAdapter(ITerminateHandler.class, fTerminateCommand);

      111: // Initialize debug model provider
      112: fDebugModelProvider = new IDebugModelProvider() {
      113: public String[] getModelIdentifiers() {
      114: return new String[] { PDAPlugin.ID_PDA_DEBUG_MODEL };
      115: }
      116: };
      117: session.registerModelAdapter(IDebugModelProvider.class, fDebugModelProvider);
      118:
      119: // Register the launch as an adapter This ensures that the launch,
      120: // and debug model ID will be associated with all DMContexts from this
      121: // session.
      122: session.registerModelAdapter(ILaunch.class, fLaunch);
      123: }
      +

      +
      +
      +
        +
      +
        +
      • Line 91 creates the View Model Adapter.  This adapter is +used to populate the content of all the Flexible Hierarchy debugger +views for the given PDA debugger instgance.
      • +
      • Line 94-95 register the source display adapter (the "MI" prefix +is a historical left over).
      • +
      • Lines 98-109 register handlers for common debug commands.
      • +
      • Lines 112 -116 Regiter an adapter to provide debug model +ID.  It is used by Debug Platform to enable custom keybord +shortcuts for the debugger.
      • +
      • Line 122 associates the launch object with the PDA debugger +elements.  This enables some actions in debug view which access +the launch (such as Edit Source +Lookup).
      • +
      +Each adapter set is created new for each PDA debug session.  They +also need to be disposed when they are no longer needed.  It could +be expected that the adapters should be disposed when the PDA debugger +is terminated.  However, the terminated debug session still +appears in the Debug view, and this requires the adapters to be +present.  Instead, the adapters are removed when the corresponding +PDA launch is removed:
      +
      +
      + + + + + + + + + + +
      org.eclipse.dd.examples.pda.ui.PDAAdapterFactory +- launchesRemoved()

      +
      +
      185:     public void launchesRemoved(ILaunch[] launches) {
      186: // Dispose the set of adapters for a launch only after the launch is
      187: // removed from the view. If the launch is terminated, the adapters
      188: // are still needed to populate the contents of the view.
      189: for (ILaunch launch : launches) {
      190: if (launch instanceof PDALaunch) {
      191: PDALaunch pdaLaunch = (PDALaunch)launch;
      192: synchronized(fLaunchAdapterSets) {
      193: if ( fLaunchAdapterSets.containsKey(pdaLaunch) ) {
      194: fLaunchAdapterSets.remove(pdaLaunch).dispose();
      195: }
      196: }
      197: }
      198: }
      199: }
      +
      +
      +

      PDA View Model

      +The PDAVMAdapter creates the VM Providers on demand for each debugger +view it supports:
      +
      +
      + + + + + + + + + + +
      org.eclipse.dd.examples.pda.ui.viewmodel.PDAVMAdapter +- createViewModelProvider()

      +
      +
       43:     protected AbstractDMVMProvider createViewModelProvider(IPresentationContext context) {
      44: if ( IDebugUIConstants.ID_DEBUG_VIEW.equals(context.getId()) ) {
      45: return new PDALaunchVMProvider(this, context, getSession());
      46: } else if (IDebugUIConstants.ID_VARIABLE_VIEW.equals(context.getId()) ) {
      47: return new VariableVMProvider(this, context, getSession());
      48: } else if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(context.getId()) ) {
      49: return new ExpressionVMProvider(this, context, getSession());
      50: }
      51: return null;
      52: }
      +
      +
      +
        +
      • Line 45 creates a VM Provider for the debug view.  This +provider is created custom for the PDA debugger.
      • +
      • Lines 47 and 49 create VM Providers for the Variables and Expressions views +respectively.  These providers are implemented in the org.eclipse.dd.dsf.debug.ui plugin +and are reused here without modification.
        +
      • +
      +

      Launch VM Provider

      +"Launch" actually refers to the internal name of the Debug view.  +The PDA debugger has a somewhat simpler presentation in Debug view than +most debuggers because it does not support multiple threads so it has +the thread node shown directly below the launch node.
      +
      + + + + + + + + + +

      +
      Image 2: Debug view screen capture
      +
      +The PDALaunchVMProvider constructor creates the VM Nodes and arranges +them in a hierarchy that mirrors the screen-shot in Image 2.
      +
      +
      + + + + + + + + + + +
      org.eclipse.dd.examples.pda.ui.viewmodel.launch.PDALaunchVMProvider +- <<constructor>>

      +
      +
       50:     public PDALaunchVMProvider(AbstractVMAdapter adapter, IPresentationContext presentationContext, DsfSession session) 
      51: {
      52: super(adapter, presentationContext, session);
      53:
      54: IRootVMNode launchNode = new LaunchRootVMNode(this);
      55: setRootNode(launchNode);

      57: // Launch node is a parent to the processes and program nodes.
      58: IVMNode pdaProgramNode = new PDAProgramVMNode(this, getSession());
      59: IVMNode processesNode = new StandardProcessVMNode(this);
      60: addChildNodes(launchNode, new IVMNode[] { pdaProgramNode, processesNode});
      61:
      62: // Stack frames node is under the PDA program node.
      63: IVMNode stackFramesNode = new StackFramesVMNode(this, getSession());
      64: addChildNodes(pdaProgramNode, new IVMNode[] { stackFramesNode });

      66: // Register the LaunchVM provider as a listener to debug and launch
      67: // events. These events are used by the launch and processes nodes.
      68: DebugPlugin.getDefault().addDebugEventListener(this);
      69: DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this);
      70: }
      +
      +
      +
        +
      • Lines 54,55 create the root node for the PDA hierarchy, which +tracks the single PDA Launch element.
      • +
      • Line 58 creates the PDA program node, which tracks the single PDA +program execution context.
        +
      • +
      • Line 59 creates the processes node.  This node supplies the +elements corresponding to process objects returned by +ILaunch.getProcesses(). 
        +
      • +
      • Line 60 sets the program and processes nodes as children of the +root node so that their elements appear under the launch.
      • +
      • Lines 63,64 add the stack frame node as a child directly under +the program node.
      • +
      • Line 68 adds the Launch VM Provider as a listener to the standard +debug model events.  These events are used by the StandardProcessVMNode to update the +processes' state.
        +
      • +
      • Line 69 add the Launch VM Provider as a listener to the launch +events.  These events are used by the LaunchVMRootNode to update +the state and content of the launch if it has been changed or +terminated.
      • +
      +

      PDA Program VM Node

      +
        +
      +

      Elements

      +The PDA Program Node is the most complex component of the PDA View +Model.  It supplies an element representing the PDA program and it +operates in three modes:
      +
        +
      1. Not Initialized +- After the PDALaunch object +has been created, but the services have not yet been initialized.  +In this mode the PDA Program is not shown in Debug view.
        +
      2. +
      3. Running - After +the PDALaunch and PDACommandControl are initialized, the PDAProgramDMContext object is used +as the underlying Data Model element shown in Debug view. 
        +
      4. +
      5. Shut down - +After a program has terminated, it is still shown in the Debug view, as +is consistent with the established workflow.  However, at this +point the PDACommandControl +service is shut down and the PDAProgramDMContext +is not available.  Hence, a separate TerminatedProgramVMContext +wrapper element is used which does not have an underlying Data Model +element.
      6. +
      +The following two methods implement the logic of supplying the elements +of the above modes:
      +
      +
      + + + + + + + + + + +
      org.eclipse.dd.examples.pda.ui.viewmodel.launch.PDALaunchVMNode +- update(IChildrenUpdate[])
      +
      119:     @Override
      120: public void update(IChildrenUpdate[] updates) {
      121: for (IChildrenUpdate update : updates) {
      122: PDALaunch launch = findLaunchInPath(update.getElementPath());
      123: if (launch != null && launch.isInitialized() && launch.isShutDown()) {
      124: // If the debug session has been shut down, add a dummy
      125: // VM context representing the PDA thread.
      126: update.setChild(new TerminatedProgramVMContext(getVMProvider().getVMAdapter(), this), 0);
      127: update.done();
      128: } else {
      129: super.update(new IChildrenUpdate[] { update });
      130: }
      131: }
      132: }
      133:
      134: @Override
      135: protected void updateElementsInSessionThread(final IChildrenUpdate update) {
      136: // Get the instance of the service. Note that there is no race condition
      137: // in getting the service since this method is called only in the
      138: // service executor thread.
      139: final PDACommandControl commandControl = getServicesTracker().getService(PDACommandControl.class);

      141: // Check if the service is available. If it is not, no elements are
      142: // updated.
      143: if (commandControl == null) {
      144: handleFailedUpdate(update);
      145: return;
      146: }
      147:
      148: update.setChild(createVMContext(commandControl.getProgramDMContext()), 0);
      149: update.done();
      150: }
      +

      +
      +
      +
      +
        +
      • Line 120 overrides the AbstractDMVMNode.update(IChildrenUpdate[]) +update in order to update the terminated element if the PDA program is +already terminated.  The super-class implementation only changes +the execution thread to the DSF session and calls updateElementsInSessionThread(), +which is not needed nor possible after the PDA program is terminated.
      • +
      • Line 126 cretes the dummy View Model context which represents a +terminated PDA program.
      • +
      • Line 135 implements the elements update method which is called in +the DSF session thread. 
        +
      • +
      • Line 139 retrieves the PDACommandControl service and line 143 +confirms that it is still available.  Normally if the DSF session +is still active, then the service should also be available.  +However if the session is in the process of shutting down, this call +may be caught in a race condition, therefore a check if service is +available is necessary.
      • +
      +

      Label

      +Calculating the label for the PDA program element is also split into +two parts depending on whether the program is terminated.  +Similarly as when calculating the element, if the program is +terminated, the label is calculated in the View Model thread, if the +program is running, the execution is switched to the session executor +thread.  This is accomplished in the update(ILabelUpdate[]) +implementation:
      +
      +
      + + + + + + + + + + +
      org.eclipse.dd.examples.pda.ui.viewmodel.launch.PDALaunchVMNode +- update(ILabelUpdate[]) +

      +
      +
      152:     public void update(final ILabelUpdate[] updates) {
      153: for (final ILabelUpdate update : updates) {
      154: if (update.getElement() instanceof TerminatedProgramVMContext) {
      155: // If the element is a terminated program, update the label
      156: // in the View Model thread.
      157: updateTerminatedThreadLabel(update);
      158: } else {
      159: // If the element is the PDA Program context, try to switch
      160: // to the DSF session thread before updating the label.
      161: try {
      162: getSession().getExecutor().execute(new DsfRunnable() {
      163: public void run() {
      164: updateProgramLabelInSessionThread(update);
      165: }});
      166: } catch (RejectedExecutionException e) {
      167: // Acceptable race condition: DSF session terminated.
      168: handleFailedUpdate(update);
      169: }
      170: }
      171: }
      172: }
      +
      +
      +
        +
      • Line 153 iterates through the udptes. The +IElementLabelProvider.update() method takes an array of updates as an +argument to allow the implementation to process the udpates in bunches, +improving performance. 
        +
      • +
      • Line 157 calls a subroutine to handle the terminated program +label.
      • +
      • Lines 161-169 call a subroutine to update the active program's +session.  The execution thread is first changed to the session +executor thread.
      • +
      +The updateProgramLabelInSessionThread() +is rather long, but it is useful to look at it in detail because it is +representative of what all label providers must do.
      +
      +
      + + + + + + + + + + +
      org.eclipse.dd.examples.pda.ui.viewmodel.launch.PDALaunchVMNode +- updateProgramLabelInSessionThread()

      +
      +
      174:     @ConfinedToDsfExecutor("getSession().getExecutor()")
      175: private void updateProgramLabelInSessionThread(final ILabelUpdate update) {
      176: // Get a reference to the run control service.
      177: final IRunControl runControl = getServicesTracker().getService(IRunControl.class);
      178: if (runControl == null) {
      179: handleFailedUpdate(update);
      180: return;
      181: }
      182:
      183: // Find the PDA program context.
      184: final PDAProgramDMContext programCtx =
      185: findDmcInPath(update.getViewerInput(), update.getElementPath(), PDAProgramDMContext.class);

      187: // Call service to get current program state
      188: final boolean isSuspended = runControl.isSuspended(programCtx);

      190: // Set the program icon based on the running state of the program.
      191: String imageKey = null;
      192: if (isSuspended) {
      193: imageKey = IDebugUIConstants.IMG_OBJS_THREAD_SUSPENDED;
      194: } else {
      195: imageKey = IDebugUIConstants.IMG_OBJS_THREAD_RUNNING;
      196: }
      197: update.setImageDescriptor(DebugUITools.getImageDescriptor(imageKey), 0);

      199: // Retrieve the last state chagne reason
      200: runControl.getExecutionData(
      201: programCtx,
      202: new DataRequestMonitor<IExecutionDMData>(ImmediateExecutor.getInstance(), null)
      203: {
      204: @Override
      205: public void handleCompleted(){
      206: // If the request failed, fail the udpate.
      207: if (!getStatus().isOK()) {
      208: handleFailedUpdate(update);
      209: return;
      210: }
      211:
      212: // Compose the thread name string.
      213: final StringBuilder builder = new StringBuilder();
      214:
      215: builder.append("PDA [");
      216: builder.append(programCtx.getProgram());
      217: builder.append("]");
      218:
      219: if(isSuspended) {
      220: builder.append(" (Suspended");
      221: } else {
      222: builder.append(" (Running");
      223: }
      224: // Reason will be null before ContainerSuspendEvent is fired
      225: if(getData().getStateChangeReason() != null) {
      226: builder.append(" : ");
      227: builder.append(getData().getStateChangeReason());
      228: }
      229: builder.append(")");
      230: update.setLabel(builder.toString(), 0);
      231: update.done();
      232: }
      233: });
      234: }
      +
      +
      +
        +
      • Line 174 declares the routine as to be called only on the session +thread.  Accessing services on a different thread is a violation +of their API contract.
      • +
      • Lines 177-184 retrieve the IRunControl +service, always checking that the service is actually available.
      • +
      • Lines 184,185 retrieve the PDAProgramDMContext from the +update.  This context can actually be expected to be in the IDMVMConext wrapper returned by IViewerUpdate.getElement().  +However the AbstractDMVMNode.findDmcInPath() +utility method searches the full tree path in the update and is +typically used to extract the Data Model context from the update.
      • +
      • Line 188 retrieves the running state of the program using a +synchronous IRunControl.isSuspended() method.
      • +
      • Lines 191-197 calculate and update the program icon based on the +running state of the program.
      • +
      • Lines 200-233 call an asynchronous IRunControl.getExecutionData() +method to retrieve additional information about the state of the PDA +program.  The label update is completed only after request monitor +of this method is called.
      • +
      • Lines 207-210 perform error handling.
      • +
      • Lines 213-229 finally calcuate the label string for the +program. 
        +
      • +
      • On line 227, The result of the getExecutionData() +call, accessed using DataRequestMonitor.getData(), +is used to fill in the reason for the current state of the program.
      • +
      • Line 230 writes the label to the upate.  This call assumes +that there is no columns in Debug view, so it uses 0 as the column index.
        +
      • +
      +

      Delta

      +Translating the Data Model events into IModelDelta objects that can be +processed by the Flehible Hierarchy views, is the most complicated task +performed by the View Model infrastructure.  The model deltas +require that a path be formed by the IModelDelta objects which matches +the hierarchy elements found in the view, including such details as +indexes of elements and their number at each level.  Normally this +requires that the model event handler should know the full hierarchy of +the elements in a given view.  However, with the DSF View Model, +this logic is split into two parts:
      +
        +
      1. The event handler in the VM Provider
      2. +
      3. The build delta methods in the VM Nodes.
      4. +
      +The debug model event handler below is an example of the event handler +implementation in the VM Provider.  The event handler for Data +Model events is already implemented in the AbstractDMVMProvider base class:
      +
      +
      + + + + + + + + + + +
      org.eclipse.dd.examples.pda.ui.viewmodel.launch.PDALaunchVMProvider +- handleDebugEvents()
      +
       73:     public void handleDebugEvents(final DebugEvent[] events) {
      74: if (isDisposed()) return;
      75:
      76: // This method may be called on any thread. Switch to the
      77: // view model executor thread before processing.
      78: try {
      79: getExecutor().execute(new Runnable() {
      80: public void run() {
      81: if (isDisposed()) return;
      82:
      83: for (final DebugEvent event : events) {
      84: handleEvent(event);
      85: }
      86: }});
      87: } catch (RejectedExecutionException e) {
      88: // Ignore. This exception could be thrown if the view model is being
      89: // shut down.
      90: }
      91: }
      +

      +
      +
      +
        +
      • Line 84 calls the base class handleEvent() +method which does the hard work care of calling the VM Nodes to build +and send the delta to the views.
      • +
      +The PDA program node implements methods to add the delta nodes for its +elements:
      +
      +
      + + + + + + + + + + +
      org.eclipse.dd.examples.pda.ui.viewmodel.launch.PDALaunchVMNode +- buildDelta()

      +
      +
      265:     public int getDeltaFlags(Object e) {
      266: if(e instanceof IResumedDMEvent || e instanceof ISuspendedDMEvent) {
      267: return IModelDelta.STATE;
      268: }
      269: if (e instanceof PDAStartedEvent) {
      270: return IModelDelta.EXPAND | IModelDelta.SELECT;
      271: }
      272: return IModelDelta.NO_CHANGE;
      273: }
      274:
      275: public void buildDelta(Object e, VMDelta parentDelta, int nodeOffset, RequestMonitor rm) {
      276: if(e instanceof IResumedDMEvent || e instanceof ISuspendedDMEvent) {
      277: // If a suspended/resumed event is received, just update the
      278: // state of the program. StackFramesVMNode will take care of
      279: // refreshing the stack frames.
      280: parentDelta.addNode(createVMContext(((IDMEvent<?>)e).getDMContext()), IModelDelta.STATE);
      281: }
      282: if (e instanceof PDAStartedEvent) {
      283: // When debug session is started expand and select the program.
      284: // If the program hits a breakpoint, the top stack frame will then
      285: // be selected.
      286: parentDelta.addNode(createVMContext(((PDAStartedEvent)e).getDMContext()), IModelDelta.EXPAND | IModelDelta.SELECT);
      287: }
      288: rm.done();
      289: }
      290: }
      +
      +
      +
        +
      • Lines 265-273 implement the synchronous +IVMNode.getDeltaFlags().  This method only needs to return what +flags this node may create +for the given event and it is used optimize the logic of building the +model deltas.
      • +
      • Line 270 tells the View Model logic that this node may add the +IModelDelta.EXPAND and IModelDelta.SELECT flags.  These flags are +especially costly in calculating the delta, because they require +calculating of indexes and element counts for all nodes in the path to +this node.
      • +
      • Lines 276-281 handle the run control events.  They tell the +view to refresh the label of the PDA program.  The flags needed to +refresh the stack frames are added to the delta by the +StackFramesVMNode.
      • +
      • Line 280 adds a delta element to the parent delta.  With a +call to AbstractDMVMNode.createVMContext(), +it creates a wrapper element based on the Data Model context contained +in the event. 
        +
      • +
      • Lines 282-287 handle the started event, which is issued when the +PDACommandControl service is initialized.  It causes the PDA +context to be selected.
        +
      • +
      • Line 288 completes the execution of this asynchronous method.
      • +
      + + + + + + +
      Note: In theory, each VM Node +should only generate delta flags that only affect its own +elements.  In this way, the layout of the VM Nodes in a view could +be costomized as needed.  In practice, testing and fine-tuning of +the view requires adjustments in the flags returned by the various VM +Nodes in a given view.
      +

      Step 4 - Run Control

      +Up to this point most of the work in creating the new PDA debugger has +gone into infrastructure.  Now it is time to start adding +functionality to do some actual debugging.  The work needed to get +run control functionality implemented is all encapsulated in the PDARunControl service.
      +

      State Tracking

      +The primary function of the run control system is to track the current +execution state of the program and to issue the corresponding events to +the run control service clients.  Both of these tasks are +accomplished by the ICommandControl's IEventListner.eventReceived() +implementation in combination with service event handlers for +IRunControl.IResumedDMEvent and IRunControl.ISuspendedDMEvent.  It +may seem odd that the run control service is listening to its own +events in order to change its internal state, but doing so guarantees +that the execution state reported by the service is consistent with the +events it sends out.
      +
      +
      + + + + + + + + + + +
      org.eclipse.dd.examples.pda.service.PDARunControl +- eventReceived()

      +
      +
      181:     public void eventReceived(Object output) {
      182: if (!(output instanceof String)) return;
      183: String event = (String)output;
      184:
      185: // Handle PDA debugger suspended/resumed events and issue the
      186: // corresponding Data Model events. Do not update the state
      187: // information until we start dispatching the service events.
      188: if (event.startsWith("suspended")) {
      189: IDMEvent<?> dmEvent = new SuspendedEvent(fCommandControl.getProgramDMContext(), event);
      190: getSession().dispatchEvent(dmEvent, getProperties());
      191: } else if (event.startsWith("resumed")) {
      192: IDMEvent<?> dmEvent = new ResumedEvent(fCommandControl.getProgramDMContext(), event);
      193: getSession().dispatchEvent(dmEvent, getProperties());
      194: }
      195: }
      196:
      197:
      198: @DsfServiceEventHandler
      199: public void eventDispatched(ResumedEvent e) {
      200: // This service should be the first to receive the ResumedEvent,
      201: // (before any other listeners are called). Here, update the
      202: // service state information based on the the resumed event.
      203: fSuspended = false;
      204: fResumePending = false;
      205: fStateChangeReason = e.getReason();
      206: fStepping = e.getReason().equals(StateChangeReason.STEP);
      207: }
      208:
      209:
      210: @DsfServiceEventHandler
      211: public void eventDispatched(SuspendedEvent e) {
      212: // This service should be the first to receive the SuspendedEvent also,
      213: // (before any other listeners are called). Here, update the
      214: // service state information based on the the suspended event.
      215: fStateChangeReason = e.getReason();
      216: fResumePending = false;
      217: fSuspended = true;
      218: fStepping = false;
      219: }
      +
      +
        -
      • Cut and Paste
      • +
      • Lines 181-195 implement the IEventListener.eventReceived() +method.  This method is called any time an out of band record is +received from the PDA debugger. 
        +
      • +
      • Lines 182, 183 cast the opaque output object from PDA debugger to +a String.  The type of this object depends on the specific +debugger connection implementation.  For the PDA debugger, the +events are always a String.
      • +
      • Lines 188-193 generate the suspended/resumed Data Model events.
      • +
      • Lines 199-207 implement the ResumedEvent Data Model event +handler.  This handler is guaranteed to be called first by the DSF +service event framework, before any other listeners are called. It +updates the flags tracking the current state of the debugger.  As +usual, no synchronization is needed because these flags can only be +modified in the session executor thread.
      • +
      • Line 205 retrieves the state change reason from the resumed +event.  This reason is calculated by the ResumedEvent constructor based on +the event string received from the PDA debugger.
      • +
      • Lines 211-219 update the state flags based on the stopped event.
      -

      Launching
      -

      +One remarkable aspect of the state tracking logic is the use of the fResumePending flag.  This +flag is set to true when a resume or step command is sent to the PDA +debugger.  It is then used by the canResume() method to disallow +sending another resume command.  This kind of predictive state +logic an improve the efficiency of the IDE commands.
      +
      +
      + + + + + + + + + + +
      org.eclipse.dd.examples.pda.service.PDARunControl +- canResume()

      +
      +
      222:     public boolean canResume(IExecutionDMContext context) {
      223: return isSuspended(context) && !fResumePending;
      224: }
      +
      +
      +

      Commands

      +The command control commands all follow the same patter shown below by +example of the resume() command:
      +
      +
      + + + + + + + + + + +
      org.eclipse.dd.examples.pda.service.PDARunControl +- resume()

      +
      +
      238:     public void resume(IExecutionDMContext context, final RequestMonitor rm) {
      239: assert context != null;
      240:
      241: if (canResume(context)) {
      242: fResumePending = true;
      243: fCommandControl.queueCommand(
      244: new PDAResumeCommand(fCommandControl.getProgramDMContext()),
      245: new DataRequestMonitor<PDACommandResult>(getExecutor(), rm) {
      246: @Override
      247: protected void handleErrorOrCancel() {
      248: // If the resume command failed, we no longer
      249: // expect to receive a resumed event.
      250: fResumePending = false;
      251: super.handleErrorOrCancel();
      252: }
      253: }
      254: );
      255: } else {
      256: PDAPlugin.failRequest(rm, INVALID_STATE, "Given context: " + context + ", is already running.");
      257: }
      258: }
      +
      +
        -
      • Create custom launch object PDALaunch
      • -
      -
       51:     public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) throws CoreException {

      52: // Need to configure the source locator before creating the launch
      53: // because once the launch is created and added to launch manager,
      54: // the adapters will be created for the whole session, including
      55: // the source lookup adapter.
      56: ISourceLocator locator = getSourceLocator(configuration);

      58: return new PDALaunch(configuration, mode, locator);
      59: }
      -
        -
      • Creating DSF session and executor
      • -
      • Services Initialize Sequence
      • -
      • Optional diagram showing the relationship between the above
      • -
      • Shutting down (is hard to do)
        +
      • Line 241 checks if the resume command can be called.  If +not, the command fails immediately.
      • +
      • Line 242 updates the fResumePending +state flag.
      • +
      • Lines 244-253 send the resume command to the PDA debugger.
        +
      • +
      • Lines 247-252 adds error handling in case the result command +fails.  It resotres the service state.
      • +
      • Line 251 calls the super class's handleErrorOrCancel() +method.  The super class relays the error status to the parent +request monitor and completes it.
      -

      Connecting
      -

      -
        -
      • First service, mechanics of DSF services?
      • -
      • Sockets, queues, synchronization
      • -
      • Diagram showing relationship of different command control -components
        -
      • -
      • Event and command listeners
        -
      • -
      -

      View Model

      -
        -
      • The adapter glue
      • -
      • View Model components
        -
      • -
      • Launch view VM provider
      • -
      • Program VM Node
        -
      • -
      -

      Run Control

      • Second service, depends on command control
      • Tracking program running state
      -

      Breakpoints

      +

      IExecutionDMData

      +There is very little data that the run control servie interface returns +for a given execution context.  The intention behind this is to +allow the service to remain very generic and thus applicable to any +debugger.  In specific debuggers, additional data about processes, +threads, cores, etc, should be retrieved from other services or service +extensions.  IExpressionDMData is the only object which is +retrieved asynchronously from the run control service, and it only +contains the state change reason for the last debugger state +change. 
      +

      Step 5 - Breakpoints

      +Managing breakpoints is one of the complicated tasks that need to be +implemented by Eclipse debuggers.  The source of this complexity +is the fact that Eclipse breakpoints (IDE breakpoints) are managed +independently of breakpoints that are installed in the debugger +(target-side breakpoints).  The Eclipse debugger integration has +to keep these two sets of breakpoints synchronized. 
      +

      IDE Breakpoints

      +Eclipse breakpoints are based on markers, which are special tags in the +Eclispe resource system and are associated with files and +folders.  By using markers, breakpoints gain the benefit of the +resource system synchronization mechanism and the automatic +persistence.  Also some other cool features such as adjusting the +breakpoint line number when the source file is edited, are also +automatically gained by using markers. 
      +

      An eclipse breakpoint declaration comes in three parts:
      +

      +
        +
      1. org.eclipse.core.resources.markers extension - A debugger must +use this extension to declare a marker type for the new +breakpoint.  Markers are hierarchical and a breakpoint should have +one of the platform breakpoint objects as a super type.
      2. +
      3. org.eclipse.debug.core.breakpoints extension - A breakpoint must +be declared using this extension point, which requires a valid marker +type.
      4. +
      5. org.eclipse.debug.core.model.IBreakpoint implementation - A +breakpoint object must implement this interface.
      6. +
      +Finally, in order to have breakpoints to appear in the Breakpoints +view, they need to be registered with the breakpoint manager, which is +represented by the org.eclipse.debug.core.IBreakpointManager +interface.  The breakpoint manager also relays events for +notifying of breakpoint changes and for a debugger it is the central +object used to find the IDE breakpoints that need to be installed on +target.
      +
      +Code listings are omitted here since implementing Eclipse breakpoints +is described in fine detail the How +to write an Eclipse debugger article.
      +

      +

      Target-Side Breakpoints

      +DSF defines the IBreakpoints interface for a service which the fuctions +of managing breakpoints installed on the target.  These functions +include:
      +
        +
      • Installing a breakpoint
        +
      • +
      • removing a breakpoint
      • +
      • changing breakpoint attributes (if supported)
      • +
      • listing installed breakpoints
      • +
      • retrieving breakpoint detailed data
      • +
      +

      Breakpoint Context
      +

      +It is expected that primary client of this service is going to be +another service which reads IDE Breakpoints, however under certain +circumstances such as launching or testing, this interface could be +used by other clients, therefore it is desirable that the interface +itself should not have any dependencies on the IDE Breakpoint +API.  To remain generic, the attributes for breakpoints to be +created or update are specified using a simple property bag of type: Map<String, Object>.  +After the target-side breakpoint is created, it is represented using an +opaque Data Model context of type IBreakpointDMContext.  +As an example the PDA line breakpoint context implementation is the +following:
      +
      +
      + + + + + + + + + + +
      org.eclipse.dd.examples.pda.service.PDABreakpoints +- BreakpointDMContext

      +
      +
       50:     private static class BreakpointDMContext extends AbstractDMContext implements IBreakpointDMContext {
      51:
      52: final Integer fLine;
      53:
      54: public BreakpointDMContext(String sessionId, PDAProgramDMContext commandControlCtx, Integer line) {
      55: super(sessionId, new IDMContext[] { commandControlCtx });
      56: fLine = line;
      57: }
      58:
      59: @Override
      60: public boolean equals(Object obj) {
      61: return baseEquals(obj) && (fLine.equals(((BreakpointDMContext) obj).fLine));
      62: }
      63:
      64: @Override
      65: public int hashCode() {
      66: return baseHashCode() + fLine.hashCode();
      67: }
      68:
      69: @Override
      70: public String toString() {
      71: return baseToString() + ".breakpoint(" + fLine + ")"; //$NON-NLS-1$//$NON-NLS-2$*/
      72: }
      73: }

      +
      +
      +
        +
      • Line 52 declares the fLine variable, which uniquely identifies a +line breakpoint in a PDA debug session.
      • +
      +It is also important to note that the IBreakpoints interface is +designed to work with debuggers that can track separate breakpoint sets +for different cores/processes/threads.  Each context which +represents a "breakpoint space" must implement an IBreakpointsTargetDMContext +interface, which is then used as a parent context of the IBreakpointDMContext object +instances.
      +

      Inserting a Breakpoint

      +PDA debugger supports two types of breakpoints.  The +IBreakpoints.insertBreakpoint() implementation performs the task of +what type of breakpoint should be installed and delegates to the proper +subroutine:
      +
      +
      + + + + + + + + + + +
      org.eclipse.dd.examples.pda.service.PDABreakpoints +- insertBreakpoint()

      +
      +
      180:         public void insertBreakpoint(IBreakpointsTargetDMContext context, Map<String, Object> attributes, 
      181: DataRequestMonitor<IBreakpointDMContext> rm)
      182: {
      183: Boolean enabled = (Boolean)attributes.get(IBreakpoint.ENABLED);
      184: if (enabled != null && !enabled.booleanValue()) {
      185: // If the breakpoint is disabled, just fail the request.
      186: PDAPlugin.failRequest(rm, REQUEST_FAILED, "Breakpoint is disabled");
      187: } else {
      188: String type = (String) attributes.get(ATTR_BREAKPOINT_TYPE);
      189:
      190: if (PDA_LINE_BREAKPOINT.equals(type)) {
      191: // Retrieve the PDA program context from the context given in the
      192: // argument. This service is typically only called by the
      193: // breakpoints mediator, which was called with the program context
      194: // in the services initialization sequence. So checking if
      195: // programCtx != null is mostly a formality.
      196: PDAProgramDMContext programCtx = DMContexts.getAncestorOfType(context, PDAProgramDMContext.class);
      197: if (programCtx != null) {
      198: doInsertBreakpoint(programCtx, attributes, rm);
      199: } else {
      200: PDAPlugin.failRequest(rm, INVALID_HANDLE, "Unknown breakpoint type");
      201: }
      202: }
      203: else if (PDA_WATCHPOINT.equals(type)) {
      204: doInsertWatchpoint(attributes, rm);
      205: }
      206: else {
      207: PDAPlugin.failRequest(rm, REQUEST_FAILED, "Unknown breakpoint type");
      208: }
      209: }
      210: }
      +
      +
      +
        +
      • Lines 183-186 determine if the breakpoint is enabled.  If it +is not, the insert command fails with an expected error. 
        +
      • +
      • Line 188 retrieves the breakpoint type attribute, shich is used +to determine which breakpoint insert subroutine to call.
      • +
      • Line 196 retrieves the PDAProgramDMContext +from the breakpoint target context.  This context is the only +breakpoints target context in the PDA debugger.
      • +
      • Finally, lines 198 and 207 delegate to the proper subroutine to +create the breakpoint.
      • +
      +The doInserBreakpoint() subroutine is listed next:
      +
      +
      + + + + + + + + + + +
      org.eclipse.dd.examples.pda.service.PDABreakpoints +- doInsertBreakpoint()

      +
      +
      212:     private void doInsertBreakpoint(PDAProgramDMContext programCtx, final Map<String, Object> attributes, final DataRequestMonitor<IBreakpointDMContext> rm) 
      213: {
      214: // Compare the program path in the breakpoint with the path in the PDA
      215: // program context. Only insert the breakpoint if the program matches.
      216: String program = (String)attributes.get(ATTR_PROGRAM_PATH);
      217: if (!programCtx.getProgram().equals(program)) {
      218: PDAPlugin.failRequest(rm, REQUEST_FAILED, "Invalid file name");
      219: return;
      220: }

      222: // Retrieve the line.
      223: Integer line = (Integer)attributes.get(IMarker.LINE_NUMBER);
      224: if (line == null) {
      225: PDAPlugin.failRequest(rm, REQUEST_FAILED, "No breakpoint line specified");
      226: return;
      227: }

      229: // Create a new breakpoint context object and check that it's not
      230: // installed already. PDA can only track a single breakpoint at a
      231: // given line, attempting to set the second breakpoint should fail.
      232: final BreakpointDMContext breakpointCtx =
      233: new BreakpointDMContext(getSession().getId(), fCommandControl.getProgramDMContext(), line);
      234: if (fBreakpoints.contains(breakpointCtx)) {
      235: PDAPlugin.failRequest(rm, REQUEST_FAILED, "Breakpoint already set");
      236: return;
      237: }

      239: // Add the new breakpoint context to the list of known breakpoints.
      240: // Adding it here, before the set command is completed will prevent
      241: // a possibility of a second breakpoint being installed in the same
      242: // location while this breakpoint is being processed. It will also
      243: // allow the breakpoint to be removed or updated even while it is
      244: // still being processed here.
      245: fBreakpoints.add(breakpointCtx);
      246: fCommandControl.queueCommand(
      247: new PDASetBreakpointCommand(fCommandControl.getProgramDMContext(), line),
      248: new DataRequestMonitor<PDACommandResult>(getExecutor(), rm) {
      249: @Override
      250: protected void handleOK() {
      251: rm.setData(breakpointCtx);
      252: rm.done();
      253: }

      255: @Override
      256: protected void handleErrorOrCancel() {
      257: // If inserting of the breakpoint failed, remove it from
      258: // the set of installed breakpoints.
      259: fBreakpoints.remove(breakpointCtx);
      260: super.handleErrorOrCancel();
      261: }
      262: });
      263: }

      +
      +
      +

      Removing a Breakpoint

      +The PDABreakpoints.removeBreakpoint() command takes the +IBreakpointDMContext as an argument, but otherwise follows the same +general logic as the insertBreakpoint() implementation.
      +

      Updating a Breakpoint

      +Updating a breakpoint involves motifying some of the attributes of an +existing breakpoint.  Not all debuggers may support this +functionality and for debuggers that do, not all types of breakpoints +and not all attributes may be updated.  The IBreakpoints interface +does not provide a way for the clients to discover what breakpoints and +what attributes may be updated.  It is up to the client to know +this information in advance. 
      +

      The PDA debugger allows watchpoints to be updated, but only with +respect to what operations may trigger the watchpoint:
      +

      +
      + + + + + + + + + + +
      org.eclipse.dd.examples.pda.service.PDABreakpoints +- updateBreakpoint()

      +
      +
      367:     public void updateBreakpoint(final IBreakpointDMContext bpCtx, Map<String, Object> attributes, final RequestMonitor rm) {
      368: if (!fBreakpoints.contains(bpCtx)) {
      369: PDAPlugin.failRequest(rm, REQUEST_FAILED, "Breakpoint not installed");
      370: return;
      371: }

      373: if (bpCtx instanceof BreakpointDMContext) {
      374: PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Modifying PDA breakpoints is not supported");
      375: } else if (bpCtx instanceof WatchpointDMContext) {
      376: WatchpointDMContext wpCtx = (WatchpointDMContext)bpCtx;
      377: if (!wpCtx.fFunction.equals(attributes.get(PDAWatchpoint.FUNCTION_NAME)) ||
      378: !wpCtx.fVariable.equals(attributes.get(PDAWatchpoint.VAR_NAME)) )
      379: {
      380: PDAPlugin.failRequest(rm, REQUEST_FAILED, "Cannot modify watchpoint function or variable");
      381: return;
      382: }
      383:
      384: // PDA debugger can only track one watchpoint in the same location,
      385: // so we can simply remove the existing context from the set and
      386: // call insert again.
      387: fBreakpoints.remove(bpCtx);
      388: doInsertWatchpoint(
      389: attributes,
      390: new DataRequestMonitor<IBreakpointDMContext>(getExecutor(), rm) {
      391: @Override
      392: protected void handleOK() {
      393: // The inserted watchpoint context will equal the
      394: // current context.
      395: assert bpCtx.equals(getData());
      396: rm.done();
      397: }
      398: });
      399: } else {
      400: PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid breakpoint");
      401: }
      402: }

      +
      +
      +
        +
      • Lines 368-371 verify that the given breakpoint exists.  If +it does not exist the update request fails. 
        +
      • +
      • Lines 377-382 verify that only the data access attributes of the +watchpoint were modified.
      • +
      • Lines 387 -398 re-insert the watchpoint which effectively updates +the watchpoint attributes.
        +
      • +
      • Target Side Breakpoints
      • Mediator
      • Diagram showing Mediator's role
      -

      Stack

      +

      Step 6 - Stack

      • Command Cache at work
      -

      Source Display

      +

      Step 7 - Source Display

      • Source lookup director
      -

      Variables

      +

      Step 8 - Variables

      • Reading and writing variables
      • @@ -150,5 +2232,23 @@ components
      • Expressions view
      +
      + + + + + + + + + + +
      org.eclipse.dd.examples.dsf.timers.TimersVMNode +

      +

      +
      +
      From 5a1d9522fa6cc40a14c88709ac5a81e959c230b5 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 12 Mar 2008 19:35:38 +0000 Subject: [PATCH 295/834] [220446] Updated the "PDA Debugger Introduction" document. --- .../docs/pda/pda_tutorial_outline.html | 37 ++++++++++++++++++- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/pda/pda_tutorial_outline.html b/plugins/org.eclipse.dd.doc.dsf/docs/pda/pda_tutorial_outline.html index ff01755a0c8..f87e58b80c8 100644 --- a/plugins/org.eclipse.dd.doc.dsf/docs/pda/pda_tutorial_outline.html +++ b/plugins/org.eclipse.dd.doc.dsf/docs/pda/pda_tutorial_outline.html @@ -2205,9 +2205,42 @@ it does not exist the update request fails. 
    • Lines 377-382 verify that only the data access attributes of the watchpoint were modified.
    • Lines 387 -398 re-insert the watchpoint which effectively updates -the watchpoint attributes.
      -
    • +the watchpoint attributes. +

      Listing Breakpoints

      +The PDA Breakpoints service tracks the inserted breakpoints using the fBreakpoints field.  Returning +the list of breakpoints only requires returning the current state of +this field.
      +

      Retrieving Breakpoint Detailed Data

      +The simple PDA debugger does not track detailed breakpoint data, such +has hit counts, addresses etc.  So this function simply returns an +error.
      +

      Breakpoints Mediator

      +With the APIs for managing IDE and Target-Side breakpoints clearly +defined, there is a need for a component which will keep the two sets +of breakpoint objects synchronized.  DSF provides a standard +BreakpointsMediator service to accomplish this task. 
      + + + + + + + + + +

      +
      Image 3: Mediating IDE and Target-Side +breakpoints
      +
      +
      +
      • Target Side Breakpoints
      • Mediator
      • From c27cddf3c7a3813602d068af2b42723f0ae3c667 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 12 Mar 2008 19:38:12 +0000 Subject: [PATCH 296/834] [220446] Updated Excercise 3 instructions. --- .../dd/examples/dsf/requestmonitor/AsyncQuicksort.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/requestmonitor/AsyncQuicksort.java b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/requestmonitor/AsyncQuicksort.java index f1ff70d406c..1f7c12de2d0 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/requestmonitor/AsyncQuicksort.java +++ b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/requestmonitor/AsyncQuicksort.java @@ -113,8 +113,10 @@ public class AsyncQuicksort { // a request monitor. return store; //#else - //# rm.setData(store); - //# rm.done(); +//# // Java 5 automatically converts the int type of the store variable +//# // to an Integer object. +//# rm.setData(store); +//# rm.done(); //#endif } From 7586dfa95a65e3fd04b10f341433557af7ce7215 Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Wed, 12 Mar 2008 20:54:36 +0000 Subject: [PATCH 297/834] Bugzilla 220446. Changed the spelling of excercises to exercises throuhgout the code/examples and build processes. --- .../build_preprocess.xml | 2 +- .../filebrowser/FileBrowserModelAdapter.java | 4 +- .../dsf/dataviewer/AsyncDataViewer.java | 2 +- .../dataviewer/DataGeneratorWithExecutor.java | 54 +++++++++---------- .../dataviewer/DataGeneratorWithThread.java | 2 +- .../dsf/dataviewer/IDataGenerator.java | 4 +- .../dsf/dataviewer/SyncDataViewer.java | 10 ++-- .../dsf/requestmonitor/Async2Plus2.java | 2 +- .../dsf/requestmonitor/AsyncHelloWorld.java | 6 +-- .../dsf/requestmonitor/AsyncQuicksort.java | 8 +-- .../tests/dsf/concurrent/DsfQueryTests.java | 2 +- .../dsf/concurrent/DsfSequenceTests.java | 2 +- 12 files changed, 49 insertions(+), 49 deletions(-) diff --git a/plugins/org.eclipse.dd.examples.dsf/build_preprocess.xml b/plugins/org.eclipse.dd.examples.dsf/build_preprocess.xml index a0cb444f0d3..70e3d4beaf5 100644 --- a/plugins/org.eclipse.dd.examples.dsf/build_preprocess.xml +++ b/plugins/org.eclipse.dd.examples.dsf/build_preprocess.xml @@ -37,7 +37,7 @@ - + diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileBrowserModelAdapter.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileBrowserModelAdapter.java index d77d489a7be..a91aa54f8ef 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileBrowserModelAdapter.java +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileBrowserModelAdapter.java @@ -24,8 +24,8 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationCont * IDMContext.getAdapter() and IVMContext.getAdapter() methods, * which both call {@link DsfSession#getModelAdapter(Class)}. *

        - * The adapter implementation for this excercise is hard-coded to provide - * contents for only one view. In turn the view contens are determined using + * The adapter implementation for this exercise is hard-coded to provide + * contents for only one view. In turn the view contents are determined using * the configurable ViewModelProvider. For demonstration purposes, this model * adapter has two different layout configurations that can be used. These * layout configurations can be set by calling the {@link #setViewLayout} method. diff --git a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/AsyncDataViewer.java b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/AsyncDataViewer.java index 35f928b0b64..b9e04d83d2b 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/AsyncDataViewer.java +++ b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/AsyncDataViewer.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -//#ifdef excercises +//#ifdef exercises package org.eclipse.dd.examples.dsf.dataviewer; //#else //#package org.eclipse.dd.examples.dsf.dataviewer.answers; diff --git a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithExecutor.java b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithExecutor.java index d3c392c8e2c..74eeb8c87a6 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithExecutor.java +++ b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithExecutor.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -//#ifdef excercises +//#ifdef exercises package org.eclipse.dd.examples.dsf.dataviewer; //#else //#package org.eclipse.dd.examples.dsf.dataviewer.answers; @@ -49,7 +49,7 @@ import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; * be accessed while running in the executor thread. *

        */ -//#ifdef excercises +//#ifdef exercises //TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) //indicating allowed thread access to this class/method/member //#else @@ -59,8 +59,8 @@ public class DataGeneratorWithExecutor implements IDataGenerator { // Request objects are used to serialize the interface calls into objects // which can then be pushed into a queue. - //#ifdef excercises - // TODO Excercise 4 - Add an annotationindicating allowed concurrency access + //#ifdef exercises + // TODO Ecercise 4 - Add an annotationindicating allowed concurrency access // Hint: Request and its subclasses have all their fields declared as final. //#else //# @Immutable @@ -73,7 +73,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { } } - //#ifdef excercises + //#ifdef exercises // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) // indicating allowed thread access to this class/method/member //#else @@ -85,7 +85,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { } } - //#ifdef excercises + //#ifdef exercises // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) // indicating allowed thread access to this class/method/member //#else @@ -100,7 +100,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { } // The executor used to access all internal data of the generator. - //#ifdef excercises + //#ifdef exercises // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) // indicating allowed thread access to this class/method/member // Hint: If a member does not have an annotation, the programmer can assume @@ -113,7 +113,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { // and shutdown() methods write into the queue, while the serviceQueue() // method reads from it. // The executor used to access all internal data of the generator. - //#ifdef excercises + //#ifdef exercises // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) // indicating allowed thread access to this class/method/member //#else @@ -123,7 +123,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { // List of listeners is not synchronized, it also has to be accessed // using the executor. - //#ifdef excercises + //#ifdef exercises // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) // indicating allowed thread access to this class/method/member //#else @@ -132,7 +132,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { private List fListeners = new LinkedList(); // Current number of elements in this generator. - //#ifdef excercises + //#ifdef exercises // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) // indicating allowed thread access to this class/method/member //#else @@ -141,7 +141,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { private int fCount = MIN_COUNT; // Counter used to determine when to reset the element count. - //#ifdef excercises + //#ifdef exercises // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) // indicating allowed thread access to this class/method/member //#else @@ -150,7 +150,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { private int fCountResetTrigger = 0; // Elements which were modified since the last reset. - //#ifdef excercises + //#ifdef exercises // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) // indicating allowed thread access to this class/method/member //#else @@ -159,7 +159,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { private Set fChangedIndexes = new HashSet(); // Flag used to ensure that requests are processed sequentially. - //#ifdef excercises + //#ifdef exercises // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) // indicating allowed thread access to this class/method/member //#else @@ -167,7 +167,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { //#endif private boolean fServiceQueueInProgress = false; - //#ifdef excercises + //#ifdef exercises // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) // indicating allowed thread access to this class/method/member //#endif @@ -187,7 +187,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { TimeUnit.MILLISECONDS); } - //#ifdef excercises + //#ifdef exercises // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) // indicating allowed thread access to this class/method/member //#endif @@ -214,7 +214,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { } } - //#ifdef excercises + //#ifdef exercises // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) // indicating allowed thread access to this class/method/member //#endif @@ -232,7 +232,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { } } - //#ifdef excercises + //#ifdef exercises // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) // indicating allowed thread access to this class/method/member //#endif @@ -250,7 +250,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { } } - //#ifdef excercises + //#ifdef exercises // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) // indicating allowed thread access to this class/method/member //#endif @@ -264,7 +264,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { } catch (RejectedExecutionException e) {} } - //#ifdef excercises + //#ifdef exercises // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) // indicating allowed thread access to this class/method/member //#endif @@ -279,7 +279,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { } // Main processing function of this generator. - //#ifdef excercises + //#ifdef exercises // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) // indicating allowed thread access to this class/method/member //#else @@ -287,8 +287,8 @@ public class DataGeneratorWithExecutor implements IDataGenerator { //#endif private void serviceQueue() { - //#ifdef excercises - // TODO Excercise 3 - Add logic to discard requests from queue. + //#ifdef exercises + // TODO Exercise 3 - Add logic to discard cancelled requests from queue. // Hint: Since serviceQueue() is called using the executor, and the // fQueue list can only be modified when running in the executor // thread. This method can safely iterate and modify fQueue without @@ -335,7 +335,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { } } - //#ifdef excercises + //#ifdef exercises // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) // indicating allowed thread access to this class/method/member //#else @@ -349,7 +349,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { rm.done(); } - //#ifdef excercises + //#ifdef exercises // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) // indicating allowed thread access to this class/method/member //#else @@ -370,7 +370,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { /** * This method simulates changes in the supplier's data set. */ - //#ifdef excercises + //#ifdef exercises // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) // indicating allowed thread access to this class/method/member //#else @@ -389,7 +389,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { /** * Calculates new size for provider's data set. */ - //#ifdef excercises + //#ifdef exercises // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) // indicating allowed thread access to this class/method/member //#else @@ -412,7 +412,7 @@ public class DataGeneratorWithExecutor implements IDataGenerator { /** * Invalidates a random range of indexes. */ - //#ifdef excercises + //#ifdef exercises // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) // indicating allowed thread access to this class/method/member //#else diff --git a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithThread.java b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithThread.java index 6a4aa133dc4..1e18691eedc 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithThread.java +++ b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithThread.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -//#ifdef excercises +//#ifdef exercises package org.eclipse.dd.examples.dsf.dataviewer; //#else //#package org.eclipse.dd.examples.dsf.dataviewer.answers; diff --git a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/IDataGenerator.java b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/IDataGenerator.java index 8e54e8648b2..2d120da4ad9 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/IDataGenerator.java +++ b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/IDataGenerator.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -//#ifdef excercises +//#ifdef exercises package org.eclipse.dd.examples.dsf.dataviewer; //#else //#package org.eclipse.dd.examples.dsf.dataviewer.answers; @@ -29,7 +29,7 @@ import org.eclipse.dd.dsf.concurrent.RequestMonitor; * view to receive events indicating when the data supplied by the generator * is changed. */ -//#ifdef excercises +//#ifdef exercises // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) // indicating allowed thread access to this class/method/member //#else diff --git a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/SyncDataViewer.java b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/SyncDataViewer.java index 91e52cee3f9..b1186f236be 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/SyncDataViewer.java +++ b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/SyncDataViewer.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -//#ifdef excercises +//#ifdef exercises package org.eclipse.dd.examples.dsf.dataviewer; //#else //#package org.eclipse.dd.examples.dsf.dataviewer.answers; @@ -122,8 +122,8 @@ public class SyncDataViewer } private void refreshViewer() { - //#ifdef excercises - // TODO Excercise 5 - Add a call to getElements() to force a deadlock. + //#ifdef exercises + // TODO Exercise 5 - Add a call to getElements() to force a deadlock. //#else //# getElements(null); //#endif @@ -154,8 +154,8 @@ public class SyncDataViewer tableViewer.getControl().setLayoutData(data); // Create the data generator. - //#ifdef excercises - // TODO Excercise 5 - Use the DataGeneratorWithExecutor() instead. + //#ifdef exercises + // TODO Exercise 5 - Use the DataGeneratorWithExecutor() instead. final IDataGenerator generator = new DataGeneratorWithThread(); //#else //# final IDataGenerator generator = new DataGeneratorWithExecutor(); diff --git a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/requestmonitor/Async2Plus2.java b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/requestmonitor/Async2Plus2.java index e7146eb2ae5..3dc8c9a94b9 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/requestmonitor/Async2Plus2.java +++ b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/requestmonitor/Async2Plus2.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -//#ifdef excercises +//#ifdef exercises package org.eclipse.dd.examples.dsf.requestmonitor; //#else //#package org.eclipse.dd.examples.dsf.requestmonitor.answers; diff --git a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/requestmonitor/AsyncHelloWorld.java b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/requestmonitor/AsyncHelloWorld.java index d7f08ea312e..68cc2395805 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/requestmonitor/AsyncHelloWorld.java +++ b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/requestmonitor/AsyncHelloWorld.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -//#ifdef excercises +//#ifdef exercises package org.eclipse.dd.examples.dsf.requestmonitor; //#else //#package org.eclipse.dd.examples.dsf.requestmonitor.answers; @@ -37,7 +37,7 @@ public class AsyncHelloWorld { static void asyncHelloWorld(RequestMonitor rm) { System.out.println("Hello world"); - //#ifdef excercises + //#ifdef exercises // TODO Exercise 1: - Call the second async. "Hello world 2" method. // Hint: Calling an asynchronous method requires passing to it a // request monitor. A new request monitor can be constructed with @@ -51,7 +51,7 @@ public class AsyncHelloWorld { //#endif } - //#ifdef excercises + //#ifdef exercises // TODO: Exercise 1 - Add a second async. "Hello world 2" method. //#else //# static void asyncHelloWorld2(RequestMonitor rm) { diff --git a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/requestmonitor/AsyncQuicksort.java b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/requestmonitor/AsyncQuicksort.java index 1f7c12de2d0..84dae922109 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/requestmonitor/AsyncQuicksort.java +++ b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/requestmonitor/AsyncQuicksort.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -//#ifdef excercises +//#ifdef exercises package org.eclipse.dd.examples.dsf.requestmonitor; //#else //#package org.eclipse.dd.examples.dsf.requestmonitor.answers; @@ -51,7 +51,7 @@ public class AsyncQuicksort { { if (right > left) { int pivot = left; - //#ifdef excercises + //#ifdef exercises // TODO: Exercise 2 - Convert the call to partition into an // asynchronous call to asyncPartition(). // Hint: The rest of the code below should be executed inside @@ -84,7 +84,7 @@ public class AsyncQuicksort { } } - //#ifdef excercises + //#ifdef exercises // TODO Exercise 2 - Convert partition to an asynchronous method. // Hint: a DataRequestMonitor should be used to carry the // return value to the caller. @@ -108,7 +108,7 @@ public class AsyncQuicksort { array[right] = array[store]; array[store] = pivotValue; - //#ifdef excercises + //#ifdef exercises // TODO: Request Monitors Exercise 2 - Return the data to caller using // a request monitor. return store; diff --git a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/concurrent/DsfQueryTests.java b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/concurrent/DsfQueryTests.java index e4015eba8ae..c1f519f142a 100644 --- a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/concurrent/DsfQueryTests.java +++ b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/concurrent/DsfQueryTests.java @@ -31,7 +31,7 @@ import org.junit.Before; import org.junit.Test; /** - * Tests that excercise the Query object. + * Tests that exercise the Query object. */ public class DsfQueryTests { TestDsfExecutor fExecutor; diff --git a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/concurrent/DsfSequenceTests.java b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/concurrent/DsfSequenceTests.java index 0f1985acd73..b84c2e57367 100644 --- a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/concurrent/DsfSequenceTests.java +++ b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/concurrent/DsfSequenceTests.java @@ -30,7 +30,7 @@ import org.junit.Before; import org.junit.Test; /** - * Tests that excercise the Sequence object. + * Tests that exercise the Sequence object. */ public class DsfSequenceTests { TestDsfExecutor fExecutor; From 9504323dd53d6e502fe73ab2ba687101e947915a Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 13 Mar 2008 06:41:35 +0000 Subject: [PATCH 298/834] [220446] Updated the "PDA Debugger Introduction" document. --- .../docs/pda/pda_tutorial_outline.html | 881 +++++++++++++++--- .../docs/pda/source_display_1.dia | Bin 0 -> 2451 bytes .../docs/pda/source_display_1.png | Bin 0 -> 25113 bytes .../docs/pda/stack_1.dia | Bin 0 -> 2012 bytes 4 files changed, 744 insertions(+), 137 deletions(-) create mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/pda/source_display_1.dia create mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/pda/source_display_1.png create mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/pda/stack_1.dia diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/pda/pda_tutorial_outline.html b/plugins/org.eclipse.dd.doc.dsf/docs/pda/pda_tutorial_outline.html index f87e58b80c8..18f154334d6 100644 --- a/plugins/org.eclipse.dd.doc.dsf/docs/pda/pda_tutorial_outline.html +++ b/plugins/org.eclipse.dd.doc.dsf/docs/pda/pda_tutorial_outline.html @@ -7,17 +7,95 @@

        How to write a DSF-based debugger

        Summary

        -

        DSF

        - -

        Debug Services

        -

        TODO: remove this sesion?

        -Use of services is intended to allow for maximum level of extendability -and customization.  To achieve this, service interfaces should -encapsulate functionality that logically belongs together and at the -same time allow for a managable number of services which have a clear -hierarchy.  DSF defines a set of standard debug interfaces (in the -org.eclipse.dd.dsf.debug plugin), and supplies a set of classes that -populate the standard debug views using those interfaces (in the -org.eclipse.dd.dsf.debug.ui plugin).  However there are very few -dependencies in these service interfaces and a given debugger -implementation may leave out or replace any of them as its custom -functionality dictates. 
        -

        The standard debug service interfaces include:

        -
          -
        • BreakpiontsMediator -- Not actually an interface, but a utility service implementation which -mediates between IDE and target-side  breakpoints.
          -
        • -
        • IBreakpionts - -Service for managing target-side breakpoints.
          -
        • -
        • IDisassembly - -Service for retrieving lines of disassembly.
          -
        • -
        • IExpressions - -Service for evaluating expressions, including variables.
          -
        • -
        • IMemory - -Service for reading target memory.
          -
        • -
        • IModules - -Service for examining target executable module information.
          -
        • -
        • IRegisters - -Service for reading register data.
          -
        • -
        • IRunControl - -Service for controlling execution state of the target.
          -
        • -
        • ISourceLookup - -Service for mapping target-side to host-side source paths.  This -service is intended to be used by other services and not to replace the -platform source lookup APIs.
          -
        • -
        • IStack - Service -for reading stack information.
          -
        • -
        • ISymbols - -Service for reading symbol information about the loaded modules.
          -
        • -
        -

        Step 1 - Launching
        +

        Step 1 - Launching

        The first task in integrating a debugger in Eclipse is creating and managing the debugger process.  The Eclipse Platform provides an @@ -270,7 +296,7 @@ extensive API for this purpose, which is nicely presented in the article.  This section (as this tutorial) concentrates on the DSF-specific tasks of launching the PDA debugger.
        -

        Launch Delegate

        +

        Launch Delegate

        At first glance, there's nothing unusual about the PDA debugger launch delegate.  Just like the Debug Platform version it:
          @@ -299,7 +325,7 @@ extension interface, in order to create a custom launch object:

          -
           51:  51:  public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) throws CoreException {

          52: // Need to configure the source locator before creating the launch
          name="line55"> 55: // the source lookup adapter.
          56: ISourceLocator locator = getSourceLocator(configuration);

          58: return new PDALaunch(configuration, mode, locator);
          59: }
          + name="line59"> 59: }
          @@ -316,7 +342,7 @@ extension interface, in order to create a custom launch object:
          -

          PDALaunch

          +

          PDALaunch

          The PDALaunch object plays two main roles:
          1. Serve as the root element of the PDA View Model hierarchy
          2. @@ -513,7 +539,8 @@ these race conditions.
            -

            Launch/Shutdown Sequence

            +

            Launch/Shutdown +Sequence

            The actual task of calling the asynchronous IDsfService's initialize() and -

            Step 2 - Connecting 

            +

            Step 2 - +Connecting 

            With the launch framework in place, the debugger back end is running and the DSF session and executor are started.  The next step is to create the first service and to connect to the debugger.  DSF @@ -604,7 +632,7 @@ target state change events.
            -

            Synchronization

            +

            Synchronization

            Since there are several threads being used by the PDA Command Control protecting state data becomes very important.

            @@ -677,7 +705,7 @@ used only as a means of synchronization with the send job. flag.  It needs to be thread safe to allow the command and event processing jobs to access it.
            -
          3. Lines 86-95 declare the commuication sockets.  They are +
          4. Lines 86-95 declare the communication sockets.  They are marked as thread-safe though only used by dedicated threads after being created.
      @@ -745,10 +773,11 @@ thread. -

      Command/Event Listeners

      +

      Command/Event +Listeners

      As mentioned before there are two types of listeners that can be -registered with the comands control: event -listners and command listeners.  The most important +registered with the commands control: event +listeners and command listeners.  The most important feature of these listeners, is that they are called by the command control synchronously.  As a result of this, the command listeners can expect to see the state @@ -809,7 +838,7 @@ new command. send commands to the debugger.  The separate runnable is used to allow the command listeners to modify the queue as well. -

      PDAProgramDMContext

      +

      PDAProgramDMContext

      Finally the command control also declares a Data Model context, which is a parent to all other contexts for a given PDA debugger session.  Each command used with the command control has to @@ -820,7 +849,7 @@ instance returned by PDACommandControl.getProg However in other debuggers this context can have two other functions:
      1. To identify the command -control instnace - In debugger sessions that connect to multiple +control instance - In debugger sessions that connect to multiple back ends, the context can be used to identify which command control should process a given command.
      2. To help control @@ -828,13 +857,13 @@ debugger command protocol state - The PDA debug protocol is stateless, which means that any command acts independently of any commands that came before it.  For debuggers which do have protocol state, e.g. GDB/MI, the command control needs to check the -context of each command and set the protocol by preceeding the command +context of each command and set the protocol by preceding the command being processed with other commands.
      -

      PDA Commands

      -To increase type safetly and make the code more readable the plain text +

      PDA Commands

      +To increase type safely and make the code more readable the plain text PDA commands are abstracted using specific command objects.  Below is an example of a command class:

      @@ -933,9 +962,12 @@ immutable helps guard the integrity of these caches. -

      -

      Step 3 - View Model

      -

      Adapter Glue
      +

      +

      Step +3 - View Model

      +

      Adapter Glue

      • Line 91 creates the View Model Adapter.  This adapter is used to populate the content of all the Flexible Hierarchy debugger -views for the given PDA debugger instgance.
      • -
      • Line 94-95 register the source display adapter (the "MI" prefix +views for the given PDA debugger instance.
      • +
      • Line 94-95 +register the source display adapter (the "MI" prefix is a historical left over).
      • Lines 98-109 register handlers for common debug commands.
      • -
      • Lines 112 -116 Regiter an adapter to provide debug model -ID.  It is used by Debug Platform to enable custom keybord +
      • Lines 112 -116 Register an adapter to provide debug model +ID.  It is used by Debug Platform to enable custom keyboard shortcuts for the debugger.
      • Line 122 associates the launch object with the PDA debugger elements.  This enables some actions in debug view which access @@ -1159,7 +1192,7 @@ PDA launch is removed:
      -

      PDA View Model

      +

      PDA View Model

      The PDAVMAdapter creates the VM Providers on demand for each debugger view it supports:

      @@ -1203,7 +1236,7 @@ respectively.  These providers are implemented in the -

      Launch VM Provider

      +

      Launch VM Provider

      "Launch" actually refers to the internal name of the Debug view.  The PDA debugger has a somewhat simpler presentation in Debug view than most debuggers because it does not support multiple threads so it has @@ -1288,7 +1321,7 @@ events.  These events are used by the LaunchVMRootNode to update the state and content of the launch if it has been changed or terminated. -

      PDA Program VM Node

      +

      PDA Program VM Node

      Elements

      @@ -1371,7 +1404,7 @@ already terminated.  The super-class implementation only changes the execution thread to the DSF session and calls updateElementsInSessionThread(), which is not needed nor possible after the PDA program is terminated. -
    • Line 126 cretes the dummy View Model context which represents a +
    • Line 126 creates the dummy View Model context which represents a terminated PDA program.
    • Line 135 implements the elements update method which is called in the DSF session thread. 
      @@ -1432,9 +1465,9 @@ implementation:
        -
      • Line 153 iterates through the udptes. The +
      • Line 153 iterates through the updates. The IElementLabelProvider.update() method takes an array of updates as an -argument to allow the implementation to process the udpates in bunches, +argument to allow the implementation to process the updates in bunches, improving performance. 
      • Line 157 calls a subroutine to handle the terminated program @@ -1538,13 +1571,13 @@ method to retrieve additional information about the state of the PDA program.  The label update is completed only after request monitor of this method is called.
      • Lines 207-210 perform error handling.
      • -
      • Lines 213-229 finally calcuate the label string for the +
      • Lines 213-229 finally calculate the label string for the program. 
      • On line 227, The result of the getExecutionData() call, accessed using DataRequestMonitor.getData(), is used to fill in the reason for the current state of the program.
      • -
      • Line 230 writes the label to the upate.  This call assumes +
      • Line 230 writes the label to the update.  This call assumes that there is no columns in Debug view, so it uses 0 as the column index.
      • @@ -1552,7 +1585,7 @@ that there is no columns in Debug view, so it uses Delta Translating the Data Model events into IModelDelta objects that can be -processed by the Flehible Hierarchy views, is the most complicated task +processed by the Flexible Hierarchy views, is the most complicated task performed by the View Model infrastructure.  The model deltas require that a path be formed by the IModelDelta objects which matches the hierarchy elements found in the view, including such details as @@ -1687,19 +1720,19 @@ context to be selected.
        Note: In theory, each VM Node should only generate delta flags that only affect its own elements.  In this way, the layout of the VM Nodes in a view could -be costomized as needed.  In practice, testing and fine-tuning of +be customized as needed.  In practice, testing and fine-tuning of the view requires adjustments in the flags returned by the various VM Nodes in a given view. -

        Step 4 - Run Control

        +

        Step 4 - Run Control

        Up to this point most of the work in creating the new PDA debugger has gone into infrastructure.  Now it is time to start adding functionality to do some actual debugging.  The work needed to get run control functionality implemented is all encapsulated in the PDARunControl service.
        -

        State Tracking
        +

        State Tracking

        The primary function of the run control system is to track the current execution state of the program and to issue the corresponding events to @@ -1814,7 +1847,7 @@ logic an improve the efficiency of the IDE commands.
        -

        Commands

        +

        Commands

        The command control commands all follow the same patter shown below by example of the resume() command:

        @@ -1862,7 +1895,7 @@ state flag.
      • Lines 244-253 send the resume command to the PDA debugger.
      • Lines 247-252 adds error handling in case the result command -fails.  It resotres the service state.
      • +fails.  It restores the service state.
      • Line 251 calls the super class's handleErrorOrCancel() method.  The super class relays the error status to the parent request monitor and completes it.
        @@ -1873,8 +1906,9 @@ request monitor and completes it.
      • Tracking program running state
      -

      IExecutionDMData

      -There is very little data that the run control servie interface returns +

      IExecutionDMData

      +There is very little data that the run control service interface +returns for a given execution context.  The intention behind this is to allow the service to remain very generic and thus applicable to any debugger.  In specific debuggers, additional data about processes, @@ -1883,14 +1917,14 @@ extensions.  IExpressionDMData is the only object which is retrieved asynchronously from the run control service, and it only contains the state change reason for the last debugger state change. 
      -

      Step 5 - Breakpoints

      +

      Step 5 - Breakpoints

      Managing breakpoints is one of the complicated tasks that need to be implemented by Eclipse debuggers.  The source of this complexity is the fact that Eclipse breakpoints (IDE breakpoints) are managed independently of breakpoints that are installed in the debugger (target-side breakpoints).  The Eclipse debugger integration has to keep these two sets of breakpoints synchronized. 
      -

      IDE Breakpoints

      +

      IDE Breakpoints

      Eclipse breakpoints are based on markers, which are special tags in the Eclispe resource system and are associated with files and folders.  By using markers, breakpoints gain the benefit of the @@ -1924,8 +1958,10 @@ is described in fine detail the How to write an Eclipse debugger article.

      -

      Target-Side Breakpoints

      -DSF defines the IBreakpoints interface for a service which the fuctions +

      Target-Side +Breakpoints

      +DSF defines the IBreakpoints interface for a service which the +functions of managing breakpoints installed on the target.  These functions include:
        @@ -2054,7 +2090,7 @@ subroutine:
      • Lines 183-186 determine if the breakpoint is enabled.  If it is not, the insert command fails with an expected error. 
      • -
      • Line 188 retrieves the breakpoint type attribute, shich is used +
      • Line 188 retrieves the breakpoint type attribute, which is used to determine which breakpoint insert subroutine to call.
      • Line 196 retrieves the PDAProgramDMContext from the breakpoint target context.  This context is the only @@ -2134,7 +2170,7 @@ The PDABreakpoints.removeBreakpoint() command takes the IBreakpointDMContext as an argument, but otherwise follows the same general logic as the insertBreakpoint() implementation.

        Updating a Breakpoint

        -Updating a breakpoint involves motifying some of the attributes of an +Updating a breakpoint involves modifying some of the attributes of an existing breakpoint.  Not all debuggers may support this functionality and for debuggers that do, not all types of breakpoints and not all attributes may be updated.  The IBreakpoints interface @@ -2216,11 +2252,12 @@ this field.
        The simple PDA debugger does not track detailed breakpoint data, such has hit counts, addresses etc.  So this function simply returns an error.
        -

        Breakpoints Mediator

        +

        Breakpoints Mediator

        With the APIs for managing IDE and Target-Side breakpoints clearly defined, there is a need for a component which will keep the two sets -of breakpoint objects synchronized.  DSF provides a standard -BreakpointsMediator service to accomplish this task. 
        +of breakpoint objects synchronized.  DSF provides a standard BreakpointsMediator service to +accomplish this task.   @@ -2239,49 +2276,619 @@ breakpoints
        +The BreakpointsMediator +service is not meant to be sub-classed by specific debugger +integrations, however the specific IDE Breakpoint objects as well as +Target-Side Breakpoint attributes differ from debugger to +debugger.  +Therefore, the Breakpoints Mediator requires a helper object, which +implements IBreakpointAttributeTranslator which encapsulates the +debugger-specific functionality.  The most important function of +the attribute translator is to translate IDE Breakpoint attributes into +Target-Side breakpoint attributes.  The following listing shows +how the PDA debugger implements this function:

        -
        -
          -
        • Target Side Breakpoints
        • -
        • Mediator
        • -
        • Diagram showing Mediator's role
          -
        • -
        -

        Step 6 - Stack

        -
          -
        • Command Cache at work
          -
        • -
        -

        Step 7 - Source Display

        -
          -
        • Source lookup director
          -
        • -
        -

        Step 8 - Variables

        -
          -
        • Reading and writing variables
          -
        • -
        • Formatted values
        • -
        • Expressions view
          -
        • -
        + style="font-family: monospace; font-weight: bold;">org.eclipse.dd.examples.pda.service.PDABreakpointAttributeTranslator +- getBreakpointAttributes() -
        org.eclipse.dd.examples.dsf.timers.TimersVMNode -


        +
        +
         65:     public List<Map<String, Object>> getBreakpointAttributes(IBreakpoint bp, boolean bpManagerEnabled) 
        66: throws CoreException
        67: {
        68: Map<String, Object> attrs = new HashMap<String, Object>();

        70: // Check that the marker exists and retrieve its attributes.
        71: // Due to accepted race conditions, the breakpiont marker may become null
        72: // while this method is being invoked. In this case throw an exception
        73: // and let the caller handle it.
        74: IMarker marker = bp.getMarker();
        75: if (marker == null || !marker.exists()) {
        76: throw new DebugException(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Breakpoint marker does not exist", null));
        77: }
        78: // Suppress cast warning: platform is still on Java 1.3
        79: @SuppressWarnings("unchecked")
        80: Map<String, Object> platformBpAttrs = marker.getAttributes();

        82: // Copy breakpoint attributes.
        83: if (bp instanceof PDAWatchpoint) {
        84: attrs.put(PDABreakpoints.ATTR_BREAKPOINT_TYPE, PDABreakpoints.PDA_WATCHPOINT);

        86: copyAttributes(platformBpAttrs, attrs, fgPDAWatchpointAttributes);
        87: } else if (bp instanceof PDALineBreakpoint) {
        88: attrs.put(PDABreakpoints.ATTR_BREAKPOINT_TYPE, PDABreakpoints.PDA_LINE_BREAKPOINT);
        89: attrs.put(PDABreakpoints.ATTR_PROGRAM_PATH, marker.getResource().getFullPath().toString());

        91: copyAttributes(platformBpAttrs, attrs, fgPDALineBreakpointAttributes);
        92: }

        94: // If the breakpoint manager is disabled, override the enabled attribute.
        95: if (!bpManagerEnabled) {
        96: attrs.put(IBreakpoint.ENABLED, false);
        97: }

        99: // The breakpoint mediator allows for multiple target-side breakpoints
        100: // to be created for each IDE breakpoint. Although in case of PDA this
        101: // feature is never used, we still have to return a list of attributes.
        102: List<Map<String, Object>> retVal = new ArrayList<Map<String, Object>>(1);
        103: retVal.add(attrs);
        104: return retVal;
        105: }

        107: private void copyAttributes(Map<String, Object> srcMap, Map<String, Object> destMap, String[] attrs) {
        108: for (String attr : attrs) {
        109: if (srcMap.containsKey(attr)) {
        110: destMap.put(attr, srcMap.get(attr));
        111: }
        112: }
        113: }
        +

        Step 6 - Stack

        +

        Command Cache

        +A new feature introduced in this service is the command cache.  +The command cache is a surprisingly simple mechanism for caching +service data which otherwise would need to be retrieved repeatedly from +the debugger back end.  The command cache performs two functions:
        +
          +
        1. Map Command objects to corresponding Command Result objects.
        2. +
        3. While waiting for a Command to be processed, queue incoming +Commands for the same data and complete them when the first Command is +completed.
        4. +
        +Using the command cache greatly simplifies the logic in implementing +data retrieval commands.  As an example, the following is the +listing of the PDAStack.getFrames() method:
        +
        +
        + + + + + + + + + + +
        org.eclipse.dd.examples.pda.service.PDAStack +- getFrames()

        +
        +
        244:     public void getFrames(IDMContext context, final DataRequestMonitor<IFrameDMContext[]> rm) {
        245: // Can only create stack frames for an execution context as a parent,
        246: // however the argument context is a generic context type, so it could
        247: // be an execution context, a frame, a variable, etc. Search the
        248: // hierarchy of the argument context to find the execution one.
        249: final IExecutionDMContext execCtx = DMContexts.getAncestorOfType(context, IExecutionDMContext.class);
        250: if (execCtx == null) {
        251: PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid context " + context);
        252: return;
        253: }

        255: // Execute the stack command and create the corresponding frame contexts.
        256: fCommandCache.execute(
        257: new PDAStackCommand(fCommandControl.getProgramDMContext()),
        258: new DataRequestMonitor<PDAStackCommandResult>(getExecutor(), rm) {
        259: @Override
        260: protected void handleOK() {
        261: IFrameDMContext[] frameCtxs = new IFrameDMContext[getData().fFrames.length];
        262: for (int i = 0; i < getData().fFrames.length; i++) {
        263: frameCtxs[i] = new FrameDMContext(getSession().getId(), execCtx, i);
        264: }
        265: rm.setData(frameCtxs);
        266: rm.done();
        267: }
        268: });
        269: }
        +
        +
        +
          +
        • Lines 256-268 create a new PDAStackCommand, and execute it using +the command cache. 
          +
        • +
            +
          • If the PDAStackCommand +was previously executed, the PDAStackCommandResult +object will be returned from the cached data. 
            +
          • +
          • If the PDAStackCommand +was just sent to the debugger, and the cache is waiting for the result, +this request monitor will be put in a queue to wait for the +result. 
            +
          • +
          • If the cache does not contain an entry for the PDAStackCommand, it will create one +and send it to the debugger.
            +
          • +
          +
        • Lines 261-266 implement the handler which processes the PDAStackCommandResult.  It +creates an array of FrameDMContext objects and returns it to the client.
          +
        • +
        +

        Frame Context

        +The primary object type managed by the stack service a stack +frame.  It is implemented by the FrameDMContext object listed +below:
        +
        +
        + + + + + + + + + + +
        org.eclipse.dd.examples.pda.service.PDAStack +- FrameDMContext

        +
        +
         54:     private static class FrameDMContext extends AbstractDMContext implements IFrameDMContext {

        56: final private int fLevel;

        58: FrameDMContext(String sessionId, IExecutionDMContext execDmc, int level) {
        59: super(sessionId, new IDMContext[] { execDmc });
        60: fLevel = level;
        61: }

        63: public int getLevel() { return fLevel; }

        65: @Override
        66: public boolean equals(Object other) {
        67: return super.baseEquals(other) && ((FrameDMContext)other).fLevel == fLevel;
        68: }

        70: @Override
        71: public int hashCode() {
        72: return super.baseHashCode() ^ fLevel;
        73: }

        75: @Override
        76: public String toString() {
        77: return baseToString() + ".frame[" + fLevel + "]"; //$NON-NLS-1$ //$NON-NLS-2$
        78: }
        79: }
        +
        +
        +
          +
        • Line 56 declares the only field in the frame object, which is the +frame level. 
          +
        • +
        +The frame context, which in itself does not provide access to much +frame information, can be used to retrieve more complete frame data +implemented using the FrameDMData object.  The frame data object +is based on information parsed from the result of the PDA debugger +"stack" command, which is written into the PDAFrame object by the PDAStackCommandResult
        +
        +
        + + + + + + + + + + +
        org.eclipse.dd.examples.pda.service.PDAStack +- FrameDMData

        +
        +
         85:     private static class FrameDMData implements IFrameDMData {

        87: final private PDAFrame fFrame;

        89: FrameDMData(PDAFrame frame) {
        90: fFrame = frame;
        91: }

        93: public String getFile() {
        94: return fFrame.fFilePath.lastSegment();
        95: }

        97: public String getFunction() {
        98: return fFrame.fFunction;
        99: }

        101: public int getLine() {
        102: return fFrame.fLine + 1;
        103: }

        105: public int getColumn() {
        106: return 0;
        107: }

        109: public IAddress getAddress() {
        110: return null;
        111: }
        112: }
        +
        +
        +

        Step 7 - Source +Display

        +Integrating source display is relatively simple task, even though the +Eclipse APIs for looking up and displaying source are rather +convoluted.  Fortunately Eclipse Platform and DSF provide most of +the components needed to implement this functionality.
        + + + + + + + + + +

        +
        Image 3: Components involved in Source +Display
        +
        +The first step in integrating source lookup, is to create a source +lookup director and the source container.  This is explained in +detail in the How +to write an Eclipse debugger article referenced earlier.  +There is one difference in this process for a DSF-based debugger.  +The source lookup director does not need to initialize a source lookup +participant list.
        +

        The second step is to register a DSF source display adapter.  +This has actually already +been accomplished in Step 3 - View +Model, when registering the View Model adapters.
        +

        +

        Step 8 - Variables

        +At this point we almost have a fully functional PDA debugger.  The +only thing that is left is to populate the Variables and Expressions +views. 
        +Displaying variable data in DSF requires use of two services:
        +
          +
        1. IStack service - +This service is used to get the list of local variables' names in a +given stack frame.
          +
        2. +
        3. IExpressions service +- This service is used to evaluate the variable names as expressions in +order to retrieve full type and value information for the given +variables.
          +
        4. +
        +

        Variable Contexts

        +The stack service allows clients to retrieve two types of variables +through two methods
        +
          +
        • getLocals() - local variables
        • +
        • getArguments() - function arguments (not implemented by the PDA +debugger)
          +
        • +
        +Both of these methods return a context that implements the IStack.IVariableDMContext +interface.  The implementation of this context is very simple in +PDA
        +
        +
        + + + + + + + + + + +
        org.eclipse.dd.examples.pda.service.PDAStack +- VariableDMContext

        +
        +
        117:     @Immutable
        118: private static class VariableDMContext extends AbstractDMContext implements IVariableDMContext {

        120: final private String fVariable;

        122: VariableDMContext(String sessionId, IFrameDMContext frameCtx, String variable) {
        123: super(sessionId, new IDMContext[] { frameCtx });
        124: fVariable = variable;
        125: }

        127: String getVariable() { return fVariable; }

        129: @Override
        130: public boolean equals(Object other) {
        131: return super.baseEquals(other) && ((VariableDMContext)other).fVariable.equals(fVariable);
        132: }

        134: @Override
        135: public int hashCode() {
        136: return super.baseHashCode() + fVariable.hashCode();
        137: }

        139: @Override
        140: public String toString() {
        141: return baseToString() + ".variable(" + fVariable + ")"; //$NON-NLS-1$ //$NON-NLS-2$
        142: }
        143: }
        +
        +
        +
          +
        • Line 127 declares the fVariable +(name) field which along with the parent context uniquely identifies a +PDA variable.
          +
        • +
        +The getLocals() implementation is also very simple as it only uses the +familiar stack PDA debugger +command:
        +
        +
        + + + + + + + + + + +
        org.eclipse.dd.examples.pda.service.PDAStack +- getLocals()

        +
        +
        271:     public void getLocals(final IFrameDMContext frameCtx, final DataRequestMonitor<IVariableDMContext[]> rm) {
        272: // Execute the stack command again.
        273: fCommandCache.execute(
        274: new PDAStackCommand(fCommandControl.getProgramDMContext()),
        275: new DataRequestMonitor<PDAStackCommandResult>(getExecutor(), rm) {
        276: @Override
        277: protected void handleOK() {
        278: // Find the correct PDAFrame
        279: int frameId = getData().fFrames.length - frameCtx.getLevel() - 1;
        280: if (frameId < 0) {
        281: PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid frame level " + frameCtx);
        282: return;
        283: }
        284: PDAFrame pdaFrame = getData().fFrames[frameId];

        286: // Create variable contexts for all variables in frame.
        287: IVariableDMContext[] variableCtxs = new IVariableDMContext[pdaFrame.fVariables.length];
        288: for (int i = 0; i < pdaFrame.fVariables.length; i++) {
        289: variableCtxs[i] = new VariableDMContext(getSession().getId(), frameCtx, pdaFrame.fVariables[i]);
        290: }
        291: rm.setData(variableCtxs);
        292: rm.done();
        293: }
        294: });

        296: }
        +
        +
        +
          +
        • Lines 273-294 send the stack +command to the PDA debugger through the command cache.
        • +
        • Lines 279-284 verify the stack frame number and retrieve the +corresponding PDAFrame object +from the stack result.
        • +
        • Lines 287-290 create the variable Data Model contexts and return +then to the caller.
        • +
        +The IStack interface also defines an IVariableDMData interface which +returns information about the variable.  However, the only method +from this interface used by the Variables view is the getName() method +and it is the only method implemented by the PDA debugger integration:
        +

        Expression Contexts

        +The IExpressions interface +uses a somewhat unusual way of managing contexts.  A client can +create an IExpressionDMContext +context instance for any expression and +parent context by calling the IExpressions.createExpressions() +method.  However, when the returned expression context is +evaluated, if its expression is not valid or if it uses an invalid +parent context, it is guaranteed to fail.  The +PDAExpressions.createExpression() implementation reflects this:
        +
        +
        + + + + + + + + + + +
        org.eclipse.dd.examples.pda.service.PDAExpressions +- createExpression()

        +
        +
        213:     public IExpressionDMContext createExpression(IDMContext ctx, String expression) {
        214: // Create an expression based on the given context and string expression.
        215: // The PDA debugger can only evaluate variables as expressions and only
        216: // in context of a frame.
        217: IFrameDMContext frameCtx = DMContexts.getAncestorOfType(ctx, IFrameDMContext.class);
        218: if (frameCtx != null) {
        219: return new ExpressionDMContext(getSession().getId(), frameCtx, expression);
        220: } else {
        221: // If a frame cannot be found in context, return an "invalid"
        222: // expression context, because a null return value is not allowed.
        223: // Evaluating an invalid expression context will always yield an
        224: // error.
        225: return new InvalidExpressionDMContext(getSession().getId(), ctx, expression);
        226: }
        227: }
        +
        +
        +
        +

        Expression Data
        +

        +The IExpressions interface allows for retrieving data in two stages:
        +
          +
        1. Variable type and other data.
        2. +
        3. Variable value.
        4. +
        +The implementation of the IExpressions.IExpressionDMData interface is +required by the Variables views, however for the PDA debugger the +IExpressionDMData does not carry any additional information beyond the +expression string.
        +

        Formatted Value +Context
        +

        +The IExpressions service allows expression values to be retrieved in +different, client-selectable formats.  For the PDA debugger, only +one formatting is available, which is reflected in the implementation +of +IFormattedValues.getAvailableFormats() +method.   Also, the implementation of the IFormattedValues.getFormattedValueContext() +method is just a formality.
        +
        +
        + + + + + + + + + + +
        org.eclipse.dd.examples.pda.service.PDAExpressions +- getAvailableFormats()

        +
        +
        262:     public void getAvailableFormats(IFormattedDataDMContext dmc, DataRequestMonitor<String[]> rm) {
        263: // PDA debugger doesn't support formatting the expression. Natural
        264: // formatting is the only available option.
        265: rm.setData(new String[] { NATURAL_FORMAT });
        266: rm.done();
        267: }

        269: public FormattedValueDMContext getFormattedValueContext(IFormattedDataDMContext exprCtx, String formatId) {
        270: // Creates a context that can be used to retrieve a formatted value.
        271: return new FormattedValueDMContext(this, exprCtx, formatId);
        272: }
        +
        +
        +
        +Only when the formatted vlaue context is evaluated, the var command is sent to the PDA +debugger:
        +
        +
        + + + + + + + + + + +
        org.eclipse.dd.examples.pda.service.PDAExpressions +- getFormattedExpressionValue()

        +
        +
        274:     public void getFormattedExpressionValue(FormattedValueDMContext formattedCtx, 
        275: final DataRequestMonitor<FormattedValueDMData> rm)
        276: {
        277: final ExpressionDMContext exprCtx = DMContexts.getAncestorOfType(formattedCtx, ExpressionDMContext.class);
        278: if (exprCtx != null) {
        279: final IFrameDMContext frameCtx = DMContexts.getAncestorOfType(exprCtx, IFrameDMContext.class);
        280:
        281: // First retrieve the stack depth, needed to properly calculate
        282: // the frame index that is used by the PDAVarCommand.
        283: fStack.getStackDepth(
        284: frameCtx, 0,
        285: new DataRequestMonitor<Integer>(getExecutor(), rm) {
        286: @Override
        287: protected void handleOK() {
        288: // Calculate the frame index.
        289: int frameId = getData() - frameCtx.getLevel() - 1;
        290:
        291: // Send the command to evaluate the variable.
        292: fCommandCache.execute(
        293: new PDAVarCommand(fCommandControl.getProgramDMContext(), frameId, exprCtx.getExpression()),
        294: new DataRequestMonitor<PDACommandResult>(getExecutor(), rm) {
        295: @Override
        296: protected void handleOK() {
        297: rm.setData(new FormattedValueDMData(getData().fResponseText));
        298: rm.done();
        299: }
        300: });
        301: }
        302: });
        303: } else {
        304: PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid expression context " + formattedCtx);
        305: rm.done();
        306: }
        307: }
        +
        +
        +
          +
        • Line 277 extracts the expression context out of the formattedCtx argument.  If the +expression context is not found, the evaluation is failed.
        • +
        • Line 283 calls the stack service to retrieve the stack +depth.  This step is reqiured because the DPA debugger var command requires a stack frame +number which is counted from the bottom.  Where as the stack frame +level returned in the IFrameDMCotnext.getLevel() +is counted at the top of the stack.
        • +
        • Line 289 calculates the frame number that can be used with the var command.
        • +
        • Lines 292-300 call the var command to evaluate the given +expression and return the result to the client.
          +
        • +
        +

        Additional Resources
        +

        +

        Debug Platform

        +The platform team has evolved and improved the debug APIs over many +releases.  Before starting a debugger integration using DSF, it +would be very helpful to familiarize yourself with materials in these +documents:
        + +

        GDB

        +The DSDP Device Debugging +project is developing a DSF-based debugger integration with GDB as +the main reference implementation of the DSF APIs.  In comparison +with PDA, GDB is a much more complex and feature rich debugger +integration.  The GDB debugger integration is also being +continually developed and improve features and performance.
        +

        TCF

        +The Target Communication Framework which is being developed as part of +the DSDP Target Management +project includes a reference debugger agent implementation. This +reference debugger agent is integrated with Eclipse using DSF.  +The +TCF debugger is more limited in features than the GDB debugger, however +the TCF debugger API is considerably different than the GDB/MI protocol +and is an interesting example integration.
        +
        diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/pda/source_display_1.dia b/plugins/org.eclipse.dd.doc.dsf/docs/pda/source_display_1.dia new file mode 100644 index 0000000000000000000000000000000000000000..7c60f7d3219c6d86ad881e7e7f5031af0e286d6f GIT binary patch literal 2451 zcmV;E32gQsiwFP!000001MOW)bK*!6zVj;-^c9!u{TRlcnAzUhIZVWE#LVuM5Ksnf z3yF|~-R{Hu_N^-6wgK@JWzbqgbcYc|rm~co^;JHKAAkBfi-Sj<B6s=(c;`34*r-#$gfKYs;%)QDo6@QRpBEXZo%?3`bukS-MEZ-E!1&+$fFH zEO-p#yY8n4_v+p*$=t5c*+F|APV_L-;g{{Cp?N8F3hBAd*2&K1X&#v&#q)e)$QC;G z|2JcnqjEDSncRQ+nSLs7X?fw5R@IGeWm3$-Y!W4#e9YX$D$1f6-MKsp=9%Wk{vxU-hIqY`dtgnwd zbYjX&YfH9c5r@w@Tay3fb+HbX4|wT!-poQe{I4DrOY#0F!eks~lc#U2KE zMB}^eKjG^1tP5m_8UMF2KlAjv5+P~Kpoj3f%$t5=8~x#MoqT2l2$M;yUs?1J0*dts z1dR2t0P-|`I@YtnD9w^hXmB=}91rI|Hs$*6%khfyIGX%aN0Vu>gFXY|MEX%;CTFl} zk`+d2O;Vr8BA=#Dg9_xie_1_-OZk`wSvZas`HraqNHD4>VbH<`DVV+?`_!wvSen|& zwukE49!5P(PJYk_*&c?*>>QUqRsfnmIY7*(@zoRR5aW{`4G#mOM{iz;wpMuER)}j` zp;?ox%3{xUNJ}n#EZrK&0QYN$HN|Qzv9-kGERoc;#2aYVjUH0KrzILD((<6JFWiDi zJuirLr8>kAMZE=gpDj|rVQY)mX^VgAuf-cJF;GaN(^waFO7=uR*2ZkpCKotf8MhW={v%yvBOQE>^10dScYYp+ z^Fn7^;?6t5G}|J7X;M_Nx7UM*a2CbS<}Sk|?*@7CY~u;W8<$`GO~;SAh(_Vtu*dOt zu;Cl_g*K08v8sqWm61ru>oHsRK3nq|5Y}T9#?d61>FVdFlf~?~xvLCC9cLGh?v~aq z$ zMEv@9WpSE*S$beBxb1_}|`x43{vY4=e~a@?30((k3y>U@r@cxf9%I=54LQAMZ_`Tz1u zusK1bv!t3-{iLtm5BUXA%9UPVTY4c~riuA3y{IKroA7OuOh=*vRJ;5TQ(L2;eAixZ z##}Lk#RYvV0HM@nei=ffG5FwbX1NX{qY`hs|O&pYin^&`87Et38uIw0g=c+4+=1( zRP_|#NH!tj@mUWSli)v*erln{nW2VJ0w^ITEzY>&1js*hI@9J`BjbgB(_h0$np7?S zXQ*pM7$VX`#$}kzibtnJ0pyS(#|cB$mxiH|E*&Q@^oj`1BIF^^fO-v0oOt7Ll<56s zT4=381l3?>UBF@|3R!my$FO*a;`jg-*AH~uT)Cy@n99S-rQ)dhi=+8qnr6{An@)&# z3b%Hq%+YL&$Fj?2eI{oDZnX<|x%a~|7(fUM(Q_quNc9DvP*Q3ABx*)Ol&!Pt{Q3dw z?7U+)zHHNAZ4*>O!$fQ~Ote|z?I}(q&JriW!f(aQ&CBUP!ni%sBhYWEs;*2|(3nly zV9~V)i)8(#A=~AGmG9<5Y^&8I;GEci5oM02Buyxw{rfm->t#JOT`v`nP}HWS8i_Z= zWxAYD?fP8gpf2})5)6XEmB%OwX&(cQsZH2Rz(^CioW|v$6G3O$=hU%{PHl(N`*b*M zDroB%uerf#XJLmyn8q9yl0pK_SFYqW1%t`FvR9qb?Kl!L^H#vD-Xg=+lWX02#;S0lUuWNYuI>u=f$wcJ2Y&ye;r}n=Q^ob^(f<8G4qrmPf!Nw zy)07QqJ!KzS*+F)QOf2wHe_{N5mJ|m z^tY#sa%@Hs2)ndcik9Bzr3kJ4CJ@wv)1yub30a?_Y<0CeY4nASKsfGyqmc%e?m^ao z|C6o{HQquXXz%*J`_1{b;SU>k9zT9uTkE5*ukY<$^X(lsL!$ZZJ9m=B-PsK`h8w6v zL_|Iw+)f}ccHN1xmHq42<;$0^UtgRotYv0lVL5Ohx8^;yh;3J1UBDjYsLelvo8IdS z-NGz;2n71)%x)A14jlOM`LpM*S39NFe%00Arwd`0$a(nGW4PaKu&KE@ig$B$vXG9? z(9b=53qiW>QSGRWr6nx`!%CCLU@K=uMTJ(TYFSCi+`@vyjbABa&9SkuTefU@_Uzfl z#zp`o)Bb*r9(x|c@W{xK(NQZ~+XH*|hQ`JoEemlQYfbIy>WV&QvY+q8jo)d~tiKi( zXilHC3B9>Az5c6i&$ySNk_3i2IeyuRNx*_sBK%&<=;6bM)siLqKY#w*)WpZfXaDXY(|i&c8QH+V!20UK z+~VRu@#XsoLPu=|YrOEsrlzLEKc1acQcwsj8?`O0zCQHY|6B;Oh9irFhs#7q_R^q_ znVpEinTL$RHa|ZXWvV8!`?hI=IGu)pluyPb7f z@oabQVLo47kd>wX%r17UOVVp2y28uTbF90jrY15nGN{AMz+mMAPhqR0oZ0>HFXb~I zV+HpxiOn}0PTng+iU0T!??}lYaMn&l^i0h{ml1Kb2HZyzv6Pf7lAc|82Aj+8q{zw1 zxzv(8XNMb}K0PkCbqAhD_4$I)mSi_)=f|cL{;ww{Yy<^MOn00Wrj0!AHr+SU7_HSH zEGXza+MF2v=RMhMe)+)a+FXl~kx}j1tn$RhdVw8+RV|^9GubsrrHuBf@X4;V|OI` zY`CkdtE)+I;%Qs(7CGqC-j^c{^E~;;JEi{3n>Vjtziw=_#fKDDFUE~Y;)a!#l(_l% z>B#-D-7a3dsP*K0>O+Au^)g)IezQ29o>grm2>_)0DM!2Vjj$xx04GmI)znj92k4(?$rQxrWGF{(paMljMN!c5 zrtH|Z4a*RF%#~tWM5+-z!T0UF!$lm*#5?#fLW;RU0e-`M_y3RI$oEpd^i^*RwA~R^ zwUf}wUTQ3SHX>GME)!RzVO?SK$dd8V`#b`n*FP$kOT9<+l1W)dV5s>PLMcgu&Qxj4 zaHtvnduxM^tdRI?(rs}BLMds3PPI@U8!rzox|M@NPq^K|T=qK+LE0$PxKs7MBITiY z{1pC)N$CI^FZl}oCIWwRTeKmVt%r&5GKIAwXP@l;17ZPN2tvCWbQb74|L4a9LydKU zW66SV#WEA5L)a>ENG?S%2s%p2SWiPD=Geo`jGRji0-_@<1loZY!a67l$6r zr@$TTvpfV}L;Rb&1?fDA@7D>0O3DTulCh7geI1XVy(rVDBTW5K zQ#ODyvX|`qWv)e*vDqI#ERRJ`e*OA&XlNh$SXY<4gBY3&j4FSMubE z<+nG13=9lTTjhz1%M@ySGb3}V7Kf)ZSFZ(C|I0IbQBl#_ja42U)y~#mJ3Tg2Qdk`w zXFh!RfbQmc{klU>u|Ic9W8-(H3gcttIXT=sJd;0rO3V*)b8{P_9xP6MiRLv(dyg~f zOP*?^?=CU1_eoiKIUO}Mc6=Gu>G^ZC2>b2=6PytrhY$xGtv7*G{AM-hNn<5$UcYf; z`O#4=4p|#(>-Wvg=w*YoKDGJz`Rvgt;hTM9v^xkXY!%#vORxiU^91lBQH-8iLQPkDLy6DLlfoN1Qd_4h|L8W|q$=;#m<5?aI2lS%zm;rfv2 z^s}6toYGS5Fv2e$99*noWa_-v2iM6ivh7>j!f_>RvUm5&==1(I^+TV1{`}OGsf+9lY#bdMhv**v!j9InELeZsn)MRAD9j=Y-<*p?3hw|X5nxf_>;p6Tl1k|5?9R5#Qbf9ha!Z<+1=prFdi z%87}Ivm*OsOuZI5^YZd`A2?}YY01refVih~z9!j*EIg52ZqHCQFfhRVK6vnei;Jtd zxf!)3M#@K$ZFsEhalDA5gPq;a>FFojg}J##RoACh=0?fbC@Cp@RvOJt9i;Rch&Zgq z#mT9oqhnxbD1Y|s$9R#DwH48BJQhCvrx)7N3b%hW!#_1+ba zShFwyKx-`f-Hpq-jKp*6v8SPIXUq#)kD2jFSNt7wcy8LROhv0xdgO!@E`5? z^5MgWz*ZXzlid{Lt=f35mp( zQQ+*^iZF$TmvAu0n(B)=j+oF8e4Ah8ocb^}p0HnYr%+MP&+qR-Zo0cSh~;3{qS8e3 zn?12P<@^H$@=}&c2#eJ9Yu8qAXNif4EQ%#o4 zSGb{BsPL*yKP~s$kr<^SzlRrJNADUtu^PX3Tim1W$6%zKJ2r*#JDwtpfGEIr-SQhl`{ z@2GHp5Dk0xR^I_>C!M=FPa?;@loyVD0ivU$i%v*L2s?Ccac0nrb?@ii-gYC-xrmNn zl>OY?+@_Bose{kF(!IgYZxH6fV{qGrf*?k|WE`3PFsu&Cc~&i%eW;6JtQ@1`8ux6{pji}X3Rip41MIee(Cjm^a4b0K14VycN^^+Q)5 zWpVshm=)!t5HjtZJ)_Iu#77w0&7n7vE#CCAzp6Yh@8g#*UphNo|13`73Y4@3u6=v6 zyuAG8%~_BmH@78hEPx25ey#CjlInvBd93x$`IU#ZG*OZJo1sboa|v61qz58pVMzv? zprAWueY!wO!~R`ljij{W)8mHE%U#@r#X9AWi5co|OaGzW_qdZR$g|;1eSLrRO%ZnX z*F8NIj)OJ8NGQQg4Gk+Be`bVfe#{*eVaTzx*=CWMU6>a^Us4elf22hluX>2RHp<5KMf8J zc6FU(Wo6~zxqmErt?r3(y6U~C`1k|V)D~z~lauj@i7G6e@uJPc=Z^SL<^QAawNz() z{P@w=mw9wm@Z>)?&kH2eoa&lVs^fok%%gh{Yk=i^+OKWLkv)X)mM!Z~AGP%}y6g^Ar(4j*z z3Z|ya(Tysqs*AsWXBQT#DJjLBc00Cm>0wEFdiu+kFXQ6kuy<2s1KLZ9kI1O{1#LIe z)~04+s>Vm);zpBfTaqNMT)BdNQRT5P@gb6D=Wa%7YU=bGSt*hzoV%GO4(fhVF}HW6 zXuP%4Dpv6oe=K(0?c29=^$I~KY3b;yDk^}oZI^!yp&GQcwcWaPtHZ&nIbj9F1IJM{ zef?#IGRNVw@&9PNZ<=$L4_Xy_t2GAxs(57uJe-+1GgzCvae{3#t+==tr00C(=JNLt zMMcFyucgGk7MczUL80szoE~+NL{d#1i?YjM=B~H1v&T!Xe9GcDyqENb_&}Vnt$=_4 z+UD7K7jJLx?m{!YbeSTuHjr1^y?a?J;@h1Q+J?^_ky@VmQcg!h!-Vqr_2n({q{ese z0=%atCyfjYdLFBv@w(cgQ}4ol^F*zCzM;9u8V? zG+pary=|%|+yC|w%bHLJjY0u;-CA%)mD=uXzt63Q#km?SCcE;fNVlhP zg0{-u-Noh?%pmwAJ>BmZ|Iwp3MX9FoadDE~YcT`bT3Uxjsqr)-#K;Uoew>O>QuT8> zxlhKjC8^qHa|0NI<@EL7V~>0^Km+OWn>stoM8fWn13vDL(9^QA)Hb|zmv@fo)YS{9 z{F!RWMC9}HCodo0?%lhIG@p!(#b@nAbR!=R53UEb^M_MKV>Ex}Ll1CXckzKcJNIng z`U<*)UV-t^QR;(~R(Q66GbSb`IB@fR)=D3*amf>}sVzD*GP3Mq-QABL&&wSPY8;7* zj;7dtdvrMBUk+S#{zbSHR=*&mfC3cdbc&;g4X7#OH+ zf9Tx9;j5?SIenj9*iR;Geqknehi1(~EbEf;W=Ur~}SxBmt~S`Yjp?0N~KEMt?0G;h6)2tA>dOrc;RW1;z? zkdY3FiatU8V0i9b>r=I9Jvo%tuebW%e#-r@_sX?b2Zf9}Q>&`tKjiU7Eg$4f;hvXb z(9+VPprBAwYXL8>S?skogKn!>bRn}V05cT~+=7oJth1&(ivUe`*T$>;N^yJAC ztX%!OcYpr;as2X3MI}@A*^W+`^5eb&t#Ww`Z{NNJ%wU0bwMT00>hEv$=p&jV3VtuI zf{u~aP|WYIyeItj<40Z`LX@Ucr()JBQX4EwRy@5uJUp;_&Yjy?wr1ntFbyRLt*D-B zB=aQa;lrD=jr@n?gO?%wh`CK0=jbUqkx!$7O59vjkN8<=T;cTUHc7bEquQrT^t`3U zuG@ATIYBGG&o($Dq@~QZJKf>i+)DgO`%3S1u}Fitxw%8Y6o(Gs3qF1NwBoq|7M(2t z5$L(`vFOJ9oE)$Wv73v$D~ICSb02Hn{4qTIYh?`>x3||2mDRSp0NX$zNh3dcS0zOQ zO-ea^r(E6wp~LEZD4SZ6cv$68QPGu*Xj1`!)y;xalF7*l3F2O>E|)G{5)mnfYQ=Q= zx_bQesouz#m}RIEj0X-t;qzFU?k`r2PD)A&4LyGGwV(I;>H`)jNjA2j8K2FnJi)E^ zUYXscO!<@7TK>^uj9s@pU=Ir=v$*~Qmz$egTR9Yr#wb22zVT0^n+NuT)liU!M zmY)l^s~b_I4+zWZEOB@_^R){{Hp8Tei{i z>Jw$YWIdam3xQOJ-#$2CWoKt+WwlgKXSP=c*g$e+n97;>YYxrh;X}%X_v7SRnws(t z80CaJfcl|N33@L7LR$eYZy=W+X-<}!`SF9xRSU|S+#oqonVQ(KPus1CJTP&e^saE8 zPk{sW^@(~vw9a`y2npF-UmBd8n1D>9sjeDSgJ)0n0 zZV2Z*AmRW8OcCT3It?iss%7o^q7i-&JIchQztVMb_>H=up`orW*IrUmHvIStj|Cf4 z@+L5g!5Tgu`cCj+s5Eg>J~iy8Z{E0p9VIvM;jWjjCef!oP z5&8=BZ);Y}hq=jDcXmcZMBs5aT)Y^TkZ_*n33^p}y1tRo9!8-fpmB!}pY!J2wquty ze%aVSN9+Iz%eKL4@$&M@2h+bAovU5>aX>V{XJcg)$d`RV?9ib*Eu&C@cQJ_xadOH9 zUZC#o?9?$cOOA-3qNWzY{wN>xHVOkwO+!}$m`alL>h0>%)z^Q1 zm$A``jNNq2QomLhCU4a>;KKzv3aqRxl`hRXhMwu>CbCegy)Kg)T5nF~FT?)l;S3fY z7lJZ!UPT2}<<6Zu^*O@A!c!9y`%fo$@aS4wSah_tv57^U(><<<`YyXU5+4%-4gCgi zdTgrV#8tolD9KNcYCTbphmsZh=#jRL4(IBlW>5tY$ALb`yZ!wt-HU(g1koPUR)1>) zkDTQR?6WHOhCf&<6o{$l5E&2{|EW`__R8Q1Cnh9RR#icA)G;=;v$yAS*Idaw4QyI` zxp8`+y3w-4XLbDWxpU`a6tHnFT(|(evDSN?S<2ha#zu*>0?qY4f6b9tV|zP0^sof5 zhy4bx6#V%aS})CuuvPlUDt9sI_PKY`(6;X2JWSBZK6lz{i|6>^RX3C%~SNoMEg z(~xe*34J^&LN8#UfWBnG2?eh(FVAyzK3n~W=i*NWo&5|9J$-$iGXoNo0kZwg^Yin4 zMVHP2F2Yc-w$AFf5p~R@5@>97brm~Lvp=W!_Lk%N5Zi3h!`D81|NXJ43HK@N(02+D z4z*;TjO6UYad#1`T@AH(Wii4FA!4g;j&Kl7i|AP$kS z;dC&cF!zJsfel_(CLHqakl)Y2+D%Y$+!OFqTL05D2uNRXB*w=@J?5=%-n=RLia^in zLLu1U9G`jqkE5T%MN#b=n+wrq-mxbxy~T;U$@Hk}tMZO{`bvM-JvG5DdNW@NhlYms zFpFE;*#$p*_=KyQguo^1beX-4?2Vjr&X^IFl&|_@A(RLl?Q2d>jN&(bJyD6*W@IE} zF=N^9DJ7V@YtKssSp;@L>)EHj8A<$tUT5a|E$R<%W$u<^t!1yc%^cz0(iythB+EY( za&BKork`06VO8Zr&Z*UPn(X^LQ7QS4qqS!MeZ=bUKGgoSzJ za;KV(UTvY7r%!V3Jn=qnHFIf7&qLQM?lWbJiDhKHxjlrgH~02gT3Vud1BIo3aO|(7 zIe1Xqx|NlRDk3E%1>TEd0dOb}A7f+tZ+g&_Zq*Yp0 z*3;9Y@j$Q5xvaGG#jn>C9hBG<0D%&frY;nBOv6_aa=ky*pUt>`LRRhQx|xBulh?FB zE-$Sz>)v~O<4UBkPk^b8^6)(N2+!U&(&s$Y#;4Dr*LvysDEUiP8^&qd%a?WZ^Z?wG zByP%&=rwrZ*5s<6yU#tz$lzR9MT0P_aJuZ}RgE()tdq6eSdO!2 zx4Sw<)(!C*KM&=$b958|G!Yig&&{PEBTFT}oKHPaS0xac4}Uv`4;K$E&a}&^=;?3FB$I+zPqVZCeXHj z8v9GI?`FY!&6gGv*0o!Ge=rz3kz6=6tVfXWMLk;f5I)b?SUC26i#ipD9+R)5^tQ7t z{v58RvV;q#IP?fVWav)#J`{K~9CV^Qd5UvzDHGwnU)Rajtc;O+ zQAy`JO*&))2;m*;>B5Eugvv9e>p@(3?4br{C|x(*i5*_>?C8=tD%~?N<=xdIj&dL8nDxiGptMy$1p4^2r&TOBHXaZ_f(6rKxCrHRh!%CZ_2go7$4&5>YS)eaNef?eZ$1eb(K|Vb@9J^bTWova{y*U_G3xvMUpKq)!{|1*x z{ZMbCJ0*PECY6lh<=)j~(1TVcc{a;EydjY zN~GxK_N$(d*xe`7OkKcBK&p@_iv#M232&(Xo50BAfb3nE?cFr{)7Z_o2< z-=XQk-aKafT$%`}c1KaQBeg z9gU8AnM14`93*WzvH<8-{`^^*><-yGJD!=W8Ygt+!=s~sX8NVpZB;Wh%2NkvXoP{T z20SUTmOmJ!4}_X`o;yPA4eIMyz0d^#5x@a9E(pZfjKp2_DZ2%I7X`_Y88>+2qobpz z#l-f@ZKkbuB!qT2uiP~T>9aD7g8cIqCoUAyuM3!^=>o?Zu6>sW+>nu#-L`F;)biImNhV1H{a0z`;FUtT{Eqdup(LMwKs!@EF(T0o3XQ4` zt^3sJ(@Qu@1qIVMZ*WZpeKxCiG#9X*jL(0qCRmq#si}iWo8%IUaqNPho)&Bfxm#Q98{e#d1*a9QFCV%F4=Z>$rt=w6d=5ZaCOPH-2*#AjEB| z7r;&Y+PAY11aJ{FIPM?mKm^=91y=9PEGB(I3kigUal$V#|GNAEvb#~^PR7G(o9KU!w zHr4>X2X=iVrOsv^@dSK`?0vX(K47>bFl|Mr+#%0e&fNUlL}xDGxtaS2&CZ3bhVMAVJWA#WirAweV-SYIuzPi}}1RJhKrtRaC;{Zms@D7GRFeMc%cu@mtnSjpwL2OQ6X3LFaw3WD?>BXlLaJr(Lkdh=-g z{?y2^^!`4TlUJcb`XfD7cMYEoH6_eqK@ z10S_W{`nd2SfjyFvR`KZ{{1hitN$!aj!sQgUv7-Tx6dEZW=b0%JNQQJNr&gYn~OiM zSX+Na{KUzMLu{eSXmsn2>cdj0+`r3nqPNApA>F=}Im8VjU~q6SXpWw)Zo69<&TM~Q zUzX98@JqMH_MeRR`m<O7?PFvFO1k#b6Ekjp> zf`T>>8-b0d-fVD|e*!cuWJDGQBb65333Oh0ST&rW2oQQ8&WI2D&?| z3~GLN7lRBbgP`SkMMW|b)4xczOf}$|*V^)lYWOqq%|~&~dd9}Q2Gc`BX9_Q792DL6 zq30~ot6c=0#-8)~`T0bp`i5Mhl#glYNw|^&XPYe;RSG0j4xr0!z2(b%Wfvj%wz2YQ z06Oq_7(D$rxjj9w3>g_2SBC;v_RC2AMUIXBQVNcl)qEUr8t2S}b*aM~vh?-Uwp-Fr zwd7VFQzNnQuLkGX#dMHuapoBqnaCf(SmWX4HGXm9TFC8as?-FPc}|PVm+e14y~V75 zXfq9`&E361n)L`jf5`p&6uWm%X=I7{wejiQN&DKbo1I$_AgIfJ{lG4w=#IHPR8gGF^&oLxS?sR}w8M#f6>dUBMcr%#_^7r@qE9CPks^YCs|33$8nXp-^Z&6#R^J_O>a zzKS`i%@wsPSF-a+?DctR1M1+DH9}g!LeGvgW_N=vNNuhOmet|O)gY)ud%p~5bI+a- zP^f(}H^fcBeo!pHd+X}z;EP?K8E7&u`q7e{92d9x?LL3b?>hvEj0=rAWm=@!&t%3p zf1IC4S5|I55n;-u*Px>}!qE*Ie9wWCc_k&E-n{YiwzssD?`H`YW8)0duZuKfimEqX zU;N^T1~#!u`to?|WB*8p3hw1Zhz&vt1s=CIGCr=^YOkI1?GWcaToI&7$+{8;d1U)m zk1P66L~L%kWarkITc61COE`C}qfO&usG~FMjws{UjU%cv3^J0(1q5sy9W$AIt3cR8 z9#*?f(snx0B!;$s_>hCF0<_1G)UEGR-$y4(_Gb$tT#^^p_GODo`2A3aukf`b7!aSmX5p!7<*jJ2kxbJ*<6K4dE$4ATe!g5KUV2S&Ik?G`_EK4d?HA8koFKTXedlAEq%l|S`9=6 zmnSMRvLCWKLKhu4)8(cwZWKYh&(6+~~H>b+F zJzVlS$c|plr$oFcXl%+v2w&D?cO9`x$XsmcNOc@P{xmi9OtZ=vkKo`34^&J|lS)cT ztk*Tqbsh1r7ZZq6)cdwwolG`nV=w)~w#f=j4mx{#8=JIfH+bC7!Fksh$J#Oh86%D9 zo~5SVGNev}-iI>YlD`|_&qT^t(j&*n zx>p=6o3Wy|(KmKSlP-a<{^`rGn9s%9~x*hcUOOga>3C@L;29BH~#8Qqy0fGx_W4Nx!dK-BiUM+ zVy91++x5uI{O|n0Zhp}S%i)ocYsmRT!$L!lz;*GbL3ZZAe`ZS0IEGUxB3b~X3^su; z0B)eCqLSUPrZ8vTllHFv^~Yp=dau_PVp{pmr&g(fnZPXrvP3k2k%@`#nbAK(Kuk_+ z%h&k%`5Tndqdq1{oE8`N1XU;eU_x+MueD}^m z8Y83PQlCtFY!pNPy6?4u34(JSbk{)nu%J6xJfA{&mQeu8m64G_$;HA8dp}o8-gG?y zX_Ciu6I5yI)~!iZ@gX65)_c3V%drzZ_@wsRs5%9KX7yj%MJ=IL5bQ5`kr3MJL{35B zeC-+vF@va+1&$ZV)?4}ceASVLbxMN6=Wg?#Sn;^tvhelQ9c*s(X~C(cqE+(UwuHS} zXnAyWR*sGcclgLCT)S43kT}A>T@-rZN`Mx&vs&#j*p9BQI_&#NWCadNC>KD;KKJmT z#`K-ZrXm7i$Lr2cfWifAOOzX|Uz$}%7|z24pkr~3-oLd+3!VBAC&Vg9ww{6bWNds; zqD3u)UE?@MU0cbpp_$pt=xAnNtcP=6(wR9Xf<+I4kp>2_fW*1ElPD@EK*K)|;v6tD zt4c*3;yQjj^xb#+-csE6m4O%T#WlB}it6R*4}JZ*7yOi&SrWLO^KYMjXR*p!2{3$m zY)rq}LwG^G16PQ8jQpiOuP#hBTU?FdmWrcb?2teLxTtf^@bFfaUN{8{kk4rx}xubrcT;+@j~q7>w#zvT&_6v zsiVUM=}|tTXS{}`SunD(6hxL@V!6Alb8nOf34vhJQF6K^%`NA0{uiaf7Vc4f(W2S|=%i5SLlr5Xr_Tx1;$oLhch!%Kw@W zAjUvRi7lYcB7F)O(T;m@lQhzGyK+Z9m=_71d_#6An@~!jwRq>?#Kv4}ZdC4?gMPln z>3Onk)?sX;dMD%U-$xg^dVF?@v`Y$#vgZ1diZ3+`IChP%J$INp?$r4FlX~$0;ZzC02WuQ-WY z*Hlq#5;{WsIr&$8uMI8E?n)WTh^4S-es@o34KS9655&As!<9 z#^B~gd3Ch}+b}o~QhMGfj-Q7*jKBw1W-p`9iE11F}@o+PPSj? zKx&&6Y8_ZkhwZ8y+yk&xMbh!zrp8|&)(a!V_$Rv7x zf4jRuNjFbl1Ew#?DZgbr+>0cFbE!M`QuFBYy+BuS#=< zVf*Ra2{)P%93>#N1;ncO(6k-6Ym-5_UIAwz= zM)dTQ{jV8QavUy>9d)5Vaz2Y9oM-IhND_6q|BTo$KtlwIHR-&k7`5)$0XjcEqXNbrluNDx1n_t$s`u<UK zG4ok33keCy&!0lJ4Jq1VR=4y|#^ZBPUsUYF%fxug_U6S&arl4LIOuiBI^>&rzK9HI zd=tjA+?<@){otmP?AW1ctEWh-dCnf#6m~SE*s0~;-{mIv<%8;Wc61>7|Cf{vHG16r z<538xVPRo2FXkw#Z2}SmmGU>?7(X6mDK9E&Xl!)8e*K9XxY>W$CmItYjbd2x7(&Q5 zYv1;eZwMVedi03n@L^&)LQ>KjW;8%eD&5_P%1E((aD6=J5M8Nq0IT=a*Iz~e+3w_NWQ^W@ zN9g?gct}C?nBxTwJ+Dho8#>>=&%)KBlKbtwC4Irhrnj?`vn*81W`3*V~jH#AZ zpc*0N+%SJ6x78$8my`{dEUhqm;p*@~h0D4!_p-CEgiIU1H)PVSiq)Zp)0u>5zPE*i z1*H4xn@b4$!@;;rqnVeVj|4>~!U}$V+hy+ktHuCVW4s@x399QkrkblmG7S+>Qg9-* zk5Fq49x84=lIyJjHOU0yNM2s+n8^@5NXf?WZ;=V3rx(tsNo_f9p(I{re(~b9jkT38 z<&J|D&Y4gNeoEe3%U9CN-EQNmKOtN##`_p(H0d*R2^6q{OiW0B-~!#nlk#MGK~E6_ z!+Z&Nb~!`}Kn2WR{aIP5Mhb3T5-|xUH#hJP#I@49pQTqr`I)KtQxF^5lbP%d#ro)I zaPb5kqK*G#=UVF~$=<8ukg%Vej}^G^(pT<2ZS|k&Dv9;&FOMJXpFHN1t(`%qsk0_+ zK=CFhtP~O!?r{)7|0s^y}jHF6=NF!_z;fqWizB~Xt}-EC+L+UeTAL$yR6%d5H|H2 z&Y=YCy;bq2Oone;oS)1^WO`r&AtZ%53=0q0bk)am8?I$F8fImn|(<|NQyV+q+}?c1Ws${_G3~7jDO;G=mGieS4Q1`rp3}8$AiZ z^iiUiYYtYZuy6)?BF&yJf8`Hn0foYXGZD!~Oc4hU6SIInt7yezUYNJrwsk8mX?=Yi zBbgkz|2Ed7tg^a*pf#p*_oP)}$o3_&S-)ep5U5jmY~PQuV2S?QBvbX#!-oS}M)8%v zV{l;LI53GioedL10ugBzlyOyw_D9jt??y1wR4|n?ZhAdlnCkcuB&71HRlCUNv zB@uDlybw09SJJAmvdu9kWPkhKB1@_Y;-)ns;ggBisnQlVd|q8$jn0Q>18xaX8C3@( zIE=7Y;SRgFxLmlvTJ{C%uH@#LGq;}N;^THsyOV#=OMv|6pWqgdrcsL(ko)-py%a;Y zu_x^r7oK4>lbd@2=rDYr($q6VqF^I-6mDr_k`G}v(bnb=<>x`e`rleh+7AE5aasrL zl~dQg;l9b(phTepAOe}$JdM14SXgTKTb@e)$dtaUucOQ`U9%8Z#*SHH7m`2}>4An; z%T;W9PtP?p4^EbJjj6yl*6UB=**k>SQ~ys{@mh1tbK&_EDEMoyrsBErVJg&F!yWk*lq_ISUV|EohHy-yw#1yM`|{;9ez5co^0I#qj~{iv@xQbmuRTmeA--n$ z8---D8Yyv50qHVqdY`ACxyLfFk6^lKm^DwR-Vh5@&(Qq7O9cn_Z?j<%VoG^OrJH0n zjAc@vLYFCVJ8_$pst{ zndIt)95_;ajy5*ze(9N+_tynl#iMrhK2TD5LwhkJS~sI`3EIc2SFi5u*e!741Q|Jb zB?v*-v(MZQOsREC)$NLO+FW%qy40p3kX^O=d>keP3Mv-|2Tzk{(EkYCb;RN{HN*1)^?`uuUcUx9SgPA2bjqyh|U7GVk3PZ8Pt+cNh@CL9v9+$Mwgwa})f%T(jC z6ES`C|87<(dzBd1c*Zu4z^_UWo9NUt8~J?$X}Z0n+v)gCA4wT-{#zPUxI&ce|1i?S zVh_{_4;V+}pJUbyUbOtC#>U2d0|Ns{+(Ui!*tbK56cYj%Y9`$d&IWX&a zH9w|t?%X>Fx?|Qyv1tHRpf>g*yep^2phd>1d7<3TG^xlWox-|ty38Pd4K8yqj8DX7qNtp&F%+JWl)dRd^AQtvQ zwnlxipKI(L?n^d~6)z*vxGK`kLO;@Q&i>PwfC0&YwKF5%S$$Oaec7u`0!;OC*Afsh|8 zr=A{BUS2!Yf_Y!AhL`^cym6EFvI)*xKMjmL7!q_#FT!eBh_)JL_CA;tmH z9J=+$2&dKECxTYZh=Gj4hXjZ#d@=h09E9oM!7Q)+R8-lGkcl}E2CmyH@uHx>0dpJL z2fAOq8shg^p$MqkSDgl8i{PNy^Q#vztE1#SR?M$X>l*B;$q^}F6&yLto|h-JM}_+z z!M#-zAY@=(W4lPsq9b|qZ8mad%K2u^5C=z(&E!z&)3>G{wP9@Ka9#X5TCl?HaYI8R zEHROZZ5R?gaoi9~^+vUAU|{Y4XfI+F3-q1Jii&!WI0gkm*T-C-xr4(1DA1)#5z*0yD?fAJudhU=nE2X_ z{rhG3$a&;-i-Fk_*2lY16*WEG_1?-jb<*c^=%IcTCHtCFe8lJ=x{22JD`%5Cj_~k& z0d~Y_)%gVut(_kX_e;<6$!1;NPc{|?ia^w$P=g@RRix(FT> zfyRk3e|pAMsRZ`T>QH0hyRptof`UhLf+{Vow~p;@V-ru~4>e~ffcm}g&X~b`#4w0d zx-r!FR^XdrUQOP)wiO-fO7@o*E=p4!j~g31{6kIc;#cY!svWXV-g&)F3pGBo^WN^` z@R)rKKllOPiN->4)g4iP=b}=uBZ;``@D@uS`y8*E`<@S={`kF z0^FJUfMJ>5oI?0SXEHD}-qn9NqWFEWVdmH2PR9E?r6*&Oj6n=hiIE6PL+Z)?-PVt{ zd2?MgrLJZxQpeKl+Wk1f*4};!4Gy4SZG9b4CAT7XF}$&3cxJ}&ulK1)Ho2Kszrh>sP#(h2^9jJ=-t}x1i<6Bi!6+U79h%ws?C0 zwFLiUh}6b&>o)dmy|&(7F(mE*S*c_`+g;byjT+Oy4#x-|Q`pHX?-N9w;fnzc%U7eh zAnGILwJKCLhtN*-ix(X(Q`M=TFyu$eT&#WjcCFm7Px$O%yVtu^CJx0JWUp)ue1ER# zBU$`>Fy+VAN64yquifBAGzaS8N$<5~u(P9Zj`nIA7>s}aE<5vca#Fe0;mQ?71%>x5 zEr=jK=@Q5IjL&YDqQ|gHFO#TiXcXD?AluvKf#geMjZo_@gE@(P76xS82k-msiDer* zd;eLU?s1U{ODiiDd>gdtG=Bt5lnR{u{QWDQKS#JB_@HPp2_K4<{j`fi61IJ;TH;Q)D~C&(8<*`!&GZhRVdW zc6aYIWbFy%+!1?O`00+YAr~M< zJL`n#3&ds&j?Da+m_Qa_6;>xySp1u|NkgqM;@C8NI`I5#r~i31fcMd}a&o_Kya272 z@LDZ}w*T}gaVX5@g=H)CitUGqLHewLUFS5n3h)pv+BqQ!iJ^%kixr3o+2_nLkzHZa znFF{A@e)y$z=C&Rodb9yiKC+)bHnTtort;i=K&|Z&!+3c;egeKUs?!ES)DGGDNCu*|j&E=jEK@4{nlA`G#zF zZfl!gy4z;gNnWQ^uzYBnj>hr+#bQ-o)7Q~S&**iXNYq)<Un+YBj!>!<%ocE4KPdUUK@r!{bgvY$Rgd@PeHF zFW;|nqZvZBOJqW(N!g!!f(VVnMk+nsxc#sH%C!(yE0gr0BL3#TysJgpPi9CDgV|k1 zjt>|F-=Y`1dv}) zzJJF{1)e$d8zLkHLK+)8J~UJW@x=ZervqlsV6GTdx?BNj3fT7w;q4meFn9g@`tZhthf(WzYsr7S4u#9T zx_IJ|k6bv5vWiL*KrwC~A#D*LNC4Z0O3(hkRt#Vbi8cvXC=gEY?hoQyKjxn#Bpk#v zVO$(c*v8R0#9>{B-|v%~82bs_mKmHye zj$+lrQq7o4gj^5wPe)5jeC-Dp*WIDGKCyQK_O9BC5k%#00_%;BE&b*<|ZGzSkm(@gk@=VHch1IAF&Mc(L_NjRn&3f zsCPLKGWHpgIZ?r_U0sU+!1D6#j-w4Bf>Kh04Gn?45P69y4G6gk)!R>?E}?tA@LVbW z-0U>*$QjS35kG)6*OZ&)MOHfw^?)m+#1wGY0;Yzje|lnstG@l_F;x20LX{=Nav zrU8O-PR{JoQl=Y(#VYUhN_HCD^8K1>SP|0FzQYcnndTyHf9AsmGKr=NZUSMm^Aox& z*FXo`3t`iZCz&cj`GZ1&=q-MaW*$Kmk|#D|7WVmF@xRLoW%f#Z&4a{OHnBFpe}9CF zOP+VPc(i_q2IPDiQKci)x_Ww_E@cn@T3kew1G881A!%vqOgn-||669nK7_a{%~=|; zTB9FhwJ?|m)e*-LD#6`=03Leoh@m9B70IC7AyJxjFCX3qz<_tIu~|T&L<4eh#~Z*9 zWn6&h_tzW1xN@|#qy9cW`9A}dVXRWCV~-*J<9#|sv!$g%E7v}}GB0}LP4y@$>TP{} z&zCRAOeF7R7q(oXu4NCZs=A3cV8O^GdSrN5Nl6c5iLdK>kDQ<7$Czty0ANaBgaj|Q z!8AEWjzjm(;x*Pmntvg)3BRDwuq@|q^X_1XL=VQb11d*_aY1sj z*1fUSeKoWcBqehA3};{oa;*xeX}Ry%*5_g`K@R?Hpv;DHxN3~|Vb znHg^`jKHj}YRvIl9$j*(2~K#I20Sm!OkH<#({ejPoFT(b#>Ep~WF!kUKyA)8q+slE zh$JFVwTshI&jMFNzAtAAa9yfALHexm?PudjfeRhgBcCv7#f&*Zrgy_ars zwGn+AXK0oG%_WClk2R@BBsa+8_Y58-oYhS@{(aDVA+u=ZAq8PC&GS?;0-=EvE-A+$ z?5)t?t0V+zf!FAk|KET3fUwZ^t{CPvoo=r1vgF7^a)LR-5aWq~i?rvT<{MWKHRf@X z$lI+X|4(IC9u9T>$G>dHY$cSV#m|vVnCQ?@G?6XYO-UK!7?fRNgbt>XGpy)P+lC@# zw9bqz24ftpj@?2frg7|yRaX|6mL=U-S9AKkxVJV(g@# zo2txH)-UpR1iAry>w4%i{0zXw zci(-7J;Q&C1x5}qiQ3`*NTooZJ@)!)bnAW4s$W8h4N&vz6gsxO*jK&E1945Y?;cX2 z)`jW>rzLw^|F1hde{@|TJJGC*XSjU+yt2Cb>l&+5_qc`+BS$4-VNlH|HGYV`R&wX< zv*za25H$5asaBL>X>f#|+uXJ|;S`<Hhz1S;BQpwpXnVqd z3z!V(9}f#y*kp*29JrOFVV%s)pKlj8iOr2~(X|~_(JWoXa22{JNh*)m@g`*Y#}2&d;%vI-xEE*VKO%>l$|3=Ju~MR`rX!6XNmsBTg3y}Z?w-IQG`Mao%Mr9 zkJM~4t)rzVI{zu8gNdBNp#!0esx6{=K!B1#lz8EL7s{eDf-9_At-b;_`uMDp@^oF- z9;rfAFGNG3}!5NeJTuUvtnk^YOM@*L>`I z_td}0^dqBlNkUPx?wML6w@#V%<$><8aeMxV>=htL7-S$!N#?foj{rZ~6gTI?L}|kM z`1P#4!I9>yrVS>24QxJ?F@+6ym`f4EbHpp4w7vBut`RNA+oK?Sa{O#`g-;~LG@9tR zdX45ctLC-^N}?z(MWUC73K}|2AP<1-%2A+jgC3oIYtB;>r45hVwwJ7ozIRY!vHCpf zAP_XHcH?C7+`~i@HU&fr9nZ3OSKNcBOwmP5KcwNIJg5_VO>b{6#IX50LMHNrBH*Q@ zJsMj-tghBWL1S%xZSBV8%YS~X8@Jv@U;0sD@<6qw!_|$EP#B=9?NUM1NMl7Jc9|;G zg`$T>RpV$yj7rq>*qVUT=aP%f#Gtx6+5C=vPU4;OSy^6gZUsCYi(nQA4ot93esHes zWTKA=hx-M9(Iil1QcnaChz%!O_(z}-)Yn)ZAhK0eRK|k&KKGI#A7x!JHPgT!$p7x~ zx>%jF6%g2wBjf4QPC0f+XT@n)w=E8x3JU}?4rb|GsqnEH!A%HQ8TiKQFpVAXOi`~9 z$yGS6+xn|5d{}Kf!Nkv(iUbFnRGmVw^w2~G1qYi#$7*bxJbZxAeMe!=qC#P8VIl55 z@cFW3@FeIxy(1U%i`lrs_E?AUHOsZG<2c35K1H6GP-@8%EV@L**sl(%lqZyo46dr3 zHeRB}EV=hSL&-8zAU%vy zh3f$cvd_;iYNUN%eWiKfsEhRFHvZ)Tu(w{d5#wOM5r-g+o{8kg&eZ2iQn%BLW2ypL zaxsc_?k^{8FCAq8pwG=S`r*@iUw1L2-MOoScbR0Wxm@UK4?sr%+Lj#@L}T9&)~eHd zM3SzUBSy#xS zvBgRWN??UnQmGk$%AWI`GK9`!@};Q$~rtd=119!_LSceCaC7)i!ZBeak?6C`vEmZThCj0!K1(HK+K{m z*^fs~wGtD1l6DX3eP#k5LDOWn#=*!TJKr3=4?ktg+pJy6@|E@Uq=WPI@!>Z4b;4%m z(&bD!h*%V%g!e-l*AP3+UDY?KH+f$lzGlY)EKF22;)KY=;h zC8#FYI`%Z?3JOyI;t$5|fkOgVKOhRI?mA?71$Z5_hP%AcX&~q1v^L#+__~a(4ss64 zMo8A6;&6w2ZdLxKUXMbTubnT698Efdx6UR`CgoA%`}I!#{|V@LbLWv7>~f&0Xf&A= zC-^+^Rv=X*SsSl-V?KcV_I{4uU9ia*8LhTGv(+igbl3fKk9GUy_VC?3P1CAwnD`?^%3w#P>z@agt82bN5rtb@ za75si(PXfIO}-q3-)$m3$`P{+4eDw8a~-eNf(b;`KzJr>3*+X7MnqrVK2jhXtrhzf^{xJqfr+oP9TIrBFhYpo3Ctz z@v34Ueo7^D7dUA0xWdJ|cR;PI=kp4!w(e2~ZC+-UJW>Dn_ilFlli5W4+3`CUwea!M z_#MW%5+Y_OIq5+Ei5s}b`9?f7b{;{=aQzhhdcDE7^$hy4mnv$665En-@TlFj2Sdl@ zBj-i$-4l+l$3~?QV>_Djh5{8|PqzV@6Tn3}u>i)+Cog6Xi*It%YyLhm}{9UI8< z63%ErB_F4_aSXY5Xfcl=uoH3X62IUIVMEyvMqobBq?C;lzq|>B{(}vdGOz|S373>c|>O+i}C~qaa4d`WVxRr*6_{$dY zaONW0dZnS^PO=`5Ii3(`Gd%_n6Vtp^N11yv1f{-gF|3`q0{g$aW zY0ZN%NS3w!(7L;$0mFgi?S<&#fS&NvAc-D-kz!qzhBaNIVL<49n?8Oy&~Ug{yz=Q6 z1Th?zt00CdjuhZ@G(Z`k$uD!AHnYgOaN&hy48jwvSUru;iQC^}y`fF?h9(O0yX@`J zC=9%`z-LSNh$*6T`qEQNN?`egK@K?ud<6g>i+N6;5RJOB62XMD<+@kG6{N?JYD>gd zV9r6ZQ(9^&&z=8OMIx9lAOn>Gft!;`MJK6ghNcNdjbHjX5WTK+FS8di5QlBEc~ny0 zqjqHeCpKf3IPSQ|UhnU!{J$PP|GLip<&QUFkvSTyPcF&3b0*JzVFaQ7m literal 0 HcmV?d00001 diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/pda/stack_1.dia b/plugins/org.eclipse.dd.doc.dsf/docs/pda/stack_1.dia new file mode 100644 index 0000000000000000000000000000000000000000..e07bbeef391a45bdc2419101a8f8fa12956dfe53 GIT binary patch literal 2012 zcmV<22P60&iwFP!000001MQtlZ{s!)fbaelg7@mse2Jnqn=E$G7A??451XD1+F~4a zWyz4}JbLJFFDc3KLy}*z;s`4PNnm+AL((&&k3*XI^!a%fSdTJJ{3yKXBLMrB3@4H2 zhtr$>-*>-V@&4!A-Y3r&AN9{P7Bfq~BTUS*oBo4R^N+*f)6)|OUJ{|A7zF+TBy#wl z2m&$GLc{)T&$8APctQztEx#(1iv96INh=gHdD9<@$&YCqEkduKN#$~rD2QU~Q3N;r z5BKS#Kg`t(H}ve#Jr`3sj-~ifts3fw>z<-|F5_*rvw4*GT136f3nCSI%;y7y2P|1@37EWgusx zNfd`gFgQ<-QUht~DE4ZZHtZUzAEZBhP}RB-0^Ejc4|JL_Kh#4s+6>E*z%*egPwY?f z5Iv1b=yU(A^%yJJhdqjg=P!~S;|7ppQ3g3ZRC zy9z%<0dG9|YV_xj=%c{t0`TVyz&rV@)*=w)5r}I?AO^(IF~Wh1?FJ(eY2bupfE>UH z=O!9$>I^Uh5SWb!@*iF78P zD4lVVLYysMu^x1e%KcGADHK?%S8w{fIG@;3dY(*3YR?69N@_k2Vhk`s{526`1{}_D zdotl#^0Rv1q<%?7ahC?qn+BJ@*d@W1CPCP65-gvO(YiU1=ow3*8dg4kRmi4ID{p+*u6 z9M%RT`LcXR(z}Z_8w4GaoF7S6-iTQTC9Q-KdJ!mLb@L!428Np~6Ke}}Stq70Acjbo z-6WFK>eE3BHI0{w8SF~MZQ>E9b{w*0ZH_k?ixfc4(gF!agkMt*7$a$cgmBgZ8u{aw zUpGp`R_~h##Z-1ga%Lh~`lAE5i#j4{BayJCiA4VE%lJ<}lqF!o+mR44GYQZgAd?u8 zb8XN8V=_PtaO|8|2N=tLM_GD0wtppJ*s#ndaFmoZ9pD@yR<{bD--wMXB-Kt03vDQU z?I>;vy^)CH=xIkN;hL&Pfefd+un(SG<9ao*2P_Y^aOQ+i{a*4$HP;HRa%d;TsI{MXfu9Ibo%0i z81Qgy-XI8-_O7(pgVWZb-Ew+f>KuSeXW+|@gxX9(um%ay3z1Om4ao$ii(rkW5e_IZ zbs?75g%Gg0sSCL+sS7RUp3vgGaRGxm_Gz4b3jW!FPkX_KwqrGn7%PMt7I19Lv(>O{ zv!d%j_6}CV4&fO`Q6yX-CXLsAI58=Myw-jYXYK&oz-a~a zXb1GH-d6ReEBm}5`V_siL!b7d4{OW%m-(_NX6ar?OzgDmgKdfoN)SZwyI24-8=F%& z+gTst=`tAt-Cm%Mf0|hSy3k%ARC|*(P8SsP&86wO55zc49Lu^7b*V-mX7(7i27xM0 z<>*-GEm^44V>=vbFAni`EPFLUF%#1&A}QvwLyyB!5SDg<A1)L^zIH<~?cfH*hb!2~YV1f=I89GmAln~*jTkRK*8 zR{0L-;c^{porpRhx(pDNxNnC;t;Hb>TXV!B1rD)Ux_D0^H$a3axASv7oCb-gqK74d z%(Q0DrXW)mGM(VvH^n+KI^meXcUv98=qzNkSvEa?8essXC$nZ;q;H_qL1up64lb%X uskN7XN6hNJBld Date: Thu, 13 Mar 2008 15:53:03 +0000 Subject: [PATCH 299/834] [222415] Fixed processing of multiple command responses to avoid double processing of accumulated events. --- .../dd/mi/service/command/AbstractMIControl.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java index 96758120a14..5772bbb3fb9 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java @@ -509,6 +509,7 @@ public abstract class AbstractMIControl extends AbstractDsfService * required for processing the results of CLI commands. */ private final List fAccumulatedOOBRecords = new ArrayList(); + public RxThread(InputStream inputStream) { super("MI RX Thread"); //$NON-NLS-1$ fInputStream = inputStream; @@ -599,9 +600,6 @@ public abstract class AbstractMIControl extends AbstractDsfService if (recordType == MIParser.RecordType.ResultRecord) { final MIResultRecord rr = fMiParser.parseMIResultRecord(line); - final MIOutput response = new MIOutput(rr, - fAccumulatedOOBRecords.toArray(new MIOOBRecord[fAccumulatedOOBRecords.size()]) ); - fAccumulatedOOBRecords.clear(); /* @@ -612,6 +610,9 @@ public abstract class AbstractMIControl extends AbstractDsfService final CommandHandle commandHandle = fRxCommands.remove(id); if (commandHandle != null) { + final MIOutput response = new MIOutput( + rr, fAccumulatedOOBRecords.toArray(new MIOOBRecord[fAccumulatedOOBRecords.size()]) ); + fAccumulatedOOBRecords.clear(); MIInfo result = commandHandle.getCommand().getResult(response); DataRequestMonitor rm = commandHandle.getRequestMonitor(); @@ -663,7 +664,6 @@ public abstract class AbstractMIControl extends AbstractDsfService * example and the CommandDone listeners there handle the IO as part * of the work. */ - final ICommandResult finalResult = result; getExecutor().execute(new DsfRunnable() { public void run() { @@ -678,9 +678,12 @@ public abstract class AbstractMIControl extends AbstractDsfService } else { /* * GDB apparently can sometimes send multiple responses to the same command. In those cases, - * the command handle is gone, so post the result as an event. Again this must be done on the - * DSF thread for integrity. + * the command handle is gone, so post the result as an event. To avoid processing OOB records + * as events multiple times, do not include the accumulated OOB record list in the response + * MIOutput object. */ + final MIOutput response = new MIOutput(rr, new MIOOBRecord[0]); + getExecutor().execute(new DsfRunnable() { public void run() { processEvent(response); From fd0cf814ccf001f6d46da90a8f090b1f5a7912a4 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 13 Mar 2008 17:50:32 +0000 Subject: [PATCH 300/834] [220446] Updated the PDA Debugger example. --- .../dd/examples/pda/ui/PDAAdapterFactory.java | 1 - .../pda/ui/PDAAdapterFactory.java.html | 223 +++++++ .../pda/ui/viewmodel/PDAVMAdapter.java | 8 +- .../pda/ui/viewmodel/PDAVMAdapter.java.html | 66 +++ ...Provider.java => PDALaunchVMProvider.java} | 10 +- .../launch/PDALaunchVMProvider.java.html | 149 +++++ .../ui/viewmodel/launch/PDAProgramVMNode.java | 23 +- .../launch/PDAProgramVMNode.java.html | 303 ++++++++++ .../dd/examples/pda/launch/PDALaunch.java | 90 ++- .../examples/pda/launch/PDALaunch.java.html | 271 +++++++++ .../pda/launch/PDALaunchDelegate.java.html | 234 ++++++++ .../pda/launch/PDAServicesInitSequence.java | 19 +- .../launch/PDAServicesInitSequence.java.html | 140 +++++ .../PDABreakpointAttributeTranslator.java | 10 +- ...PDABreakpointAttributeTranslator.java.html | 148 +++++ .../examples/pda/service/PDABreakpoints.java | 250 ++++---- .../pda/service/PDABreakpoints.java.html | 416 +++++++++++++ .../pda/service/PDACommandControl.java | 11 +- .../pda/service/PDACommandControl.java.html | 547 ++++++++++++++++++ .../pda/service/PDAExpressions.java.html | 386 ++++++++++++ .../examples/pda/service/PDARunControl.java | 3 +- .../pda/service/PDARunControl.java.html | 330 +++++++++++ .../dd/examples/pda/service/PDAStack.java | 48 +- .../examples/pda/service/PDAStack.java.html | 393 +++++++++++++ .../service/commands/AbstractPDACommand.java | 2 + .../commands/PDAClearBreakpointCommand.java | 2 + .../service/commands/PDACommandResult.java | 2 + .../pda/service/commands/PDADataCommand.java | 8 +- .../service/commands/PDADataCommand.java.html | 46 ++ .../commands/PDADataCommandResult.java | 3 + .../commands/PDADataCommandResult.java.html | 55 ++ .../service/commands/PDADropFrameCommand.java | 2 + .../pda/service/commands/PDAEvalCommand.java | 2 + .../service/commands/PDAEventStopCommand.java | 2 + .../pda/service/commands/PDAExitCommand.java | 2 + .../pda/service/commands/PDAFrame.java | 2 + .../service/commands/PDAPopDataCommand.java | 2 + .../service/commands/PDAPushDataCommand.java | 2 + .../service/commands/PDAResumeCommand.java | 2 + .../commands/PDAResumeCommand.java.html | 47 ++ .../commands/PDASetBreakpointCommand.java | 2 + .../service/commands/PDASetDataCommand.java | 2 + .../service/commands/PDASetVarCommand.java | 2 + .../pda/service/commands/PDAStackCommand.java | 2 + .../commands/PDAStackCommandResult.java | 3 + .../pda/service/commands/PDAStepCommand.java | 4 +- .../commands/PDAStepReturnCommand.java | 2 + .../service/commands/PDASuspendCommand.java | 2 + .../pda/service/commands/PDAVarCommand.java | 2 + .../pda/service/commands/PDAWatchCommand.java | 2 + .../sourcelookup/PDASourceLookupDirector.java | 2 +- 51 files changed, 4048 insertions(+), 237 deletions(-) create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java.html create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java.html rename plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/{LaunchVMProvider.java => PDALaunchVMProvider.java} (92%) create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDALaunchVMProvider.java.html create mode 100644 plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDAProgramVMNode.java.html create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunch.java.html create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunchDelegate.java.html create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java.html create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpointAttributeTranslator.java.html create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpoints.java.html create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java.html create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAExpressions.java.html create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java.html create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java.html create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommand.java.html create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommandResult.java.html create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAResumeCommand.java.html diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java index c519506f688..5fba35f857a 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java @@ -174,7 +174,6 @@ public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2 // Returns the adapter type for the launch object. if (adapterType.equals(IElementContentProvider.class)) return adapterSet.fViewModelAdapter; else if (adapterType.equals(IModelProxyFactory.class)) return adapterSet.fViewModelAdapter; - else if (adapterType.equals(IColumnPresentationFactory.class)) return adapterSet.fViewModelAdapter; else return null; } diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java.html b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java.html new file mode 100644 index 00000000000..3d98e729b68 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java.html @@ -0,0 +1,223 @@ + + + +PDAAdapterFactory.java + + + + + +
          1: /*******************************************************************************
        +  2:  * Copyright (c) 2006 Wind River Systems and others.
        +  3:  * All rights reserved. This program and the accompanying materials
        +  4:  * are made available under the terms of the Eclipse Public License v1.0
        +  5:  * which accompanies this distribution, and is available at
        +  6:  * http://www.eclipse.org/legal/epl-v10.html
        +  7:  * 
        +  8:  * Contributors:
        +  9:  *     Wind River Systems - initial API and implementation
        + 10:  *******************************************************************************/
        + 11: package org.eclipse.dd.examples.pda.ui;
        +
        + 13: import java.util.Collections;
        + 14: import java.util.HashMap;
        + 15: import java.util.Map;
        +
        + 17: import org.eclipse.core.runtime.IAdapterFactory;
        + 18: import org.eclipse.dd.dsf.concurrent.Immutable;
        + 19: import org.eclipse.dd.dsf.concurrent.ThreadSafe;
        + 20: import org.eclipse.dd.dsf.debug.ui.actions.DsfResumeCommand;
        + 21: import org.eclipse.dd.dsf.debug.ui.actions.DsfStepIntoCommand;
        + 22: import org.eclipse.dd.dsf.debug.ui.actions.DsfStepOverCommand;
        + 23: import org.eclipse.dd.dsf.debug.ui.actions.DsfStepReturnCommand;
        + 24: import org.eclipse.dd.dsf.debug.ui.actions.DsfSuspendCommand;
        + 25: import org.eclipse.dd.dsf.debug.ui.sourcelookup.MISourceDisplayAdapter;
        + 26: import org.eclipse.dd.dsf.service.DsfSession;
        + 27: import org.eclipse.dd.examples.pda.PDAPlugin;
        + 28: import org.eclipse.dd.examples.pda.launch.PDALaunch;
        + 29: import org.eclipse.dd.examples.pda.ui.actions.PDATerminateCommand;
        + 30: import org.eclipse.dd.examples.pda.ui.viewmodel.PDAVMAdapter;
        + 31: import org.eclipse.debug.core.DebugPlugin;
        + 32: import org.eclipse.debug.core.ILaunch;
        + 33: import org.eclipse.debug.core.ILaunchesListener2;
        + 34: import org.eclipse.debug.core.commands.IResumeHandler;
        + 35: import org.eclipse.debug.core.commands.IStepIntoHandler;
        + 36: import org.eclipse.debug.core.commands.IStepOverHandler;
        + 37: import org.eclipse.debug.core.commands.IStepReturnHandler;
        + 38: import org.eclipse.debug.core.commands.ISuspendHandler;
        + 39: import org.eclipse.debug.core.commands.ITerminateHandler;
        + 40: import org.eclipse.debug.core.model.IDebugModelProvider;
        + 41: import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector;
        + 42: import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory;
        + 43: import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider;
        + 44: import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory;
        + 45: import org.eclipse.debug.ui.sourcelookup.ISourceDisplay;
        +
        + 47: /**
        + 48:  * The adapter factory is the central point of control of view model and other
        + 49:  * UI adapters of a DSF-based debugger.  As new launches are created and 
        + 50:  * old ones removed, this factory manages the life cycle of the associated
        + 51:  * UI adapters.    
        + 52:  * <p>
        + 53:  * As a platform adapter factory, this factory only  provides adapters for
        + 54:  * the launch object.  Adapters for all other objects in the DSF model hierarchy
        + 55:  * are registered with the DSF session. 
        + 56:  * </p>
        + 57:  */
        + 58: @ThreadSafe
        + 59: @SuppressWarnings({"restriction"})
        + 60: public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2
        + 61: {
        + 62:     /**
        + 63:      * Contains the set of adapters that are created for eacy launch instance.
        + 64:      */
        + 65:     @Immutable
        + 66:     private static class LaunchAdapterSet {
        + 67:         // View Model adapter
        + 68:         final PDAVMAdapter fViewModelAdapter;
        + 69:         
        + 70:         // Source lookup and positioning adapter
        + 71:         final MISourceDisplayAdapter fSourceDisplayAdapter;
        + 72:         
        + 73:         // Command adapters
        + 74:         final DsfStepIntoCommand fStepIntoCommand;
        + 75:         final DsfStepOverCommand fStepOverCommand;
        + 76:         final DsfStepReturnCommand fStepReturnCommand;
        + 77:         final DsfSuspendCommand fSuspendCommand;
        + 78:         final DsfResumeCommand fResumeCommand;
        + 79:         final PDATerminateCommand fTerminateCommand;
        + 80:         
        + 81:         // Adapters for integration with other UI actions
        + 82:         final IDebugModelProvider fDebugModelProvider;
        + 83:         final PDALaunch fLaunch;
        +
        + 85:         LaunchAdapterSet(PDALaunch launch) {
        + 86:             // Initialize launch and session.
        + 87:             fLaunch = launch;
        + 88:             DsfSession session = launch.getSession();
        + 89:             
        + 90:             // Initialize VM
        + 91:             fViewModelAdapter = new PDAVMAdapter(session);
        +
        + 93:             // Initialize source lookup
        + 94:             fSourceDisplayAdapter = new MISourceDisplayAdapter(session, (ISourceLookupDirector)launch.getSourceLocator());
        + 95:             session.registerModelAdapter(ISourceDisplay.class, fSourceDisplayAdapter);
        + 96:             
        + 97:             // Initialize retargetable command handler.
        + 98:             fStepIntoCommand = new DsfStepIntoCommand(session);
        + 99:             fStepOverCommand = new DsfStepOverCommand(session);
        +100:             fStepReturnCommand = new DsfStepReturnCommand(session);
        +101:             fSuspendCommand = new DsfSuspendCommand(session);
        +102:             fResumeCommand = new DsfResumeCommand(session);
        +103:             fTerminateCommand = new PDATerminateCommand(session);
        +104:             session.registerModelAdapter(IStepIntoHandler.class, fStepIntoCommand);
        +105:             session.registerModelAdapter(IStepOverHandler.class, fStepOverCommand);
        +106:             session.registerModelAdapter(IStepReturnHandler.class, fStepReturnCommand);
        +107:             session.registerModelAdapter(ISuspendHandler.class, fSuspendCommand);
        +108:             session.registerModelAdapter(IResumeHandler.class, fResumeCommand);
        +109:             session.registerModelAdapter(ITerminateHandler.class, fTerminateCommand);
        +
        +111:             // Initialize debug model provider
        +112:             fDebugModelProvider = new IDebugModelProvider() {
        +113:                 public String[] getModelIdentifiers() {
        +114:                     return new String[] { PDAPlugin.ID_PDA_DEBUG_MODEL };
        +115:                 }
        +116:             };
        +117:             session.registerModelAdapter(IDebugModelProvider.class, fDebugModelProvider);
        +118:             
        +119:             // Register the launch as an adapter This ensures that the launch, 
        +120:             // and debug model ID will be associated with all DMContexts from this 
        +121:             // session.  
        +122:             session.registerModelAdapter(ILaunch.class, fLaunch);
        +123:         }
        +124:         
        +125:         void dispose() {
        +126:             DsfSession session = fLaunch.getSession();
        +
        +128:             fViewModelAdapter.dispose();
        +
        +130:             session.unregisterModelAdapter(ISourceDisplay.class);
        +131:             if (fSourceDisplayAdapter != null) fSourceDisplayAdapter.dispose();
        +132:             
        +133:             session.unregisterModelAdapter(IStepIntoHandler.class);
        +134:             session.unregisterModelAdapter(IStepOverHandler.class);
        +135:             session.unregisterModelAdapter(IStepReturnHandler.class);
        +136:             session.unregisterModelAdapter(ISuspendHandler.class);
        +137:             session.unregisterModelAdapter(IResumeHandler.class);
        +138:             session.unregisterModelAdapter(ITerminateHandler.class);            
        +139:             fStepIntoCommand.dispose();
        +140:             fStepOverCommand.dispose();
        +141:             fStepReturnCommand.dispose();
        +142:             fSuspendCommand.dispose();
        +143:             fResumeCommand.dispose();
        +144:             fTerminateCommand.dispose();
        +145:         }        
        +146:     }        
        +
        +148:     private Map<PDALaunch, LaunchAdapterSet> fLaunchAdapterSets = 
        +149:         Collections.synchronizedMap(new HashMap<PDALaunch, LaunchAdapterSet>());
        +150:     
        +151:     public PDAAdapterFactory() {
        +152:         DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this);
        +153:     }
        +
        +155:     // This IAdapterFactory method returns adapters for the PDA launch object only.  
        +156:     @SuppressWarnings("unchecked") // IAdapterFactory is Java 1.3
        +157:     public Object getAdapter(Object adaptableObject, Class adapterType) {
        +158:         if (!(adaptableObject instanceof PDALaunch)) return null; 
        +
        +160:         PDALaunch launch = (PDALaunch)adaptableObject;
        +
        +162:         // Find the correct set of adapters based on the launch.  If not found
        +163:         // it means that we have a new launch, and we have to create a 
        +164:         // new set of adapters. 
        +165:         LaunchAdapterSet adapterSet;
        +166:         synchronized(fLaunchAdapterSets) {
        +167:             adapterSet = fLaunchAdapterSets.get(launch);
        +168:             if (adapterSet == null) {
        +169:                 adapterSet = new LaunchAdapterSet(launch);
        +170:                 fLaunchAdapterSets.put(launch, adapterSet);
        +171:             }
        +172:         }
        +173:         
        +174:         // Returns the adapter type for the launch object.
        +175:         if (adapterType.equals(IElementContentProvider.class)) return adapterSet.fViewModelAdapter;
        +176:         else if (adapterType.equals(IModelProxyFactory.class)) return adapterSet.fViewModelAdapter;
        +177:         else return null;
        +178:     }
        +
        +180:     @SuppressWarnings("unchecked") // IAdapterFactory is Java 1.3
        +181:     public Class[] getAdapterList() {
        +182:         return new Class[] { IElementContentProvider.class, IModelProxyFactory.class, IColumnPresentationFactory.class };
        +183:     }
        +
        +185:     public void launchesRemoved(ILaunch[] launches) {
        +186:         // Dispose the set of adapters for a launch only after the launch is 
        +187:         // removed from the view.  If the launch is terminated, the adapters
        +188:         // are still needed to populate the contents of the view.
        +189:         for (ILaunch launch : launches) {
        +190:             if (launch instanceof PDALaunch) {
        +191:                 PDALaunch pdaLaunch = (PDALaunch)launch;
        +192:                 synchronized(fLaunchAdapterSets) {
        +193:                     if ( fLaunchAdapterSets.containsKey(pdaLaunch) ) {
        +194:                         fLaunchAdapterSets.remove(pdaLaunch).dispose();
        +195:                     }
        +196:                 }
        +197:             }                
        +198:         }
        +199:     }
        +
        +201:     public void launchesTerminated(ILaunch[] launches) {
        +202:     }
        +
        +204:     public void launchesAdded(ILaunch[] launches) {
        +205:     }
        +206:     
        +207:     public void launchesChanged(ILaunch[] launches) {
        +208:     }
        +209:     
        +210: }
        +
        + + + diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java index ac1adb19cc3..0fe04f06fc6 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java @@ -12,13 +12,11 @@ package org.eclipse.dd.examples.pda.ui.viewmodel; import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.ExpressionVMProvider; -import org.eclipse.dd.dsf.debug.ui.viewmodel.modules.ModulesVMProvider; -import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterVMProvider; import org.eclipse.dd.dsf.debug.ui.viewmodel.variable.VariableVMProvider; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMAdapter; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; -import org.eclipse.dd.examples.pda.ui.viewmodel.launch.LaunchVMProvider; +import org.eclipse.dd.examples.pda.ui.viewmodel.launch.PDALaunchVMProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.ui.IDebugUIConstants; @@ -44,11 +42,9 @@ public class PDAVMAdapter extends AbstractDMVMAdapter @Override protected AbstractDMVMProvider createViewModelProvider(IPresentationContext context) { if ( IDebugUIConstants.ID_DEBUG_VIEW.equals(context.getId()) ) { - return new LaunchVMProvider(this, context, getSession()); + return new PDALaunchVMProvider(this, context, getSession()); } else if (IDebugUIConstants.ID_VARIABLE_VIEW.equals(context.getId()) ) { return new VariableVMProvider(this, context, getSession()); - } else if (IDebugUIConstants.ID_REGISTER_VIEW.equals(context.getId()) ) { - return new RegisterVMProvider(this, context, getSession()); } else if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(context.getId()) ) { return new ExpressionVMProvider(this, context, getSession()); } diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java.html b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java.html new file mode 100644 index 00000000000..3b9ea80e322 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java.html @@ -0,0 +1,66 @@ + + + +PDAVMAdapter.java + + + + + +
          1: /*******************************************************************************
        +  2:  * Copyright (c) 2006 Wind River Systems and others.
        +  3:  * All rights reserved. This program and the accompanying materials
        +  4:  * are made available under the terms of the Eclipse Public License v1.0
        +  5:  * which accompanies this distribution, and is available at
        +  6:  * http://www.eclipse.org/legal/epl-v10.html
        +  7:  * 
        +  8:  * Contributors:
        +  9:  *     Wind River Systems - initial API and implementation
        + 10:  *******************************************************************************/
        + 11: package org.eclipse.dd.examples.pda.ui.viewmodel;
        +
        + 13: import org.eclipse.dd.dsf.concurrent.ThreadSafe;
        + 14: import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.ExpressionVMProvider;
        + 15: import org.eclipse.dd.dsf.debug.ui.viewmodel.variable.VariableVMProvider;
        + 16: import org.eclipse.dd.dsf.service.DsfSession;
        + 17: import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMAdapter;
        + 18: import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
        + 19: import org.eclipse.dd.examples.pda.ui.viewmodel.launch.LaunchVMProvider;
        + 20: import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory;
        + 21: import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
        + 22: import org.eclipse.debug.ui.IDebugUIConstants;
        +
        + 24: /* 
        + 25:  * 
        + 26:  */
        + 27: @ThreadSafe
        + 28: @SuppressWarnings("restriction")
        + 29: public class PDAVMAdapter extends AbstractDMVMAdapter
        + 30: {
        + 31:     public PDAVMAdapter(DsfSession session) {
        + 32:         super(session);
        + 33:         getSession().registerModelAdapter(IColumnPresentationFactory.class, this);
        + 34:     }    
        +
        + 36:     @Override
        + 37:     public void dispose() {
        + 38:         getSession().unregisterModelAdapter(IColumnPresentationFactory.class);
        + 39:         super.dispose();
        + 40:     }
        + 41:     
        + 42:     @Override
        + 43:     protected AbstractDMVMProvider createViewModelProvider(IPresentationContext context) {
        + 44:         if ( IDebugUIConstants.ID_DEBUG_VIEW.equals(context.getId()) ) {
        + 45:             return new PDALaunchVMProvider(this, context, getSession()); 
        + 46:         } else if (IDebugUIConstants.ID_VARIABLE_VIEW.equals(context.getId()) ) {
        + 47:             return new VariableVMProvider(this, context, getSession());
        + 48:         } else if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(context.getId()) ) {
        + 49:             return new ExpressionVMProvider(this, context, getSession());
        + 50:         } 
        + 51:         return null;
        + 52:     }    
        + 53: }
        +
        + + + diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/LaunchVMProvider.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDALaunchVMProvider.java similarity index 92% rename from plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/LaunchVMProvider.java rename to plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDALaunchVMProvider.java index 3cbd4c36cef..44ff9952a85 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/LaunchVMProvider.java +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDALaunchVMProvider.java @@ -43,11 +43,11 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationCont *
      */ @SuppressWarnings("restriction") -public class LaunchVMProvider extends AbstractDMVMProvider +public class PDALaunchVMProvider extends AbstractDMVMProvider implements IDebugEventSetListener, ILaunchesListener2 { @ThreadSafe - public LaunchVMProvider(AbstractVMAdapter adapter, IPresentationContext presentationContext, DsfSession session) + public PDALaunchVMProvider(AbstractVMAdapter adapter, IPresentationContext presentationContext, DsfSession session) { super(adapter, presentationContext, session); @@ -55,13 +55,13 @@ public class LaunchVMProvider extends AbstractDMVMProvider setRootNode(launchNode); // Launch node is a parent to the processes and program nodes. - IVMNode threadsNode = new PDAProgramVMNode(this, getSession()); + IVMNode pdaProgramNode = new PDAProgramVMNode(this, getSession()); IVMNode processesNode = new StandardProcessVMNode(this); - addChildNodes(launchNode, new IVMNode[] { threadsNode, processesNode}); + addChildNodes(launchNode, new IVMNode[] { pdaProgramNode, processesNode}); // Stack frames node is under the PDA program node. IVMNode stackFramesNode = new StackFramesVMNode(this, getSession()); - addChildNodes(threadsNode, new IVMNode[] { stackFramesNode }); + addChildNodes(pdaProgramNode, new IVMNode[] { stackFramesNode }); // Register the LaunchVM provider as a listener to debug and launch // events. These events are used by the launch and processes nodes. diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDALaunchVMProvider.java.html b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDALaunchVMProvider.java.html new file mode 100644 index 00000000000..0c9a409f3c6 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDALaunchVMProvider.java.html @@ -0,0 +1,149 @@ + + + +PDALaunchVMProvider.java + + + + + +
        1: /*******************************************************************************
      +  2:  * Copyright (c) 2006 Wind River Systems and others.
      +  3:  * All rights reserved. This program and the accompanying materials
      +  4:  * are made available under the terms of the Eclipse Public License v1.0
      +  5:  * which accompanies this distribution, and is available at
      +  6:  * http://www.eclipse.org/legal/epl-v10.html
      +  7:  * 
      +  8:  * Contributors:
      +  9:  *     Wind River Systems - initial API and implementation
      + 10:  *     Ericsson                          - Modified for new functionality        
      + 11:  *******************************************************************************/
      + 12: package org.eclipse.dd.examples.pda.ui.viewmodel.launch;
      +
      + 14: import java.util.concurrent.RejectedExecutionException;
      +
      + 16: import org.eclipse.dd.dsf.concurrent.ThreadSafe;
      + 17: import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.LaunchRootVMNode;
      + 18: import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.StackFramesVMNode;
      + 19: import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.StandardProcessVMNode;
      + 20: import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.LaunchRootVMNode.LaunchesEvent;
      + 21: import org.eclipse.dd.dsf.service.DsfSession;
      + 22: import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter;
      + 23: import org.eclipse.dd.dsf.ui.viewmodel.IRootVMNode;
      + 24: import org.eclipse.dd.dsf.ui.viewmodel.IVMNode;
      + 25: import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
      + 26: import org.eclipse.debug.core.DebugEvent;
      + 27: import org.eclipse.debug.core.DebugPlugin;
      + 28: import org.eclipse.debug.core.IDebugEventSetListener;
      + 29: import org.eclipse.debug.core.ILaunch;
      + 30: import org.eclipse.debug.core.ILaunchesListener2;
      + 31: import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
      +
      +
      + 34: /**
      + 35:  * View Model provider for the Launch (AKA Debug) view.  The PDA debugger is 
      + 36:  * single-threaded, so there is no need for a debug target element to be visible
      + 37:  * in the debug view.  Therefore the launch VM provider is configured with three nodes:
      + 38:  * <ul>
      + 39:  * <li> LaunchRootVMNode - This is the root of the PDA view model.</li>  
      + 40:  * <li> ThreadVMNode - Supplies the PDA program element.</li>  
      + 41:  * <li> StackFramesVMNode - Supplies the stack frame elements.</li>  
      + 42:  * <li> StandardProcessVMNode - Supplies elements representing the PDA debugger process.</li>
      + 43:  * </ul> 
      + 44:  */
      + 45: @SuppressWarnings("restriction")
      + 46: public class PDALaunchVMProvider extends AbstractDMVMProvider 
      + 47:     implements IDebugEventSetListener, ILaunchesListener2
      + 48: {
      + 49:     @ThreadSafe
      + 50:     public PDALaunchVMProvider(AbstractVMAdapter adapter, IPresentationContext presentationContext, DsfSession session) 
      + 51:     {
      + 52:         super(adapter, presentationContext, session);
      + 53:         
      + 54:         IRootVMNode launchNode = new LaunchRootVMNode(this);
      + 55:         setRootNode(launchNode);
      +
      + 57:         // Launch node is a parent to the processes and program nodes.
      + 58:         IVMNode pdaProgramNode = new PDAProgramVMNode(this, getSession());
      + 59:         IVMNode processesNode = new StandardProcessVMNode(this);
      + 60:         addChildNodes(launchNode, new IVMNode[] { pdaProgramNode, processesNode});
      + 61:         
      + 62:         // Stack frames node is under the PDA program node.
      + 63:         IVMNode stackFramesNode = new StackFramesVMNode(this, getSession());
      + 64:         addChildNodes(pdaProgramNode, new IVMNode[] { stackFramesNode });
      +
      + 66:         // Register the LaunchVM provider as a listener to debug and launch 
      + 67:         // events.  These events are used by the launch and processes nodes.
      + 68:         DebugPlugin.getDefault().addDebugEventListener(this);
      + 69:         DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this);
      + 70:     }
      + 71:     
      + 72:     
      + 73:     public void handleDebugEvents(final DebugEvent[] events) {
      + 74:         if (isDisposed()) return;
      + 75:         
      + 76:         // This method may be called on any thread.  Switch to the 
      + 77:         // view model executor thread before processing.
      + 78:         try {
      + 79:             getExecutor().execute(new Runnable() {
      + 80:                 public void run() {
      + 81:                     if (isDisposed()) return;
      + 82:     
      + 83:                     for (final DebugEvent event : events) {
      + 84:                         handleEvent(event);
      + 85:                     }
      + 86:                 }});
      + 87:         } catch (RejectedExecutionException e) {
      + 88:             // Ignore.  This exception could be thrown if the view model is being 
      + 89:             // shut down.  
      + 90:         }
      + 91:     }
      +
      + 93:     @Override
      + 94:     public void dispose() {
      + 95:         DebugPlugin.getDefault().removeDebugEventListener(this);
      + 96:         DebugPlugin.getDefault().getLaunchManager().removeLaunchListener(this);
      + 97:         super.dispose();
      + 98:     }
      + 99:     
      +100:     public void launchesAdded(ILaunch[] launches) {
      +101:         handleLaunchesEvent(new LaunchesEvent(launches, LaunchesEvent.Type.ADDED)); 
      +102:     }
      +103:     
      +104:     public void launchesRemoved(ILaunch[] launches) {
      +105:         handleLaunchesEvent(new LaunchesEvent(launches, LaunchesEvent.Type.REMOVED)); 
      +106:     }
      +107:     
      +108:     public void launchesChanged(ILaunch[] launches) {
      +109:         handleLaunchesEvent(new LaunchesEvent(launches, LaunchesEvent.Type.CHANGED)); 
      +110:     }
      +111:     
      +112:     public void launchesTerminated(ILaunch[] launches) {
      +113:         handleLaunchesEvent(new LaunchesEvent(launches, LaunchesEvent.Type.TERMINATED)); 
      +114:     }
      +115:     
      +116:     private void handleLaunchesEvent(final LaunchesEvent event) {
      +117:         if (isDisposed()) return;
      +118:         
      +119:         // This method also may be called on any thread.  Switch to the 
      +120:         // view model executor thread before processing.
      +121:         try {
      +122:             getExecutor().execute(new Runnable() {
      +123:                 public void run() {
      +124:                     if (isDisposed()) return;
      +125:     
      +126:                     IRootVMNode rootLayoutNode = getRootVMNode();
      +127:                     if (rootLayoutNode != null && rootLayoutNode.getDeltaFlags(event) != 0) {
      +128:                         handleEvent(event);
      +129:                     }
      +130:                 }});
      +131:         } catch (RejectedExecutionException e) {
      +132:             // Ignore.  This exception could be thrown if the view model is being 
      +133:             // shut down.  
      +134:         }
      +135:     }
      +136: }
      +
      + + + diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDAProgramVMNode.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDAProgramVMNode.java index 16b27393312..b5ebe9f9544 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDAProgramVMNode.java +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDAProgramVMNode.java @@ -133,16 +133,18 @@ public class PDAProgramVMNode extends AbstractDMVMNode @Override protected void updateElementsInSessionThread(final IChildrenUpdate update) { - // Check if service is still available. checkService() is a convenience - // method that marks the update as failed if the needed service is not - // available. - if (!checkService(PDACommandControl.class, null, update)) return; - // Get the instance of the service. Note that there is no race condition // in getting the service since this method is called only in the - // service executor thred. + // service executor thread. final PDACommandControl commandControl = getServicesTracker().getService(PDACommandControl.class); - + + // Check if the service is available. If it is not, no elements are + // updated. + if (commandControl == null) { + handleFailedUpdate(update); + return; + } + update.setChild(createVMContext(commandControl.getProgramDMContext()), 0); update.done(); } @@ -172,8 +174,11 @@ public class PDAProgramVMNode extends AbstractDMVMNode @ConfinedToDsfExecutor("getSession().getExecutor()") private void updateProgramLabelInSessionThread(final ILabelUpdate update) { // Get a reference to the run control service. - if (!checkService(IRunControl.class, null, update)) return; final IRunControl runControl = getServicesTracker().getService(IRunControl.class); + if (runControl == null) { + handleFailedUpdate(update); + return; + } // Find the PDA program context. final PDAProgramDMContext programCtx = @@ -191,7 +196,7 @@ public class PDAProgramVMNode extends AbstractDMVMNode } update.setImageDescriptor(DebugUITools.getImageDescriptor(imageKey), 0); - // Retrieve the last state chagne reason + // Retrieve the last state change reason runControl.getExecutionData( programCtx, new DataRequestMonitor(ImmediateExecutor.getInstance(), null) diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDAProgramVMNode.java.html b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDAProgramVMNode.java.html new file mode 100644 index 00000000000..04e9f04ba22 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDAProgramVMNode.java.html @@ -0,0 +1,303 @@ + + + +PDAProgramVMNode.java + + + + + +
        1: /*******************************************************************************
      +  2:  * Copyright (c) 2006 Wind River Systems and others.
      +  3:  * All rights reserved. This program and the accompanying materials
      +  4:  * are made available under the terms of the Eclipse Public License v1.0
      +  5:  * which accompanies this distribution, and is available at
      +  6:  * http://www.eclipse.org/legal/epl-v10.html
      +  7:  * 
      +  8:  * Contributors:
      +  9:  *     Wind River Systems - initial API and implementation
      + 10:  *     Ericsson                   - Modified for multi threaded functionality        
      + 11:  *******************************************************************************/
      + 12: package org.eclipse.dd.examples.pda.ui.viewmodel.launch;
      +
      + 14: import java.util.concurrent.RejectedExecutionException;
      +
      + 16: import org.eclipse.core.runtime.CoreException;
      + 17: import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor;
      + 18: import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
      + 19: import org.eclipse.dd.dsf.concurrent.DsfRunnable;
      + 20: import org.eclipse.dd.dsf.concurrent.ImmediateExecutor;
      + 21: import org.eclipse.dd.dsf.concurrent.RequestMonitor;
      + 22: import org.eclipse.dd.dsf.datamodel.IDMEvent;
      + 23: import org.eclipse.dd.dsf.debug.service.IRunControl;
      + 24: import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
      + 25: import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMData;
      + 26: import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent;
      + 27: import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent;
      + 28: import org.eclipse.dd.dsf.service.DsfSession;
      + 29: import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMContext;
      + 30: import org.eclipse.dd.dsf.ui.viewmodel.IVMAdapter;
      + 31: import org.eclipse.dd.dsf.ui.viewmodel.IVMNode;
      + 32: import org.eclipse.dd.dsf.ui.viewmodel.VMDelta;
      + 33: import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMNode;
      + 34: import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
      + 35: import org.eclipse.dd.examples.pda.PDAPlugin;
      + 36: import org.eclipse.dd.examples.pda.launch.PDALaunch;
      + 37: import org.eclipse.dd.examples.pda.service.PDACommandControl;
      + 38: import org.eclipse.dd.examples.pda.service.PDAProgramDMContext;
      + 39: import org.eclipse.dd.examples.pda.service.PDAStartedEvent;
      + 40: import org.eclipse.debug.core.ILaunch;
      + 41: import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate;
      + 42: import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
      + 43: import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider;
      + 44: import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate;
      + 45: import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
      + 46: import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
      + 47: import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate;
      + 48: import org.eclipse.debug.ui.DebugUITools;
      + 49: import org.eclipse.debug.ui.IDebugUIConstants;
      + 50: import org.eclipse.jface.viewers.TreePath;
      +
      + 52: /**
      + 53:  * View Model node representing a PDA program. 
      + 54:  */
      + 55: @SuppressWarnings("restriction")
      + 56: public class PDAProgramVMNode extends AbstractDMVMNode 
      + 57:     implements IElementLabelProvider
      + 58: {
      + 59:     // View model context representing a terminated PDA program.
      + 60:     // It's purpose is to show a terminated program in the debug view
      + 61:     // even after the DSF session is terminated.
      + 62:     // 
      + 63:     // Note: this context does not implement the IDMVMContext
      + 64:     // interfaces, as it does not use an IDMContext as its root.
      + 65:     // 
      + 66:     // To implement comparison methods, this contexts uses the
      + 67:     // VM node object, such that two terminated program contexts
      + 68:     // from the same instance of VM node will be equal. 
      + 69:     private static class TerminatedProgramVMContext extends AbstractVMContext {
      + 70:         TerminatedProgramVMContext(IVMAdapter adapter, IVMNode node) {
      + 71:             super(adapter, node);
      + 72:         }
      + 73:         
      + 74:         @Override
      + 75:         public boolean equals(Object obj) {
      + 76:             if (obj instanceof TerminatedProgramVMContext) {
      + 77:                 TerminatedProgramVMContext context = (TerminatedProgramVMContext)obj;
      + 78:                 return getVMNode().equals(context.getVMNode());
      + 79:             }
      + 80:             return false;
      + 81:         }
      + 82:         
      + 83:         @Override
      + 84:         public int hashCode() {
      + 85:             return getVMNode().hashCode();
      + 86:         }
      + 87:     }
      + 88:     
      + 89:     public PDAProgramVMNode(AbstractDMVMProvider provider, DsfSession session) {
      + 90:         super(provider, session, IExecutionDMContext.class);
      + 91:     }
      +
      + 93:     @Override
      + 94:     public void update(IHasChildrenUpdate[] updates) {
      + 95:         for (IHasChildrenUpdate update : updates) {
      + 96:             // Check if the launch is initialized.  PDA program element should 
      + 97:             // be shown only if the launch has completed initializing.
      + 98:             PDALaunch launch = findLaunchInPath(update.getElementPath());
      + 99:             update.setHasChilren(launch != null && launch.isInitialized());
      +100:             update.done();
      +101:         }        
      +102:     }
      +
      +104:     @Override
      +105:     public void update(IChildrenCountUpdate[] updates) {
      +106:         for (IChildrenCountUpdate update : updates) {
      +107:             // Check if the launch is initialized.  PDA program element should 
      +108:             // be shown only if the launch has completed initializing.
      +109:             PDALaunch launch = findLaunchInPath(update.getElementPath());
      +110:             if (launch != null && launch.isInitialized()) {
      +111:                 update.setChildCount(1);
      +112:             } else {
      +113:                 update.setChildCount(0);
      +114:             }
      +115:             update.done();
      +116:         }        
      +117:     }
      +
      +119:     @Override
      +120:     public void update(IChildrenUpdate[] updates) {
      +121:         for (IChildrenUpdate update : updates) {
      +122:             PDALaunch launch = findLaunchInPath(update.getElementPath());
      +123:             if (launch != null && launch.isInitialized() && launch.isShutDown()) {
      +124:                 // If the debug session has been shut down, add a dummy 
      +125:                 // VM context representing the PDA thread.
      +126:                 update.setChild(new TerminatedProgramVMContext(getVMProvider().getVMAdapter(), this), 0);
      +127:                 update.done();
      +128:             } else {
      +129:                 super.update(new IChildrenUpdate[] { update });
      +130:             }
      +131:         }
      +132:     }
      +133:     
      +134:     @Override
      +135:     protected void updateElementsInSessionThread(final IChildrenUpdate update) {
      +136:             // Get the instance of the service.  Note that there is no race condition
      +137:             // in getting the service since this method is called only in the 
      +138:             // service executor thread.
      +139:         final PDACommandControl commandControl = getServicesTracker().getService(PDACommandControl.class);
      +
      +141:         // Check if the service is available.  If it is not, no elements are 
      +142:         // updated.
      +143:         if (commandControl == null) {
      +144:             handleFailedUpdate(update);
      +145:             return;
      +146:         }
      +147:         
      +148:         update.setChild(createVMContext(commandControl.getProgramDMContext()), 0);
      +149:         update.done();
      +150:     }
      +
      +152:     public void update(final ILabelUpdate[] updates) {
      +153:         for (final ILabelUpdate update : updates) {
      +154:             if (update.getElement() instanceof TerminatedProgramVMContext) {
      +155:                 // If the element is a terminated program, update the label 
      +156:                 // in the View Model thread.
      +157:                 updateTerminatedThreadLabel(update);
      +158:             } else {
      +159:                 // If the element is the PDA Program context, try to switch
      +160:                 // to the DSF session thread before updating the label.
      +161:                 try {
      +162:                     getSession().getExecutor().execute(new DsfRunnable() {
      +163:                         public void run() {
      +164:                             updateProgramLabelInSessionThread(update);
      +165:                         }});
      +166:                 } catch (RejectedExecutionException e) {
      +167:                     // Acceptable race condition: DSF session terminated.
      +168:                     handleFailedUpdate(update);
      +169:                 }
      +170:             }
      +171:         }
      +172:     }
      +173:     
      +174:     @ConfinedToDsfExecutor("getSession().getExecutor()")
      +175:     private void updateProgramLabelInSessionThread(final ILabelUpdate update) {
      +176:         // Get a reference to the run control service.
      +177:         final IRunControl runControl = getServicesTracker().getService(IRunControl.class);
      +178:         if (runControl == null) {
      +179:             handleFailedUpdate(update);
      +180:             return;
      +181:         }
      +182:         
      +183:         // Find the PDA program context.
      +184:         final PDAProgramDMContext programCtx = 
      +185:             findDmcInPath(update.getViewerInput(), update.getElementPath(), PDAProgramDMContext.class);
      +
      +187:         // Call service to get current program state
      +188:         final boolean isSuspended = runControl.isSuspended(programCtx);
      +
      +190:         // Set the program icon based on the running state of the program.
      +191:         String imageKey = null;
      +192:         if (isSuspended) {
      +193:             imageKey = IDebugUIConstants.IMG_OBJS_THREAD_SUSPENDED;
      +194:         } else {
      +195:             imageKey = IDebugUIConstants.IMG_OBJS_THREAD_RUNNING;
      +196:         }
      +197:         update.setImageDescriptor(DebugUITools.getImageDescriptor(imageKey), 0);
      +
      +199:         // Retrieve the last state chagne reason 
      +200:         runControl.getExecutionData(
      +201:             programCtx, 
      +202:             new DataRequestMonitor<IExecutionDMData>(ImmediateExecutor.getInstance(), null) 
      +203:             { 
      +204:                 @Override
      +205:                 public void handleCompleted(){
      +206:                     // If the request failed, fail the udpate. 
      +207:                     if (!getStatus().isOK()) {
      +208:                         handleFailedUpdate(update);
      +209:                         return;
      +210:                     }
      +211:     
      +212:                     // Compose the thread name string.
      +213:                     final StringBuilder builder = new StringBuilder(); 
      +214:     
      +215:                     builder.append("PDA [");
      +216:                     builder.append(programCtx.getProgram());
      +217:                     builder.append("]");
      +218:                     
      +219:                     if(isSuspended) {
      +220:                         builder.append(" (Suspended"); 
      +221:                     } else {
      +222:                         builder.append(" (Running"); 
      +223:                     }
      +224:                     // Reason will be null before ContainerSuspendEvent is fired
      +225:                     if(getData().getStateChangeReason() != null) {
      +226:                         builder.append(" : "); 
      +227:                         builder.append(getData().getStateChangeReason());
      +228:                     }
      +229:                     builder.append(")"); 
      +230:                     update.setLabel(builder.toString(), 0);
      +231:                     update.done();
      +232:                 }
      +233:             });        
      +234:     }
      +235:     
      +236:     private void updateTerminatedThreadLabel(ILabelUpdate update) {
      +237:         update.setLabel("<terminated> PDA [" + getProgramName(update) + "]", 0);
      +238:         update.setImageDescriptor(DebugUITools.getImageDescriptor(IDebugUIConstants.IMG_OBJS_DEBUG_TARGET_TERMINATED), 0);
      +239:         update.done();
      +240:     }
      +
      +242:     private String getProgramName(IViewerUpdate update) {
      +243:         // Retrieve the program name from the launch object in the update path.
      +244:         String program = "unknown program";
      +245:         ILaunch launch = findLaunchInPath(update.getElementPath());
      +246:         if (launch != null) {
      +247:             try {
      +248:                 program = launch.getLaunchConfiguration().getAttribute(PDAPlugin.ATTR_PDA_PROGRAM, program);
      +249:             } catch (CoreException e) {
      +250:                 // Ignore, label will revert to default.
      +251:             }
      +252:         } 
      +253:         return program;
      +254:     }
      +255:     
      +256:     private PDALaunch findLaunchInPath(TreePath path) {
      +257:         for (int i = 0; i < path.getSegmentCount(); i++) {
      +258:             if (path.getSegment(i) instanceof PDALaunch) {
      +259:                 return (PDALaunch)path.getSegment(i);
      +260:             }
      +261:         }
      +262:         return null;
      +263:     }
      +
      +265:     public int getDeltaFlags(Object e) {
      +266:         if(e instanceof IResumedDMEvent || e instanceof ISuspendedDMEvent) {
      +267:             return IModelDelta.STATE;
      +268:         } 
      +269:         if (e instanceof PDAStartedEvent) {
      +270:             return IModelDelta.EXPAND | IModelDelta.SELECT;
      +271:         }
      +272:         return IModelDelta.NO_CHANGE;
      +273:     }
      +
      +275:     public void buildDelta(Object e, VMDelta parentDelta, int nodeOffset, RequestMonitor rm) {
      +276:         if(e instanceof IResumedDMEvent || e instanceof ISuspendedDMEvent) {
      +277:             // If a suspended/resumed event is received, just update the 
      +278:             // state of the program.  StackFramesVMNode will take care of 
      +279:             // refreshing the stack frames.
      +280:             parentDelta.addNode(createVMContext(((IDMEvent<?>)e).getDMContext()), IModelDelta.STATE);
      +281:         } 
      +282:         if (e instanceof PDAStartedEvent) {
      +283:             // When debug session is started expand and select the program.
      +284:             // If the program hits a breakpoint, the top stack frame will then
      +285:             // be selected.
      +286:             parentDelta.addNode(createVMContext(((PDAStartedEvent)e).getDMContext()), IModelDelta.EXPAND | IModelDelta.SELECT);            
      +287:         }
      +288:         rm.done();
      +289:            }
      +290: }
      +
      + + + diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunch.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunch.java index 6341c937efe..99d726d6d2d 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunch.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunch.java @@ -43,17 +43,19 @@ import org.eclipse.debug.core.model.ITerminate; */ @ThreadSafe public class PDALaunch extends Launch - implements ITerminate +implements ITerminate { // DSF executor and session. Both are created and shutdown by the launch. private final DefaultDsfExecutor fExecutor; private final DsfSession fSession; // Objects used to track the status of the DSF session. - private Sequence fInitializationSequence = null; private boolean fInitialized = false; private boolean fShutDown = false; + @ConfinedToDsfExecutor("getSession().getExecutor()") + private Sequence fInitializationSequence = null; + /** * Launch constructor creates the launch for given parameters. The * constructor also creates a DSF session and an executor, so that @@ -90,7 +92,7 @@ public class PDALaunch extends Launch { // Double-check that we're being called in the correct thread. assert fExecutor.isInExecutorThread(); - + // Check if shutdownServices() was called already, which would be // highly unusual, but if so we don't need to do anything except set // the initialized flag. @@ -100,51 +102,47 @@ public class PDALaunch extends Launch return; } } - + // Register the launch as listener for services events. fSession.addServiceEventListener(PDALaunch.this, null); - - // Initialize the fInitializationSequence attribute in a synchronized - // block, because it may be accessed in another thread by shutdown(). + // The initialization sequence is stored in a field to allow it to be // canceled if shutdownServices() is called before the sequence // completes. - synchronized(this) { - fInitializationSequence = new PDAServicesInitSequence( - getSession(), program, requestPort, eventPort, - new RequestMonitor(ImmediateExecutor.getInstance(), rm) { - @Override - protected void handleCompleted() { - // Set the initialized flag and check whether the - // shutdown flag is set. Access the flags in a - // synchronized section as these flags can be accessed - // on any thread. - boolean doShutdown = false; - synchronized (this) { - fInitialized = true; - fInitializationSequence = null; - if (fShutDown) { - doShutdown = true; - } + fInitializationSequence = new PDAServicesInitSequence( + getSession(), program, requestPort, eventPort, + new RequestMonitor(ImmediateExecutor.getInstance(), rm) { + @Override + protected void handleCompleted() { + // Set the initialized flag and check whether the + // shutdown flag is set. Access the flags in a + // synchronized section as these flags can be accessed + // on any thread. + boolean doShutdown = false; + synchronized (this) { + fInitialized = true; + fInitializationSequence = null; + if (fShutDown) { + doShutdown = true; } - - if (doShutdown) { - // If shutdownServices() was already called, start the - // shutdown sequence now. - doShutdown(rm); - } else { - // If there was an error in the startup sequence, - // report the error to the client. - if (getStatus().getSeverity() == IStatus.ERROR) { - rm.setStatus(getStatus()); - } - rm.done(); - } - fireChanged(); } - }); - } - + + if (doShutdown) { + // If shutdownServices() was already called, start the + // shutdown sequence now. + doShutdown(rm); + } else { + // If there was an error in the startup sequence, + // report the error to the client. + if (getStatus().getSeverity() == IStatus.ERROR) { + rm.setStatus(getStatus()); + } + rm.done(); + } + fireChanged(); + } + }); + // Finally, execute the sequence. getSession().getExecutor().execute(fInitializationSequence); } @@ -163,7 +161,7 @@ public class PDALaunch extends Launch public synchronized boolean isInitialized() { return fInitialized; } - + /** * Returns whether the DSF services have been set to shut down. * @return @@ -171,7 +169,7 @@ public class PDALaunch extends Launch public synchronized boolean isShutDown() { return fShutDown; } - + @Override public boolean canTerminate() { return super.canTerminate() && isInitialized() && !isShutDown(); @@ -223,7 +221,7 @@ public class PDALaunch extends Launch rm.done(); } } - + @ConfinedToDsfExecutor("getSession().getExecutor()") private void doShutdown(final RequestMonitor rm) { fExecutor.execute( new PDAServicesShutdownSequence( @@ -242,13 +240,13 @@ public class PDALaunch extends Launch // session-ended event, finish step only after the dispatch. fExecutor.shutdown(); fireTerminate(); - + rm.setStatus(getStatus()); rm.done(); } }) ); } - + @SuppressWarnings("unchecked") @Override public Object getAdapter(Class adapter) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunch.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunch.java.html new file mode 100644 index 00000000000..fb914a97cd8 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunch.java.html @@ -0,0 +1,271 @@ + + + +PDALaunch.java + + + + + +
        1: /*******************************************************************************
      +  2:  * Copyright (c) 2008 Wind River Systems and others.
      +  3:  * All rights reserved. This program and the accompanying materials
      +  4:  * are made available under the terms of the Eclipse Public License v1.0
      +  5:  * which accompanies this distribution, and is available at
      +  6:  * http://www.eclipse.org/legal/epl-v10.html
      +  7:  * 
      +  8:  * Contributors:
      +  9:  *     Wind River Systems - initial API and implementation
      + 10:  *******************************************************************************/
      + 11: package org.eclipse.dd.examples.pda.launch;
      +
      + 13: import org.eclipse.core.runtime.IStatus;
      + 14: import org.eclipse.core.runtime.MultiStatus;
      + 15: import org.eclipse.core.runtime.Platform;
      + 16: import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor;
      + 17: import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor;
      + 18: import org.eclipse.dd.dsf.concurrent.ImmediateExecutor;
      + 19: import org.eclipse.dd.dsf.concurrent.RequestMonitor;
      + 20: import org.eclipse.dd.dsf.concurrent.Sequence;
      + 21: import org.eclipse.dd.dsf.concurrent.ThreadSafe;
      + 22: import org.eclipse.dd.dsf.service.DsfServiceEventHandler;
      + 23: import org.eclipse.dd.dsf.service.DsfSession;
      + 24: import org.eclipse.dd.examples.pda.PDAPlugin;
      + 25: import org.eclipse.dd.examples.pda.service.PDATerminatedEvent;
      + 26: import org.eclipse.debug.core.DebugException;
      + 27: import org.eclipse.debug.core.ILaunchConfiguration;
      + 28: import org.eclipse.debug.core.Launch;
      + 29: import org.eclipse.debug.core.model.ISourceLocator;
      + 30: import org.eclipse.debug.core.model.ITerminate;
      +
      + 32: /**
      + 33:  * The PDA launch object. In general, a DSF-based debugger has to override 
      + 34:  * the base launch class in order to supply its own content providers for the 
      + 35:  * debug view.  Additionally, the PDA launch is used to monitor the state of the
      + 36:  * PDA debugger and to shutdown the DSF services and session belonging to the 
      + 37:  * launch.
      + 38:  * <p>
      + 39:  * The PDA launch class mostly contains methods and fields that can be accessed
      + 40:  * on any thread.  However, some fields and methods used for managing the DSF
      + 41:  * session need to be synchronized using the DSF executor.
      + 42:  * </p>
      + 43:  */
      + 44: @ThreadSafe
      + 45: public class PDALaunch extends Launch
      + 46: implements ITerminate
      + 47: {   
      + 48:     // DSF executor and session.  Both are created and shutdown by the launch. 
      + 49:     private final DefaultDsfExecutor fExecutor;
      + 50:     private final DsfSession fSession;
      +
      + 52:     // Objects used to track the status of the DSF session.
      + 53:     private boolean fInitialized = false;
      + 54:     private boolean fShutDown = false;
      + 55:     
      + 56:     @ConfinedToDsfExecutor("getSession().getExecutor()")
      + 57:     private Sequence fInitializationSequence = null;
      +
      + 59:     /**
      + 60:      * Launch constructor creates the launch for given parameters.  The
      + 61:      * constructor also creates a DSF session and an executor, so that 
      + 62:      * {@link #getSession()} returns a valid value, however no services 
      + 63:      * are initialized yet. 
      + 64:      * 
      + 65:      * @see Launch
      + 66:      */
      + 67:     public PDALaunch(ILaunchConfiguration launchConfiguration, String mode, ISourceLocator locator) {
      + 68:         super(launchConfiguration, mode, locator);
      +
      + 70:         // Create the dispatch queue to be used by debugger control and services 
      + 71:         // that belong to this launch
      + 72:         final DefaultDsfExecutor dsfExecutor = new DefaultDsfExecutor(PDAPlugin.ID_PDA_DEBUG_MODEL);
      + 73:         dsfExecutor.prestartCoreThread();
      + 74:         fExecutor = dsfExecutor;
      + 75:         fSession = DsfSession.startSession(fExecutor, PDAPlugin.ID_PDA_DEBUG_MODEL);
      + 76:     }
      +
      + 78:     /**
      + 79:      * Returns the DSF services session that belongs to this launch.  This 
      + 80:      * method will always return a DsfSession object, however if the debugger 
      + 81:      * is shut down, the session will no longer active.
      + 82:      */
      + 83:     public DsfSession getSession() { return fSession; }
      +
      + 85:     /**
      + 86:      * Initializes the DSF services using the specified parameters.  This 
      + 87:      * method has to be called on the executor thread in order to avoid 
      + 88:      * synchronization issues.  
      + 89:      */
      + 90:     @ConfinedToDsfExecutor("getSession().getExecutor()")
      + 91:     public void initializeServices(String program, int requestPort, int eventPort, final RequestMonitor rm)
      + 92:     {
      + 93:         // Double-check that we're being called in the correct thread.
      + 94:         assert fExecutor.isInExecutorThread();
      +
      + 96:         // Check if shutdownServices() was called already, which would be 
      + 97:         // highly unusual, but if so we don't need to do anything except set 
      + 98:         // the initialized flag.
      + 99:         synchronized(this) {
      +100:             if (fShutDown) {
      +101:                 fInitialized = true;
      +102:                 return;
      +103:             }
      +104:         }
      +
      +106:         // Register the launch as listener for services events.
      +107:         fSession.addServiceEventListener(PDALaunch.this, null);
      +
      +109:         // The initialization sequence is stored in a field to allow it to be 
      +110:         // canceled if shutdownServices() is called before the sequence 
      +111:         // completes.
      +112:         fInitializationSequence = new PDAServicesInitSequence(
      +113:             getSession(), program, requestPort, eventPort, 
      +114:             new RequestMonitor(ImmediateExecutor.getInstance(), rm) {
      +115:                 @Override
      +116:                 protected void handleCompleted() {
      +117:                     // Set the initialized flag and check whether the 
      +118:                     // shutdown flag is set.  Access the flags in a 
      +119:                     // synchronized section as these flags can be accessed
      +120:                     // on any thread.
      +121:                     boolean doShutdown = false;
      +122:                     synchronized (this) { 
      +123:                         fInitialized = true;
      +124:                         fInitializationSequence = null;
      +125:                         if (fShutDown) {
      +126:                             doShutdown = true;
      +127:                         }
      +128:                     }
      +
      +130:                     if (doShutdown) {
      +131:                         // If shutdownServices() was already called, start the 
      +132:                         // shutdown sequence now.
      +133:                         doShutdown(rm);
      +134:                     } else {
      +135:                         // If there was an error in the startup sequence, 
      +136:                         // report the error to the client.
      +137:                         if (getStatus().getSeverity() == IStatus.ERROR) {
      +138:                             rm.setStatus(getStatus());
      +139:                         }
      +140:                         rm.done();
      +141:                     }
      +142:                     fireChanged();
      +143:                 }
      +144:             });
      +
      +146:         // Finally, execute the sequence. 
      +147:         getSession().getExecutor().execute(fInitializationSequence);
      +148:     }
      +
      +150:     /**
      +151:      * Event handler for a debugger terminated event.    
      +152:      */
      +153:     @DsfServiceEventHandler 
      +154:     public void eventDispatched(PDATerminatedEvent event) {
      +155:         shutdownServices(new RequestMonitor(ImmediateExecutor.getInstance(), null));
      +156:     }
      +
      +158:     /**
      +159:      * Returns whether the DSF service initialization sequence has completed yet.
      +160:      */
      +161:     public synchronized boolean isInitialized() {
      +162:         return fInitialized;
      +163:     }
      +
      +165:     /**
      +166:      * Returns whether the DSF services have been set to shut down.
      +167:      * @return
      +168:      */
      +169:     public synchronized boolean isShutDown() {
      +170:         return fShutDown;
      +171:     }
      +
      +173:     @Override
      +174:     public boolean canTerminate() {
      +175:         return super.canTerminate() && isInitialized() && !isShutDown();
      +176:     }
      +
      +178:     @Override
      +179:     public boolean isTerminated() {
      +180:         return super.isTerminated() || isShutDown();
      +181:     }
      +
      +
      +184:     @Override
      +185:     public void terminate() throws DebugException {
      +186:         if (isShutDown()) return;
      +187:         super.terminate();
      +188:     }
      +
      +190:     /**
      +191:      * Shuts down the services, the session and the executor associated with 
      +192:      * this launch.  
      +193:      * <p>
      +194:      * Note: The argument request monitor to this method should NOT use the
      +195:      * executor that belongs to this launch.  By the time the shutdown is 
      +196:      * complete, this executor will not be dispatching anymore and the 
      +197:      * request monitor will never be invoked.  Instead callers should use
      +198:      * the {@link ImmediateExecutor}.
      +199:      * </p>
      +200:      * @param rm The request monitor invoked when the shutdown is complete.    
      +201:      */
      +202:     @ConfinedToDsfExecutor("getSession().getExecutor()")
      +203:     public void shutdownServices(final RequestMonitor rm) {
      +204:         // Check initialize and shutdown flags to determine if the shutdown
      +205:         // sequence can be called yet.
      +206:         boolean doShutdown = false;
      +207:         synchronized (this) {
      +208:             if (!fInitialized && fInitializationSequence != null) {
      +209:                 // Launch has not yet initialized, try to cancel the 
      +210:                 // shutdown sequence.
      +211:                 fInitializationSequence.cancel(false);
      +212:             } else {
      +213:                 doShutdown = !fShutDown && fInitialized;
      +214:             }
      +215:             fShutDown = true;
      +216:         }
      +
      +218:         if (doShutdown) {
      +219:             doShutdown(rm);
      +220:         } else {
      +221:             rm.done();
      +222:         }
      +223:     }
      +
      +225:     @ConfinedToDsfExecutor("getSession().getExecutor()")
      +226:     private void doShutdown(final RequestMonitor rm) {
      +227:         fExecutor.execute( new PDAServicesShutdownSequence(
      +228:             fExecutor, fSession.getId(),
      +229:             new RequestMonitor(fSession.getExecutor(), rm) { 
      +230:                 @Override
      +231:                 public void handleCompleted() {
      +232:                     fSession.removeServiceEventListener(PDALaunch.this);
      +233:                     if (!getStatus().isOK()) {
      +234:                         PDAPlugin.getDefault().getLog().log(new MultiStatus(
      +235:                             PDAPlugin.PLUGIN_ID, -1, new IStatus[]{getStatus()}, "Session shutdown failed", null)); //$NON-NLS-1$
      +236:                     }
      +237:                     // Last order of business, shutdown the dispatch queue.
      +238:                     DsfSession.endSession(fSession);
      +239:                     // endSession takes a full dispatch to distribute the 
      +240:                     // session-ended event, finish step only after the dispatch.
      +241:                     fExecutor.shutdown();
      +242:                     fireTerminate();
      +
      +244:                     rm.setStatus(getStatus());
      +245:                     rm.done();
      +246:                 }
      +247:             }) );
      +248:     }
      +
      +250:     @SuppressWarnings("unchecked")
      +251:     @Override
      +252:     public Object getAdapter(Class adapter) {
      +253:         // Force adapters to be loaded.  Otherwise the adapter manager may not find
      +254:         // the model proxy adapter for DSF-based debug elements.
      +255:         Platform.getAdapterManager().loadAdapter(this, adapter.getName());
      +256:         return super.getAdapter(adapter);
      +257:     }
      +258: }
      +
      + + + diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunchDelegate.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunchDelegate.java.html new file mode 100644 index 00000000000..f6c4b38f025 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunchDelegate.java.html @@ -0,0 +1,234 @@ + + + +PDALaunchDelegate.java + + + + + +
        1: /*******************************************************************************
      +  2:  * Copyright (c) 2005, 2008 IBM Corporation and others.
      +  3:  * All rights reserved. This program and the accompanying materials
      +  4:  * are made available under the terms of the Eclipse Public License v1.0
      +  5:  * which accompanies this distribution, and is available at
      +  6:  * http://www.eclipse.org/legal/epl-v10.html
      +  7:  *
      +  8:  * Contributors:
      +  9:  *     IBM Corporation - initial API and implementation
      + 10:  *     Bjorn Freeman-Benson - initial API and implementation
      + 11:  *     Wind River Systems - adopted to use with DSF
      + 12:  *******************************************************************************/
      + 13: package org.eclipse.dd.examples.pda.launch;
      +
      + 15: import java.io.File;
      + 16: import java.io.IOException;
      + 17: import java.net.ServerSocket;
      + 18: import java.text.MessageFormat;
      + 19: import java.util.ArrayList;
      + 20: import java.util.List;
      + 21: import java.util.concurrent.ExecutionException;
      +
      + 23: import org.eclipse.core.resources.IFile;
      + 24: import org.eclipse.core.resources.ResourcesPlugin;
      + 25: import org.eclipse.core.runtime.CoreException;
      + 26: import org.eclipse.core.runtime.IProgressMonitor;
      + 27: import org.eclipse.core.runtime.IStatus;
      + 28: import org.eclipse.core.runtime.Path;
      + 29: import org.eclipse.core.runtime.Status;
      + 30: import org.eclipse.core.variables.IValueVariable;
      + 31: import org.eclipse.core.variables.VariablesPlugin;
      + 32: import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
      + 33: import org.eclipse.dd.dsf.concurrent.Query;
      + 34: import org.eclipse.dd.examples.pda.PDAPlugin;
      + 35: import org.eclipse.debug.core.DebugException;
      + 36: import org.eclipse.debug.core.DebugPlugin;
      + 37: import org.eclipse.debug.core.ILaunch;
      + 38: import org.eclipse.debug.core.ILaunchConfiguration;
      + 39: import org.eclipse.debug.core.model.IPersistableSourceLocator;
      + 40: import org.eclipse.debug.core.model.ISourceLocator;
      + 41: import org.eclipse.debug.core.model.LaunchConfigurationDelegate;
      + 42: import org.eclipse.debug.core.sourcelookup.IPersistableSourceLocator2;
      +
      +
      + 45: /**
      + 46:  * Launches PDA program on a PDA interpretter written in Perl 
      + 47:  */
      + 48: public class PDALaunchDelegate extends LaunchConfigurationDelegate {
      +
      + 50:     @Override
      + 51:     public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) throws CoreException {
      + 52:         // Need to configure the source locator before creating the launch
      + 53:         // because once the launch is created and added to launch manager, 
      + 54:         // the adapters will be created for the whole session, including 
      + 55:         // the source lookup adapter.
      + 56:         ISourceLocator locator = getSourceLocator(configuration);
      +
      + 58:         return new PDALaunch(configuration, mode, locator);
      + 59:     }
      +
      + 61:     @Override
      + 62:     public boolean buildForLaunch(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException {
      + 63:         // PDA programs do not require building.
      + 64:         return false;
      + 65:     }
      +
      + 67:     /**
      + 68:      * Returns a source locator created based on the attributes in the launch configuration.
      + 69:      */
      + 70:     private ISourceLocator getSourceLocator(ILaunchConfiguration configuration) throws CoreException {
      + 71:         String type = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_ID, (String)null);
      + 72:         if (type == null) {
      + 73:             type = configuration.getType().getSourceLocatorId();
      + 74:         }
      + 75:         if (type != null) {
      + 76:             IPersistableSourceLocator locator = DebugPlugin.getDefault().getLaunchManager().newSourceLocator(type);
      + 77:             String memento = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_MEMENTO, (String)null);
      + 78:             if (memento == null) {
      + 79:                 locator.initializeDefaults(configuration);
      + 80:             } else {
      + 81:                 if(locator instanceof IPersistableSourceLocator2)
      + 82:                     ((IPersistableSourceLocator2)locator).initializeFromMemento(memento, configuration);
      + 83:                 else
      + 84:                     locator.initializeFromMemento(memento);
      + 85:             }
      + 86:             return locator;
      + 87:         }
      + 88:         return null;
      + 89:     }
      +
      + 91:     public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException {
      + 92:         String program = configuration.getAttribute(PDAPlugin.ATTR_PDA_PROGRAM, (String)null);
      + 93:         if (program == null) {
      + 94:             abort("Perl program unspecified.", null);
      + 95:         }
      +
      + 97:         int requestPort = findFreePort();
      + 98:         int eventPort = findFreePort();
      + 99:         if (requestPort == -1 || eventPort == -1) {
      +100:             abort("Unable to find free port", null);
      +101:         }
      +
      +103:         launchProcess(launch, program, requestPort, eventPort);
      +104:         PDALaunch pdaLaunch = (PDALaunch)launch; 
      +105:         initServices(pdaLaunch, program, requestPort, eventPort);
      +106:     }
      +
      +108:     /**
      +109:      * Launches PDA interpreter with the given program.
      +110:      *  
      +111:      * @param launch Launch that will contain the new process.
      +112:      * @param program PDA program to use in the interpreter.
      +113:      * @param requestPort The port number for connecting the request socket.
      +114:      * @param eventPort The port number for connecting the events socket.
      +115:      * 
      +116:      * @throws CoreException 
      +117:      */
      +118:     private void launchProcess(ILaunch launch, String program, int requestPort, int eventPort) throws CoreException {
      +119:         List<String> commandList = new ArrayList<String>();
      +
      +121:         // Find Perl executable
      +122:         IValueVariable perl = VariablesPlugin.getDefault().getStringVariableManager().getValueVariable(PDAPlugin.VARIALBE_PERL_EXECUTABLE);
      +123:         if (perl == null) {
      +124:             abort("Perl executable location undefined. Check value of ${dsfPerlExecutable}.", null);
      +125:         }
      +126:         String path = perl.getValue();
      +127:         if (path == null) {
      +128:             abort("Perl executable location unspecified. Check value of ${dsfPerlExecutable}.", null);
      +129:         }
      +130:         File exe = new File(path);
      +131:         if (!exe.exists()) {
      +132:             abort(MessageFormat.format("Specified Perl executable {0} does not exist. Check value of $dsfPerlExecutable.", new Object[]{path}), null);
      +133:         }
      +134:         commandList.add(path);
      +
      +136:         // Add PDA VM
      +137:         File vm = PDAPlugin.getFileInPlugin(new Path("pdavm/pda.pl"));
      +138:         if (vm == null) {
      +139:             abort("Missing PDA VM", null);
      +140:         }
      +141:         commandList.add(vm.getAbsolutePath());
      +
      +143:         // Add PDA program
      +144:         IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(program));
      +145:         if (!file.exists()) {
      +146:             abort(MessageFormat.format("Perl program {0} does not exist.", new Object[] {file.getFullPath().toString()}), null);
      +147:         }
      +
      +149:         commandList.add(file.getLocation().toOSString());
      +
      +151:         // Add debug arguments - i.e. '-debug requestPort eventPort'
      +152:         commandList.add("-debug");
      +153:         commandList.add("" + requestPort);
      +154:         commandList.add("" + eventPort);
      +
      +156:         // Launch the perl process.
      +157:         String[] commandLine = commandList.toArray(new String[commandList.size()]);
      +158:         Process process = DebugPlugin.exec(commandLine, null);
      +
      +160:         // Create a debug platform process object and add it to the launch.
      +161:         DebugPlugin.newProcess(launch, process, path);
      +162:     }
      +
      +164:     /**
      +165:      * Calls the launch to initialize DSF services for this launch.
      +166:      */
      +167:     private void initServices(final PDALaunch pdaLaunch, final String program, final int requestPort, final int eventPort) 
      +168:     throws CoreException 
      +169:     {
      +170:         // Synchronization object to use when waiting for the services initialization.
      +171:         Query<Object> initQuery = new Query<Object>() {
      +172:             @Override
      +173:             protected void execute(DataRequestMonitor<Object> rm) {
      +174:                 pdaLaunch.initializeServices(program, requestPort, eventPort, rm);
      +175:             }
      +176:         };
      +
      +178:         // Submit the query to the executor.
      +179:         pdaLaunch.getSession().getExecutor().execute(initQuery);
      +180:         try {
      +181:             // Block waiting for query results.
      +182:             initQuery.get();
      +183:         } catch (InterruptedException e1) {
      +184:             throw new DebugException(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, "Interrupted Exception in dispatch thread", e1)); //$NON-NLS-1$
      +185:         } catch (ExecutionException e1) {
      +186:             throw new DebugException(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Error in launch sequence", e1.getCause())); //$NON-NLS-1$
      +187:         }
      +188:     }
      +
      +190:     /**
      +191:      * Throws an exception with a new status containing the given
      +192:      * message and optional exception.
      +193:      * 
      +194:      * @param message error message
      +195:      * @param e underlying exception
      +196:      * @throws CoreException
      +197:      */
      +198:     private void abort(String message, Throwable e) throws CoreException {
      +199:         throw new CoreException(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, 0, message, e));
      +200:     }
      +
      +202:     /**
      +203:      * Returns a free port number on localhost, or -1 if unable to find a free port.
      +204:      */
      +205:     public static int findFreePort() {
      +206:         ServerSocket socket= null;
      +207:         try {
      +208:             socket= new ServerSocket(0);
      +209:             return socket.getLocalPort();
      +210:         } catch (IOException e) { 
      +211:         } finally {
      +212:             if (socket != null) {
      +213:                 try {
      +214:                     socket.close();
      +215:                 } catch (IOException e) {
      +216:                 }
      +217:             }
      +218:         }
      +219:         return -1;                
      +220:     }                
      +221: }
      +
      + + + diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java index a92a61fc79d..781e8c505e3 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java @@ -44,12 +44,6 @@ public class PDAServicesInitSequence extends Sequence { fCommandControl = new PDACommandControl(fSession, fProgram, fRequestPort, fEventPort); fCommandControl.initialize(requestMonitor); } - - @Override - public void rollBack(RequestMonitor rm) { - // TODO Auto-generated method stub - super.rollBack(rm); - } }, new Step() { @Override @@ -77,7 +71,7 @@ public class PDAServicesInitSequence extends Sequence { @Override public void execute(final RequestMonitor requestMonitor) { // Create the breakpoint mediator and start tracking PDA breakpoints. - + final BreakpointsMediator bpmService = new BreakpointsMediator( fSession, new PDABreakpointAttributeTranslator()); bpmService.initialize(new RequestMonitor(getExecutor(), requestMonitor) { @@ -88,19 +82,22 @@ public class PDAServicesInitSequence extends Sequence { }); } }, - new Step() { @Override + new Step() { + @Override public void execute(RequestMonitor requestMonitor) { // Start the stack service. new PDAStack(fSession).initialize(requestMonitor); } }, - new Step() { @Override + new Step() { + @Override public void execute(RequestMonitor requestMonitor) { // Start the service to track expressions. new PDAExpressions(fSession).initialize(requestMonitor); } }, - new Step() { @Override + new Step() { + @Override public void execute(RequestMonitor requestMonitor) { fRunControl.resume(fCommandControl.getProgramDMContext(), requestMonitor); } @@ -125,7 +122,7 @@ public class PDAServicesInitSequence extends Sequence { fRequestPort = requestPort; fEventPort = eventPort; } - + @Override public Step[] getSteps() { return fSteps; diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java.html new file mode 100644 index 00000000000..7f4aae65d3d --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java.html @@ -0,0 +1,140 @@ + + + +PDAServicesInitSequence.java + + + + + +
        1: /*******************************************************************************
      +  2:  * Copyright (c) 2008 Wind River Systems and others.
      +  3:  * All rights reserved. This program and the accompanying materials
      +  4:  * are made available under the terms of the Eclipse Public License v1.0
      +  5:  * which accompanies this distribution, and is available at
      +  6:  * http://www.eclipse.org/legal/epl-v10.html
      +  7:  * 
      +  8:  * Contributors:
      +  9:  *     Wind River Systems - initial API and implementation
      + 10:  *******************************************************************************/
      + 11: package org.eclipse.dd.examples.pda.launch;
      +
      + 13: import org.eclipse.dd.dsf.concurrent.RequestMonitor;
      + 14: import org.eclipse.dd.dsf.concurrent.Sequence;
      + 15: import org.eclipse.dd.dsf.debug.service.BreakpointsMediator;
      + 16: import org.eclipse.dd.dsf.debug.service.StepQueueManager;
      + 17: import org.eclipse.dd.dsf.service.DsfSession;
      + 18: import org.eclipse.dd.examples.pda.service.PDABreakpointAttributeTranslator;
      + 19: import org.eclipse.dd.examples.pda.service.PDABreakpoints;
      + 20: import org.eclipse.dd.examples.pda.service.PDACommandControl;
      + 21: import org.eclipse.dd.examples.pda.service.PDAExpressions;
      + 22: import org.eclipse.dd.examples.pda.service.PDARunControl;
      + 23: import org.eclipse.dd.examples.pda.service.PDAStack;
      +
      + 25: /**
      + 26:  * The initialization sequence for PDA debugger services.  This sequence contains
      + 27:  * the series of steps that are executed to properly initialize the PDA-DSF debug
      + 28:  * session.  If any of the individual steps fail, the initialization will abort.   
      + 29:  * <p>
      + 30:  * The order in which services are initialized is important.  Some services depend
      + 31:  * on other services and they assume that they will be initialized only if those
      + 32:  * services are active.  Also the service events are prioritized and their priority
      + 33:  * depends on the order in which the services were initialized.
      + 34:  * </p>
      + 35:  */
      + 36: public class PDAServicesInitSequence extends Sequence {
      +
      + 38:     Step[] fSteps = new Step[] {
      + 39:         new Step() 
      + 40:         { 
      + 41:             @Override
      + 42:             public void execute(RequestMonitor requestMonitor) {
      + 43:                 // Create the connection to PDA debugger.
      + 44:                 fCommandControl = new PDACommandControl(fSession, fProgram, fRequestPort, fEventPort);
      + 45:                 fCommandControl.initialize(requestMonitor);
      + 46:             }
      + 47:         },
      + 48:         new Step() { 
      + 49:             @Override
      + 50:             public void execute(RequestMonitor requestMonitor) {
      + 51:                 // Start the run control service.
      + 52:                 fRunControl = new PDARunControl(fSession);
      + 53:                 fRunControl.initialize(requestMonitor);
      + 54:             }
      + 55:         },
      + 56:         new Step() { 
      + 57:             @Override
      + 58:             public void execute(RequestMonitor requestMonitor) {
      + 59:                 // Start the service to manage step actions.
      + 60:                 new StepQueueManager(fSession).initialize(requestMonitor);
      + 61:             }
      + 62:         },
      + 63:         new Step() { 
      + 64:             @Override
      + 65:             public void execute(final RequestMonitor requestMonitor) {
      + 66:                 // Start the low-level breakpoint service 
      + 67:                 new PDABreakpoints(fSession).initialize(new RequestMonitor(getExecutor(), requestMonitor));
      + 68:             }
      + 69:         },
      + 70:         new Step() { 
      + 71:             @Override
      + 72:             public void execute(final RequestMonitor requestMonitor) {
      + 73:                 // Create the breakpoint mediator and start tracking PDA breakpoints.
      +
      + 75:                 final BreakpointsMediator bpmService = new BreakpointsMediator(
      + 76:                     fSession, new PDABreakpointAttributeTranslator());
      + 77:                 bpmService.initialize(new RequestMonitor(getExecutor(), requestMonitor) {
      + 78:                     @Override
      + 79:                     protected void handleOK() {
      + 80:                         bpmService.startTrackingBreakpoints(fCommandControl.getProgramDMContext(), requestMonitor);
      + 81:                     }
      + 82:                 }); 
      + 83:             }
      + 84:         },
      + 85:         new Step() { @Override
      + 86:             public void execute(RequestMonitor requestMonitor) {
      + 87:             // Start the stack service.
      + 88:             new PDAStack(fSession).initialize(requestMonitor);
      + 89:         }
      + 90:         },
      + 91:         new Step() { @Override
      + 92:             public void execute(RequestMonitor requestMonitor) {
      + 93:             // Start the service to track expressions.
      + 94:             new PDAExpressions(fSession).initialize(requestMonitor);
      + 95:         }
      + 96:         },
      + 97:         new Step() { @Override
      + 98:             public void execute(RequestMonitor requestMonitor) {
      + 99:             fRunControl.resume(fCommandControl.getProgramDMContext(), requestMonitor);
      +100:         }
      +101:         },
      +102:     };
      +
      +104:     // Sequence input parameters, used in initializing services.
      +105:     private DsfSession fSession;
      +106:     private String fProgram;
      +107:     private int fRequestPort;
      +108:     private int fEventPort;
      +
      +110:     // Service references, initialized when created and used in initializing other services.
      +111:     private PDACommandControl fCommandControl;
      +112:     private PDARunControl fRunControl;
      +
      +114:     public PDAServicesInitSequence(DsfSession session, String program, int requestPort, int eventPort, RequestMonitor rm) 
      +115:     {
      +116:         super(session.getExecutor(), rm);
      +117:         fSession = session;
      +118:         fProgram = program;
      +119:         fRequestPort = requestPort;
      +120:         fEventPort = eventPort;
      +121:     }
      +
      +123:     @Override
      +124:     public Step[] getSteps() {
      +125:         return fSteps;
      +126:     }
      +127: }
      +
      + + + diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpointAttributeTranslator.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpointAttributeTranslator.java index ccdf9aef3ca..c8dc52927c6 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpointAttributeTranslator.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpointAttributeTranslator.java @@ -63,7 +63,7 @@ public class PDABreakpointAttributeTranslator implements IBreakpointAttributeTra } public List> getBreakpointAttributes(IBreakpoint bp, boolean bpManagerEnabled) - throws CoreException + throws CoreException { Map attrs = new HashMap(); @@ -82,15 +82,15 @@ public class PDABreakpointAttributeTranslator implements IBreakpointAttributeTra // Copy breakpoint attributes. if (bp instanceof PDAWatchpoint) { attrs.put(PDABreakpoints.ATTR_BREAKPOINT_TYPE, PDABreakpoints.PDA_WATCHPOINT); - + copyAttributes(platformBpAttrs, attrs, fgPDAWatchpointAttributes); } else if (bp instanceof PDALineBreakpoint) { attrs.put(PDABreakpoints.ATTR_BREAKPOINT_TYPE, PDABreakpoints.PDA_LINE_BREAKPOINT); attrs.put(PDABreakpoints.ATTR_PROGRAM_PATH, marker.getResource().getFullPath().toString()); - + copyAttributes(platformBpAttrs, attrs, fgPDALineBreakpointAttributes); } - + // If the breakpoint manager is disabled, override the enabled attribute. if (!bpManagerEnabled) { attrs.put(IBreakpoint.ENABLED, false); @@ -111,7 +111,7 @@ public class PDABreakpointAttributeTranslator implements IBreakpointAttributeTra } } } - + public boolean canUpdateAttributes(IBreakpointDMContext bp, Map delta) { // PDA debugger only allows updating of the action property of the watchpoint. // All other breakpoint updates will require a re-installation. diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpointAttributeTranslator.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpointAttributeTranslator.java.html new file mode 100644 index 00000000000..7696dc71e9e --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpointAttributeTranslator.java.html @@ -0,0 +1,148 @@ + + + +PDABreakpointAttributeTranslator.java + + + + + +
        1: /*******************************************************************************
      +  2:  * Copyright (c) 2008 Wind River Systems and others.
      +  3:  * All rights reserved. This program and the accompanying materials
      +  4:  * are made available under the terms of the Eclipse Public License v1.0
      +  5:  * which accompanies this distribution, and is available at
      +  6:  * http://www.eclipse.org/legal/epl-v10.html
      +  7:  * 
      +  8:  * Contributors:
      +  9:  *     Wind River Systems - initial API and implementation
      + 10:  *******************************************************************************/
      + 11: package org.eclipse.dd.examples.pda.service;
      +
      + 13: import java.util.ArrayList;
      + 14: import java.util.HashMap;
      + 15: import java.util.List;
      + 16: import java.util.Map;
      +
      + 18: import org.eclipse.core.resources.IMarker;
      + 19: import org.eclipse.core.runtime.CoreException;
      + 20: import org.eclipse.core.runtime.IStatus;
      + 21: import org.eclipse.core.runtime.Status;
      + 22: import org.eclipse.dd.dsf.debug.service.BreakpointsMediator;
      + 23: import org.eclipse.dd.dsf.debug.service.IBreakpointAttributeTranslator;
      + 24: import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointDMContext;
      + 25: import org.eclipse.dd.examples.pda.PDAPlugin;
      + 26: import org.eclipse.dd.examples.pda.breakpoints.PDALineBreakpoint;
      + 27: import org.eclipse.dd.examples.pda.breakpoints.PDAWatchpoint;
      + 28: import org.eclipse.debug.core.DebugException;
      + 29: import org.eclipse.debug.core.model.IBreakpoint;
      +
      + 31: /**
      + 32:  * Translator between {@link PDALineBreakpoint} object attributes and 
      + 33:  * attributes used by the {@link PDABreakpoints} service.  
      + 34:  * <p>
      + 35:  * The attribute translator is used by the standard {@link BreakpointsMediator} 
      + 36:  * service to map between platform breakpoint attributes and target-side DSF
      + 37:  * breakpoint attributes.  Thus, this object encapsulates the model-specific
      + 38:  * functionality of synchronizing target side and IDE-side breakpoint objects.  
      + 39:  * </p>
      + 40:  */
      + 41: public class PDABreakpointAttributeTranslator implements IBreakpointAttributeTranslator {
      +
      + 43:     // Arrays of common attributes between the two breakpoint types.  These 
      + 44:     // attributes can be copied directly without translation.
      + 45:     private static final String[] fgPDALineBreakpointAttributes = {
      + 46:         IBreakpoint.ENABLED,
      + 47:         IMarker.LINE_NUMBER,
      + 48:     };
      + 49:     private static final String[] fgPDAWatchpointAttributes = {
      + 50:         IBreakpoint.ENABLED,
      + 51:         PDAWatchpoint.FUNCTION_NAME,
      + 52:         PDAWatchpoint.VAR_NAME,
      + 53:         PDAWatchpoint.ACCESS,
      + 54:         PDAWatchpoint.MODIFICATION
      + 55:     };
      +
      + 57:     // PDA breakpoints translator doesn't keep any state and it doesn't 
      + 58:     // need to initialize or clean up.
      + 59:     public void initialize(BreakpointsMediator mediator) {
      + 60:     }
      +
      + 62:     public void dispose() {
      + 63:     }
      +
      + 65:     public List<Map<String, Object>> getBreakpointAttributes(IBreakpoint bp, boolean bpManagerEnabled) 
      + 66:     throws CoreException 
      + 67:     {
      + 68:         Map<String, Object> attrs = new HashMap<String, Object>(); 
      +
      + 70:         // Check that the marker exists and retrieve its attributes.  
      + 71:         // Due to accepted race conditions, the breakpiont marker may become null 
      + 72:         // while this method is being invoked.  In this case throw an exception
      + 73:         // and let the caller handle it.
      + 74:         IMarker marker = bp.getMarker();
      + 75:         if (marker == null || !marker.exists()) {
      + 76:             throw new DebugException(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Breakpoint marker does not exist", null)); 
      + 77:         }
      + 78:         // Suppress cast warning: platform is still on Java 1.3
      + 79:         @SuppressWarnings("unchecked")
      + 80:         Map<String, Object> platformBpAttrs = marker.getAttributes();
      +
      + 82:         // Copy breakpoint attributes.
      + 83:         if (bp instanceof PDAWatchpoint) {
      + 84:             attrs.put(PDABreakpoints.ATTR_BREAKPOINT_TYPE, PDABreakpoints.PDA_WATCHPOINT);
      +
      + 86:             copyAttributes(platformBpAttrs, attrs, fgPDAWatchpointAttributes);
      + 87:         } else if (bp instanceof PDALineBreakpoint) {
      + 88:             attrs.put(PDABreakpoints.ATTR_BREAKPOINT_TYPE, PDABreakpoints.PDA_LINE_BREAKPOINT);
      + 89:             attrs.put(PDABreakpoints.ATTR_PROGRAM_PATH, marker.getResource().getFullPath().toString()); 
      +
      + 91:             copyAttributes(platformBpAttrs, attrs, fgPDALineBreakpointAttributes);
      + 92:         }
      +
      + 94:         // If the breakpoint manager is disabled, override the enabled attribute.
      + 95:         if (!bpManagerEnabled) {
      + 96:             attrs.put(IBreakpoint.ENABLED, false);
      + 97:         }
      +
      + 99:         // The breakpoint mediator allows for multiple target-side breakpoints 
      +100:         // to be created for each IDE breakpoint.  Although in case of PDA this 
      +101:         // feature is never used, we still have to return a list of attributes.
      +102:         List<Map<String, Object>> retVal = new ArrayList<Map<String, Object>>(1);
      +103:         retVal.add(attrs);
      +104:         return retVal;
      +105:     }
      +
      +107:     private void copyAttributes(Map<String, Object> srcMap, Map<String, Object> destMap, String[] attrs) {
      +108:         for (String attr : attrs) {
      +109:             if (srcMap.containsKey(attr)) {
      +110:                 destMap.put(attr, srcMap.get(attr));
      +111:             }
      +112:         }
      +113:     }
      +
      +115:     public boolean canUpdateAttributes(IBreakpointDMContext bp, Map<String, Object> delta) {
      +116:         // PDA debugger only allows updating of the action property of the watchpoint.
      +117:         // All other breakpoint updates will require a re-installation.
      +118:         if (bp instanceof PDAWatchpoint) {
      +119:             Map<String, Object> deltaCopy = new HashMap<String, Object>(delta);
      +120:             deltaCopy.remove(PDAWatchpoint.ACCESS);
      +121:             deltaCopy.remove(PDAWatchpoint.MODIFICATION);
      +122:             return !deltaCopy.isEmpty();
      +123:         }
      +124:         return false;
      +125:     }
      +
      +127:     public boolean supportsBreakpoint(IBreakpoint bp) {
      +128:         return bp.getModelIdentifier().equals(PDAPlugin.ID_PDA_DEBUG_MODEL);
      +129:     }
      +
      +131:     public void updateBreakpointStatus(IBreakpoint bp) {
      +132:         // PDA breakpoints do not support status reporting
      +133:     }
      +
      +135: }
      +
      + + + diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpoints.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpoints.java index b0a4aa77e41..adfa26047b1 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpoints.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpoints.java @@ -60,7 +60,7 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints public boolean equals(Object obj) { return baseEquals(obj) && (fLine.equals(((BreakpointDMContext) obj).fLine)); } - + @Override public int hashCode() { return baseHashCode() + fLine.hashCode(); @@ -71,7 +71,7 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints return baseToString() + ".breakpoint(" + fLine + ")"; //$NON-NLS-1$//$NON-NLS-2$*/ } } - + /** * Context representing a watch point. In PDA debugger, a watchpoint is * uniquely identified using the function and variable. @@ -97,7 +97,7 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints } return false; } - + @Override public int hashCode() { return baseHashCode() + fFunction.hashCode() + fVariable.hashCode(); @@ -108,119 +108,119 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints return baseToString() + ".watchpoint(" + fFunction + "::" + fVariable + ")"; } } - + // Attribute names public static final String ATTR_BREAKPOINT_TYPE = PDAPlugin.PLUGIN_ID + ".pdaBreakpointType"; //$NON-NLS-1$ public static final String PDA_LINE_BREAKPOINT = "breakpoint"; //$NON-NLS-1$ public static final String PDA_WATCHPOINT = "watchpoint"; //$NON-NLS-1$ public static final String ATTR_PROGRAM_PATH = PDAPlugin.PLUGIN_ID + ".pdaProgramPath"; //$NON-NLS-1$ - + // Services private PDACommandControl fCommandControl; // Breakpoints currently installed private Set fBreakpoints = new HashSet(); - /** - * The service constructor - * - * @param session The debugging session this service belongs to. - */ - public PDABreakpoints(DsfSession session) { - super(session); - } + /** + * The service constructor + * + * @param session The debugging session this service belongs to. + */ + public PDABreakpoints(DsfSession session) { + super(session); + } - @Override - public void initialize(final RequestMonitor rm) { - super.initialize(new RequestMonitor(getExecutor(), rm) { - @Override - protected void handleOK() { - doInitialize(rm); - } - }); - } + @Override + public void initialize(final RequestMonitor rm) { + super.initialize(new RequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + doInitialize(rm); + } + }); + } - private void doInitialize(final RequestMonitor rm) { - // Get the services references - fCommandControl = getServicesTracker().getService(PDACommandControl.class); + private void doInitialize(final RequestMonitor rm) { + // Get the services references + fCommandControl = getServicesTracker().getService(PDACommandControl.class); - // Register this service - register(new String[] { IBreakpoints.class.getName(), PDABreakpoints.class.getName() }, - new Hashtable()); + // Register this service + register(new String[] { IBreakpoints.class.getName(), PDABreakpoints.class.getName() }, + new Hashtable()); - rm.done(); - } + rm.done(); + } - @Override - public void shutdown(final RequestMonitor rm) { - unregister(); - rm.done(); - } + @Override + public void shutdown(final RequestMonitor rm) { + unregister(); + rm.done(); + } - @Override - protected BundleContext getBundleContext() { - return PDAPlugin.getBundleContext(); - } + @Override + protected BundleContext getBundleContext() { + return PDAPlugin.getBundleContext(); + } - public void getBreakpoints(final IBreakpointsTargetDMContext context, final DataRequestMonitor rm) { - // Validate the context - if (!fCommandControl.getProgramDMContext().equals(context)) { - PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid breakpoints target context"); - return; - } - - rm.setData(fBreakpoints.toArray(new IBreakpointDMContext[fBreakpoints.size()])); - rm.done(); - } - - public void getBreakpointDMData(IBreakpointDMContext dmc, DataRequestMonitor rm) { - PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Retrieving breakpoint data is not supported"); - } - - public void insertBreakpoint(IBreakpointsTargetDMContext context, Map attributes, - DataRequestMonitor rm) - { - Boolean enabled = (Boolean)attributes.get(IBreakpoint.ENABLED); - if (enabled != null && !enabled.booleanValue()) { - // If the breakpoint is disabled, just fail the request. - PDAPlugin.failRequest(rm, REQUEST_FAILED, "Breakpoint is disabled"); - } else { - String type = (String) attributes.get(ATTR_BREAKPOINT_TYPE); - - if (PDA_LINE_BREAKPOINT.equals(type)) { - // Retrieve the PDA program context from the context given in the - // argument. This service is typically only called by the - // breakpoints mediator, which was called with the program context - // in the services initialization sequence. So checking if - // programCtx != null is mostly a formality. - PDAProgramDMContext programCtx = DMContexts.getAncestorOfType(context, PDAProgramDMContext.class); - if (programCtx != null) { - doInsertBreakpoint(programCtx, attributes, rm); - } else { - PDAPlugin.failRequest(rm, INVALID_HANDLE, "Unknown breakpoint type"); - } - } - else if (PDA_WATCHPOINT.equals(type)) { - doInsertWatchpoint(attributes, rm); - } - else { - PDAPlugin.failRequest(rm, REQUEST_FAILED, "Unknown breakpoint type"); - } - } - } - - private void doInsertBreakpoint(PDAProgramDMContext programCtx, final Map attributes, final DataRequestMonitor rm) - { - // Compare the program path in the breakpoint with the path in the PDA - // program context. Only insert the breakpoint if the program matches. - String program = (String)attributes.get(ATTR_PROGRAM_PATH); - if (!programCtx.getProgram().equals(program)) { - PDAPlugin.failRequest(rm, REQUEST_FAILED, "Invalid file name"); + public void getBreakpoints(final IBreakpointsTargetDMContext context, final DataRequestMonitor rm) { + // Validate the context + if (!fCommandControl.getProgramDMContext().equals(context)) { + PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid breakpoints target context"); return; - } - - // Retrieve the line. - Integer line = (Integer)attributes.get(IMarker.LINE_NUMBER); + } + + rm.setData(fBreakpoints.toArray(new IBreakpointDMContext[fBreakpoints.size()])); + rm.done(); + } + + public void getBreakpointDMData(IBreakpointDMContext dmc, DataRequestMonitor rm) { + PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Retrieving breakpoint data is not supported"); + } + + public void insertBreakpoint(IBreakpointsTargetDMContext context, Map attributes, + DataRequestMonitor rm) + { + Boolean enabled = (Boolean)attributes.get(IBreakpoint.ENABLED); + if (enabled != null && !enabled.booleanValue()) { + // If the breakpoint is disabled, just fail the request. + PDAPlugin.failRequest(rm, REQUEST_FAILED, "Breakpoint is disabled"); + } else { + String type = (String) attributes.get(ATTR_BREAKPOINT_TYPE); + + if (PDA_LINE_BREAKPOINT.equals(type)) { + // Retrieve the PDA program context from the context given in the + // argument. This service is typically only called by the + // breakpoints mediator, which was called with the program context + // in the services initialization sequence. So checking if + // programCtx != null is mostly a formality. + PDAProgramDMContext programCtx = DMContexts.getAncestorOfType(context, PDAProgramDMContext.class); + if (programCtx != null) { + doInsertBreakpoint(programCtx, attributes, rm); + } else { + PDAPlugin.failRequest(rm, INVALID_HANDLE, "Unknown breakpoint type"); + } + } + else if (PDA_WATCHPOINT.equals(type)) { + doInsertWatchpoint(attributes, rm); + } + else { + PDAPlugin.failRequest(rm, REQUEST_FAILED, "Unknown breakpoint type"); + } + } + } + + private void doInsertBreakpoint(PDAProgramDMContext programCtx, final Map attributes, final DataRequestMonitor rm) + { + // Compare the program path in the breakpoint with the path in the PDA + // program context. Only insert the breakpoint if the program matches. + String program = (String)attributes.get(ATTR_PROGRAM_PATH); + if (!programCtx.getProgram().equals(program)) { + PDAPlugin.failRequest(rm, REQUEST_FAILED, "Invalid file name"); + return; + } + + // Retrieve the line. + Integer line = (Integer)attributes.get(IMarker.LINE_NUMBER); if (line == null) { PDAPlugin.failRequest(rm, REQUEST_FAILED, "No breakpoint line specified"); return; @@ -235,7 +235,7 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints PDAPlugin.failRequest(rm, REQUEST_FAILED, "Breakpoint already set"); return; } - + // Add the new breakpoint context to the list of known breakpoints. // Adding it here, before the set command is completed will prevent // a possibility of a second breakpoint being installed in the same @@ -251,7 +251,7 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints rm.setData(breakpointCtx); rm.done(); } - + @Override protected void handleErrorOrCancel() { // If inserting of the breakpoint failed, remove it from @@ -260,10 +260,10 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints super.handleErrorOrCancel(); } }); - } + } - private void doInsertWatchpoint(final Map attributes, final DataRequestMonitor rm) - { + private void doInsertWatchpoint(final Map attributes, final DataRequestMonitor rm) + { String function = (String)attributes.get(PDAWatchpoint.FUNCTION_NAME); if (function == null) { PDAPlugin.failRequest(rm, REQUEST_FAILED, "No function specified"); @@ -291,7 +291,7 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints PDAPlugin.failRequest(rm, REQUEST_FAILED, "Watchpoint already set"); return; } - + // Determine the watch operation to perform. PDAWatchCommand.WatchOperation watchOperation = PDAWatchCommand.WatchOperation.NONE; if (isAccess && isModification) { @@ -317,7 +317,7 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints rm.setData(watchpointCtx); rm.done(); } - + @Override protected void handleErrorOrCancel() { // Since the command failed, we need to remove the breakpoint from @@ -326,29 +326,29 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints super.handleErrorOrCancel(); } }); - } + } - public void removeBreakpoint(IBreakpointDMContext bpCtx, RequestMonitor rm) { - if (!fBreakpoints.contains(bpCtx)) { + public void removeBreakpoint(IBreakpointDMContext bpCtx, RequestMonitor rm) { + if (!fBreakpoints.contains(bpCtx)) { PDAPlugin.failRequest(rm, REQUEST_FAILED, "Breakpoint already removed"); return; - } - + } + if (bpCtx instanceof BreakpointDMContext) { - doRemoveBreakpoint((BreakpointDMContext)bpCtx, rm); - } else if (bpCtx instanceof WatchpointDMContext) { + doRemoveBreakpoint((BreakpointDMContext)bpCtx, rm); + } else if (bpCtx instanceof WatchpointDMContext) { doRemoveWatchpoint((WatchpointDMContext)bpCtx, rm); - } else { - PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid breakpoint"); - } - } + } else { + PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid breakpoint"); + } + } private void doRemoveBreakpoint(BreakpointDMContext bpCtx, RequestMonitor rm) { // Remove the breakpoint from the table right away, so that even when // the remove is being processed, a new breakpoint can be created at the same // location. fBreakpoints.remove(bpCtx); - + fCommandControl.queueCommand( new PDAClearBreakpointCommand(fCommandControl.getProgramDMContext(), bpCtx.fLine), new DataRequestMonitor(getExecutor(), rm)); @@ -356,23 +356,31 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints private void doRemoveWatchpoint(WatchpointDMContext bpCtx, RequestMonitor rm) { fBreakpoints.remove(bpCtx); - + // Watchpoints are cleared using the same command, but with a "no watch" operation fCommandControl.queueCommand( new PDAWatchCommand( fCommandControl.getProgramDMContext(), bpCtx.fFunction, bpCtx.fVariable, PDAWatchCommand.WatchOperation.NONE), - new DataRequestMonitor(getExecutor(), rm)); + new DataRequestMonitor(getExecutor(), rm)); } - public void updateBreakpoint(final IBreakpointDMContext bpCtx, Map attributes, final RequestMonitor rm) { + public void updateBreakpoint(final IBreakpointDMContext bpCtx, Map attributes, final RequestMonitor rm) { if (!fBreakpoints.contains(bpCtx)) { PDAPlugin.failRequest(rm, REQUEST_FAILED, "Breakpoint not installed"); return; } - + if (bpCtx instanceof BreakpointDMContext) { PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Modifying PDA breakpoints is not supported"); } else if (bpCtx instanceof WatchpointDMContext) { + WatchpointDMContext wpCtx = (WatchpointDMContext)bpCtx; + if (!wpCtx.fFunction.equals(attributes.get(PDAWatchpoint.FUNCTION_NAME)) || + !wpCtx.fVariable.equals(attributes.get(PDAWatchpoint.VAR_NAME)) ) + { + PDAPlugin.failRequest(rm, REQUEST_FAILED, "Cannot modify watchpoint function or variable"); + return; + } + // PDA debugger can only track one watchpoint in the same location, // so we can simply remove the existing context from the set and // call insert again. @@ -391,5 +399,5 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints } else { PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid breakpoint"); } - } + } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpoints.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpoints.java.html new file mode 100644 index 00000000000..5976bfa268d --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpoints.java.html @@ -0,0 +1,416 @@ + + + +PDABreakpoints.java + + + + + +
        1: /*******************************************************************************
      +  2:  * Copyright (c) 2007 Ericsson and others.
      +  3:  * All rights reserved. This program and the accompanying materials
      +  4:  * are made available under the terms of the Eclipse Public License v1.0
      +  5:  * which accompanies this distribution, and is available at
      +  6:  * http://www.eclipse.org/legal/epl-v10.html
      +  7:  *
      +  8:  * Contributors:
      +  9:  *     Ericsson - Initial API and implementation
      + 10:  *******************************************************************************/
      +
      + 12: package org.eclipse.dd.examples.pda.service;
      +
      + 14: import java.util.HashSet;
      + 15: import java.util.Hashtable;
      + 16: import java.util.Map;
      + 17: import java.util.Set;
      +
      + 19: import org.eclipse.core.resources.IMarker;
      + 20: import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
      + 21: import org.eclipse.dd.dsf.concurrent.Immutable;
      + 22: import org.eclipse.dd.dsf.concurrent.RequestMonitor;
      + 23: import org.eclipse.dd.dsf.datamodel.AbstractDMContext;
      + 24: import org.eclipse.dd.dsf.datamodel.DMContexts;
      + 25: import org.eclipse.dd.dsf.datamodel.IDMContext;
      + 26: import org.eclipse.dd.dsf.debug.service.IBreakpoints;
      + 27: import org.eclipse.dd.dsf.service.AbstractDsfService;
      + 28: import org.eclipse.dd.dsf.service.DsfSession;
      + 29: import org.eclipse.dd.examples.pda.PDAPlugin;
      + 30: import org.eclipse.dd.examples.pda.breakpoints.PDAWatchpoint;
      + 31: import org.eclipse.dd.examples.pda.service.commands.PDAClearBreakpointCommand;
      + 32: import org.eclipse.dd.examples.pda.service.commands.PDACommandResult;
      + 33: import org.eclipse.dd.examples.pda.service.commands.PDASetBreakpointCommand;
      + 34: import org.eclipse.dd.examples.pda.service.commands.PDAWatchCommand;
      + 35: import org.eclipse.debug.core.model.IBreakpoint;
      + 36: import org.osgi.framework.BundleContext;
      +
      + 38: /**
      + 39:  * Initial breakpoint service implementation.
      + 40:  * Implements the IBreakpoints interface.
      + 41:  */
      + 42: public class PDABreakpoints extends AbstractDsfService implements IBreakpoints
      + 43: {
      + 44:     /**
      + 45:      * Context representing a PDA line breakpoint.  In PDA debugger, since there is only 
      + 46:      * one file being debugged at a time, a breakpoint is uniquely identified using the 
      + 47:      * line number only.
      + 48:      */
      + 49:     @Immutable
      + 50:     private static class BreakpointDMContext extends AbstractDMContext implements IBreakpointDMContext {
      +
      + 52:         final Integer fLine;
      +
      + 54:         public BreakpointDMContext(String sessionId, PDAProgramDMContext commandControlCtx, Integer line) {
      + 55:             super(sessionId, new IDMContext[] { commandControlCtx });
      + 56:             fLine = line;
      + 57:         }
      +
      + 59:         @Override
      + 60:         public boolean equals(Object obj) {
      + 61:             return baseEquals(obj) && (fLine.equals(((BreakpointDMContext) obj).fLine));
      + 62:         }
      +
      + 64:         @Override
      + 65:         public int hashCode() {
      + 66:             return baseHashCode() + fLine.hashCode();
      + 67:         }
      +
      + 69:         @Override
      + 70:         public String toString() {
      + 71:             return baseToString() + ".breakpoint(" + fLine + ")";  //$NON-NLS-1$//$NON-NLS-2$*/
      + 72:         }
      + 73:     }
      +
      + 75:     /**
      + 76:      * Context representing a watch point.  In PDA debugger, a watchpoint is 
      + 77:      * uniquely identified using the function and variable.
      + 78:      */
      + 79:     @Immutable
      + 80:     private static class WatchpointDMContext extends AbstractDMContext implements IBreakpointDMContext {
      + 81:         final String fFunction;
      + 82:         final String fVariable; 
      +
      + 84:         public WatchpointDMContext(String sessionId, PDAProgramDMContext commandControlCtx, String function, 
      + 85:             String variable) 
      + 86:         {
      + 87:             super(sessionId, new IDMContext[] { commandControlCtx });
      + 88:             fFunction = function;
      + 89:             fVariable = variable;
      + 90:         }
      +
      + 92:         @Override
      + 93:         public boolean equals(Object obj) {
      + 94:             if (baseEquals(obj)) {
      + 95:                 WatchpointDMContext watchpointCtx = (WatchpointDMContext)obj;
      + 96:                 return fFunction.equals(watchpointCtx.fFunction) && fVariable.equals(watchpointCtx.fVariable);
      + 97:             }
      + 98:             return false;
      + 99:         }
      +
      +101:         @Override
      +102:         public int hashCode() {
      +103:             return baseHashCode() + fFunction.hashCode() + fVariable.hashCode();
      +104:         }
      +
      +106:         @Override
      +107:         public String toString() {
      +108:             return baseToString() + ".watchpoint(" + fFunction + "::" + fVariable + ")";
      +109:         }
      +110:     }
      +
      +112:     // Attribute names
      +113:     public static final String ATTR_BREAKPOINT_TYPE = PDAPlugin.PLUGIN_ID + ".pdaBreakpointType";      //$NON-NLS-1$
      +114:     public static final String PDA_LINE_BREAKPOINT = "breakpoint";                 //$NON-NLS-1$
      +115:     public static final String PDA_WATCHPOINT = "watchpoint";                 //$NON-NLS-1$
      +116:     public static final String ATTR_PROGRAM_PATH = PDAPlugin.PLUGIN_ID + ".pdaProgramPath";      //$NON-NLS-1$
      +
      +118:     // Services
      +119:     private PDACommandControl fCommandControl;
      +
      +121:     // Breakpoints currently installed
      +122:     private Set<IBreakpointDMContext> fBreakpoints = new HashSet<IBreakpointDMContext>();
      +
      +124:     /**
      +125:      * The service constructor
      +126:      * 
      +127:      * @param session The debugging session this service belongs to.
      +128:      */
      +129:     public PDABreakpoints(DsfSession session) {
      +130:         super(session);
      +131:     }
      +
      +133:     @Override
      +134:     public void initialize(final RequestMonitor rm) {
      +135:         super.initialize(new RequestMonitor(getExecutor(), rm) {
      +136:             @Override
      +137:             protected void handleOK() {
      +138:                 doInitialize(rm);
      +139:             }
      +140:         });
      +141:     }
      +
      +143:     private void doInitialize(final RequestMonitor rm) {
      +144:         // Get the services references
      +145:         fCommandControl = getServicesTracker().getService(PDACommandControl.class);
      +
      +147:         // Register this service
      +148:         register(new String[] { IBreakpoints.class.getName(), PDABreakpoints.class.getName() },
      +149:             new Hashtable<String, String>());
      +
      +151:         rm.done();
      +152:     }
      +
      +154:     @Override
      +155:     public void shutdown(final RequestMonitor rm) {
      +156:         unregister();
      +157:         rm.done();
      +158:     }
      +
      +160:     @Override
      +161:     protected BundleContext getBundleContext() {
      +162:         return PDAPlugin.getBundleContext();
      +163:     }
      +
      +165:     public void getBreakpoints(final IBreakpointsTargetDMContext context, final DataRequestMonitor<IBreakpointDMContext[]> rm) {
      +166:         // Validate the context
      +167:         if (!fCommandControl.getProgramDMContext().equals(context)) {
      +168:             PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid breakpoints target context");
      +169:             return;
      +170:         }
      +
      +172:         rm.setData(fBreakpoints.toArray(new IBreakpointDMContext[fBreakpoints.size()]));
      +173:         rm.done();
      +174:     }
      +
      +176:     public void getBreakpointDMData(IBreakpointDMContext dmc, DataRequestMonitor<IBreakpointDMData> rm) {
      +177:         PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Retrieving breakpoint data is not supported");
      +178:     }
      +
      +180:     public void insertBreakpoint(IBreakpointsTargetDMContext context, Map<String, Object> attributes, 
      +181:         DataRequestMonitor<IBreakpointDMContext> rm) 
      +182:     {
      +183:         Boolean enabled = (Boolean)attributes.get(IBreakpoint.ENABLED);
      +184:         if (enabled != null && !enabled.booleanValue()) {
      +185:             // If the breakpoint is disabled, just fail the request. 
      +186:             PDAPlugin.failRequest(rm, REQUEST_FAILED, "Breakpoint is disabled");
      +187:         } else {
      +188:             String type = (String) attributes.get(ATTR_BREAKPOINT_TYPE);
      +
      +190:             if (PDA_LINE_BREAKPOINT.equals(type)) {
      +191:                 // Retrieve the PDA program context from the context given in the 
      +192:                 // argument.  This service is typically only called by the 
      +193:                 // breakpoints mediator, which was called with the program context
      +194:                 // in the services initialization sequence.  So checking if 
      +195:                 // programCtx != null is mostly a formality.
      +196:                 PDAProgramDMContext programCtx = DMContexts.getAncestorOfType(context, PDAProgramDMContext.class);
      +197:                 if (programCtx != null) {
      +198:                     doInsertBreakpoint(programCtx, attributes, rm);
      +199:                 } else {
      +200:                     PDAPlugin.failRequest(rm, INVALID_HANDLE, "Unknown breakpoint type");
      +201:                 }
      +202:             }
      +203:             else if (PDA_WATCHPOINT.equals(type)) {
      +204:                 doInsertWatchpoint(attributes, rm);
      +205:             }
      +206:             else {
      +207:                 PDAPlugin.failRequest(rm, REQUEST_FAILED, "Unknown breakpoint type");
      +208:             }
      +209:         }
      +210:     }
      +
      +212:     private void doInsertBreakpoint(PDAProgramDMContext programCtx, final Map<String, Object> attributes, final DataRequestMonitor<IBreakpointDMContext> rm) 
      +213:     {
      +214:         // Compare the program path in the breakpoint with the path in the PDA 
      +215:         // program context. Only insert the breakpoint if the program matches. 
      +216:         String program = (String)attributes.get(ATTR_PROGRAM_PATH);
      +217:         if (!programCtx.getProgram().equals(program)) {
      +218:             PDAPlugin.failRequest(rm, REQUEST_FAILED, "Invalid file name");
      +219:             return;
      +220:         }
      +
      +222:         // Retrieve the line.
      +223:         Integer line = (Integer)attributes.get(IMarker.LINE_NUMBER);
      +224:         if (line == null) {
      +225:             PDAPlugin.failRequest(rm, REQUEST_FAILED, "No breakpoint line specified");
      +226:             return;
      +227:         }
      +
      +229:         // Create a new breakpoint context object and check that it's not 
      +230:         // installed already. PDA can only track a single breakpoint at a 
      +231:         // given line, attempting to set the second breakpoint should fail.
      +232:         final BreakpointDMContext breakpointCtx = 
      +233:             new BreakpointDMContext(getSession().getId(), fCommandControl.getProgramDMContext(), line);
      +234:         if (fBreakpoints.contains(breakpointCtx)) {
      +235:             PDAPlugin.failRequest(rm, REQUEST_FAILED, "Breakpoint already set");
      +236:             return;
      +237:         }
      +
      +239:         // Add the new breakpoint context to the list of known breakpoints.  
      +240:         // Adding it here, before the set command is completed will prevent 
      +241:         // a possibility of a second breakpoint being installed in the same 
      +242:         // location while this breakpoint is being processed.  It will also
      +243:         // allow the breakpoint to be removed or updated even while it is 
      +244:         // still being processed here.
      +245:         fBreakpoints.add(breakpointCtx);
      +246:         fCommandControl.queueCommand(
      +247:             new PDASetBreakpointCommand(fCommandControl.getProgramDMContext(), line), 
      +248:             new DataRequestMonitor<PDACommandResult>(getExecutor(), rm) {
      +249:                 @Override
      +250:                 protected void handleOK() {
      +251:                     rm.setData(breakpointCtx);
      +252:                     rm.done();
      +253:                 }
      +
      +255:                 @Override
      +256:                 protected void handleErrorOrCancel() {
      +257:                     // If inserting of the breakpoint failed, remove it from
      +258:                     // the set of installed breakpoints.
      +259:                     fBreakpoints.remove(breakpointCtx);
      +260:                     super.handleErrorOrCancel();
      +261:                 }
      +262:             });
      +263:     }
      +
      +265:     private void doInsertWatchpoint(final Map<String, Object> attributes, final DataRequestMonitor<IBreakpointDMContext> rm) 
      +266:     {
      +267:         String function = (String)attributes.get(PDAWatchpoint.FUNCTION_NAME);
      +268:         if (function == null) {
      +269:             PDAPlugin.failRequest(rm, REQUEST_FAILED, "No function specified");
      +270:             return;
      +271:         }
      +
      +273:         String variable = (String)attributes.get(PDAWatchpoint.VAR_NAME);
      +274:         if (variable == null) {
      +275:             PDAPlugin.failRequest(rm, REQUEST_FAILED, "No variable specified");
      +276:             return;
      +277:         }
      +
      +279:         Boolean isAccess = (Boolean)attributes.get(PDAWatchpoint.ACCESS);
      +280:         isAccess = isAccess != null ? isAccess : Boolean.FALSE; 
      +
      +282:         Boolean isModification = (Boolean)attributes.get(PDAWatchpoint.MODIFICATION);
      +283:         isModification = isModification != null ? isModification : Boolean.FALSE; 
      +
      +285:         // Create a new watchpoint context object and check that it's not 
      +286:         // installed already. PDA can only track a single watchpoint for a given
      +287:         // function::variable, attempting to set the second breakpoint should fail.
      +288:         final WatchpointDMContext watchpointCtx = 
      +289:             new WatchpointDMContext(getSession().getId(), fCommandControl.getProgramDMContext(), function, variable);
      +290:         if (fBreakpoints.contains(watchpointCtx)) {
      +291:             PDAPlugin.failRequest(rm, REQUEST_FAILED, "Watchpoint already set");
      +292:             return;
      +293:         }
      +
      +295:         // Determine the watch operation to perform.
      +296:         PDAWatchCommand.WatchOperation watchOperation = PDAWatchCommand.WatchOperation.NONE;
      +297:         if (isAccess && isModification) {
      +298:             watchOperation = PDAWatchCommand.WatchOperation.BOTH;
      +299:         } else if (isAccess) {
      +300:             watchOperation = PDAWatchCommand.WatchOperation.READ;
      +301:         } else if (isModification) {
      +302:             watchOperation = PDAWatchCommand.WatchOperation.WRITE;
      +303:         }
      +
      +305:         // Add the new breakpoint context to the list of known breakpoints.  
      +306:         // Adding it here, before the set command is completed will prevent 
      +307:         // a possibility of a second breakpoint being installed in the same 
      +308:         // location while this breakpoint is being processed.  It will also
      +309:         // allow the breakpoint to be removed or updated even while it is 
      +310:         // still being processed here.
      +311:         fBreakpoints.add(watchpointCtx);
      +312:         fCommandControl.queueCommand(
      +313:             new PDAWatchCommand(fCommandControl.getProgramDMContext(), function, variable, watchOperation), 
      +314:             new DataRequestMonitor<PDACommandResult>(getExecutor(), rm) {
      +315:                 @Override
      +316:                 protected void handleOK() {
      +317:                     rm.setData(watchpointCtx);
      +318:                     rm.done();
      +319:                 }
      +
      +321:                 @Override
      +322:                 protected void handleErrorOrCancel() {
      +323:                     // Since the command failed, we need to remove the breakpoint from 
      +324:                     // the existing breakpoint set.
      +325:                     fBreakpoints.remove(watchpointCtx);
      +326:                     super.handleErrorOrCancel();
      +327:                 }
      +328:             });
      +329:     }
      +
      +331:     public void removeBreakpoint(IBreakpointDMContext bpCtx, RequestMonitor rm) {
      +332:         if (!fBreakpoints.contains(bpCtx)) {
      +333:             PDAPlugin.failRequest(rm, REQUEST_FAILED, "Breakpoint already removed");
      +334:             return;
      +335:         }
      +
      +337:         if (bpCtx instanceof BreakpointDMContext) {
      +338:             doRemoveBreakpoint((BreakpointDMContext)bpCtx, rm);
      +339:         } else if (bpCtx instanceof WatchpointDMContext) {
      +340:             doRemoveWatchpoint((WatchpointDMContext)bpCtx, rm);
      +341:         } else {
      +342:             PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid breakpoint");
      +343:         }
      +344:     }
      +
      +346:     private void doRemoveBreakpoint(BreakpointDMContext bpCtx, RequestMonitor rm) {
      +347:         // Remove the breakpoint from the table right away, so that even when 
      +348:         // the remove is being processed, a new breakpoint can be created at the same 
      +349:         // location.
      +350:         fBreakpoints.remove(bpCtx);
      +
      +352:         fCommandControl.queueCommand(
      +353:             new PDAClearBreakpointCommand(fCommandControl.getProgramDMContext(), bpCtx.fLine), 
      +354:             new DataRequestMonitor<PDACommandResult>(getExecutor(), rm));        
      +355:     }
      +
      +357:     private void doRemoveWatchpoint(WatchpointDMContext bpCtx, RequestMonitor rm) {
      +358:         fBreakpoints.remove(bpCtx);
      +
      +360:         // Watchpoints are cleared using the same command, but with a "no watch" operation
      +361:         fCommandControl.queueCommand(
      +362:             new PDAWatchCommand(
      +363:                 fCommandControl.getProgramDMContext(), bpCtx.fFunction, bpCtx.fVariable, PDAWatchCommand.WatchOperation.NONE), 
      +364:                 new DataRequestMonitor<PDACommandResult>(getExecutor(), rm));        
      +365:     }
      +
      +367:     public void updateBreakpoint(final IBreakpointDMContext bpCtx, Map<String, Object> attributes, final RequestMonitor rm) {
      +368:         if (!fBreakpoints.contains(bpCtx)) {
      +369:             PDAPlugin.failRequest(rm, REQUEST_FAILED, "Breakpoint not installed");
      +370:             return;
      +371:         }
      +
      +373:         if (bpCtx instanceof BreakpointDMContext) {
      +374:             PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Modifying PDA breakpoints is not supported");
      +375:         } else if (bpCtx instanceof WatchpointDMContext) {
      +376:             WatchpointDMContext wpCtx = (WatchpointDMContext)bpCtx;
      +377:             if (!wpCtx.fFunction.equals(attributes.get(PDAWatchpoint.FUNCTION_NAME)) || 
      +378:                 !wpCtx.fVariable.equals(attributes.get(PDAWatchpoint.VAR_NAME)) )
      +379:             {
      +380:                 PDAPlugin.failRequest(rm, REQUEST_FAILED, "Cannot modify watchpoint function or variable");
      +381:                 return;
      +382:             }
      +383:             
      +384:             // PDA debugger can only track one watchpoint in the same location, 
      +385:             // so we can simply remove the existing context from the set and 
      +386:             // call insert again.  
      +387:             fBreakpoints.remove(bpCtx);
      +388:             doInsertWatchpoint(
      +389:                 attributes, 
      +390:                 new DataRequestMonitor<IBreakpointDMContext>(getExecutor(), rm) {
      +391:                     @Override
      +392:                     protected void handleOK() {
      +393:                         // The inserted watchpoint context will equal the 
      +394:                         // current context.
      +395:                         assert bpCtx.equals(getData());
      +396:                         rm.done();
      +397:                     }
      +398:                 });
      +399:         } else {
      +400:             PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid breakpoint");
      +401:         }
      +402:     }
      +403: }
      +
      + + + diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java index d835a549554..e7b77ceeb0d 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java @@ -83,15 +83,20 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon private final List fEventListeners = new ArrayList(); // Sockets for communicating with PDA debugger + @ThreadSafe private Socket fRequestSocket; + @ThreadSafe private PrintWriter fRequestWriter; + @ThreadSafe private BufferedReader fRequestReader; + @ThreadSafe private Socket fEventSocket; + @ThreadSafe private BufferedReader fEventReader; // Jobs servicing the sockets. private EventDispatchJob fEventDispatchJob; - private CommandSendJob fRequestJob; + private CommandSendJob fCommandSendJob; /** * Command control constructor. @@ -170,8 +175,8 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon fEventDispatchJob = new EventDispatchJob(); fEventDispatchJob.schedule(); - fRequestJob = new CommandSendJob(); - fRequestJob.schedule(); + fCommandSendJob = new CommandSendJob(); + fCommandSendJob.schedule(); socketsInitializeRm.done(); } catch (UnknownHostException e) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java.html new file mode 100644 index 00000000000..556bfa472ed --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java.html @@ -0,0 +1,547 @@ + + + +PDACommandControl.java + + + + + +
        1: package org.eclipse.dd.examples.pda.service;
      +
      +  3: import java.io.BufferedReader;
      +  4: import java.io.IOException;
      +  5: import java.io.InputStreamReader;
      +  6: import java.io.PrintWriter;
      +  7: import java.net.Socket;
      +  8: import java.net.UnknownHostException;
      +  9: import java.util.ArrayList;
      + 10: import java.util.Hashtable;
      + 11: import java.util.Iterator;
      + 12: import java.util.LinkedList;
      + 13: import java.util.List;
      + 14: import java.util.concurrent.BlockingQueue;
      + 15: import java.util.concurrent.LinkedBlockingQueue;
      + 16: import java.util.concurrent.RejectedExecutionException;
      +
      + 18: import org.eclipse.core.runtime.IProgressMonitor;
      + 19: import org.eclipse.core.runtime.IStatus;
      + 20: import org.eclipse.core.runtime.Status;
      + 21: import org.eclipse.core.runtime.jobs.Job;
      + 22: import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
      + 23: import org.eclipse.dd.dsf.concurrent.DsfRunnable;
      + 24: import org.eclipse.dd.dsf.concurrent.RequestMonitor;
      + 25: import org.eclipse.dd.dsf.concurrent.ThreadSafe;
      + 26: import org.eclipse.dd.dsf.debug.service.command.ICommand;
      + 27: import org.eclipse.dd.dsf.debug.service.command.ICommandControl;
      + 28: import org.eclipse.dd.dsf.debug.service.command.ICommandListener;
      + 29: import org.eclipse.dd.dsf.debug.service.command.ICommandResult;
      + 30: import org.eclipse.dd.dsf.debug.service.command.IEventListener;
      + 31: import org.eclipse.dd.dsf.service.AbstractDsfService;
      + 32: import org.eclipse.dd.dsf.service.DsfSession;
      + 33: import org.eclipse.dd.examples.pda.PDAPlugin;
      + 34: import org.eclipse.dd.examples.pda.service.commands.AbstractPDACommand;
      + 35: import org.eclipse.dd.examples.pda.service.commands.PDACommandResult;
      + 36: import org.eclipse.dd.examples.pda.service.commands.PDAExitCommand;
      + 37: import org.osgi.framework.BundleContext;
      +
      +
      + 40: /**
      + 41:  * Service that handles communication with a PDA debugger back end.  
      + 42:  */
      + 43: public class PDACommandControl extends AbstractDsfService implements ICommandControl {
      +
      + 45:     // Structure used to store command information in services internal queues.
      + 46:     private static class CommandHandle {
      + 47:         final private AbstractPDACommand<PDACommandResult> fCommand;
      + 48:         final private DataRequestMonitor<PDACommandResult> fRequestMonitor;
      + 49:         
      + 50:         CommandHandle(AbstractPDACommand<PDACommandResult> c, DataRequestMonitor<PDACommandResult> rm) {
      + 51:             fCommand = c; 
      + 52:             fRequestMonitor = rm;
      + 53:         }
      + 54:     }
      +
      + 56:     // Parameters that the command control is created with.
      + 57:     final private String fProgram;
      + 58:     final private int fRequestPort;
      + 59:     final private int fEventPort;
      +
      + 61:     // Queue of commands waiting to be sent to the debugger.  As long as commands
      + 62:     // are in this queue, they can still be removed by clients. 
      + 63:     private final List<CommandHandle> fCommandQueue = new LinkedList<CommandHandle>();
      + 64:     
      + 65:     // Queue of commands that are being sent to the debugger.  This queue is read
      + 66:     // by the send job, so as soon as commands are inserted into this queue, they can
      + 67:     // be considered as sent.
      + 68:     @ThreadSafe
      + 69:     private final BlockingQueue<CommandHandle> fTxCommands = new LinkedBlockingQueue<CommandHandle>();
      + 70:     
      + 71:     // Flag indicating that the PDA debugger started
      + 72:     private boolean fStarted = false;
      + 73:     
      + 74:     // Flag indicating that the PDA debugger has been disconnected 
      + 75:     @ThreadSafe
      + 76:     private boolean fTerminated = false;
      + 77:     
      + 78:     //  Data Model context of this command control. 
      + 79:     private PDAProgramDMContext fDMContext;
      +
      + 81:     // Synchronous listeners for commands and events.
      + 82:     private final List<ICommandListener> fCommandListeners = new ArrayList<ICommandListener>();
      + 83:     private final List<IEventListener>   fEventListeners = new ArrayList<IEventListener>();
      + 84:     
      + 85:     // Sockets for communicating with PDA debugger 
      + 86:     @ThreadSafe
      + 87:     private Socket fRequestSocket;
      + 88:     @ThreadSafe
      + 89:     private PrintWriter fRequestWriter;
      + 90:     @ThreadSafe
      + 91:     private BufferedReader fRequestReader;
      + 92:     @ThreadSafe
      + 93:     private Socket fEventSocket;
      + 94:     @ThreadSafe
      + 95:     private BufferedReader fEventReader;
      +
      + 97:     // Jobs servicing the sockets.
      + 98:     private EventDispatchJob fEventDispatchJob;
      + 99:     private CommandSendJob fCommandSendJob;
      +100:     
      +101:     /**
      +102:      * Command control constructor. 
      +103:      * @param session The DSF session that this service is a part of. 
      +104:      * @param requestPort Port number for sending PDA commands.
      +105:      * @param eventPort Port for listening to PDA events.
      +106:      */
      +107:     public PDACommandControl(DsfSession session, String program, int requestPort, int eventPort) {
      +108:         super(session);
      +109:         fProgram = program;
      +110:         fRequestPort = requestPort;
      +111:         fEventPort = eventPort;
      +112:     }
      +113:     
      +114:     @Override
      +115:     public void initialize(final RequestMonitor rm) {
      +116:         // Call the super-class to perform initialization first.
      +117:         super.initialize( new RequestMonitor(getExecutor(), rm) {
      +118:             @Override
      +119:             protected void handleOK() {
      +120:                 doInitialize(rm);
      +121:             }
      +122:         });
      +123:     }
      +
      +125:     private void doInitialize(final RequestMonitor rm) {
      +126:         // Create the control's data model context.
      +127:         fDMContext = new PDAProgramDMContext(getSession().getId(), fProgram);
      +
      +129:         // Add a listener for PDA events to track the started/terminated state.
      +130:         addEventListener(new IEventListener() {
      +131:             public void eventReceived(Object output) {
      +132:                 if ("started".equals(output)) {
      +133:                     setStarted();
      +134:                 } else if ("terminated".equals(output)) {
      +135:                     setTerminated();
      +136:                 }
      +137:             }
      +138:         });
      +139:         
      +140:         // Request monitor that will be invoked when the socket initialization is
      +141:         // completed.  
      +142:         final RequestMonitor socketsInitializeRm = new RequestMonitor(getExecutor(), rm) {
      +143:             @Override
      +144:             protected void handleOK() {
      +145:                 // Register the service with OSGi as the last step in initialization of 
      +146:                 // the service.
      +147:                 register(
      +148:                     new String[]{ ICommandControl.class.getName(), PDACommandControl.class.getName() }, 
      +149:                     new Hashtable<String,String>());
      +150:                 rm.done();
      +151:             }
      +152:         };
      +153:         
      +154:         // To avoid blocking the DSF dispatch thread use a job to initialize communication sockets.  
      +155:         new Job("PDA Initialize") {
      +156:             @Override
      +157:             protected IStatus run(IProgressMonitor monitor) {
      +158:                 try {
      +159:                     // give interpreter a chance to start
      +160:                     try {
      +161:                         Thread.sleep(1000);
      +162:                     } catch (InterruptedException e) {
      +163:                     }
      +164:                     fRequestSocket = new Socket("localhost", fRequestPort);
      +165:                     fRequestWriter = new PrintWriter(fRequestSocket.getOutputStream());
      +166:                     fRequestReader = new BufferedReader(new InputStreamReader(fRequestSocket.getInputStream()));
      +167:                     // give interpreter a chance to open next socket
      +168:                     try {
      +169:                         Thread.sleep(1000);
      +170:                     } catch (InterruptedException e) {
      +171:                     }
      +172:                     fEventSocket = new Socket("localhost", fEventPort);
      +173:                     fEventReader = new BufferedReader(new InputStreamReader(fEventSocket.getInputStream()));
      +
      +175:                     fEventDispatchJob = new EventDispatchJob();
      +176:                     fEventDispatchJob.schedule();
      +177:                     
      +178:                     fCommandSendJob = new CommandSendJob();
      +179:                     fCommandSendJob.schedule();
      +
      +181:                     socketsInitializeRm.done();
      +182:                 } catch (UnknownHostException e) {
      +183:                     socketsInitializeRm.setStatus(new Status(
      +184:                         IStatus.ERROR, PDAPlugin.PLUGIN_ID, REQUEST_FAILED, "Unable to connect to PDA VM", e));
      +185:                     socketsInitializeRm.done();
      +186:                 } catch (IOException e) {
      +187:                     socketsInitializeRm.setStatus(new Status(
      +188:                         IStatus.ERROR, PDAPlugin.PLUGIN_ID, REQUEST_FAILED, "Unable to connect to PDA VM", e));
      +189:                     socketsInitializeRm.done();
      +190:                 }
      +191:                 return Status.OK_STATUS;
      +192:             }
      +193:         }.schedule();
      +194:     }
      +
      +196:     @Override
      +197:     public void shutdown(final RequestMonitor requestMonitor) {
      +198:         // Unregister the service first, so that clients may no longer gain access to it.
      +199:         unregister();
      +200:         
      +201:         if (!isTerminated()) {
      +202:             // If the debugger is still connected, send it the exit command.
      +203:             terminate(new RequestMonitor(getExecutor(), requestMonitor) {
      +204:                 @Override
      +205:                 protected void handleCompleted() {
      +206:                     // Mark the command control as terminated.
      +207:                     setTerminated();
      +
      +209:                     // Ignore any error resulting from the exit command.  
      +210:                     // Errors will most likely result if the PDA process is 
      +211:                     // already terminated.
      +212:                     requestMonitor.done();
      +213:                 }
      +214:             });
      +215:         } else {
      +216:             requestMonitor.done();
      +217:         }
      +218:     }        
      +
      +220:     @Override
      +221:     protected BundleContext getBundleContext() {
      +222:         return PDAPlugin.getBundleContext();
      +223:     }
      +224:     
      +225:     /**
      +226:      *  Job that services the send command queue. 
      +227:      */
      +228:     private class CommandSendJob extends Job {
      +229:         CommandSendJob() {
      +230:             super("PDA Command Send");
      +231:             setSystem(true);
      +232:         }
      +233:         
      +234:         @Override
      +235:         protected IStatus run(IProgressMonitor monitor) {
      +236:             while (!isTerminated()) {
      +237:                 synchronized(fTxCommands) {
      +238:                     try {
      +239:                         // Remove comamnd from send queue.
      +240:                         final CommandHandle commandHandle = fTxCommands.take();
      +241:                         
      +242:                         // Send the request to PDA
      +243:                         fRequestWriter.println(commandHandle.fCommand.getRequest());
      +244:                         fRequestWriter.flush();
      +245:                         
      +246:                         try {
      +247:                             // wait for reply
      +248:                             final String response = fRequestReader.readLine();
      +249:                             
      +250:                             // Process the reply in the executor thread.
      +251:                             try {
      +252:                                 getExecutor().execute(new DsfRunnable() {
      +253:                                     public void run() {
      +254:                                         processCommandDone(commandHandle, response);
      +255:                                     }
      +256:                                 });
      +257:                             } catch (RejectedExecutionException e) {
      +258:                                 // Acceptable race condition may see the session shut down
      +259:                                 // while we're waiting for command response.  Still complete
      +260:                                 // the request monitor.
      +261:                                 assert isTerminated();
      +262:                                 assert isTerminated();
      +263:                                 PDAPlugin.failRequest(commandHandle.fRequestMonitor, REQUEST_FAILED, "Command control shut down.");
      +264:                             }
      +265:                         } catch (final IOException e) {
      +266:                             // Process error it in the executor thread
      +267:                             try {
      +268:                                 getExecutor().execute(new DsfRunnable() {
      +269:                                     public void run() {
      +270:                                         processCommandException(commandHandle, e);
      +271:                                     }
      +272:                                 });
      +273:                             } catch (RejectedExecutionException re) {
      +274:                                 // Acceptable race condition... see above
      +275:                                 assert isTerminated();
      +276:                                 PDAPlugin.failRequest(commandHandle.fRequestMonitor, REQUEST_FAILED, "Command control shut down.");
      +277:                             }
      +278:                         }
      +279:                     } catch (InterruptedException e) {
      +280:                         break;  // Shutting down.
      +281:                     }
      +282:                 }
      +283:             }
      +284:             return Status.OK_STATUS;
      +285:         }        
      +286:         
      +287:     }
      +288:     
      +289:     /**
      +290:      * Job that services the PDA event socket.
      +291:      */
      +292:     class EventDispatchJob extends Job {
      +293:         
      +294:         public EventDispatchJob() {
      +295:             super("PDA Event Listner");
      +296:             setSystem(true);
      +297:         }
      +
      +299:         @Override
      +300:         protected IStatus run(IProgressMonitor monitor) {
      +301:             while (!isTerminated()) {
      +302:                 try {
      +303:                     // Wait for an event.
      +304:                     final String event = fEventReader.readLine();
      +305:                     if (event != null) {
      +306:                         try {
      +307:                             // Process the event in executor thread.
      +308:                             getExecutor().execute(new DsfRunnable() {
      +309:                                 public void run() {
      +310:                                     processEventReceived(event);
      +311:                                 }
      +312:                             });
      +313:                         } catch (RejectedExecutionException e) {}                
      +314:                     } else {
      +315:                         break;
      +316:                     }
      +317:                 } catch (IOException e) {
      +318:                     break;
      +319:                 }
      +320:             }
      +321:             if (!isTerminated()) {
      +322:                 // Exception from the event socket is an indicator that the PDA debugger
      +323:                 // has exited.  Call setTerminated() in executor thread.
      +324:                 try {
      +325:                     getExecutor().execute(new DsfRunnable() {
      +326:                         public void run() {
      +327:                             setTerminated();
      +328:                         }
      +329:                     });
      +330:                 } catch (RejectedExecutionException e) {}                
      +331:             }
      +332:             return Status.OK_STATUS;
      +333:         }
      +334:         
      +335:     }
      +336:     
      +337:     public <V extends ICommandResult> void queueCommand(ICommand<V> command, DataRequestMonitor<V> rm) {
      +338:         if (command instanceof AbstractPDACommand<?>) {
      +339:             // Cast from command with "<V extends ICommandResult>" to a more concrete
      +340:             // type to use internally in the command control.
      +341:             @SuppressWarnings("unchecked")
      +342:             AbstractPDACommand<PDACommandResult> pdaCommand = (AbstractPDACommand<PDACommandResult>)command;
      +343:             
      +344:             // Similarly, cast the request monitor to a more concrete type.
      +345:             @SuppressWarnings("unchecked")
      +346:             DataRequestMonitor<PDACommandResult> pdaRM = (DataRequestMonitor<PDACommandResult>)rm;
      +
      +348:             // Add the command to the queue and notify command listeners.
      +349:             fCommandQueue.add( new CommandHandle(pdaCommand, pdaRM) );
      +350:             for (ICommandListener listener : fCommandListeners) {
      +351:                 listener.commandQueued(command);
      +352:             }
      +353:             
      +354:             // In a separate dispatch cycle.  This allows command listeners to repond to the 
      +355:             // command queued event.  
      +356:             getExecutor().execute(new DsfRunnable() {
      +357:                 public void run() {
      +358:                     processQueues();
      +359:                 }
      +360:             });
      +361:             
      +362:         } else {
      +363:             PDAPlugin.failRequest(rm, INTERNAL_ERROR, "Unrecognized command: " + command);
      +364:         }
      +365:     }
      +
      +367:     public void cancelCommand(ICommand<? extends ICommandResult> command) {
      +368:         // This debugger is unable of canceling commands once they have 
      +369:         // been sent.
      +370:     }
      +
      +372:     public void removeCommand(ICommand<? extends ICommandResult> command) {
      +373:         // Removes given command from the queue and notify the listeners
      +374:         for (Iterator<CommandHandle> itr = fCommandQueue.iterator(); itr.hasNext();) {
      +375:             CommandHandle handle = itr.next();
      +376:             if (command.equals(handle.fCommand)) {
      +377:                 itr.remove();
      +378:                 for (ICommandListener listener : fCommandListeners) {
      +379:                     listener.commandRemoved(command);
      +380:                 }                
      +381:             }
      +382:         }
      +383:     }
      +384:     
      +385:     public void addCommandListener(ICommandListener processor) { 
      +386:         fCommandListeners.add(processor); 
      +387:     }
      +388:     
      +389:     public void removeCommandListener(ICommandListener processor) { 
      +390:         fCommandListeners.remove(processor); 
      +391:     }
      +392:     
      +393:     public void addEventListener(IEventListener processor) { 
      +394:         fEventListeners.add(processor); 
      +395:     }
      +396:     
      +397:     public void removeEventListener(IEventListener processor) { 
      +398:         fEventListeners.remove(processor); 
      +399:     }
      +
      +401:     private void processCommandDone(CommandHandle handle, String response) {
      +402:         // Trace to debug output.
      +403:         PDAPlugin.debug("R: " + response);
      +404:         
      +405:         // Given the PDA response string, create the result using the command
      +406:         // that was sent.
      +407:         PDACommandResult result = handle.fCommand.createResult(response);
      +408:         
      +409:         // Set the result to the request monitor and return to sender.
      +410:         // Note: as long as PDA sends some response, a PDA command will never
      +411:         // return an error.
      +412:         handle.fRequestMonitor.setData(result);
      +413:         handle.fRequestMonitor.done();
      +
      +415:         // Notify listeners of the response
      +416:         for (ICommandListener listener : fCommandListeners) {
      +417:             listener.commandDone(handle.fCommand, result);
      +418:         }
      +419:         
      +420:         // Process next command in queue.
      +421:         processQueues();
      +422:     }
      +
      +424:     
      +425:     private void processCommandException(CommandHandle handle, Throwable exception) {
      +426:         
      +427:         // If sending a command resulted in an exception, notify the client.
      +428:         handle.fRequestMonitor.setStatus(new Status(
      +429:             IStatus.ERROR, PDAPlugin.PLUGIN_ID, REQUEST_FAILED, "Exception reading request response", exception));
      +430:         handle.fRequestMonitor.done();                            
      +
      +432:         // Notify listeners also.
      +433:         for (ICommandListener listener : fCommandListeners) {
      +434:             listener.commandDone(handle.fCommand, null);
      +435:         }
      +436:     }
      +
      +438:     private void processEventReceived(String event) {
      +439:         // Notify the listeners only.
      +440:         PDAPlugin.debug("E: " + event);
      +441:         for (IEventListener listener : fEventListeners) {
      +442:             listener.eventReceived(event);
      +443:         }
      +444:     }
      +445:     
      +446:     private synchronized void processQueues() {
      +447:         if (isTerminated()) {
      +448:             // If the PDA debugger is terminated.  Return all submitted commands 
      +449:             // with an error.
      +450:             for (CommandHandle handle : fCommandQueue) {
      +451:                 handle.fRequestMonitor.setStatus(new Status(
      +452:                     IStatus.ERROR, PDAPlugin.PLUGIN_ID, INVALID_STATE, "Command control is terminated", null));
      +453:                 handle.fRequestMonitor.done();
      +454:             }
      +455:             fCommandQueue.clear();
      +456:         } else if (fStarted && fTxCommands.isEmpty() && !fCommandQueue.isEmpty()) {
      +457:             // Process the queues if:
      +458:             // - the PDA debugger has started,
      +459:             // - there are no pending commands in the send queue,
      +460:             // - and there are commands waiting to be sent.
      +461:             CommandHandle handle = fCommandQueue.remove(0); 
      +462:             fTxCommands.add(handle);
      +463:             PDAPlugin.debug("C: " + handle.fCommand.getRequest());
      +464:             for (ICommandListener listener : fCommandListeners) {
      +465:                 listener.commandSent(handle.fCommand);
      +466:             }            
      +467:         }
      +468:     }
      +469:     
      +470:     /**
      +471:      * Return the PDA Debugger top-level Data Model context. 
      +472:      * @see PDAProgramDMContext
      +473:      */
      +474:     @ThreadSafe
      +475:     public PDAProgramDMContext getProgramDMContext() {
      +476:         return fDMContext;
      +477:     }
      +
      +479:     private void setStarted() {
      +480:         // Mark the command control as started and ready to process commands.
      +481:         fStarted = true;
      +482:         
      +483:         // Process any commands which may have been queued before the 
      +484:         processQueues();
      +
      +486:         // Issue a data model event.
      +487:         getSession().dispatchEvent(new PDAStartedEvent(getProgramDMContext()), getProperties());
      +488:     }
      +489:     
      +490:     /**
      +491:      * Returns whether the PDA debugger has started and is processing commands.
      +492:      */
      +493:     public boolean isStarted() {
      +494:         return fStarted;
      +495:     }
      +496:     
      +497:     @ThreadSafe
      +498:     private synchronized void setTerminated() {
      +499:         // Set terminated may be called more than once: by event listener thread, 
      +500:         // by the terminate command, etc, so protect against sending events multiple
      +501:         // times.
      +502:         if (!fTerminated) {
      +503:             fTerminated = true;
      +504:             
      +505:             // Process any waiting commands, they all should return with an error.
      +506:             processQueues();
      +507:             
      +508:             // Issue a data model event.
      +509:             getSession().dispatchEvent(new PDATerminatedEvent(getProgramDMContext()), getProperties());
      +510:         }
      +511:     }
      +
      +513:     /**
      +514:      * Returns whether the PDA debugger has been terminated.
      +515:      */
      +516:     @ThreadSafe
      +517:     public synchronized boolean isTerminated() {
      +518:         return fTerminated;
      +519:     }
      +
      +521:     /**
      +522:      * Sends a command to PDA debugger to terminate.
      +523:      */
      +524:     public void terminate(RequestMonitor rm) {
      +525:         if (!isTerminated()) {
      +526:             queueCommand(
      +527:                 new PDAExitCommand(fDMContext),
      +528:                 new DataRequestMonitor<PDACommandResult>(getExecutor(), rm));
      +529:         } else {
      +530:             // If already terminated, indicate success.
      +531:             rm.done();
      +532:         }
      +533:     }    
      +534: }
      +
      + + + diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAExpressions.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAExpressions.java.html new file mode 100644 index 00000000000..8292629dd69 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAExpressions.java.html @@ -0,0 +1,386 @@ + + + +PDAExpressions.java + + + + + +
        1: /*******************************************************************************
      +  2:  * Copyright (c) 2008 Wind River Systems and others.
      +  3:  * All rights reserved. This program and the accompanying materials
      +  4:  * are made available under the terms of the Eclipse Public License v1.0
      +  5:  * which accompanies this distribution, and is available at
      +  6:  * http://www.eclipse.org/legal/epl-v10.html
      +  7:  * 
      +  8:  * Contributors:
      +  9:  *     Wind River Systems - initial API and implementation
      + 10:  *******************************************************************************/
      + 11: package org.eclipse.dd.examples.pda.service;
      +
      + 13: import java.util.Hashtable;
      + 14: import java.util.Map;
      +
      + 16: import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
      + 17: import org.eclipse.dd.dsf.concurrent.Immutable;
      + 18: import org.eclipse.dd.dsf.concurrent.RequestMonitor;
      + 19: import org.eclipse.dd.dsf.datamodel.AbstractDMContext;
      + 20: import org.eclipse.dd.dsf.datamodel.AbstractDMEvent;
      + 21: import org.eclipse.dd.dsf.datamodel.DMContexts;
      + 22: import org.eclipse.dd.dsf.datamodel.IDMContext;
      + 23: import org.eclipse.dd.dsf.debug.service.IExpressions;
      + 24: import org.eclipse.dd.dsf.debug.service.IStack;
      + 25: import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext;
      + 26: import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent;
      + 27: import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent;
      + 28: import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason;
      + 29: import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext;
      + 30: import org.eclipse.dd.dsf.debug.service.command.CommandCache;
      + 31: import org.eclipse.dd.dsf.service.AbstractDsfService;
      + 32: import org.eclipse.dd.dsf.service.DsfServiceEventHandler;
      + 33: import org.eclipse.dd.dsf.service.DsfSession;
      + 34: import org.eclipse.dd.examples.pda.PDAPlugin;
      + 35: import org.eclipse.dd.examples.pda.service.commands.PDACommandResult;
      + 36: import org.eclipse.dd.examples.pda.service.commands.PDASetVarCommand;
      + 37: import org.eclipse.dd.examples.pda.service.commands.PDAVarCommand;
      + 38: import org.osgi.framework.BundleContext;
      +
      + 40: /**
      + 41:  * 
      + 42:  */
      + 43: public class PDAExpressions extends AbstractDsfService implements IExpressions {
      +
      + 45:     @Immutable
      + 46:     private static class ExpressionDMContext extends AbstractDMContext implements IExpressionDMContext {
      +
      + 48:         final private String fExpression;
      + 49:         
      + 50:         ExpressionDMContext(String sessionId, IFrameDMContext frameDmc, String expressin) {
      + 51:             super(sessionId, new IDMContext[] { frameDmc });
      + 52:             fExpression = expressin;
      + 53:         }
      +
      + 55:         public String getExpression() { 
      + 56:             return fExpression;
      + 57:         }
      + 58:         
      + 59:         @Override
      + 60:         public boolean equals(Object other) {
      + 61:             return super.baseEquals(other) && ((ExpressionDMContext)other).fExpression.equals(fExpression);
      + 62:         }
      + 63:         
      + 64:         @Override
      + 65:         public int hashCode() {
      + 66:             return super.baseHashCode() + fExpression.hashCode();
      + 67:         }
      + 68:         
      + 69:         @Override
      + 70:         public String toString() { 
      + 71:             return baseToString() + ".expression(" + fExpression + ")";  
      + 72:         }
      + 73:     }
      +
      + 75:     /**
      + 76:      * PDA expressions are simply variables.  Only the variable name 
      + 77:      * is relevant for its data.
      + 78:      */
      + 79:     @Immutable
      + 80:     private static class ExpressionDMData implements IExpressionDMData {
      +
      + 82:         final private String fExpression;
      + 83:         
      + 84:         public ExpressionDMData(String expression) {
      + 85:             fExpression = expression;
      + 86:         }
      + 87:         
      + 88:         public BasicType getBasicType() {
      + 89:             return BasicType.basic;
      + 90:         }
      +
      + 92:         public String getEncoding() {
      + 93:             return null;
      + 94:         }
      +
      + 96:         public Map<String, Integer> getEnumerations() {
      + 97:             return null;
      + 98:         }
      +
      +100:         public String getName() {
      +101:             return fExpression;
      +102:         }
      +
      +104:         public IRegisterDMContext getRegister() {
      +105:             return null;
      +106:         }
      +
      +108:         public String getStringValue() {
      +109:             return null;
      +110:         }
      +
      +112:         public String getTypeId() {
      +113:             return null;
      +114:         }
      +
      +116:         public String getTypeName() {
      +117:             return null;
      +118:         }
      +
      +120:     }
      +
      +122:     // @see #createExpression()
      +123:     @Immutable
      +124:     private static class InvalidExpressionDMContext extends AbstractDMContext implements IExpressionDMContext {
      +125:         final private String fExpression;
      +126:     
      +127:         public InvalidExpressionDMContext(String sessionId, IDMContext parent, String expr) {
      +128:             super(sessionId, new IDMContext[] { parent });
      +129:             fExpression = expr;
      +130:         }
      +131:     
      +132:         @Override
      +133:         public boolean equals(Object other) {
      +134:             return super.baseEquals(other) && 
      +135:                 fExpression == null 
      +136:                     ? ((InvalidExpressionDMContext) other).getExpression() == null 
      +137:                     : fExpression.equals(((InvalidExpressionDMContext) other).getExpression());
      +138:         }
      +139:     
      +140:         @Override
      +141:         public int hashCode() {
      +142:             return fExpression == null ? super.baseHashCode() : super.baseHashCode() ^ fExpression.hashCode();
      +143:         }
      +144:     
      +145:         @Override
      +146:         public String toString() {
      +147:             return baseToString() + ".invalid_expr[" + fExpression + "]"; 
      +148:         }
      +149:     
      +150:         public String getExpression() {
      +151:             return fExpression;
      +152:         }
      +153:     }
      +154:     
      +155:     @Immutable
      +156:     private static class ExpressionChangedDMEvent extends AbstractDMEvent<IExpressionDMContext> 
      +157:         implements IExpressionChangedDMEvent 
      +158:     {
      +159:         ExpressionChangedDMEvent(IExpressionDMContext expression) {
      +160:             super(expression);
      +161:         }
      +162:     }
      +
      +164:     
      +165:     private PDACommandControl fCommandControl;
      +166:     private IStack fStack;
      +
      +168:     private CommandCache fCommandCache;
      +
      +170:     public PDAExpressions(DsfSession session) {
      +171:         super(session);
      +172:     }
      +
      +174:     @Override
      +175:     protected BundleContext getBundleContext() {
      +176:         return PDAPlugin.getBundleContext();
      +177:     }
      +
      +179:     @Override
      +180:     public void initialize(final RequestMonitor rm) {
      +181:         super.initialize(
      +182:             new RequestMonitor(getExecutor(), rm) { 
      +183:                 @Override
      +184:                 protected void handleOK() {
      +185:                     doInitialize(rm);
      +186:                 }});
      +187:     }
      +
      +189:     private void doInitialize(final RequestMonitor rm) {
      +190:         fCommandControl = getServicesTracker().getService(PDACommandControl.class);
      +191:         fStack = getServicesTracker().getService(IStack.class);
      +192:         fCommandCache = new CommandCache(fCommandControl);
      +
      +194:         getSession().addServiceEventListener(this, null);
      +195:         
      +196:         register(new String[]{IExpressions.class.getName(), PDAExpressions.class.getName()}, new Hashtable<String,String>());
      +197:         
      +198:         rm.done();
      +199:     }
      +
      +201:     @Override
      +202:     public void shutdown(final RequestMonitor rm) {
      +203:         getSession().removeServiceEventListener(this);
      +204:         fCommandCache.reset();
      +205:         super.shutdown(rm);
      +206:     }
      +
      +208:     public void canWriteExpression(IExpressionDMContext expressionContext, DataRequestMonitor<Boolean> rm) {
      +209:         rm.setData(true);
      +210:         rm.done();
      +211:     }
      +
      +213:     public IExpressionDMContext createExpression(IDMContext ctx, String expression) {
      +214:         // Create an expression based on the given context and string expression.  
      +215:         // The PDA debugger can only evaluate variables as expressions and only
      +216:         // in context of a frame.  
      +217:         IFrameDMContext frameCtx = DMContexts.getAncestorOfType(ctx, IFrameDMContext.class);
      +218:         if (frameCtx != null) {
      +219:             return new ExpressionDMContext(getSession().getId(), frameCtx, expression);
      +220:         } else {
      +221:             // If a frame cannot be found in context, return an "invalid" 
      +222:             // expression context, because a null return value is not allowed.
      +223:             // Evaluating an invalid expression context will always yield an 
      +224:             // error.
      +225:             return new InvalidExpressionDMContext(getSession().getId(), ctx, expression);
      +226:         }
      +227:     }
      +
      +229:     public void getBaseExpressions(IExpressionDMContext exprContext, DataRequestMonitor<IExpressionDMContext[]> rm) {
      +230:         PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Not supported");
      +231:     }
      +
      +233:     public void getExpressionAddressData(IExpressionDMContext dmc, DataRequestMonitor<IExpressionDMAddress> rm) {
      +234:         PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Not supported");
      +235:     }
      +
      +237:     public void getExpressionData(final IExpressionDMContext exprCtx, final DataRequestMonitor<IExpressionDMData> rm) {
      +238:         // Since expression data doesn't contain any more information than the 
      +239:         // context, it doesn't require any debugger commmands.
      +240:         if (exprCtx instanceof ExpressionDMContext) {
      +241:             rm.setData(new ExpressionDMData(exprCtx.getExpression()));
      +242:             rm.done();
      +243:         } else {
      +244:             PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid expression context " + exprCtx);
      +245:         }
      +246:     }
      +
      +248:     public void getSubExpressionCount(IExpressionDMContext exprCtx, DataRequestMonitor<Integer> rm) {
      +249:         PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Not supported");
      +250:     }
      +
      +252:     public void getSubExpressions(IExpressionDMContext exprCtx, DataRequestMonitor<IExpressionDMContext[]> rm) {
      +253:         PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Not supported");
      +254:     }
      +
      +256:     public void getSubExpressions(IExpressionDMContext exprCtx, int startIndex, int length,
      +257:         DataRequestMonitor<IExpressionDMContext[]> rm) 
      +258:     {
      +259:         PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Not supported");
      +260:     }
      +
      +262:     public void getAvailableFormats(IFormattedDataDMContext dmc, DataRequestMonitor<String[]> rm) {
      +263:         // PDA debugger doesn't support formatting the expression.  Natural 
      +264:         // formatting is the only available option.
      +265:         rm.setData(new String[] { NATURAL_FORMAT });
      +266:         rm.done();
      +267:     }
      +
      +269:     public FormattedValueDMContext getFormattedValueContext(IFormattedDataDMContext exprCtx, String formatId) {
      +270:         // Creates a context that can be used to retrieve a formatted value.
      +271:         return new FormattedValueDMContext(this, exprCtx, formatId);
      +272:     }
      +
      +274:     public void getFormattedExpressionValue(FormattedValueDMContext formattedCtx, 
      +275:         final DataRequestMonitor<FormattedValueDMData> rm) 
      +276:     {
      +277:         final ExpressionDMContext exprCtx = DMContexts.getAncestorOfType(formattedCtx, ExpressionDMContext.class);
      +278:         if (exprCtx != null) {
      +279:             final IFrameDMContext frameCtx = DMContexts.getAncestorOfType(exprCtx, IFrameDMContext.class);
      +280:             
      +281:             // First retrieve the stack depth, needed to properly calculate
      +282:             // the frame index that is used by the PDAVarCommand. 
      +283:             fStack.getStackDepth(
      +284:                 frameCtx, 0,
      +285:                 new DataRequestMonitor<Integer>(getExecutor(), rm) {
      +286:                     @Override
      +287:                     protected void handleOK() {
      +288:                         // Calculate the frame index.
      +289:                         int frameId = getData() - frameCtx.getLevel() - 1;
      +290:                         
      +291:                         // Send the command to evaluate the variable.
      +292:                         fCommandCache.execute(
      +293:                             new PDAVarCommand(fCommandControl.getProgramDMContext(), frameId, exprCtx.getExpression()), 
      +294:                             new DataRequestMonitor<PDACommandResult>(getExecutor(), rm) {
      +295:                                 @Override
      +296:                                 protected void handleOK() {
      +297:                                     rm.setData(new FormattedValueDMData(getData().fResponseText));
      +298:                                     rm.done();
      +299:                                 }
      +300:                             });        
      +301:                     }
      +302:                 });
      +303:         } else {
      +304:             PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid expression context " + formattedCtx);
      +305:             rm.done();
      +306:         }
      +307:     }
      +
      +309:     public void writeExpression(final IExpressionDMContext exprCtx, final String exprValue, String formatId, 
      +310:         final RequestMonitor rm) 
      +311:     {
      +312:         if (exprCtx instanceof ExpressionDMContext) {
      +313:             final IFrameDMContext frameCtx = DMContexts.getAncestorOfType(exprCtx, IFrameDMContext.class);
      +314:             
      +315:             // Similarly to retrieving the variable, retrieve the 
      +316:             // stack depth first.
      +317:             fStack.getStackDepth(
      +318:                 frameCtx, 0,
      +319:                 new DataRequestMonitor<Integer>(getExecutor(), rm) {
      +320:                     @Override
      +321:                     protected void handleOK() {
      +322:                         // Calculate the frame index.
      +323:                         int frameId = getData() - frameCtx.getLevel() - 1;
      +324:                         
      +325:                         // Send the "write" command to PDA debugger
      +326:                         fCommandCache.execute(
      +327:                             new PDASetVarCommand(fCommandControl.getProgramDMContext(), frameId, exprCtx.getExpression(), exprValue), 
      +328:                             new DataRequestMonitor<PDACommandResult>(getExecutor(), rm) {
      +329:                                 @Override
      +330:                                 protected void handleOK() {
      +331:                                     getSession().dispatchEvent(new ExpressionChangedDMEvent(exprCtx), getProperties());
      +332:                                     rm.done();
      +333:                                 }
      +334:                             });
      +335:                     }
      +336:                 });
      +337:         } else {
      +338:             PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid expression context " + exprCtx);
      +339:             rm.done();
      +340:         }
      +341:     }
      +
      +343:     @SuppressWarnings("unchecked")
      +344:     @Deprecated
      +345:     public void getModelData(IDMContext dmc, DataRequestMonitor<?> rm) {
      +346:         if (dmc instanceof IExpressionDMContext) {
      +347:             getExpressionData((IExpressionDMContext) dmc, (DataRequestMonitor<IExpressionDMData>) rm);
      +348:         } else if (dmc instanceof FormattedValueDMContext) {
      +349:             getFormattedExpressionValue((FormattedValueDMContext) dmc, (DataRequestMonitor<FormattedValueDMData>) rm);
      +350:         } else {
      +351:             PDAPlugin.failRequest(rm, INVALID_HANDLE, "Unknown DMC type");
      +352:             rm.done();
      +353:         }
      +354:     }
      +
      +356:     @DsfServiceEventHandler 
      +357:     public void eventDispatched(IResumedDMEvent e) {
      +358:         // Mark the cache as not available, so that data retrieval commands 
      +359:         // will fail.  Also reset the cache unless it was a step command.
      +360:         fCommandCache.setTargetAvailable(false);
      +361:         if (!e.getReason().equals(StateChangeReason.STEP)) {
      +362:             fCommandCache.reset();
      +363:         }
      +364:     }    
      +
      +
      +367:     @DsfServiceEventHandler 
      +368:     public void eventDispatched(ISuspendedDMEvent e) {
      +369:         // Enable sending commands to target and clear the cache.
      +370:         fCommandCache.setTargetAvailable(true);
      +371:         fCommandCache.reset();
      +372:     }
      +373: }
      +
      + + + diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java index 62a59002dfa..bf4fbedf66b 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java @@ -182,7 +182,7 @@ public class PDARunControl extends AbstractDsfService if (!(output instanceof String)) return; String event = (String)output; - // Handle PDA debugger suspende/resumed events and issue the + // Handle PDA debugger suspended/resumed events and issue the // corresponding Data Model events. Do not update the state // information until we start dispatching the service events. if (event.startsWith("suspended")) { @@ -248,6 +248,7 @@ public class PDARunControl extends AbstractDsfService // If the resume command failed, we no longer // expect to receive a resumed event. fResumePending = false; + super.handleErrorOrCancel(); } } ); diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java.html new file mode 100644 index 00000000000..00690033f51 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java.html @@ -0,0 +1,330 @@ + + + +PDARunControl.java + + + + + +
        1: /*******************************************************************************
      +  2:  * Copyright (c) 2006 Wind River Systems and others.
      +  3:  * All rights reserved. This program and the accompanying materials
      +  4:  * are made available under the terms of the Eclipse Public License v1.0
      +  5:  * which accompanies this distribution, and is available at
      +  6:  * http://www.eclipse.org/legal/epl-v10.html
      +  7:  * 
      +  8:  * Contributors:
      +  9:  *     Wind River Systems - initial API and implementation
      + 10:  *     Ericsson        AB                  - Modified for handling of multiple threads
      + 11:  *******************************************************************************/
      + 12: package org.eclipse.dd.examples.pda.service;
      +
      + 14: import java.util.Hashtable;
      +
      + 16: import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
      + 17: import org.eclipse.dd.dsf.concurrent.Immutable;
      + 18: import org.eclipse.dd.dsf.concurrent.RequestMonitor;
      + 19: import org.eclipse.dd.dsf.datamodel.AbstractDMEvent;
      + 20: import org.eclipse.dd.dsf.datamodel.IDMContext;
      + 21: import org.eclipse.dd.dsf.datamodel.IDMEvent;
      + 22: import org.eclipse.dd.dsf.debug.service.IRunControl;
      + 23: import org.eclipse.dd.dsf.debug.service.command.IEventListener;
      + 24: import org.eclipse.dd.dsf.service.AbstractDsfService;
      + 25: import org.eclipse.dd.dsf.service.DsfServiceEventHandler;
      + 26: import org.eclipse.dd.dsf.service.DsfSession;
      + 27: import org.eclipse.dd.dsf.service.IDsfService;
      + 28: import org.eclipse.dd.examples.pda.PDAPlugin;
      + 29: import org.eclipse.dd.examples.pda.service.commands.PDACommandResult;
      + 30: import org.eclipse.dd.examples.pda.service.commands.PDAResumeCommand;
      + 31: import org.eclipse.dd.examples.pda.service.commands.PDAStepCommand;
      + 32: import org.eclipse.dd.examples.pda.service.commands.PDASuspendCommand;
      + 33: import org.osgi.framework.BundleContext;
      +
      +
      + 36: /**
      + 37:  * Service for monitoring and controlling execution state of the DPA 
      + 38:  * program.
      + 39:  * <p>
      + 40:  * This service depends on the {@link PDACommandControl} service.
      + 41:  * It must be initialized before this service is initialized.
      + 42:  * </p>
      + 43:  */
      + 44: public class PDARunControl extends AbstractDsfService 
      + 45:     implements IRunControl, IEventListener
      + 46: {
      + 47:     // Implementation note about tracking execution state:
      + 48:     // This class implements event handlers for the events that are generated by 
      + 49:     // this service itself.  When the event is dispatched, these handlers will
      + 50:     // be called first, before any of the clients.  These handlers update the 
      + 51:     // service's internal state information to make them consistent with the 
      + 52:     // events being issued.  Doing this in the handlers as opposed to when 
      + 53:     // the events are generated, guarantees that the state of the service will
      + 54:     // always be consistent with the events.
      + 55:     // The purpose of this pattern is to allow clients that listen to service 
      + 56:     // events and track service state, to be perfectly in sync with the service
      + 57:     // state.
      + 58:     
      + 59:     @Immutable 
      + 60:     private static class ExecutionDMData implements IExecutionDMData {
      + 61:         private final StateChangeReason fReason;
      + 62:         ExecutionDMData(StateChangeReason reason) {
      + 63:             fReason = reason;
      + 64:         }
      + 65:         public StateChangeReason getStateChangeReason() { return fReason; }
      + 66:     }
      + 67:     
      + 68:     @Immutable 
      + 69:     private static class ResumedEvent extends AbstractDMEvent<IExecutionDMContext> 
      + 70:         implements IResumedDMEvent
      + 71:     {
      + 72:         private final String fPDAEvent;
      +
      + 74:         ResumedEvent(IExecutionDMContext ctx, String pdaEvent) { 
      + 75:             super(ctx);
      + 76:             fPDAEvent = pdaEvent;
      + 77:         }
      + 78:         
      + 79:         public StateChangeReason getReason() {
      + 80:             if (fPDAEvent.startsWith("resumed breakpoint") || fPDAEvent.startsWith("suspended watch")) {
      + 81:                 return StateChangeReason.BREAKPOINT;
      + 82:             } else if (fPDAEvent.equals("resumed step") || fPDAEvent.equals("resumed drop")) {
      + 83:                 return StateChangeReason.STEP;
      + 84:             } else if (fPDAEvent.equals("resumed client")) {
      + 85:                 return StateChangeReason.USER_REQUEST;
      + 86:             } else {
      + 87:                 return StateChangeReason.UNKNOWN;
      + 88:             } 
      + 89:         }
      + 90:     }
      + 91:     
      + 92:     @Immutable
      + 93:     private static class SuspendedEvent extends AbstractDMEvent<IExecutionDMContext> 
      + 94:         implements ISuspendedDMEvent
      + 95:     {
      + 96:         private final String fPDAEvent;
      + 97:         
      + 98:         SuspendedEvent(IExecutionDMContext ctx, String pdaEvent) { 
      + 99:             super(ctx);
      +100:             fPDAEvent = pdaEvent;
      +101:         }
      +102:         
      +103:         public StateChangeReason getReason() {
      +104:             if (fPDAEvent.startsWith("suspended breakpoint") || fPDAEvent.startsWith("suspended watch")) {
      +105:                 return StateChangeReason.BREAKPOINT;
      +106:             } else if (fPDAEvent.equals("suspended step") || fPDAEvent.equals("suspended drop")) {
      +107:                 return StateChangeReason.STEP;
      +108:             } else if (fPDAEvent.equals("suspended client")) {
      +109:                 return StateChangeReason.USER_REQUEST;
      +110:             } else {
      +111:                 return StateChangeReason.UNKNOWN;
      +112:             } 
      +113:         }
      +114:     }
      +
      +116:     // Services 
      +117:     private PDACommandControl fCommandControl;
      +118:     
      +119:     // State flags
      +120:         private boolean fSuspended = true;
      +121:     private boolean fResumePending = false;
      +122:         private boolean fStepping = false;
      +123:         private StateChangeReason fStateChangeReason;
      +124:         
      +125:     public PDARunControl(DsfSession session) {
      +126:         super(session);
      +127:     }
      +128:     
      +129:     @Override
      +130:     protected BundleContext getBundleContext() {
      +131:         return PDAPlugin.getBundleContext();
      +132:     }
      +133:     
      +134:     @Override
      +135:     public void initialize(final RequestMonitor rm) {
      +136:         super.initialize(
      +137:             new RequestMonitor(getExecutor(), rm) { 
      +138:                 @Override
      +139:                 protected void handleOK() {
      +140:                     doInitialize(rm);
      +141:                 }});
      +142:     }
      +
      +144:     private void doInitialize(final RequestMonitor rm) {
      +145:         fCommandControl = getServicesTracker().getService(PDACommandControl.class);
      +
      +147:         // Add ourselves as a listener to PDA events, to catch suspended/resumed 
      +148:         // events.
      +149:         fCommandControl.addEventListener(this);
      +150:         
      +151:         // Add ourselves as a listener to service events, in order to process
      +152:         // our own suspended/resumed events.
      +153:         getSession().addServiceEventListener(this, null);
      +154:         
      +155:         // Register the service with OSGi
      +156:         register(new String[]{IRunControl.class.getName(), PDARunControl.class.getName()}, new Hashtable<String,String>());
      +157:         
      +158:         rm.done();
      +159:     }
      +
      +161:     @Override
      +162:     public void shutdown(final RequestMonitor rm) {
      +163:         fCommandControl.removeEventListener(this);
      +164:         getSession().removeServiceEventListener(this);
      +165:         super.shutdown(rm);
      +166:     }
      +167:     
      +168:     @Deprecated
      +169:     @SuppressWarnings("unchecked")
      +170:     public void getModelData(IDMContext dmc, DataRequestMonitor<?> rm) {
      +171:         // The getModelData() is deprecated and clients are expected to switch
      +172:         // to getExecutionData() and other data retrieve methods directly.
      +173:         // However the UI cache still uses it for now.
      +174:         if (dmc instanceof IExecutionDMContext) {
      +175:             getExecutionData((IExecutionDMContext)dmc, (DataRequestMonitor<IExecutionDMData>)rm); 
      +176:         } else {
      +177:             PDAPlugin.failRequest(rm, INVALID_HANDLE, "Unknown DMC type");
      +178:         }
      +179:     }
      +180:     
      +181:     public void eventReceived(Object output) {
      +182:         if (!(output instanceof String)) return;
      +183:         String event = (String)output;
      +184:         
      +185:         // Handle PDA debugger suspended/resumed events and issue the 
      +186:         // corresponding Data Model events.  Do not update the state
      +187:         // information until we start dispatching the service events.
      +188:         if (event.startsWith("suspended")) {
      +189:             IDMEvent<?> dmEvent = new SuspendedEvent(fCommandControl.getProgramDMContext(), event);
      +190:             getSession().dispatchEvent(dmEvent, getProperties());
      +191:         } else if (event.startsWith("resumed")) {
      +192:             IDMEvent<?> dmEvent = new ResumedEvent(fCommandControl.getProgramDMContext(), event);
      +193:             getSession().dispatchEvent(dmEvent, getProperties());
      +194:         }
      +195:     }
      +196:     
      +197:     
      +198:     @DsfServiceEventHandler 
      +199:     public void eventDispatched(ResumedEvent e) {
      +200:         // This service should be the first to receive the ResumedEvent, 
      +201:         // (before any other listeners are called).  Here, update the
      +202:         // service state information based on the the resumed event.
      +203:         fSuspended = false;
      +204:         fResumePending = false;
      +205:         fStateChangeReason = e.getReason();
      +206:         fStepping = e.getReason().equals(StateChangeReason.STEP);
      +207:     }    
      +
      +
      +210:     @DsfServiceEventHandler 
      +211:     public void eventDispatched(SuspendedEvent e) {
      +212:         // This service should be the first to receive the SuspendedEvent also, 
      +213:         // (before any other listeners are called).  Here, update the
      +214:         // service state information based on the the suspended event.
      +215:         fStateChangeReason = e.getReason();
      +216:         fResumePending = false;
      +217:         fSuspended = true;
      +218:         fStepping = false;
      +219:     }
      +220:     
      +221:     
      +222:         public boolean canResume(IExecutionDMContext context) {
      +223:         return isSuspended(context) && !fResumePending;
      +224:         }
      +
      +226:         public boolean canSuspend(IExecutionDMContext context) {
      +227:         return !isSuspended(context);
      +228:         }
      +
      +230:         public boolean isSuspended(IExecutionDMContext context) {
      +231:                 return fSuspended;
      +232:         }
      +
      +234:         public boolean isStepping(IExecutionDMContext context) {
      +235:             return !isSuspended(context) && fStepping;
      +236:     }
      +
      +238:         public void resume(IExecutionDMContext context, final RequestMonitor rm) {
      +239:                 assert context != null;
      +
      +241:                 if (canResume(context)) { 
      +242:             fResumePending = true;
      +243:             fCommandControl.queueCommand(
      +244:                     new PDAResumeCommand(fCommandControl.getProgramDMContext()),
      +245:                     new DataRequestMonitor<PDACommandResult>(getExecutor(), rm) { 
      +246:                     @Override
      +247:                     protected void handleErrorOrCancel() {
      +248:                         // If the resume command failed, we no longer
      +249:                         // expect to receive a resumed event.
      +250:                         fResumePending = false;
      +251:                     }
      +252:                     }
      +253:             );
      +254:         }else {
      +255:             PDAPlugin.failRequest(rm, INVALID_STATE, "Given context: " + context + ", is already running.");
      +256:         }
      +257:         }
      +258:         
      +259:         public void suspend(IExecutionDMContext context, final RequestMonitor rm){
      +260:                 assert context != null;
      +
      +262:                 if (canSuspend(context)) {
      +263:             fCommandControl.queueCommand(
      +264:                 new PDASuspendCommand(fCommandControl.getProgramDMContext()),
      +265:                 new DataRequestMonitor<PDACommandResult>(getExecutor(), rm));
      +266:             
      +267:         } else {
      +268:             PDAPlugin.failRequest(rm, IDsfService.INVALID_STATE, "Given context: " + context + ", is already suspended."); 
      +269:         }
      +270:     }
      +271:     
      +272:     public boolean canStep(IExecutionDMContext context) {
      +273:         return canResume(context);
      +274:     }
      +275:     
      +276:     public void step(IExecutionDMContext context, StepType stepType, final RequestMonitor rm) {
      +277:             assert context != null;
      +278:             
      +279:             if (canResume(context)) {
      +280:             fResumePending = true;
      +281:             fStepping = true;
      +
      +283:             fCommandControl.queueCommand(
      +284:                 new PDAStepCommand(fCommandControl.getProgramDMContext()),
      +285:                 new DataRequestMonitor<PDACommandResult>(getExecutor(), rm) {
      +286:                     @Override
      +287:                     protected void handleErrorOrCancel() {
      +288:                         // If the step command failed, we no longer
      +289:                         // expect to receive a resumed event.
      +290:                         fResumePending = false;
      +291:                         fStepping = false;
      +292:                     }
      +293:                 });
      +
      +295:             } else {
      +296:             PDAPlugin.failRequest(rm, INVALID_STATE, "Cannot resume context"); 
      +297:             return;
      +298:         }
      +299:     }
      +
      +301:     public boolean canInstructionStep(IExecutionDMContext context) {
      +302:         return false;
      +303:     }
      +304:     
      +305:     public void instructionStep(IExecutionDMContext context, StepType stepType, RequestMonitor rm) {
      +306:         PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Operation not implemented"); 
      +307:     }
      +
      +309:     public void getExecutionContexts(final IContainerDMContext containerDmc, final DataRequestMonitor<IExecutionDMContext[]> rm) {
      +310:         PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Operation not implemented"); 
      +311:     }
      +312:     
      +313:         public void getExecutionData(IExecutionDMContext dmc, DataRequestMonitor<IExecutionDMData> rm){
      +314:         rm.setData( new ExecutionDMData(fStateChangeReason) );
      +315:         rm.done();
      +316:     }
      +317: }
      +
      + + + diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java index f85e2f9e52f..6aa231cc771 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java @@ -54,24 +54,24 @@ public class PDAStack extends AbstractDsfService implements IStack { private static class FrameDMContext extends AbstractDMContext implements IFrameDMContext { final private int fLevel; - + FrameDMContext(String sessionId, IExecutionDMContext execDmc, int level) { super(sessionId, new IDMContext[] { execDmc }); fLevel = level; } public int getLevel() { return fLevel; } - + @Override public boolean equals(Object other) { return super.baseEquals(other) && ((FrameDMContext)other).fLevel == fLevel; } - + @Override public int hashCode() { return super.baseHashCode() ^ fLevel; } - + @Override public String toString() { return baseToString() + ".frame[" + fLevel + "]"; //$NON-NLS-1$ //$NON-NLS-2$ @@ -85,11 +85,11 @@ public class PDAStack extends AbstractDsfService implements IStack { private static class FrameDMData implements IFrameDMData { final private PDAFrame fFrame; - + FrameDMData(PDAFrame frame) { fFrame = frame; } - + public String getFile() { return fFrame.fFilePath.lastSegment(); } @@ -118,24 +118,24 @@ public class PDAStack extends AbstractDsfService implements IStack { private static class VariableDMContext extends AbstractDMContext implements IVariableDMContext { final private String fVariable; - + VariableDMContext(String sessionId, IFrameDMContext frameCtx, String variable) { super(sessionId, new IDMContext[] { frameCtx }); fVariable = variable; - } - + } + String getVariable() { return fVariable; } - + @Override public boolean equals(Object other) { return super.baseEquals(other) && ((VariableDMContext)other).fVariable.equals(fVariable); } - + @Override public int hashCode() { return super.baseHashCode() + fVariable.hashCode(); } - + @Override public String toString() { return baseToString() + ".variable(" + fVariable + ")"; //$NON-NLS-1$ //$NON-NLS-2$ @@ -149,11 +149,11 @@ public class PDAStack extends AbstractDsfService implements IStack { private static class VariableDMData implements IVariableDMData { final private String fVariable; - + VariableDMData(String variable) { fVariable = variable; } - + public String getName() { return fVariable; } @@ -193,16 +193,16 @@ public class PDAStack extends AbstractDsfService implements IStack { // Initialize service references that stack service depends on fCommandControl = getServicesTracker().getService(PDACommandControl.class); fRunControl = getServicesTracker().getService(IRunControl.class); - + // Create the commands cache fCommandCache = new CommandCache(fCommandControl); // Register to listen for run control events, to clear cache accordingly. getSession().addServiceEventListener(this, null); - + // Register stack service with OSGi register(new String[]{IStack.class.getName(), PDAStack.class.getName()}, new Hashtable()); - + rm.done(); } @@ -213,7 +213,7 @@ public class PDAStack extends AbstractDsfService implements IStack { super.shutdown(rm); } - + public void getArguments(IFrameDMContext frameCtx, DataRequestMonitor rm) { PDAPlugin.failRequest(rm, IDsfService.NOT_SUPPORTED, "PDA debugger does not support function arguments."); } @@ -232,7 +232,7 @@ public class PDAStack extends AbstractDsfService implements IStack { PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid frame level " + frameCtx); return; } - + // Create the frame data object based on the corresponding PDAFrame rm.setData(new FrameDMData(getData().fFrames[frameId])); rm.done(); @@ -240,7 +240,7 @@ public class PDAStack extends AbstractDsfService implements IStack { }); } - + public void getFrames(IDMContext context, final DataRequestMonitor rm) { // Can only create stack frames for an execution context as a parent, // however the argument context is a generic context type, so it could @@ -251,7 +251,7 @@ public class PDAStack extends AbstractDsfService implements IStack { PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid context " + context); return; } - + // Execute the stack command and create the corresponding frame contexts. fCommandCache.execute( new PDAStackCommand(fCommandControl.getProgramDMContext()), @@ -282,7 +282,7 @@ public class PDAStack extends AbstractDsfService implements IStack { return; } PDAFrame pdaFrame = getData().fFrames[frameId]; - + // Create variable contexts for all variables in frame. IVariableDMContext[] variableCtxs = new IVariableDMContext[pdaFrame.fVariables.length]; for (int i = 0; i < pdaFrame.fVariables.length; i++) { @@ -334,7 +334,7 @@ public class PDAStack extends AbstractDsfService implements IStack { // The variable data doen't contain a value. So there's no need to // go to the back end to retrieve it. String variable = ((VariableDMContext)variableCtx).getVariable(); - + rm.setData(new VariableDMData(variable)); rm.done(); } @@ -359,7 +359,7 @@ public class PDAStack extends AbstractDsfService implements IStack { PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Unknown context type"); } } - + @DsfServiceEventHandler public void eventDispatched(IResumedDMEvent e) { // Mark the cache as not available, so that stack commands will diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java.html new file mode 100644 index 00000000000..efa44c42c84 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java.html @@ -0,0 +1,393 @@ + + + +PDAStack.java + + + + + +
        1: /*******************************************************************************
      +  2:  * Copyright (c) 2008 Wind River Systems and others.
      +  3:  * All rights reserved. This program and the accompanying materials
      +  4:  * are made available under the terms of the Eclipse Public License v1.0
      +  5:  * which accompanies this distribution, and is available at
      +  6:  * http://www.eclipse.org/legal/epl-v10.html
      +  7:  * 
      +  8:  * Contributors:
      +  9:  *     Wind River Systems - initial API and implementation
      + 10:  *******************************************************************************/
      + 11: package org.eclipse.dd.examples.pda.service;
      +
      + 13: import java.util.Hashtable;
      +
      + 15: import org.eclipse.cdt.core.IAddress;
      + 16: import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
      + 17: import org.eclipse.dd.dsf.concurrent.Immutable;
      + 18: import org.eclipse.dd.dsf.concurrent.RequestMonitor;
      + 19: import org.eclipse.dd.dsf.datamodel.AbstractDMContext;
      + 20: import org.eclipse.dd.dsf.datamodel.DMContexts;
      + 21: import org.eclipse.dd.dsf.datamodel.IDMContext;
      + 22: import org.eclipse.dd.dsf.debug.service.IRunControl;
      + 23: import org.eclipse.dd.dsf.debug.service.IStack;
      + 24: import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
      + 25: import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent;
      + 26: import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent;
      + 27: import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason;
      + 28: import org.eclipse.dd.dsf.debug.service.command.CommandCache;
      + 29: import org.eclipse.dd.dsf.service.AbstractDsfService;
      + 30: import org.eclipse.dd.dsf.service.DsfServiceEventHandler;
      + 31: import org.eclipse.dd.dsf.service.DsfSession;
      + 32: import org.eclipse.dd.dsf.service.IDsfService;
      + 33: import org.eclipse.dd.examples.pda.PDAPlugin;
      + 34: import org.eclipse.dd.examples.pda.service.commands.PDAFrame;
      + 35: import org.eclipse.dd.examples.pda.service.commands.PDAStackCommand;
      + 36: import org.eclipse.dd.examples.pda.service.commands.PDAStackCommandResult;
      + 37: import org.osgi.framework.BundleContext;
      +
      + 39: /**
      + 40:  * Service for retrieving PDA debugger stack data. 
      + 41:  * <p>
      + 42:  * This service depends on the {@link PDACommandControl} service and the 
      + 43:  * {@link IRunControl} service.  These services must be initialized before 
      + 44:  * this service is initialized.
      + 45:  * </p>
      + 46:  */
      + 47: public class PDAStack extends AbstractDsfService implements IStack {
      +
      + 49:     /**
      + 50:      * PDA stack frame contains only the stack frame level.  It is only 
      + 51:      * used as an index into the frame data returned by the PDA debugger.
      + 52:      */
      + 53:     @Immutable
      + 54:     private static class FrameDMContext extends AbstractDMContext implements IFrameDMContext {
      +
      + 56:         final private int fLevel;
      +
      + 58:         FrameDMContext(String sessionId, IExecutionDMContext execDmc, int level) {
      + 59:             super(sessionId, new IDMContext[] { execDmc });
      + 60:             fLevel = level;
      + 61:         }
      +
      + 63:         public int getLevel() { return fLevel; }
      +
      + 65:         @Override
      + 66:         public boolean equals(Object other) {
      + 67:             return super.baseEquals(other) && ((FrameDMContext)other).fLevel == fLevel;
      + 68:         }
      +
      + 70:         @Override
      + 71:         public int hashCode() {
      + 72:             return super.baseHashCode() ^ fLevel;
      + 73:         }
      +
      + 75:         @Override
      + 76:         public String toString() { 
      + 77:             return baseToString() + ".frame[" + fLevel + "]";  //$NON-NLS-1$ //$NON-NLS-2$
      + 78:         }
      + 79:     }
      +
      + 81:     /**
      + 82:      * Frame data based on the PDAFrame object returned by the PDA debugger.
      + 83:      */
      + 84:     @Immutable
      + 85:     private static class FrameDMData implements IFrameDMData {
      +
      + 87:         final private PDAFrame fFrame;
      +
      + 89:         FrameDMData(PDAFrame frame) {
      + 90:             fFrame = frame;
      + 91:         }
      +
      + 93:         public String getFile() {
      + 94:             return fFrame.fFilePath.lastSegment();
      + 95:         }
      +
      + 97:         public String getFunction() {
      + 98:             return fFrame.fFunction;
      + 99:         }
      +
      +101:         public int getLine() {
      +102:             return fFrame.fLine + 1;
      +103:         }
      +
      +105:         public int getColumn() {
      +106:             return 0;
      +107:         }
      +
      +109:         public IAddress getAddress() {
      +110:             return null;
      +111:         }
      +112:     }
      +
      +114:     /**
      +115:      * Context representing a variable in a given stack frame.
      +116:      */
      +117:     @Immutable
      +118:     private static class VariableDMContext extends AbstractDMContext implements IVariableDMContext {
      +
      +120:         final private String fVariable;
      +
      +122:         VariableDMContext(String sessionId, IFrameDMContext frameCtx, String variable) {
      +123:             super(sessionId, new IDMContext[] { frameCtx });
      +124:             fVariable = variable;
      +125:         }
      +
      +127:         String getVariable() { return fVariable; }
      +
      +129:         @Override
      +130:         public boolean equals(Object other) {
      +131:             return super.baseEquals(other) && ((VariableDMContext)other).fVariable.equals(fVariable);
      +132:         }
      +
      +134:         @Override
      +135:         public int hashCode() {
      +136:             return super.baseHashCode() + fVariable.hashCode();
      +137:         }
      +
      +139:         @Override
      +140:         public String toString() { 
      +141:             return baseToString() + ".variable(" + fVariable + ")";  //$NON-NLS-1$ //$NON-NLS-2$
      +142:         }
      +143:     }
      +
      +145:     /**
      +146:      * PDA variable data, only supports returning the variable name.
      +147:      */
      +148:     @Immutable
      +149:     private static class VariableDMData implements IVariableDMData {
      +
      +151:         final private String fVariable;
      +
      +153:         VariableDMData(String variable) {
      +154:             fVariable = variable;
      +155:         }
      +
      +157:         public String getName() {
      +158:             return fVariable;
      +159:         }
      +
      +161:         public String getValue() {
      +162:             return null;
      +163:         }
      +164:     }
      +
      +166:     // Services that this service depends on.
      +167:     private PDACommandControl fCommandControl;
      +168:     private IRunControl fRunControl;
      +
      +170:     // Command cache 
      +171:     private CommandCache fCommandCache;
      +
      +173:     public PDAStack(DsfSession session) {
      +174:         super(session);
      +175:     }
      +
      +177:     @Override
      +178:     protected BundleContext getBundleContext() {
      +179:         return PDAPlugin.getBundleContext();
      +180:     }
      +
      +182:     @Override
      +183:     public void initialize(final RequestMonitor rm) {
      +184:         super.initialize(
      +185:             new RequestMonitor(getExecutor(), rm) { 
      +186:                 @Override
      +187:                 protected void handleOK() {
      +188:                     doInitialize(rm);
      +189:                 }});
      +190:     }
      +
      +192:     private void doInitialize(final RequestMonitor rm) {
      +193:         // Initialize service references that stack service depends on
      +194:         fCommandControl = getServicesTracker().getService(PDACommandControl.class);
      +195:         fRunControl = getServicesTracker().getService(IRunControl.class);
      +
      +197:         // Create the commands cache
      +198:         fCommandCache = new CommandCache(fCommandControl);
      +
      +200:         // Register to listen for run control events, to clear cache accordingly.
      +201:         getSession().addServiceEventListener(this, null);
      +
      +203:         // Register stack service with OSGi
      +204:         register(new String[]{IStack.class.getName(), PDAStack.class.getName()}, new Hashtable<String,String>());
      +
      +206:         rm.done();
      +207:     }
      +
      +209:     @Override
      +210:     public void shutdown(final RequestMonitor rm) {
      +211:         getSession().removeServiceEventListener(this);
      +212:         fCommandCache.reset();
      +213:         super.shutdown(rm);
      +214:     }
      +
      +
      +217:     public void getArguments(IFrameDMContext frameCtx, DataRequestMonitor<IVariableDMContext[]> rm) {
      +218:         PDAPlugin.failRequest(rm, IDsfService.NOT_SUPPORTED, "PDA debugger does not support function arguments.");
      +219:     }
      +
      +221:     public void getFrameData(final IFrameDMContext frameCtx, final DataRequestMonitor<IFrameDMData> rm) {
      +222:         // Execute the PDA stack command, or retrieve the result from cache if already available.
      +223:         fCommandCache.execute(
      +224:             new PDAStackCommand(fCommandControl.getProgramDMContext()),
      +225:             new DataRequestMonitor<PDAStackCommandResult>(getExecutor(), rm) {
      +226:                 @Override
      +227:                 protected void handleOK() {
      +228:                     // PDAFrame array is ordered highest to lowest.  We need to 
      +229:                     // calculate the index based on frame level.
      +230:                     int frameId = getData().fFrames.length - frameCtx.getLevel() - 1;
      +231:                     if (frameId < 0) {
      +232:                         PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid frame level " + frameCtx);
      +233:                         return;
      +234:                     }
      +
      +236:                     // Create the frame data object based on the corresponding PDAFrame
      +237:                     rm.setData(new FrameDMData(getData().fFrames[frameId]));
      +238:                     rm.done();
      +239:                 }
      +240:             });
      +241:     }
      +
      +
      +244:     public void getFrames(IDMContext context, final DataRequestMonitor<IFrameDMContext[]> rm) {
      +245:         // Can only create stack frames for an execution context as a parent, 
      +246:         // however the argument context is a generic context type, so it could 
      +247:         // be an execution context, a frame, a variable, etc. Search the 
      +248:         // hierarchy of the argument context to find the execution one.
      +249:         final IExecutionDMContext execCtx = DMContexts.getAncestorOfType(context, IExecutionDMContext.class);
      +250:         if (execCtx == null) {
      +251:             PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid context " + context);
      +252:             return;
      +253:         }
      +
      +255:         // Execute the stack command and create the corresponding frame contexts.
      +256:         fCommandCache.execute(
      +257:             new PDAStackCommand(fCommandControl.getProgramDMContext()),
      +258:             new DataRequestMonitor<PDAStackCommandResult>(getExecutor(), rm) {
      +259:                 @Override
      +260:                 protected void handleOK() {
      +261:                     IFrameDMContext[] frameCtxs = new IFrameDMContext[getData().fFrames.length];
      +262:                     for (int i = 0; i < getData().fFrames.length; i++) {
      +263:                         frameCtxs[i] = new FrameDMContext(getSession().getId(), execCtx, i);
      +264:                     }
      +265:                     rm.setData(frameCtxs);
      +266:                     rm.done();
      +267:                 }
      +268:             });
      +269:     }
      +
      +271:     public void getLocals(final IFrameDMContext frameCtx, final DataRequestMonitor<IVariableDMContext[]> rm) {
      +272:         // Execute the stack command again.
      +273:         fCommandCache.execute(
      +274:             new PDAStackCommand(fCommandControl.getProgramDMContext()),
      +275:             new DataRequestMonitor<PDAStackCommandResult>(getExecutor(), rm) {
      +276:                 @Override
      +277:                 protected void handleOK() {
      +278:                     // Find the correct PDAFrame
      +279:                     int frameId = getData().fFrames.length - frameCtx.getLevel() - 1;
      +280:                     if (frameId < 0) {
      +281:                         PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid frame level " + frameCtx);
      +282:                         return;
      +283:                     }
      +284:                     PDAFrame pdaFrame = getData().fFrames[frameId];
      +
      +286:                     // Create variable contexts for all variables in frame.
      +287:                     IVariableDMContext[] variableCtxs = new IVariableDMContext[pdaFrame.fVariables.length];
      +288:                     for (int i = 0; i < pdaFrame.fVariables.length; i++) {
      +289:                         variableCtxs[i] = new VariableDMContext(getSession().getId(), frameCtx, pdaFrame.fVariables[i]);
      +290:                     }
      +291:                     rm.setData(variableCtxs);
      +292:                     rm.done();
      +293:                 }
      +294:             });
      +
      +296:     }
      +
      +298:     public void getStackDepth(IDMContext context, int maxDepth, final DataRequestMonitor<Integer> rm) {
      +299:         // Execute stack command and return the data's size.
      +300:         fCommandCache.execute(
      +301:             new PDAStackCommand(fCommandControl.getProgramDMContext()),
      +302:             new DataRequestMonitor<PDAStackCommandResult>(getExecutor(), rm) {
      +303:                 @Override
      +304:                 protected void handleOK() {
      +305:                     rm.setData(getData().fFrames.length);
      +306:                     rm.done();
      +307:                 }
      +308:             });
      +309:     }
      +
      +311:     public void getTopFrame(IDMContext context, final DataRequestMonitor<IFrameDMContext> rm) {
      +312:         // Can only create stack frames for an execution context as a parent, 
      +313:         // however the argument context is a generic context type, so it could 
      +314:         // be an execution context, a frame, a variable, etc. Search the 
      +315:         // hierarchy of the argument context to find the execution one.
      +316:         final IExecutionDMContext execCtx = DMContexts.getAncestorOfType(context, IExecutionDMContext.class);
      +317:         if (execCtx == null) {
      +318:             PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid context " + context);
      +319:             return;
      +320:         }
      +
      +322:         // Since the frame context only contain the level, there's no need to 
      +323:         // call the PDA debugger.  Simply create a context for level 0. 
      +324:         rm.setData(new FrameDMContext(getSession().getId(), execCtx, 0));
      +325:         rm.done();
      +326:     }
      +
      +328:     public void getVariableData(IVariableDMContext variableCtx, DataRequestMonitor<IVariableDMData> rm) {
      +329:         if ( !(variableCtx instanceof VariableDMContext) ) {
      +330:             PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid context " + variableCtx);
      +331:             return;
      +332:         }
      +
      +334:         // The variable data doen't contain a value.  So there's no need to 
      +335:         // go to the back end to retrieve it.
      +336:         String variable = ((VariableDMContext)variableCtx).getVariable();
      +
      +338:         rm.setData(new VariableDMData(variable));
      +339:         rm.done();
      +340:     }
      +
      +342:     public boolean isStackAvailable(IDMContext context) {
      +343:         // Stack is available if the program is suspended or stepping.
      +344:         IExecutionDMContext execCtx = DMContexts.getAncestorOfType(context, IExecutionDMContext.class);
      +345:         return execCtx != null && (fRunControl.isSuspended(execCtx) || (fRunControl.isStepping(execCtx)));
      +346:     }
      +
      +348:     @SuppressWarnings("unchecked")
      +349:     @Deprecated
      +350:     public void getModelData(IDMContext dmc, DataRequestMonitor<?> rm) {
      +351:         // The getModelData() is deprecated and clients are expected to switch
      +352:         // to getExecutionData() and other data retrieve methods directly.
      +353:         // However the UI cache still uses it for now.
      +354:         if (dmc instanceof IFrameDMContext) {
      +355:             getFrameData((IFrameDMContext)dmc, (DataRequestMonitor<IFrameDMData>)rm);
      +356:         } else if (dmc instanceof IVariableDMContext) {
      +357:             getVariableData((IVariableDMContext)dmc, (DataRequestMonitor<IVariableDMData>)rm);
      +358:         } else {
      +359:             PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Unknown context type");
      +360:         }
      +361:     }
      +
      +363:     @DsfServiceEventHandler 
      +364:     public void eventDispatched(IResumedDMEvent e) {
      +365:         // Mark the cache as not available, so that stack commands will
      +366:         // fail.  Also reset the cache unless it was a step command.
      +367:         fCommandCache.setTargetAvailable(false);
      +368:         if (!e.getReason().equals(StateChangeReason.STEP)) {
      +369:             fCommandCache.reset();
      +370:         }
      +371:     }    
      +
      +
      +374:     @DsfServiceEventHandler 
      +375:     public void eventDispatched(ISuspendedDMEvent e) {
      +376:         // Enable sending commands to target and clear the cache.
      +377:         fCommandCache.setTargetAvailable(true);
      +378:         fCommandCache.reset();
      +379:     }
      +380: }
      +
      + + + diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/AbstractPDACommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/AbstractPDACommand.java index bd75d996c63..fd73851120c 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/AbstractPDACommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/AbstractPDACommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.debug.service.command.ICommand; import org.eclipse.dd.dsf.debug.service.command.ICommandResult; @@ -20,6 +21,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * a context. Since the PDA debugger protocol is stateless, the context is only * needed to satisfy the ICommand interface. */ +@Immutable abstract public class AbstractPDACommand implements ICommand { final private IDMContext fContext; diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAClearBreakpointCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAClearBreakpointCommand.java index b0873d3254d..35b9717e3f9 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAClearBreakpointCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAClearBreakpointCommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** @@ -21,6 +22,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * */ +@Immutable public class PDAClearBreakpointCommand extends AbstractPDACommand { public PDAClearBreakpointCommand(PDAProgramDMContext context, int line) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDACommandResult.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDACommandResult.java index 053f2e99796..16cfe82fd3d 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDACommandResult.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDACommandResult.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.dsf.debug.service.command.ICommand; import org.eclipse.dd.dsf.debug.service.command.ICommandResult; @@ -19,6 +20,7 @@ import org.eclipse.dd.dsf.debug.service.command.ICommandResult; * PDA response. Sub-classes may override to optionally parse the response text * and return higher-level objects. */ +@Immutable public class PDACommandResult implements ICommandResult { final public String fResponseText; diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommand.java index fab0f679ba0..2fa76f1bed4 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** @@ -20,14 +21,15 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * R: {value 1}|{value 2}|{value 3}|...| * */ -public class PDADataCommand extends AbstractPDACommand { +@Immutable +public class PDADataCommand extends AbstractPDACommand { public PDADataCommand(PDAProgramDMContext context) { super(context, "data"); } @Override - public PDACommandResult createResult(String resultText) { - return new PDACommandResult(resultText); + public PDADataCommandResult createResult(String resultText) { + return new PDADataCommandResult(resultText); } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommand.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommand.java.html new file mode 100644 index 00000000000..311cbceb6b0 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommand.java.html @@ -0,0 +1,46 @@ + + + +PDADataCommand.java + + + + + +
        1: /*******************************************************************************
      +  2:  * Copyright (c) 2008 Wind River Systems and others.
      +  3:  * All rights reserved. This program and the accompanying materials
      +  4:  * are made available under the terms of the Eclipse Public License v1.0
      +  5:  * which accompanies this distribution, and is available at
      +  6:  * http://www.eclipse.org/legal/epl-v10.html
      +  7:  * 
      +  8:  * Contributors:
      +  9:  *     Wind River Systems - initial API and implementation
      + 10:  *******************************************************************************/
      + 11: package org.eclipse.dd.examples.pda.service.commands;
      +
      + 13: import org.eclipse.dd.examples.pda.service.PDAProgramDMContext;
      +
      + 15: /**
      + 16:  * Retrieves data stack information 
      + 17:  * 
      + 18:  * <pre>
      + 19:  *    C: data
      + 20:  *    R: {value 1}|{value 2}|{value 3}|...|
      + 21:  * </pre>
      + 22:  */
      + 23: public class PDADataCommand extends AbstractPDACommand<PDADataCommandResult> {
      +
      + 25:     public PDADataCommand(PDAProgramDMContext context) {
      + 26:         super(context, "data");
      + 27:     }
      + 28:     
      + 29:     @Override
      + 30:     public PDADataCommandResult createResult(String resultText) {
      + 31:         return new PDADataCommandResult(resultText);
      + 32:     }
      + 33: }
      +
      + + + diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommandResult.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommandResult.java index e31b1c8ae58..aff431a7ec6 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommandResult.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommandResult.java @@ -14,10 +14,13 @@ import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; +import org.eclipse.dd.dsf.concurrent.Immutable; + /** * @see PDADataCommand */ +@Immutable public class PDADataCommandResult extends PDACommandResult { final public String[] fValues; diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommandResult.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommandResult.java.html new file mode 100644 index 00000000000..b5f3ae2cb46 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommandResult.java.html @@ -0,0 +1,55 @@ + + + +PDADataCommandResult.java + + + + + +
        1: /*******************************************************************************
      +  2:  * Copyright (c) 2008 Wind River Systems and others.
      +  3:  * All rights reserved. This program and the accompanying materials
      +  4:  * are made available under the terms of the Eclipse Public License v1.0
      +  5:  * which accompanies this distribution, and is available at
      +  6:  * http://www.eclipse.org/legal/epl-v10.html
      +  7:  * 
      +  8:  * Contributors:
      +  9:  *     Wind River Systems - initial API and implementation
      + 10:  *******************************************************************************/
      + 11: package org.eclipse.dd.examples.pda.service.commands;
      +
      + 13: import java.util.ArrayList;
      + 14: import java.util.List;
      + 15: import java.util.StringTokenizer;
      +
      +
      + 18: /**
      + 19:  * @see PDADataCommand
      + 20:  */
      + 21: public class PDADataCommandResult extends PDACommandResult {
      + 22:     
      + 23:     final public String[] fValues;
      + 24:     
      + 25:     PDADataCommandResult(String response) {
      + 26:         super(response);
      + 27:         StringTokenizer st = new StringTokenizer(response, "|");
      + 28:         List<String> valuesList = new ArrayList<String>();
      + 29:         
      + 30:         while (st.hasMoreTokens()) {
      + 31:             String token = st.nextToken();
      + 32:             if (token.length() != 0) {
      + 33:                 valuesList.add(st.nextToken());
      + 34:             }
      + 35:         }
      + 36:         
      + 37:         fValues = new String[valuesList.size()];
      + 38:         for (int i = 0; i < valuesList.size(); i++) {
      + 39:             fValues[i] = valuesList.get(i);
      + 40:         }
      + 41:     }
      + 42: }
      +
      + + + diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADropFrameCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADropFrameCommand.java index 1a1f4cc8f92..d68c173dd52 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADropFrameCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADropFrameCommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** @@ -23,6 +24,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * */ +@Immutable public class PDADropFrameCommand extends AbstractPDACommand { public PDADropFrameCommand(PDAProgramDMContext context) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAEvalCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAEvalCommand.java index 082362e7415..10a4d707132 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAEvalCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAEvalCommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** @@ -25,6 +26,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * * Where event_name could be unimpinstr or nosuchlabel. */ +@Immutable public class PDAEvalCommand extends AbstractPDACommand { public PDAEvalCommand(PDAProgramDMContext context, String operation) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAEventStopCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAEventStopCommand.java index 653f2aa945a..d247f829c4b 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAEventStopCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAEventStopCommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** @@ -24,6 +25,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * * Where event_name could be unimpinstr or nosuchlabel. */ +@Immutable public class PDAEventStopCommand extends AbstractPDACommand { public enum Event { UNIMPINSTR, NOSUCHLABEL }; diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAExitCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAExitCommand.java index 0514aa675f5..7b7222b7b27 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAExitCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAExitCommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** @@ -20,6 +21,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * R: ok * */ +@Immutable public class PDAExitCommand extends AbstractPDACommand { public PDAExitCommand(PDAProgramDMContext context) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAFrame.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAFrame.java index ab2b2c5612a..5ef52dc542a 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAFrame.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAFrame.java @@ -16,12 +16,14 @@ import java.util.StringTokenizer; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; +import org.eclipse.dd.dsf.concurrent.Immutable; /** * Object representing a frame in the stack command results. * * @see PDAStackCommand */ +@Immutable public class PDAFrame { final public IPath fFilePath; diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAPopDataCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAPopDataCommand.java index 952e53cd17c..de6649b785b 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAPopDataCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAPopDataCommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** @@ -20,6 +21,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * R: ok * */ +@Immutable public class PDAPopDataCommand extends AbstractPDACommand { public PDAPopDataCommand(PDAProgramDMContext context) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAPushDataCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAPushDataCommand.java index 7226c765518..d201e9b05ec 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAPushDataCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAPushDataCommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** @@ -20,6 +21,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * R: ok * */ +@Immutable public class PDAPushDataCommand extends AbstractPDACommand { public PDAPushDataCommand(PDAProgramDMContext context, int value) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAResumeCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAResumeCommand.java index 35b83c35a13..6a7e46f1a29 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAResumeCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAResumeCommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** @@ -21,6 +22,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * E: resumed client * */ +@Immutable public class PDAResumeCommand extends AbstractPDACommand { public PDAResumeCommand(PDAProgramDMContext context) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAResumeCommand.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAResumeCommand.java.html new file mode 100644 index 00000000000..ae563692a2f --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAResumeCommand.java.html @@ -0,0 +1,47 @@ + + + +PDAResumeCommand.java + + + + + +
        1: /*******************************************************************************
      +  2:  * Copyright (c) 2008 Wind River Systems and others.
      +  3:  * All rights reserved. This program and the accompanying materials
      +  4:  * are made available under the terms of the Eclipse Public License v1.0
      +  5:  * which accompanies this distribution, and is available at
      +  6:  * http://www.eclipse.org/legal/epl-v10.html
      +  7:  * 
      +  8:  * Contributors:
      +  9:  *     Wind River Systems - initial API and implementation
      + 10:  *******************************************************************************/
      + 11: package org.eclipse.dd.examples.pda.service.commands;
      +
      + 13: import org.eclipse.dd.examples.pda.service.PDAProgramDMContext;
      +
      + 15: /**
      + 16:  * Resumes the execution  
      + 17:  * 
      + 18:  * <pre>
      + 19:  *    C: resume
      + 20:  *    R: ok
      + 21:  *    E: resumed client
      + 22:  * </pre>
      + 23:  */
      + 24: public class PDAResumeCommand extends AbstractPDACommand<PDACommandResult> {
      +
      + 26:     public PDAResumeCommand(PDAProgramDMContext context) {
      + 27:         super(context, "resume");
      + 28:     }
      + 29:     
      + 30:     @Override
      + 31:     public PDACommandResult createResult(String resultText) {
      + 32:         return new PDACommandResult(resultText);
      + 33:     }
      + 34: }
      +
      + + + diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASetBreakpointCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASetBreakpointCommand.java index 7dd14c6456a..4bfd3370df6 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASetBreakpointCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASetBreakpointCommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** @@ -23,6 +24,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * E: suspended breakpoint line_number * */ +@Immutable public class PDASetBreakpointCommand extends AbstractPDACommand { public PDASetBreakpointCommand(PDAProgramDMContext context, int line) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASetDataCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASetDataCommand.java index b66772f8688..706700c8f7f 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASetDataCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASetDataCommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** @@ -20,6 +21,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * R: ok * */ +@Immutable public class PDASetDataCommand extends AbstractPDACommand { public PDASetDataCommand(PDAProgramDMContext context, int index, String value) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASetVarCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASetVarCommand.java index 5fcf7d77b49..f18340e20d4 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASetVarCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASetVarCommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** @@ -20,6 +21,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * R: ok * */ +@Immutable public class PDASetVarCommand extends AbstractPDACommand { public PDASetVarCommand(PDAProgramDMContext context, int frame, String variable, String value) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStackCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStackCommand.java index cd26fa07ff5..aef4d4aa795 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStackCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStackCommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** @@ -20,6 +21,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * R: {file}|{line}|{function}|{var_1}|{var_2}|...#{file}|{line}|{function}|{var_1}|{var_2}|...#... * */ +@Immutable public class PDAStackCommand extends AbstractPDACommand { public PDAStackCommand(PDAProgramDMContext context) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStackCommandResult.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStackCommandResult.java index 5cc1bf1fc71..7bd9877cd19 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStackCommandResult.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStackCommandResult.java @@ -14,10 +14,13 @@ import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; +import org.eclipse.dd.dsf.concurrent.Immutable; + /** * @see PDAStackCommand */ +@Immutable public class PDAStackCommandResult extends PDACommandResult { /** diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStepCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStepCommand.java index a50713acc8b..ce50cf5c228 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStepCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStepCommand.java @@ -10,10 +10,11 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** - * Executes next instruciton + * Executes next instruction * *
        *    C: step
      @@ -22,6 +23,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext;
        *    E: suspended step
        * 
      */ +@Immutable public class PDAStepCommand extends AbstractPDACommand { public PDAStepCommand(PDAProgramDMContext context) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStepReturnCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStepReturnCommand.java index 8ba0dedfb3b..8b9d7c8a675 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStepReturnCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStepReturnCommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** @@ -22,6 +23,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * E: suspended step * */ +@Immutable public class PDAStepReturnCommand extends AbstractPDACommand { public PDAStepReturnCommand(PDAProgramDMContext context) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASuspendCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASuspendCommand.java index f1c7e548b85..5abde431178 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASuspendCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASuspendCommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** @@ -21,6 +22,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * E: suspended client * */ +@Immutable public class PDASuspendCommand extends AbstractPDACommand { public PDASuspendCommand(PDAProgramDMContext context) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAVarCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAVarCommand.java index 745fa86a491..cc57a527161 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAVarCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAVarCommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** @@ -20,6 +21,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * R: {variable_value} * */ +@Immutable public class PDAVarCommand extends AbstractPDACommand { public PDAVarCommand(PDAProgramDMContext context, int frameId, String name) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAWatchCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAWatchCommand.java index 91d54e942a0..f6bf1982545 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAWatchCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAWatchCommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** @@ -23,6 +24,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * E: suspended watch {watch_operation} {function}::{variable_name} * */ +@Immutable public class PDAWatchCommand extends AbstractPDACommand { public enum WatchOperation { READ, WRITE, BOTH, NONE }; diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/sourcelookup/PDASourceLookupDirector.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/sourcelookup/PDASourceLookupDirector.java index d22968d6be9..1c7ec8b518f 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/sourcelookup/PDASourceLookupDirector.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/sourcelookup/PDASourceLookupDirector.java @@ -19,7 +19,7 @@ import org.eclipse.debug.core.sourcelookup.AbstractSourceLookupDirector; */ public class PDASourceLookupDirector extends AbstractSourceLookupDirector { public void initializeParticipants() { - // No need to add participants here, the surce display adapter will + // No need to add participants here, the source display adapter will // add the participant with the correct session ID. } } From 77839f1f0ef8b218cc0b7089b77b380d37198884 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 13 Mar 2008 17:52:32 +0000 Subject: [PATCH 301/834] [220446] Updated the PDA Debugger example. --- .../pda/ui/PDAAdapterFactory.java.html | 223 ------- .../pda/ui/viewmodel/PDAVMAdapter.java.html | 66 --- .../launch/PDALaunchVMProvider.java.html | 149 ----- .../launch/PDAProgramVMNode.java.html | 303 ---------- .../org.eclipse.dd.examples.pda/readme.html | 2 +- .../examples/pda/launch/PDALaunch.java.html | 271 --------- .../pda/launch/PDALaunchDelegate.java.html | 234 -------- .../launch/PDAServicesInitSequence.java.html | 140 ----- ...PDABreakpointAttributeTranslator.java.html | 148 ----- .../pda/service/PDABreakpoints.java.html | 416 ------------- .../pda/service/PDACommandControl.java.html | 547 ------------------ .../pda/service/PDAExpressions.java.html | 386 ------------ .../pda/service/PDARunControl.java.html | 330 ----------- .../examples/pda/service/PDAStack.java.html | 393 ------------- .../service/commands/PDADataCommand.java.html | 46 -- .../commands/PDADataCommandResult.java.html | 55 -- .../commands/PDAResumeCommand.java.html | 47 -- 17 files changed, 1 insertion(+), 3755 deletions(-) delete mode 100644 plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java.html delete mode 100644 plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java.html delete mode 100644 plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDALaunchVMProvider.java.html delete mode 100644 plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDAProgramVMNode.java.html delete mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunch.java.html delete mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunchDelegate.java.html delete mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java.html delete mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpointAttributeTranslator.java.html delete mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpoints.java.html delete mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java.html delete mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAExpressions.java.html delete mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java.html delete mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java.html delete mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommand.java.html delete mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommandResult.java.html delete mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAResumeCommand.java.html diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java.html b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java.html deleted file mode 100644 index 3d98e729b68..00000000000 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java.html +++ /dev/null @@ -1,223 +0,0 @@ - - - -PDAAdapterFactory.java - - - - - -
        1: /*******************************************************************************
      -  2:  * Copyright (c) 2006 Wind River Systems and others.
      -  3:  * All rights reserved. This program and the accompanying materials
      -  4:  * are made available under the terms of the Eclipse Public License v1.0
      -  5:  * which accompanies this distribution, and is available at
      -  6:  * http://www.eclipse.org/legal/epl-v10.html
      -  7:  * 
      -  8:  * Contributors:
      -  9:  *     Wind River Systems - initial API and implementation
      - 10:  *******************************************************************************/
      - 11: package org.eclipse.dd.examples.pda.ui;
      -
      - 13: import java.util.Collections;
      - 14: import java.util.HashMap;
      - 15: import java.util.Map;
      -
      - 17: import org.eclipse.core.runtime.IAdapterFactory;
      - 18: import org.eclipse.dd.dsf.concurrent.Immutable;
      - 19: import org.eclipse.dd.dsf.concurrent.ThreadSafe;
      - 20: import org.eclipse.dd.dsf.debug.ui.actions.DsfResumeCommand;
      - 21: import org.eclipse.dd.dsf.debug.ui.actions.DsfStepIntoCommand;
      - 22: import org.eclipse.dd.dsf.debug.ui.actions.DsfStepOverCommand;
      - 23: import org.eclipse.dd.dsf.debug.ui.actions.DsfStepReturnCommand;
      - 24: import org.eclipse.dd.dsf.debug.ui.actions.DsfSuspendCommand;
      - 25: import org.eclipse.dd.dsf.debug.ui.sourcelookup.MISourceDisplayAdapter;
      - 26: import org.eclipse.dd.dsf.service.DsfSession;
      - 27: import org.eclipse.dd.examples.pda.PDAPlugin;
      - 28: import org.eclipse.dd.examples.pda.launch.PDALaunch;
      - 29: import org.eclipse.dd.examples.pda.ui.actions.PDATerminateCommand;
      - 30: import org.eclipse.dd.examples.pda.ui.viewmodel.PDAVMAdapter;
      - 31: import org.eclipse.debug.core.DebugPlugin;
      - 32: import org.eclipse.debug.core.ILaunch;
      - 33: import org.eclipse.debug.core.ILaunchesListener2;
      - 34: import org.eclipse.debug.core.commands.IResumeHandler;
      - 35: import org.eclipse.debug.core.commands.IStepIntoHandler;
      - 36: import org.eclipse.debug.core.commands.IStepOverHandler;
      - 37: import org.eclipse.debug.core.commands.IStepReturnHandler;
      - 38: import org.eclipse.debug.core.commands.ISuspendHandler;
      - 39: import org.eclipse.debug.core.commands.ITerminateHandler;
      - 40: import org.eclipse.debug.core.model.IDebugModelProvider;
      - 41: import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector;
      - 42: import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory;
      - 43: import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider;
      - 44: import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory;
      - 45: import org.eclipse.debug.ui.sourcelookup.ISourceDisplay;
      -
      - 47: /**
      - 48:  * The adapter factory is the central point of control of view model and other
      - 49:  * UI adapters of a DSF-based debugger.  As new launches are created and 
      - 50:  * old ones removed, this factory manages the life cycle of the associated
      - 51:  * UI adapters.    
      - 52:  * <p>
      - 53:  * As a platform adapter factory, this factory only  provides adapters for
      - 54:  * the launch object.  Adapters for all other objects in the DSF model hierarchy
      - 55:  * are registered with the DSF session. 
      - 56:  * </p>
      - 57:  */
      - 58: @ThreadSafe
      - 59: @SuppressWarnings({"restriction"})
      - 60: public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2
      - 61: {
      - 62:     /**
      - 63:      * Contains the set of adapters that are created for eacy launch instance.
      - 64:      */
      - 65:     @Immutable
      - 66:     private static class LaunchAdapterSet {
      - 67:         // View Model adapter
      - 68:         final PDAVMAdapter fViewModelAdapter;
      - 69:         
      - 70:         // Source lookup and positioning adapter
      - 71:         final MISourceDisplayAdapter fSourceDisplayAdapter;
      - 72:         
      - 73:         // Command adapters
      - 74:         final DsfStepIntoCommand fStepIntoCommand;
      - 75:         final DsfStepOverCommand fStepOverCommand;
      - 76:         final DsfStepReturnCommand fStepReturnCommand;
      - 77:         final DsfSuspendCommand fSuspendCommand;
      - 78:         final DsfResumeCommand fResumeCommand;
      - 79:         final PDATerminateCommand fTerminateCommand;
      - 80:         
      - 81:         // Adapters for integration with other UI actions
      - 82:         final IDebugModelProvider fDebugModelProvider;
      - 83:         final PDALaunch fLaunch;
      -
      - 85:         LaunchAdapterSet(PDALaunch launch) {
      - 86:             // Initialize launch and session.
      - 87:             fLaunch = launch;
      - 88:             DsfSession session = launch.getSession();
      - 89:             
      - 90:             // Initialize VM
      - 91:             fViewModelAdapter = new PDAVMAdapter(session);
      -
      - 93:             // Initialize source lookup
      - 94:             fSourceDisplayAdapter = new MISourceDisplayAdapter(session, (ISourceLookupDirector)launch.getSourceLocator());
      - 95:             session.registerModelAdapter(ISourceDisplay.class, fSourceDisplayAdapter);
      - 96:             
      - 97:             // Initialize retargetable command handler.
      - 98:             fStepIntoCommand = new DsfStepIntoCommand(session);
      - 99:             fStepOverCommand = new DsfStepOverCommand(session);
      -100:             fStepReturnCommand = new DsfStepReturnCommand(session);
      -101:             fSuspendCommand = new DsfSuspendCommand(session);
      -102:             fResumeCommand = new DsfResumeCommand(session);
      -103:             fTerminateCommand = new PDATerminateCommand(session);
      -104:             session.registerModelAdapter(IStepIntoHandler.class, fStepIntoCommand);
      -105:             session.registerModelAdapter(IStepOverHandler.class, fStepOverCommand);
      -106:             session.registerModelAdapter(IStepReturnHandler.class, fStepReturnCommand);
      -107:             session.registerModelAdapter(ISuspendHandler.class, fSuspendCommand);
      -108:             session.registerModelAdapter(IResumeHandler.class, fResumeCommand);
      -109:             session.registerModelAdapter(ITerminateHandler.class, fTerminateCommand);
      -
      -111:             // Initialize debug model provider
      -112:             fDebugModelProvider = new IDebugModelProvider() {
      -113:                 public String[] getModelIdentifiers() {
      -114:                     return new String[] { PDAPlugin.ID_PDA_DEBUG_MODEL };
      -115:                 }
      -116:             };
      -117:             session.registerModelAdapter(IDebugModelProvider.class, fDebugModelProvider);
      -118:             
      -119:             // Register the launch as an adapter This ensures that the launch, 
      -120:             // and debug model ID will be associated with all DMContexts from this 
      -121:             // session.  
      -122:             session.registerModelAdapter(ILaunch.class, fLaunch);
      -123:         }
      -124:         
      -125:         void dispose() {
      -126:             DsfSession session = fLaunch.getSession();
      -
      -128:             fViewModelAdapter.dispose();
      -
      -130:             session.unregisterModelAdapter(ISourceDisplay.class);
      -131:             if (fSourceDisplayAdapter != null) fSourceDisplayAdapter.dispose();
      -132:             
      -133:             session.unregisterModelAdapter(IStepIntoHandler.class);
      -134:             session.unregisterModelAdapter(IStepOverHandler.class);
      -135:             session.unregisterModelAdapter(IStepReturnHandler.class);
      -136:             session.unregisterModelAdapter(ISuspendHandler.class);
      -137:             session.unregisterModelAdapter(IResumeHandler.class);
      -138:             session.unregisterModelAdapter(ITerminateHandler.class);            
      -139:             fStepIntoCommand.dispose();
      -140:             fStepOverCommand.dispose();
      -141:             fStepReturnCommand.dispose();
      -142:             fSuspendCommand.dispose();
      -143:             fResumeCommand.dispose();
      -144:             fTerminateCommand.dispose();
      -145:         }        
      -146:     }        
      -
      -148:     private Map<PDALaunch, LaunchAdapterSet> fLaunchAdapterSets = 
      -149:         Collections.synchronizedMap(new HashMap<PDALaunch, LaunchAdapterSet>());
      -150:     
      -151:     public PDAAdapterFactory() {
      -152:         DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this);
      -153:     }
      -
      -155:     // This IAdapterFactory method returns adapters for the PDA launch object only.  
      -156:     @SuppressWarnings("unchecked") // IAdapterFactory is Java 1.3
      -157:     public Object getAdapter(Object adaptableObject, Class adapterType) {
      -158:         if (!(adaptableObject instanceof PDALaunch)) return null; 
      -
      -160:         PDALaunch launch = (PDALaunch)adaptableObject;
      -
      -162:         // Find the correct set of adapters based on the launch.  If not found
      -163:         // it means that we have a new launch, and we have to create a 
      -164:         // new set of adapters. 
      -165:         LaunchAdapterSet adapterSet;
      -166:         synchronized(fLaunchAdapterSets) {
      -167:             adapterSet = fLaunchAdapterSets.get(launch);
      -168:             if (adapterSet == null) {
      -169:                 adapterSet = new LaunchAdapterSet(launch);
      -170:                 fLaunchAdapterSets.put(launch, adapterSet);
      -171:             }
      -172:         }
      -173:         
      -174:         // Returns the adapter type for the launch object.
      -175:         if (adapterType.equals(IElementContentProvider.class)) return adapterSet.fViewModelAdapter;
      -176:         else if (adapterType.equals(IModelProxyFactory.class)) return adapterSet.fViewModelAdapter;
      -177:         else return null;
      -178:     }
      -
      -180:     @SuppressWarnings("unchecked") // IAdapterFactory is Java 1.3
      -181:     public Class[] getAdapterList() {
      -182:         return new Class[] { IElementContentProvider.class, IModelProxyFactory.class, IColumnPresentationFactory.class };
      -183:     }
      -
      -185:     public void launchesRemoved(ILaunch[] launches) {
      -186:         // Dispose the set of adapters for a launch only after the launch is 
      -187:         // removed from the view.  If the launch is terminated, the adapters
      -188:         // are still needed to populate the contents of the view.
      -189:         for (ILaunch launch : launches) {
      -190:             if (launch instanceof PDALaunch) {
      -191:                 PDALaunch pdaLaunch = (PDALaunch)launch;
      -192:                 synchronized(fLaunchAdapterSets) {
      -193:                     if ( fLaunchAdapterSets.containsKey(pdaLaunch) ) {
      -194:                         fLaunchAdapterSets.remove(pdaLaunch).dispose();
      -195:                     }
      -196:                 }
      -197:             }                
      -198:         }
      -199:     }
      -
      -201:     public void launchesTerminated(ILaunch[] launches) {
      -202:     }
      -
      -204:     public void launchesAdded(ILaunch[] launches) {
      -205:     }
      -206:     
      -207:     public void launchesChanged(ILaunch[] launches) {
      -208:     }
      -209:     
      -210: }
      -
      - - - diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java.html b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java.html deleted file mode 100644 index 3b9ea80e322..00000000000 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java.html +++ /dev/null @@ -1,66 +0,0 @@ - - - -PDAVMAdapter.java - - - - - -
        1: /*******************************************************************************
      -  2:  * Copyright (c) 2006 Wind River Systems and others.
      -  3:  * All rights reserved. This program and the accompanying materials
      -  4:  * are made available under the terms of the Eclipse Public License v1.0
      -  5:  * which accompanies this distribution, and is available at
      -  6:  * http://www.eclipse.org/legal/epl-v10.html
      -  7:  * 
      -  8:  * Contributors:
      -  9:  *     Wind River Systems - initial API and implementation
      - 10:  *******************************************************************************/
      - 11: package org.eclipse.dd.examples.pda.ui.viewmodel;
      -
      - 13: import org.eclipse.dd.dsf.concurrent.ThreadSafe;
      - 14: import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.ExpressionVMProvider;
      - 15: import org.eclipse.dd.dsf.debug.ui.viewmodel.variable.VariableVMProvider;
      - 16: import org.eclipse.dd.dsf.service.DsfSession;
      - 17: import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMAdapter;
      - 18: import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
      - 19: import org.eclipse.dd.examples.pda.ui.viewmodel.launch.LaunchVMProvider;
      - 20: import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory;
      - 21: import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
      - 22: import org.eclipse.debug.ui.IDebugUIConstants;
      -
      - 24: /* 
      - 25:  * 
      - 26:  */
      - 27: @ThreadSafe
      - 28: @SuppressWarnings("restriction")
      - 29: public class PDAVMAdapter extends AbstractDMVMAdapter
      - 30: {
      - 31:     public PDAVMAdapter(DsfSession session) {
      - 32:         super(session);
      - 33:         getSession().registerModelAdapter(IColumnPresentationFactory.class, this);
      - 34:     }    
      -
      - 36:     @Override
      - 37:     public void dispose() {
      - 38:         getSession().unregisterModelAdapter(IColumnPresentationFactory.class);
      - 39:         super.dispose();
      - 40:     }
      - 41:     
      - 42:     @Override
      - 43:     protected AbstractDMVMProvider createViewModelProvider(IPresentationContext context) {
      - 44:         if ( IDebugUIConstants.ID_DEBUG_VIEW.equals(context.getId()) ) {
      - 45:             return new PDALaunchVMProvider(this, context, getSession()); 
      - 46:         } else if (IDebugUIConstants.ID_VARIABLE_VIEW.equals(context.getId()) ) {
      - 47:             return new VariableVMProvider(this, context, getSession());
      - 48:         } else if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(context.getId()) ) {
      - 49:             return new ExpressionVMProvider(this, context, getSession());
      - 50:         } 
      - 51:         return null;
      - 52:     }    
      - 53: }
      -
      - - - diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDALaunchVMProvider.java.html b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDALaunchVMProvider.java.html deleted file mode 100644 index 0c9a409f3c6..00000000000 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDALaunchVMProvider.java.html +++ /dev/null @@ -1,149 +0,0 @@ - - - -PDALaunchVMProvider.java - - - - - -
        1: /*******************************************************************************
      -  2:  * Copyright (c) 2006 Wind River Systems and others.
      -  3:  * All rights reserved. This program and the accompanying materials
      -  4:  * are made available under the terms of the Eclipse Public License v1.0
      -  5:  * which accompanies this distribution, and is available at
      -  6:  * http://www.eclipse.org/legal/epl-v10.html
      -  7:  * 
      -  8:  * Contributors:
      -  9:  *     Wind River Systems - initial API and implementation
      - 10:  *     Ericsson                          - Modified for new functionality        
      - 11:  *******************************************************************************/
      - 12: package org.eclipse.dd.examples.pda.ui.viewmodel.launch;
      -
      - 14: import java.util.concurrent.RejectedExecutionException;
      -
      - 16: import org.eclipse.dd.dsf.concurrent.ThreadSafe;
      - 17: import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.LaunchRootVMNode;
      - 18: import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.StackFramesVMNode;
      - 19: import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.StandardProcessVMNode;
      - 20: import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.LaunchRootVMNode.LaunchesEvent;
      - 21: import org.eclipse.dd.dsf.service.DsfSession;
      - 22: import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter;
      - 23: import org.eclipse.dd.dsf.ui.viewmodel.IRootVMNode;
      - 24: import org.eclipse.dd.dsf.ui.viewmodel.IVMNode;
      - 25: import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
      - 26: import org.eclipse.debug.core.DebugEvent;
      - 27: import org.eclipse.debug.core.DebugPlugin;
      - 28: import org.eclipse.debug.core.IDebugEventSetListener;
      - 29: import org.eclipse.debug.core.ILaunch;
      - 30: import org.eclipse.debug.core.ILaunchesListener2;
      - 31: import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
      -
      -
      - 34: /**
      - 35:  * View Model provider for the Launch (AKA Debug) view.  The PDA debugger is 
      - 36:  * single-threaded, so there is no need for a debug target element to be visible
      - 37:  * in the debug view.  Therefore the launch VM provider is configured with three nodes:
      - 38:  * <ul>
      - 39:  * <li> LaunchRootVMNode - This is the root of the PDA view model.</li>  
      - 40:  * <li> ThreadVMNode - Supplies the PDA program element.</li>  
      - 41:  * <li> StackFramesVMNode - Supplies the stack frame elements.</li>  
      - 42:  * <li> StandardProcessVMNode - Supplies elements representing the PDA debugger process.</li>
      - 43:  * </ul> 
      - 44:  */
      - 45: @SuppressWarnings("restriction")
      - 46: public class PDALaunchVMProvider extends AbstractDMVMProvider 
      - 47:     implements IDebugEventSetListener, ILaunchesListener2
      - 48: {
      - 49:     @ThreadSafe
      - 50:     public PDALaunchVMProvider(AbstractVMAdapter adapter, IPresentationContext presentationContext, DsfSession session) 
      - 51:     {
      - 52:         super(adapter, presentationContext, session);
      - 53:         
      - 54:         IRootVMNode launchNode = new LaunchRootVMNode(this);
      - 55:         setRootNode(launchNode);
      -
      - 57:         // Launch node is a parent to the processes and program nodes.
      - 58:         IVMNode pdaProgramNode = new PDAProgramVMNode(this, getSession());
      - 59:         IVMNode processesNode = new StandardProcessVMNode(this);
      - 60:         addChildNodes(launchNode, new IVMNode[] { pdaProgramNode, processesNode});
      - 61:         
      - 62:         // Stack frames node is under the PDA program node.
      - 63:         IVMNode stackFramesNode = new StackFramesVMNode(this, getSession());
      - 64:         addChildNodes(pdaProgramNode, new IVMNode[] { stackFramesNode });
      -
      - 66:         // Register the LaunchVM provider as a listener to debug and launch 
      - 67:         // events.  These events are used by the launch and processes nodes.
      - 68:         DebugPlugin.getDefault().addDebugEventListener(this);
      - 69:         DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this);
      - 70:     }
      - 71:     
      - 72:     
      - 73:     public void handleDebugEvents(final DebugEvent[] events) {
      - 74:         if (isDisposed()) return;
      - 75:         
      - 76:         // This method may be called on any thread.  Switch to the 
      - 77:         // view model executor thread before processing.
      - 78:         try {
      - 79:             getExecutor().execute(new Runnable() {
      - 80:                 public void run() {
      - 81:                     if (isDisposed()) return;
      - 82:     
      - 83:                     for (final DebugEvent event : events) {
      - 84:                         handleEvent(event);
      - 85:                     }
      - 86:                 }});
      - 87:         } catch (RejectedExecutionException e) {
      - 88:             // Ignore.  This exception could be thrown if the view model is being 
      - 89:             // shut down.  
      - 90:         }
      - 91:     }
      -
      - 93:     @Override
      - 94:     public void dispose() {
      - 95:         DebugPlugin.getDefault().removeDebugEventListener(this);
      - 96:         DebugPlugin.getDefault().getLaunchManager().removeLaunchListener(this);
      - 97:         super.dispose();
      - 98:     }
      - 99:     
      -100:     public void launchesAdded(ILaunch[] launches) {
      -101:         handleLaunchesEvent(new LaunchesEvent(launches, LaunchesEvent.Type.ADDED)); 
      -102:     }
      -103:     
      -104:     public void launchesRemoved(ILaunch[] launches) {
      -105:         handleLaunchesEvent(new LaunchesEvent(launches, LaunchesEvent.Type.REMOVED)); 
      -106:     }
      -107:     
      -108:     public void launchesChanged(ILaunch[] launches) {
      -109:         handleLaunchesEvent(new LaunchesEvent(launches, LaunchesEvent.Type.CHANGED)); 
      -110:     }
      -111:     
      -112:     public void launchesTerminated(ILaunch[] launches) {
      -113:         handleLaunchesEvent(new LaunchesEvent(launches, LaunchesEvent.Type.TERMINATED)); 
      -114:     }
      -115:     
      -116:     private void handleLaunchesEvent(final LaunchesEvent event) {
      -117:         if (isDisposed()) return;
      -118:         
      -119:         // This method also may be called on any thread.  Switch to the 
      -120:         // view model executor thread before processing.
      -121:         try {
      -122:             getExecutor().execute(new Runnable() {
      -123:                 public void run() {
      -124:                     if (isDisposed()) return;
      -125:     
      -126:                     IRootVMNode rootLayoutNode = getRootVMNode();
      -127:                     if (rootLayoutNode != null && rootLayoutNode.getDeltaFlags(event) != 0) {
      -128:                         handleEvent(event);
      -129:                     }
      -130:                 }});
      -131:         } catch (RejectedExecutionException e) {
      -132:             // Ignore.  This exception could be thrown if the view model is being 
      -133:             // shut down.  
      -134:         }
      -135:     }
      -136: }
      -
      - - - diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDAProgramVMNode.java.html b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDAProgramVMNode.java.html deleted file mode 100644 index 04e9f04ba22..00000000000 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDAProgramVMNode.java.html +++ /dev/null @@ -1,303 +0,0 @@ - - - -PDAProgramVMNode.java - - - - - -
        1: /*******************************************************************************
      -  2:  * Copyright (c) 2006 Wind River Systems and others.
      -  3:  * All rights reserved. This program and the accompanying materials
      -  4:  * are made available under the terms of the Eclipse Public License v1.0
      -  5:  * which accompanies this distribution, and is available at
      -  6:  * http://www.eclipse.org/legal/epl-v10.html
      -  7:  * 
      -  8:  * Contributors:
      -  9:  *     Wind River Systems - initial API and implementation
      - 10:  *     Ericsson                   - Modified for multi threaded functionality        
      - 11:  *******************************************************************************/
      - 12: package org.eclipse.dd.examples.pda.ui.viewmodel.launch;
      -
      - 14: import java.util.concurrent.RejectedExecutionException;
      -
      - 16: import org.eclipse.core.runtime.CoreException;
      - 17: import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor;
      - 18: import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
      - 19: import org.eclipse.dd.dsf.concurrent.DsfRunnable;
      - 20: import org.eclipse.dd.dsf.concurrent.ImmediateExecutor;
      - 21: import org.eclipse.dd.dsf.concurrent.RequestMonitor;
      - 22: import org.eclipse.dd.dsf.datamodel.IDMEvent;
      - 23: import org.eclipse.dd.dsf.debug.service.IRunControl;
      - 24: import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
      - 25: import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMData;
      - 26: import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent;
      - 27: import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent;
      - 28: import org.eclipse.dd.dsf.service.DsfSession;
      - 29: import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMContext;
      - 30: import org.eclipse.dd.dsf.ui.viewmodel.IVMAdapter;
      - 31: import org.eclipse.dd.dsf.ui.viewmodel.IVMNode;
      - 32: import org.eclipse.dd.dsf.ui.viewmodel.VMDelta;
      - 33: import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMNode;
      - 34: import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
      - 35: import org.eclipse.dd.examples.pda.PDAPlugin;
      - 36: import org.eclipse.dd.examples.pda.launch.PDALaunch;
      - 37: import org.eclipse.dd.examples.pda.service.PDACommandControl;
      - 38: import org.eclipse.dd.examples.pda.service.PDAProgramDMContext;
      - 39: import org.eclipse.dd.examples.pda.service.PDAStartedEvent;
      - 40: import org.eclipse.debug.core.ILaunch;
      - 41: import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate;
      - 42: import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
      - 43: import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider;
      - 44: import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate;
      - 45: import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
      - 46: import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
      - 47: import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate;
      - 48: import org.eclipse.debug.ui.DebugUITools;
      - 49: import org.eclipse.debug.ui.IDebugUIConstants;
      - 50: import org.eclipse.jface.viewers.TreePath;
      -
      - 52: /**
      - 53:  * View Model node representing a PDA program. 
      - 54:  */
      - 55: @SuppressWarnings("restriction")
      - 56: public class PDAProgramVMNode extends AbstractDMVMNode 
      - 57:     implements IElementLabelProvider
      - 58: {
      - 59:     // View model context representing a terminated PDA program.
      - 60:     // It's purpose is to show a terminated program in the debug view
      - 61:     // even after the DSF session is terminated.
      - 62:     // 
      - 63:     // Note: this context does not implement the IDMVMContext
      - 64:     // interfaces, as it does not use an IDMContext as its root.
      - 65:     // 
      - 66:     // To implement comparison methods, this contexts uses the
      - 67:     // VM node object, such that two terminated program contexts
      - 68:     // from the same instance of VM node will be equal. 
      - 69:     private static class TerminatedProgramVMContext extends AbstractVMContext {
      - 70:         TerminatedProgramVMContext(IVMAdapter adapter, IVMNode node) {
      - 71:             super(adapter, node);
      - 72:         }
      - 73:         
      - 74:         @Override
      - 75:         public boolean equals(Object obj) {
      - 76:             if (obj instanceof TerminatedProgramVMContext) {
      - 77:                 TerminatedProgramVMContext context = (TerminatedProgramVMContext)obj;
      - 78:                 return getVMNode().equals(context.getVMNode());
      - 79:             }
      - 80:             return false;
      - 81:         }
      - 82:         
      - 83:         @Override
      - 84:         public int hashCode() {
      - 85:             return getVMNode().hashCode();
      - 86:         }
      - 87:     }
      - 88:     
      - 89:     public PDAProgramVMNode(AbstractDMVMProvider provider, DsfSession session) {
      - 90:         super(provider, session, IExecutionDMContext.class);
      - 91:     }
      -
      - 93:     @Override
      - 94:     public void update(IHasChildrenUpdate[] updates) {
      - 95:         for (IHasChildrenUpdate update : updates) {
      - 96:             // Check if the launch is initialized.  PDA program element should 
      - 97:             // be shown only if the launch has completed initializing.
      - 98:             PDALaunch launch = findLaunchInPath(update.getElementPath());
      - 99:             update.setHasChilren(launch != null && launch.isInitialized());
      -100:             update.done();
      -101:         }        
      -102:     }
      -
      -104:     @Override
      -105:     public void update(IChildrenCountUpdate[] updates) {
      -106:         for (IChildrenCountUpdate update : updates) {
      -107:             // Check if the launch is initialized.  PDA program element should 
      -108:             // be shown only if the launch has completed initializing.
      -109:             PDALaunch launch = findLaunchInPath(update.getElementPath());
      -110:             if (launch != null && launch.isInitialized()) {
      -111:                 update.setChildCount(1);
      -112:             } else {
      -113:                 update.setChildCount(0);
      -114:             }
      -115:             update.done();
      -116:         }        
      -117:     }
      -
      -119:     @Override
      -120:     public void update(IChildrenUpdate[] updates) {
      -121:         for (IChildrenUpdate update : updates) {
      -122:             PDALaunch launch = findLaunchInPath(update.getElementPath());
      -123:             if (launch != null && launch.isInitialized() && launch.isShutDown()) {
      -124:                 // If the debug session has been shut down, add a dummy 
      -125:                 // VM context representing the PDA thread.
      -126:                 update.setChild(new TerminatedProgramVMContext(getVMProvider().getVMAdapter(), this), 0);
      -127:                 update.done();
      -128:             } else {
      -129:                 super.update(new IChildrenUpdate[] { update });
      -130:             }
      -131:         }
      -132:     }
      -133:     
      -134:     @Override
      -135:     protected void updateElementsInSessionThread(final IChildrenUpdate update) {
      -136:             // Get the instance of the service.  Note that there is no race condition
      -137:             // in getting the service since this method is called only in the 
      -138:             // service executor thread.
      -139:         final PDACommandControl commandControl = getServicesTracker().getService(PDACommandControl.class);
      -
      -141:         // Check if the service is available.  If it is not, no elements are 
      -142:         // updated.
      -143:         if (commandControl == null) {
      -144:             handleFailedUpdate(update);
      -145:             return;
      -146:         }
      -147:         
      -148:         update.setChild(createVMContext(commandControl.getProgramDMContext()), 0);
      -149:         update.done();
      -150:     }
      -
      -152:     public void update(final ILabelUpdate[] updates) {
      -153:         for (final ILabelUpdate update : updates) {
      -154:             if (update.getElement() instanceof TerminatedProgramVMContext) {
      -155:                 // If the element is a terminated program, update the label 
      -156:                 // in the View Model thread.
      -157:                 updateTerminatedThreadLabel(update);
      -158:             } else {
      -159:                 // If the element is the PDA Program context, try to switch
      -160:                 // to the DSF session thread before updating the label.
      -161:                 try {
      -162:                     getSession().getExecutor().execute(new DsfRunnable() {
      -163:                         public void run() {
      -164:                             updateProgramLabelInSessionThread(update);
      -165:                         }});
      -166:                 } catch (RejectedExecutionException e) {
      -167:                     // Acceptable race condition: DSF session terminated.
      -168:                     handleFailedUpdate(update);
      -169:                 }
      -170:             }
      -171:         }
      -172:     }
      -173:     
      -174:     @ConfinedToDsfExecutor("getSession().getExecutor()")
      -175:     private void updateProgramLabelInSessionThread(final ILabelUpdate update) {
      -176:         // Get a reference to the run control service.
      -177:         final IRunControl runControl = getServicesTracker().getService(IRunControl.class);
      -178:         if (runControl == null) {
      -179:             handleFailedUpdate(update);
      -180:             return;
      -181:         }
      -182:         
      -183:         // Find the PDA program context.
      -184:         final PDAProgramDMContext programCtx = 
      -185:             findDmcInPath(update.getViewerInput(), update.getElementPath(), PDAProgramDMContext.class);
      -
      -187:         // Call service to get current program state
      -188:         final boolean isSuspended = runControl.isSuspended(programCtx);
      -
      -190:         // Set the program icon based on the running state of the program.
      -191:         String imageKey = null;
      -192:         if (isSuspended) {
      -193:             imageKey = IDebugUIConstants.IMG_OBJS_THREAD_SUSPENDED;
      -194:         } else {
      -195:             imageKey = IDebugUIConstants.IMG_OBJS_THREAD_RUNNING;
      -196:         }
      -197:         update.setImageDescriptor(DebugUITools.getImageDescriptor(imageKey), 0);
      -
      -199:         // Retrieve the last state chagne reason 
      -200:         runControl.getExecutionData(
      -201:             programCtx, 
      -202:             new DataRequestMonitor<IExecutionDMData>(ImmediateExecutor.getInstance(), null) 
      -203:             { 
      -204:                 @Override
      -205:                 public void handleCompleted(){
      -206:                     // If the request failed, fail the udpate. 
      -207:                     if (!getStatus().isOK()) {
      -208:                         handleFailedUpdate(update);
      -209:                         return;
      -210:                     }
      -211:     
      -212:                     // Compose the thread name string.
      -213:                     final StringBuilder builder = new StringBuilder(); 
      -214:     
      -215:                     builder.append("PDA [");
      -216:                     builder.append(programCtx.getProgram());
      -217:                     builder.append("]");
      -218:                     
      -219:                     if(isSuspended) {
      -220:                         builder.append(" (Suspended"); 
      -221:                     } else {
      -222:                         builder.append(" (Running"); 
      -223:                     }
      -224:                     // Reason will be null before ContainerSuspendEvent is fired
      -225:                     if(getData().getStateChangeReason() != null) {
      -226:                         builder.append(" : "); 
      -227:                         builder.append(getData().getStateChangeReason());
      -228:                     }
      -229:                     builder.append(")"); 
      -230:                     update.setLabel(builder.toString(), 0);
      -231:                     update.done();
      -232:                 }
      -233:             });        
      -234:     }
      -235:     
      -236:     private void updateTerminatedThreadLabel(ILabelUpdate update) {
      -237:         update.setLabel("<terminated> PDA [" + getProgramName(update) + "]", 0);
      -238:         update.setImageDescriptor(DebugUITools.getImageDescriptor(IDebugUIConstants.IMG_OBJS_DEBUG_TARGET_TERMINATED), 0);
      -239:         update.done();
      -240:     }
      -
      -242:     private String getProgramName(IViewerUpdate update) {
      -243:         // Retrieve the program name from the launch object in the update path.
      -244:         String program = "unknown program";
      -245:         ILaunch launch = findLaunchInPath(update.getElementPath());
      -246:         if (launch != null) {
      -247:             try {
      -248:                 program = launch.getLaunchConfiguration().getAttribute(PDAPlugin.ATTR_PDA_PROGRAM, program);
      -249:             } catch (CoreException e) {
      -250:                 // Ignore, label will revert to default.
      -251:             }
      -252:         } 
      -253:         return program;
      -254:     }
      -255:     
      -256:     private PDALaunch findLaunchInPath(TreePath path) {
      -257:         for (int i = 0; i < path.getSegmentCount(); i++) {
      -258:             if (path.getSegment(i) instanceof PDALaunch) {
      -259:                 return (PDALaunch)path.getSegment(i);
      -260:             }
      -261:         }
      -262:         return null;
      -263:     }
      -
      -265:     public int getDeltaFlags(Object e) {
      -266:         if(e instanceof IResumedDMEvent || e instanceof ISuspendedDMEvent) {
      -267:             return IModelDelta.STATE;
      -268:         } 
      -269:         if (e instanceof PDAStartedEvent) {
      -270:             return IModelDelta.EXPAND | IModelDelta.SELECT;
      -271:         }
      -272:         return IModelDelta.NO_CHANGE;
      -273:     }
      -
      -275:     public void buildDelta(Object e, VMDelta parentDelta, int nodeOffset, RequestMonitor rm) {
      -276:         if(e instanceof IResumedDMEvent || e instanceof ISuspendedDMEvent) {
      -277:             // If a suspended/resumed event is received, just update the 
      -278:             // state of the program.  StackFramesVMNode will take care of 
      -279:             // refreshing the stack frames.
      -280:             parentDelta.addNode(createVMContext(((IDMEvent<?>)e).getDMContext()), IModelDelta.STATE);
      -281:         } 
      -282:         if (e instanceof PDAStartedEvent) {
      -283:             // When debug session is started expand and select the program.
      -284:             // If the program hits a breakpoint, the top stack frame will then
      -285:             // be selected.
      -286:             parentDelta.addNode(createVMContext(((PDAStartedEvent)e).getDMContext()), IModelDelta.EXPAND | IModelDelta.SELECT);            
      -287:         }
      -288:         rm.done();
      -289:            }
      -290: }
      -
      - - - diff --git a/plugins/org.eclipse.dd.examples.pda/readme.html b/plugins/org.eclipse.dd.examples.pda/readme.html index 2a7cb9df3bc..c8858def16d 100644 --- a/plugins/org.eclipse.dd.examples.pda/readme.html +++ b/plugins/org.eclipse.dd.examples.pda/readme.html @@ -4,7 +4,7 @@ Linux®™ comes with Perl. For Microsoft® Windows®, we use either ActivePerl (http://www.activeperl.com/) or Indigo Perl (http://www.indigostar.com/). You also - have to set the string substitution variable named “perlExecutable” + have to set the string substitution variable named “dsfPerlExecutable” to the complete path to your Perl interpreter. (For example, ours was C:\perl\bin\perl.exe) To set a string substitution variable, use the Windows > Preferences > Run/Debug > String Substitution preferences page.
      diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunch.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunch.java.html deleted file mode 100644 index fb914a97cd8..00000000000 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunch.java.html +++ /dev/null @@ -1,271 +0,0 @@ - - - -PDALaunch.java - - - - - -
        1: /*******************************************************************************
      -  2:  * Copyright (c) 2008 Wind River Systems and others.
      -  3:  * All rights reserved. This program and the accompanying materials
      -  4:  * are made available under the terms of the Eclipse Public License v1.0
      -  5:  * which accompanies this distribution, and is available at
      -  6:  * http://www.eclipse.org/legal/epl-v10.html
      -  7:  * 
      -  8:  * Contributors:
      -  9:  *     Wind River Systems - initial API and implementation
      - 10:  *******************************************************************************/
      - 11: package org.eclipse.dd.examples.pda.launch;
      -
      - 13: import org.eclipse.core.runtime.IStatus;
      - 14: import org.eclipse.core.runtime.MultiStatus;
      - 15: import org.eclipse.core.runtime.Platform;
      - 16: import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor;
      - 17: import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor;
      - 18: import org.eclipse.dd.dsf.concurrent.ImmediateExecutor;
      - 19: import org.eclipse.dd.dsf.concurrent.RequestMonitor;
      - 20: import org.eclipse.dd.dsf.concurrent.Sequence;
      - 21: import org.eclipse.dd.dsf.concurrent.ThreadSafe;
      - 22: import org.eclipse.dd.dsf.service.DsfServiceEventHandler;
      - 23: import org.eclipse.dd.dsf.service.DsfSession;
      - 24: import org.eclipse.dd.examples.pda.PDAPlugin;
      - 25: import org.eclipse.dd.examples.pda.service.PDATerminatedEvent;
      - 26: import org.eclipse.debug.core.DebugException;
      - 27: import org.eclipse.debug.core.ILaunchConfiguration;
      - 28: import org.eclipse.debug.core.Launch;
      - 29: import org.eclipse.debug.core.model.ISourceLocator;
      - 30: import org.eclipse.debug.core.model.ITerminate;
      -
      - 32: /**
      - 33:  * The PDA launch object. In general, a DSF-based debugger has to override 
      - 34:  * the base launch class in order to supply its own content providers for the 
      - 35:  * debug view.  Additionally, the PDA launch is used to monitor the state of the
      - 36:  * PDA debugger and to shutdown the DSF services and session belonging to the 
      - 37:  * launch.
      - 38:  * <p>
      - 39:  * The PDA launch class mostly contains methods and fields that can be accessed
      - 40:  * on any thread.  However, some fields and methods used for managing the DSF
      - 41:  * session need to be synchronized using the DSF executor.
      - 42:  * </p>
      - 43:  */
      - 44: @ThreadSafe
      - 45: public class PDALaunch extends Launch
      - 46: implements ITerminate
      - 47: {   
      - 48:     // DSF executor and session.  Both are created and shutdown by the launch. 
      - 49:     private final DefaultDsfExecutor fExecutor;
      - 50:     private final DsfSession fSession;
      -
      - 52:     // Objects used to track the status of the DSF session.
      - 53:     private boolean fInitialized = false;
      - 54:     private boolean fShutDown = false;
      - 55:     
      - 56:     @ConfinedToDsfExecutor("getSession().getExecutor()")
      - 57:     private Sequence fInitializationSequence = null;
      -
      - 59:     /**
      - 60:      * Launch constructor creates the launch for given parameters.  The
      - 61:      * constructor also creates a DSF session and an executor, so that 
      - 62:      * {@link #getSession()} returns a valid value, however no services 
      - 63:      * are initialized yet. 
      - 64:      * 
      - 65:      * @see Launch
      - 66:      */
      - 67:     public PDALaunch(ILaunchConfiguration launchConfiguration, String mode, ISourceLocator locator) {
      - 68:         super(launchConfiguration, mode, locator);
      -
      - 70:         // Create the dispatch queue to be used by debugger control and services 
      - 71:         // that belong to this launch
      - 72:         final DefaultDsfExecutor dsfExecutor = new DefaultDsfExecutor(PDAPlugin.ID_PDA_DEBUG_MODEL);
      - 73:         dsfExecutor.prestartCoreThread();
      - 74:         fExecutor = dsfExecutor;
      - 75:         fSession = DsfSession.startSession(fExecutor, PDAPlugin.ID_PDA_DEBUG_MODEL);
      - 76:     }
      -
      - 78:     /**
      - 79:      * Returns the DSF services session that belongs to this launch.  This 
      - 80:      * method will always return a DsfSession object, however if the debugger 
      - 81:      * is shut down, the session will no longer active.
      - 82:      */
      - 83:     public DsfSession getSession() { return fSession; }
      -
      - 85:     /**
      - 86:      * Initializes the DSF services using the specified parameters.  This 
      - 87:      * method has to be called on the executor thread in order to avoid 
      - 88:      * synchronization issues.  
      - 89:      */
      - 90:     @ConfinedToDsfExecutor("getSession().getExecutor()")
      - 91:     public void initializeServices(String program, int requestPort, int eventPort, final RequestMonitor rm)
      - 92:     {
      - 93:         // Double-check that we're being called in the correct thread.
      - 94:         assert fExecutor.isInExecutorThread();
      -
      - 96:         // Check if shutdownServices() was called already, which would be 
      - 97:         // highly unusual, but if so we don't need to do anything except set 
      - 98:         // the initialized flag.
      - 99:         synchronized(this) {
      -100:             if (fShutDown) {
      -101:                 fInitialized = true;
      -102:                 return;
      -103:             }
      -104:         }
      -
      -106:         // Register the launch as listener for services events.
      -107:         fSession.addServiceEventListener(PDALaunch.this, null);
      -
      -109:         // The initialization sequence is stored in a field to allow it to be 
      -110:         // canceled if shutdownServices() is called before the sequence 
      -111:         // completes.
      -112:         fInitializationSequence = new PDAServicesInitSequence(
      -113:             getSession(), program, requestPort, eventPort, 
      -114:             new RequestMonitor(ImmediateExecutor.getInstance(), rm) {
      -115:                 @Override
      -116:                 protected void handleCompleted() {
      -117:                     // Set the initialized flag and check whether the 
      -118:                     // shutdown flag is set.  Access the flags in a 
      -119:                     // synchronized section as these flags can be accessed
      -120:                     // on any thread.
      -121:                     boolean doShutdown = false;
      -122:                     synchronized (this) { 
      -123:                         fInitialized = true;
      -124:                         fInitializationSequence = null;
      -125:                         if (fShutDown) {
      -126:                             doShutdown = true;
      -127:                         }
      -128:                     }
      -
      -130:                     if (doShutdown) {
      -131:                         // If shutdownServices() was already called, start the 
      -132:                         // shutdown sequence now.
      -133:                         doShutdown(rm);
      -134:                     } else {
      -135:                         // If there was an error in the startup sequence, 
      -136:                         // report the error to the client.
      -137:                         if (getStatus().getSeverity() == IStatus.ERROR) {
      -138:                             rm.setStatus(getStatus());
      -139:                         }
      -140:                         rm.done();
      -141:                     }
      -142:                     fireChanged();
      -143:                 }
      -144:             });
      -
      -146:         // Finally, execute the sequence. 
      -147:         getSession().getExecutor().execute(fInitializationSequence);
      -148:     }
      -
      -150:     /**
      -151:      * Event handler for a debugger terminated event.    
      -152:      */
      -153:     @DsfServiceEventHandler 
      -154:     public void eventDispatched(PDATerminatedEvent event) {
      -155:         shutdownServices(new RequestMonitor(ImmediateExecutor.getInstance(), null));
      -156:     }
      -
      -158:     /**
      -159:      * Returns whether the DSF service initialization sequence has completed yet.
      -160:      */
      -161:     public synchronized boolean isInitialized() {
      -162:         return fInitialized;
      -163:     }
      -
      -165:     /**
      -166:      * Returns whether the DSF services have been set to shut down.
      -167:      * @return
      -168:      */
      -169:     public synchronized boolean isShutDown() {
      -170:         return fShutDown;
      -171:     }
      -
      -173:     @Override
      -174:     public boolean canTerminate() {
      -175:         return super.canTerminate() && isInitialized() && !isShutDown();
      -176:     }
      -
      -178:     @Override
      -179:     public boolean isTerminated() {
      -180:         return super.isTerminated() || isShutDown();
      -181:     }
      -
      -
      -184:     @Override
      -185:     public void terminate() throws DebugException {
      -186:         if (isShutDown()) return;
      -187:         super.terminate();
      -188:     }
      -
      -190:     /**
      -191:      * Shuts down the services, the session and the executor associated with 
      -192:      * this launch.  
      -193:      * <p>
      -194:      * Note: The argument request monitor to this method should NOT use the
      -195:      * executor that belongs to this launch.  By the time the shutdown is 
      -196:      * complete, this executor will not be dispatching anymore and the 
      -197:      * request monitor will never be invoked.  Instead callers should use
      -198:      * the {@link ImmediateExecutor}.
      -199:      * </p>
      -200:      * @param rm The request monitor invoked when the shutdown is complete.    
      -201:      */
      -202:     @ConfinedToDsfExecutor("getSession().getExecutor()")
      -203:     public void shutdownServices(final RequestMonitor rm) {
      -204:         // Check initialize and shutdown flags to determine if the shutdown
      -205:         // sequence can be called yet.
      -206:         boolean doShutdown = false;
      -207:         synchronized (this) {
      -208:             if (!fInitialized && fInitializationSequence != null) {
      -209:                 // Launch has not yet initialized, try to cancel the 
      -210:                 // shutdown sequence.
      -211:                 fInitializationSequence.cancel(false);
      -212:             } else {
      -213:                 doShutdown = !fShutDown && fInitialized;
      -214:             }
      -215:             fShutDown = true;
      -216:         }
      -
      -218:         if (doShutdown) {
      -219:             doShutdown(rm);
      -220:         } else {
      -221:             rm.done();
      -222:         }
      -223:     }
      -
      -225:     @ConfinedToDsfExecutor("getSession().getExecutor()")
      -226:     private void doShutdown(final RequestMonitor rm) {
      -227:         fExecutor.execute( new PDAServicesShutdownSequence(
      -228:             fExecutor, fSession.getId(),
      -229:             new RequestMonitor(fSession.getExecutor(), rm) { 
      -230:                 @Override
      -231:                 public void handleCompleted() {
      -232:                     fSession.removeServiceEventListener(PDALaunch.this);
      -233:                     if (!getStatus().isOK()) {
      -234:                         PDAPlugin.getDefault().getLog().log(new MultiStatus(
      -235:                             PDAPlugin.PLUGIN_ID, -1, new IStatus[]{getStatus()}, "Session shutdown failed", null)); //$NON-NLS-1$
      -236:                     }
      -237:                     // Last order of business, shutdown the dispatch queue.
      -238:                     DsfSession.endSession(fSession);
      -239:                     // endSession takes a full dispatch to distribute the 
      -240:                     // session-ended event, finish step only after the dispatch.
      -241:                     fExecutor.shutdown();
      -242:                     fireTerminate();
      -
      -244:                     rm.setStatus(getStatus());
      -245:                     rm.done();
      -246:                 }
      -247:             }) );
      -248:     }
      -
      -250:     @SuppressWarnings("unchecked")
      -251:     @Override
      -252:     public Object getAdapter(Class adapter) {
      -253:         // Force adapters to be loaded.  Otherwise the adapter manager may not find
      -254:         // the model proxy adapter for DSF-based debug elements.
      -255:         Platform.getAdapterManager().loadAdapter(this, adapter.getName());
      -256:         return super.getAdapter(adapter);
      -257:     }
      -258: }
      -
      - - - diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunchDelegate.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunchDelegate.java.html deleted file mode 100644 index f6c4b38f025..00000000000 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunchDelegate.java.html +++ /dev/null @@ -1,234 +0,0 @@ - - - -PDALaunchDelegate.java - - - - - -
        1: /*******************************************************************************
      -  2:  * Copyright (c) 2005, 2008 IBM Corporation and others.
      -  3:  * All rights reserved. This program and the accompanying materials
      -  4:  * are made available under the terms of the Eclipse Public License v1.0
      -  5:  * which accompanies this distribution, and is available at
      -  6:  * http://www.eclipse.org/legal/epl-v10.html
      -  7:  *
      -  8:  * Contributors:
      -  9:  *     IBM Corporation - initial API and implementation
      - 10:  *     Bjorn Freeman-Benson - initial API and implementation
      - 11:  *     Wind River Systems - adopted to use with DSF
      - 12:  *******************************************************************************/
      - 13: package org.eclipse.dd.examples.pda.launch;
      -
      - 15: import java.io.File;
      - 16: import java.io.IOException;
      - 17: import java.net.ServerSocket;
      - 18: import java.text.MessageFormat;
      - 19: import java.util.ArrayList;
      - 20: import java.util.List;
      - 21: import java.util.concurrent.ExecutionException;
      -
      - 23: import org.eclipse.core.resources.IFile;
      - 24: import org.eclipse.core.resources.ResourcesPlugin;
      - 25: import org.eclipse.core.runtime.CoreException;
      - 26: import org.eclipse.core.runtime.IProgressMonitor;
      - 27: import org.eclipse.core.runtime.IStatus;
      - 28: import org.eclipse.core.runtime.Path;
      - 29: import org.eclipse.core.runtime.Status;
      - 30: import org.eclipse.core.variables.IValueVariable;
      - 31: import org.eclipse.core.variables.VariablesPlugin;
      - 32: import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
      - 33: import org.eclipse.dd.dsf.concurrent.Query;
      - 34: import org.eclipse.dd.examples.pda.PDAPlugin;
      - 35: import org.eclipse.debug.core.DebugException;
      - 36: import org.eclipse.debug.core.DebugPlugin;
      - 37: import org.eclipse.debug.core.ILaunch;
      - 38: import org.eclipse.debug.core.ILaunchConfiguration;
      - 39: import org.eclipse.debug.core.model.IPersistableSourceLocator;
      - 40: import org.eclipse.debug.core.model.ISourceLocator;
      - 41: import org.eclipse.debug.core.model.LaunchConfigurationDelegate;
      - 42: import org.eclipse.debug.core.sourcelookup.IPersistableSourceLocator2;
      -
      -
      - 45: /**
      - 46:  * Launches PDA program on a PDA interpretter written in Perl 
      - 47:  */
      - 48: public class PDALaunchDelegate extends LaunchConfigurationDelegate {
      -
      - 50:     @Override
      - 51:     public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) throws CoreException {
      - 52:         // Need to configure the source locator before creating the launch
      - 53:         // because once the launch is created and added to launch manager, 
      - 54:         // the adapters will be created for the whole session, including 
      - 55:         // the source lookup adapter.
      - 56:         ISourceLocator locator = getSourceLocator(configuration);
      -
      - 58:         return new PDALaunch(configuration, mode, locator);
      - 59:     }
      -
      - 61:     @Override
      - 62:     public boolean buildForLaunch(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException {
      - 63:         // PDA programs do not require building.
      - 64:         return false;
      - 65:     }
      -
      - 67:     /**
      - 68:      * Returns a source locator created based on the attributes in the launch configuration.
      - 69:      */
      - 70:     private ISourceLocator getSourceLocator(ILaunchConfiguration configuration) throws CoreException {
      - 71:         String type = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_ID, (String)null);
      - 72:         if (type == null) {
      - 73:             type = configuration.getType().getSourceLocatorId();
      - 74:         }
      - 75:         if (type != null) {
      - 76:             IPersistableSourceLocator locator = DebugPlugin.getDefault().getLaunchManager().newSourceLocator(type);
      - 77:             String memento = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_MEMENTO, (String)null);
      - 78:             if (memento == null) {
      - 79:                 locator.initializeDefaults(configuration);
      - 80:             } else {
      - 81:                 if(locator instanceof IPersistableSourceLocator2)
      - 82:                     ((IPersistableSourceLocator2)locator).initializeFromMemento(memento, configuration);
      - 83:                 else
      - 84:                     locator.initializeFromMemento(memento);
      - 85:             }
      - 86:             return locator;
      - 87:         }
      - 88:         return null;
      - 89:     }
      -
      - 91:     public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException {
      - 92:         String program = configuration.getAttribute(PDAPlugin.ATTR_PDA_PROGRAM, (String)null);
      - 93:         if (program == null) {
      - 94:             abort("Perl program unspecified.", null);
      - 95:         }
      -
      - 97:         int requestPort = findFreePort();
      - 98:         int eventPort = findFreePort();
      - 99:         if (requestPort == -1 || eventPort == -1) {
      -100:             abort("Unable to find free port", null);
      -101:         }
      -
      -103:         launchProcess(launch, program, requestPort, eventPort);
      -104:         PDALaunch pdaLaunch = (PDALaunch)launch; 
      -105:         initServices(pdaLaunch, program, requestPort, eventPort);
      -106:     }
      -
      -108:     /**
      -109:      * Launches PDA interpreter with the given program.
      -110:      *  
      -111:      * @param launch Launch that will contain the new process.
      -112:      * @param program PDA program to use in the interpreter.
      -113:      * @param requestPort The port number for connecting the request socket.
      -114:      * @param eventPort The port number for connecting the events socket.
      -115:      * 
      -116:      * @throws CoreException 
      -117:      */
      -118:     private void launchProcess(ILaunch launch, String program, int requestPort, int eventPort) throws CoreException {
      -119:         List<String> commandList = new ArrayList<String>();
      -
      -121:         // Find Perl executable
      -122:         IValueVariable perl = VariablesPlugin.getDefault().getStringVariableManager().getValueVariable(PDAPlugin.VARIALBE_PERL_EXECUTABLE);
      -123:         if (perl == null) {
      -124:             abort("Perl executable location undefined. Check value of ${dsfPerlExecutable}.", null);
      -125:         }
      -126:         String path = perl.getValue();
      -127:         if (path == null) {
      -128:             abort("Perl executable location unspecified. Check value of ${dsfPerlExecutable}.", null);
      -129:         }
      -130:         File exe = new File(path);
      -131:         if (!exe.exists()) {
      -132:             abort(MessageFormat.format("Specified Perl executable {0} does not exist. Check value of $dsfPerlExecutable.", new Object[]{path}), null);
      -133:         }
      -134:         commandList.add(path);
      -
      -136:         // Add PDA VM
      -137:         File vm = PDAPlugin.getFileInPlugin(new Path("pdavm/pda.pl"));
      -138:         if (vm == null) {
      -139:             abort("Missing PDA VM", null);
      -140:         }
      -141:         commandList.add(vm.getAbsolutePath());
      -
      -143:         // Add PDA program
      -144:         IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(program));
      -145:         if (!file.exists()) {
      -146:             abort(MessageFormat.format("Perl program {0} does not exist.", new Object[] {file.getFullPath().toString()}), null);
      -147:         }
      -
      -149:         commandList.add(file.getLocation().toOSString());
      -
      -151:         // Add debug arguments - i.e. '-debug requestPort eventPort'
      -152:         commandList.add("-debug");
      -153:         commandList.add("" + requestPort);
      -154:         commandList.add("" + eventPort);
      -
      -156:         // Launch the perl process.
      -157:         String[] commandLine = commandList.toArray(new String[commandList.size()]);
      -158:         Process process = DebugPlugin.exec(commandLine, null);
      -
      -160:         // Create a debug platform process object and add it to the launch.
      -161:         DebugPlugin.newProcess(launch, process, path);
      -162:     }
      -
      -164:     /**
      -165:      * Calls the launch to initialize DSF services for this launch.
      -166:      */
      -167:     private void initServices(final PDALaunch pdaLaunch, final String program, final int requestPort, final int eventPort) 
      -168:     throws CoreException 
      -169:     {
      -170:         // Synchronization object to use when waiting for the services initialization.
      -171:         Query<Object> initQuery = new Query<Object>() {
      -172:             @Override
      -173:             protected void execute(DataRequestMonitor<Object> rm) {
      -174:                 pdaLaunch.initializeServices(program, requestPort, eventPort, rm);
      -175:             }
      -176:         };
      -
      -178:         // Submit the query to the executor.
      -179:         pdaLaunch.getSession().getExecutor().execute(initQuery);
      -180:         try {
      -181:             // Block waiting for query results.
      -182:             initQuery.get();
      -183:         } catch (InterruptedException e1) {
      -184:             throw new DebugException(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, "Interrupted Exception in dispatch thread", e1)); //$NON-NLS-1$
      -185:         } catch (ExecutionException e1) {
      -186:             throw new DebugException(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Error in launch sequence", e1.getCause())); //$NON-NLS-1$
      -187:         }
      -188:     }
      -
      -190:     /**
      -191:      * Throws an exception with a new status containing the given
      -192:      * message and optional exception.
      -193:      * 
      -194:      * @param message error message
      -195:      * @param e underlying exception
      -196:      * @throws CoreException
      -197:      */
      -198:     private void abort(String message, Throwable e) throws CoreException {
      -199:         throw new CoreException(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, 0, message, e));
      -200:     }
      -
      -202:     /**
      -203:      * Returns a free port number on localhost, or -1 if unable to find a free port.
      -204:      */
      -205:     public static int findFreePort() {
      -206:         ServerSocket socket= null;
      -207:         try {
      -208:             socket= new ServerSocket(0);
      -209:             return socket.getLocalPort();
      -210:         } catch (IOException e) { 
      -211:         } finally {
      -212:             if (socket != null) {
      -213:                 try {
      -214:                     socket.close();
      -215:                 } catch (IOException e) {
      -216:                 }
      -217:             }
      -218:         }
      -219:         return -1;                
      -220:     }                
      -221: }
      -
      - - - diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java.html deleted file mode 100644 index 7f4aae65d3d..00000000000 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java.html +++ /dev/null @@ -1,140 +0,0 @@ - - - -PDAServicesInitSequence.java - - - - - -
        1: /*******************************************************************************
      -  2:  * Copyright (c) 2008 Wind River Systems and others.
      -  3:  * All rights reserved. This program and the accompanying materials
      -  4:  * are made available under the terms of the Eclipse Public License v1.0
      -  5:  * which accompanies this distribution, and is available at
      -  6:  * http://www.eclipse.org/legal/epl-v10.html
      -  7:  * 
      -  8:  * Contributors:
      -  9:  *     Wind River Systems - initial API and implementation
      - 10:  *******************************************************************************/
      - 11: package org.eclipse.dd.examples.pda.launch;
      -
      - 13: import org.eclipse.dd.dsf.concurrent.RequestMonitor;
      - 14: import org.eclipse.dd.dsf.concurrent.Sequence;
      - 15: import org.eclipse.dd.dsf.debug.service.BreakpointsMediator;
      - 16: import org.eclipse.dd.dsf.debug.service.StepQueueManager;
      - 17: import org.eclipse.dd.dsf.service.DsfSession;
      - 18: import org.eclipse.dd.examples.pda.service.PDABreakpointAttributeTranslator;
      - 19: import org.eclipse.dd.examples.pda.service.PDABreakpoints;
      - 20: import org.eclipse.dd.examples.pda.service.PDACommandControl;
      - 21: import org.eclipse.dd.examples.pda.service.PDAExpressions;
      - 22: import org.eclipse.dd.examples.pda.service.PDARunControl;
      - 23: import org.eclipse.dd.examples.pda.service.PDAStack;
      -
      - 25: /**
      - 26:  * The initialization sequence for PDA debugger services.  This sequence contains
      - 27:  * the series of steps that are executed to properly initialize the PDA-DSF debug
      - 28:  * session.  If any of the individual steps fail, the initialization will abort.   
      - 29:  * <p>
      - 30:  * The order in which services are initialized is important.  Some services depend
      - 31:  * on other services and they assume that they will be initialized only if those
      - 32:  * services are active.  Also the service events are prioritized and their priority
      - 33:  * depends on the order in which the services were initialized.
      - 34:  * </p>
      - 35:  */
      - 36: public class PDAServicesInitSequence extends Sequence {
      -
      - 38:     Step[] fSteps = new Step[] {
      - 39:         new Step() 
      - 40:         { 
      - 41:             @Override
      - 42:             public void execute(RequestMonitor requestMonitor) {
      - 43:                 // Create the connection to PDA debugger.
      - 44:                 fCommandControl = new PDACommandControl(fSession, fProgram, fRequestPort, fEventPort);
      - 45:                 fCommandControl.initialize(requestMonitor);
      - 46:             }
      - 47:         },
      - 48:         new Step() { 
      - 49:             @Override
      - 50:             public void execute(RequestMonitor requestMonitor) {
      - 51:                 // Start the run control service.
      - 52:                 fRunControl = new PDARunControl(fSession);
      - 53:                 fRunControl.initialize(requestMonitor);
      - 54:             }
      - 55:         },
      - 56:         new Step() { 
      - 57:             @Override
      - 58:             public void execute(RequestMonitor requestMonitor) {
      - 59:                 // Start the service to manage step actions.
      - 60:                 new StepQueueManager(fSession).initialize(requestMonitor);
      - 61:             }
      - 62:         },
      - 63:         new Step() { 
      - 64:             @Override
      - 65:             public void execute(final RequestMonitor requestMonitor) {
      - 66:                 // Start the low-level breakpoint service 
      - 67:                 new PDABreakpoints(fSession).initialize(new RequestMonitor(getExecutor(), requestMonitor));
      - 68:             }
      - 69:         },
      - 70:         new Step() { 
      - 71:             @Override
      - 72:             public void execute(final RequestMonitor requestMonitor) {
      - 73:                 // Create the breakpoint mediator and start tracking PDA breakpoints.
      -
      - 75:                 final BreakpointsMediator bpmService = new BreakpointsMediator(
      - 76:                     fSession, new PDABreakpointAttributeTranslator());
      - 77:                 bpmService.initialize(new RequestMonitor(getExecutor(), requestMonitor) {
      - 78:                     @Override
      - 79:                     protected void handleOK() {
      - 80:                         bpmService.startTrackingBreakpoints(fCommandControl.getProgramDMContext(), requestMonitor);
      - 81:                     }
      - 82:                 }); 
      - 83:             }
      - 84:         },
      - 85:         new Step() { @Override
      - 86:             public void execute(RequestMonitor requestMonitor) {
      - 87:             // Start the stack service.
      - 88:             new PDAStack(fSession).initialize(requestMonitor);
      - 89:         }
      - 90:         },
      - 91:         new Step() { @Override
      - 92:             public void execute(RequestMonitor requestMonitor) {
      - 93:             // Start the service to track expressions.
      - 94:             new PDAExpressions(fSession).initialize(requestMonitor);
      - 95:         }
      - 96:         },
      - 97:         new Step() { @Override
      - 98:             public void execute(RequestMonitor requestMonitor) {
      - 99:             fRunControl.resume(fCommandControl.getProgramDMContext(), requestMonitor);
      -100:         }
      -101:         },
      -102:     };
      -
      -104:     // Sequence input parameters, used in initializing services.
      -105:     private DsfSession fSession;
      -106:     private String fProgram;
      -107:     private int fRequestPort;
      -108:     private int fEventPort;
      -
      -110:     // Service references, initialized when created and used in initializing other services.
      -111:     private PDACommandControl fCommandControl;
      -112:     private PDARunControl fRunControl;
      -
      -114:     public PDAServicesInitSequence(DsfSession session, String program, int requestPort, int eventPort, RequestMonitor rm) 
      -115:     {
      -116:         super(session.getExecutor(), rm);
      -117:         fSession = session;
      -118:         fProgram = program;
      -119:         fRequestPort = requestPort;
      -120:         fEventPort = eventPort;
      -121:     }
      -
      -123:     @Override
      -124:     public Step[] getSteps() {
      -125:         return fSteps;
      -126:     }
      -127: }
      -
      - - - diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpointAttributeTranslator.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpointAttributeTranslator.java.html deleted file mode 100644 index 7696dc71e9e..00000000000 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpointAttributeTranslator.java.html +++ /dev/null @@ -1,148 +0,0 @@ - - - -PDABreakpointAttributeTranslator.java - - - - - -
        1: /*******************************************************************************
      -  2:  * Copyright (c) 2008 Wind River Systems and others.
      -  3:  * All rights reserved. This program and the accompanying materials
      -  4:  * are made available under the terms of the Eclipse Public License v1.0
      -  5:  * which accompanies this distribution, and is available at
      -  6:  * http://www.eclipse.org/legal/epl-v10.html
      -  7:  * 
      -  8:  * Contributors:
      -  9:  *     Wind River Systems - initial API and implementation
      - 10:  *******************************************************************************/
      - 11: package org.eclipse.dd.examples.pda.service;
      -
      - 13: import java.util.ArrayList;
      - 14: import java.util.HashMap;
      - 15: import java.util.List;
      - 16: import java.util.Map;
      -
      - 18: import org.eclipse.core.resources.IMarker;
      - 19: import org.eclipse.core.runtime.CoreException;
      - 20: import org.eclipse.core.runtime.IStatus;
      - 21: import org.eclipse.core.runtime.Status;
      - 22: import org.eclipse.dd.dsf.debug.service.BreakpointsMediator;
      - 23: import org.eclipse.dd.dsf.debug.service.IBreakpointAttributeTranslator;
      - 24: import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointDMContext;
      - 25: import org.eclipse.dd.examples.pda.PDAPlugin;
      - 26: import org.eclipse.dd.examples.pda.breakpoints.PDALineBreakpoint;
      - 27: import org.eclipse.dd.examples.pda.breakpoints.PDAWatchpoint;
      - 28: import org.eclipse.debug.core.DebugException;
      - 29: import org.eclipse.debug.core.model.IBreakpoint;
      -
      - 31: /**
      - 32:  * Translator between {@link PDALineBreakpoint} object attributes and 
      - 33:  * attributes used by the {@link PDABreakpoints} service.  
      - 34:  * <p>
      - 35:  * The attribute translator is used by the standard {@link BreakpointsMediator} 
      - 36:  * service to map between platform breakpoint attributes and target-side DSF
      - 37:  * breakpoint attributes.  Thus, this object encapsulates the model-specific
      - 38:  * functionality of synchronizing target side and IDE-side breakpoint objects.  
      - 39:  * </p>
      - 40:  */
      - 41: public class PDABreakpointAttributeTranslator implements IBreakpointAttributeTranslator {
      -
      - 43:     // Arrays of common attributes between the two breakpoint types.  These 
      - 44:     // attributes can be copied directly without translation.
      - 45:     private static final String[] fgPDALineBreakpointAttributes = {
      - 46:         IBreakpoint.ENABLED,
      - 47:         IMarker.LINE_NUMBER,
      - 48:     };
      - 49:     private static final String[] fgPDAWatchpointAttributes = {
      - 50:         IBreakpoint.ENABLED,
      - 51:         PDAWatchpoint.FUNCTION_NAME,
      - 52:         PDAWatchpoint.VAR_NAME,
      - 53:         PDAWatchpoint.ACCESS,
      - 54:         PDAWatchpoint.MODIFICATION
      - 55:     };
      -
      - 57:     // PDA breakpoints translator doesn't keep any state and it doesn't 
      - 58:     // need to initialize or clean up.
      - 59:     public void initialize(BreakpointsMediator mediator) {
      - 60:     }
      -
      - 62:     public void dispose() {
      - 63:     }
      -
      - 65:     public List<Map<String, Object>> getBreakpointAttributes(IBreakpoint bp, boolean bpManagerEnabled) 
      - 66:     throws CoreException 
      - 67:     {
      - 68:         Map<String, Object> attrs = new HashMap<String, Object>(); 
      -
      - 70:         // Check that the marker exists and retrieve its attributes.  
      - 71:         // Due to accepted race conditions, the breakpiont marker may become null 
      - 72:         // while this method is being invoked.  In this case throw an exception
      - 73:         // and let the caller handle it.
      - 74:         IMarker marker = bp.getMarker();
      - 75:         if (marker == null || !marker.exists()) {
      - 76:             throw new DebugException(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Breakpoint marker does not exist", null)); 
      - 77:         }
      - 78:         // Suppress cast warning: platform is still on Java 1.3
      - 79:         @SuppressWarnings("unchecked")
      - 80:         Map<String, Object> platformBpAttrs = marker.getAttributes();
      -
      - 82:         // Copy breakpoint attributes.
      - 83:         if (bp instanceof PDAWatchpoint) {
      - 84:             attrs.put(PDABreakpoints.ATTR_BREAKPOINT_TYPE, PDABreakpoints.PDA_WATCHPOINT);
      -
      - 86:             copyAttributes(platformBpAttrs, attrs, fgPDAWatchpointAttributes);
      - 87:         } else if (bp instanceof PDALineBreakpoint) {
      - 88:             attrs.put(PDABreakpoints.ATTR_BREAKPOINT_TYPE, PDABreakpoints.PDA_LINE_BREAKPOINT);
      - 89:             attrs.put(PDABreakpoints.ATTR_PROGRAM_PATH, marker.getResource().getFullPath().toString()); 
      -
      - 91:             copyAttributes(platformBpAttrs, attrs, fgPDALineBreakpointAttributes);
      - 92:         }
      -
      - 94:         // If the breakpoint manager is disabled, override the enabled attribute.
      - 95:         if (!bpManagerEnabled) {
      - 96:             attrs.put(IBreakpoint.ENABLED, false);
      - 97:         }
      -
      - 99:         // The breakpoint mediator allows for multiple target-side breakpoints 
      -100:         // to be created for each IDE breakpoint.  Although in case of PDA this 
      -101:         // feature is never used, we still have to return a list of attributes.
      -102:         List<Map<String, Object>> retVal = new ArrayList<Map<String, Object>>(1);
      -103:         retVal.add(attrs);
      -104:         return retVal;
      -105:     }
      -
      -107:     private void copyAttributes(Map<String, Object> srcMap, Map<String, Object> destMap, String[] attrs) {
      -108:         for (String attr : attrs) {
      -109:             if (srcMap.containsKey(attr)) {
      -110:                 destMap.put(attr, srcMap.get(attr));
      -111:             }
      -112:         }
      -113:     }
      -
      -115:     public boolean canUpdateAttributes(IBreakpointDMContext bp, Map<String, Object> delta) {
      -116:         // PDA debugger only allows updating of the action property of the watchpoint.
      -117:         // All other breakpoint updates will require a re-installation.
      -118:         if (bp instanceof PDAWatchpoint) {
      -119:             Map<String, Object> deltaCopy = new HashMap<String, Object>(delta);
      -120:             deltaCopy.remove(PDAWatchpoint.ACCESS);
      -121:             deltaCopy.remove(PDAWatchpoint.MODIFICATION);
      -122:             return !deltaCopy.isEmpty();
      -123:         }
      -124:         return false;
      -125:     }
      -
      -127:     public boolean supportsBreakpoint(IBreakpoint bp) {
      -128:         return bp.getModelIdentifier().equals(PDAPlugin.ID_PDA_DEBUG_MODEL);
      -129:     }
      -
      -131:     public void updateBreakpointStatus(IBreakpoint bp) {
      -132:         // PDA breakpoints do not support status reporting
      -133:     }
      -
      -135: }
      -
      - - - diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpoints.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpoints.java.html deleted file mode 100644 index 5976bfa268d..00000000000 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpoints.java.html +++ /dev/null @@ -1,416 +0,0 @@ - - - -PDABreakpoints.java - - - - - -
        1: /*******************************************************************************
      -  2:  * Copyright (c) 2007 Ericsson and others.
      -  3:  * All rights reserved. This program and the accompanying materials
      -  4:  * are made available under the terms of the Eclipse Public License v1.0
      -  5:  * which accompanies this distribution, and is available at
      -  6:  * http://www.eclipse.org/legal/epl-v10.html
      -  7:  *
      -  8:  * Contributors:
      -  9:  *     Ericsson - Initial API and implementation
      - 10:  *******************************************************************************/
      -
      - 12: package org.eclipse.dd.examples.pda.service;
      -
      - 14: import java.util.HashSet;
      - 15: import java.util.Hashtable;
      - 16: import java.util.Map;
      - 17: import java.util.Set;
      -
      - 19: import org.eclipse.core.resources.IMarker;
      - 20: import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
      - 21: import org.eclipse.dd.dsf.concurrent.Immutable;
      - 22: import org.eclipse.dd.dsf.concurrent.RequestMonitor;
      - 23: import org.eclipse.dd.dsf.datamodel.AbstractDMContext;
      - 24: import org.eclipse.dd.dsf.datamodel.DMContexts;
      - 25: import org.eclipse.dd.dsf.datamodel.IDMContext;
      - 26: import org.eclipse.dd.dsf.debug.service.IBreakpoints;
      - 27: import org.eclipse.dd.dsf.service.AbstractDsfService;
      - 28: import org.eclipse.dd.dsf.service.DsfSession;
      - 29: import org.eclipse.dd.examples.pda.PDAPlugin;
      - 30: import org.eclipse.dd.examples.pda.breakpoints.PDAWatchpoint;
      - 31: import org.eclipse.dd.examples.pda.service.commands.PDAClearBreakpointCommand;
      - 32: import org.eclipse.dd.examples.pda.service.commands.PDACommandResult;
      - 33: import org.eclipse.dd.examples.pda.service.commands.PDASetBreakpointCommand;
      - 34: import org.eclipse.dd.examples.pda.service.commands.PDAWatchCommand;
      - 35: import org.eclipse.debug.core.model.IBreakpoint;
      - 36: import org.osgi.framework.BundleContext;
      -
      - 38: /**
      - 39:  * Initial breakpoint service implementation.
      - 40:  * Implements the IBreakpoints interface.
      - 41:  */
      - 42: public class PDABreakpoints extends AbstractDsfService implements IBreakpoints
      - 43: {
      - 44:     /**
      - 45:      * Context representing a PDA line breakpoint.  In PDA debugger, since there is only 
      - 46:      * one file being debugged at a time, a breakpoint is uniquely identified using the 
      - 47:      * line number only.
      - 48:      */
      - 49:     @Immutable
      - 50:     private static class BreakpointDMContext extends AbstractDMContext implements IBreakpointDMContext {
      -
      - 52:         final Integer fLine;
      -
      - 54:         public BreakpointDMContext(String sessionId, PDAProgramDMContext commandControlCtx, Integer line) {
      - 55:             super(sessionId, new IDMContext[] { commandControlCtx });
      - 56:             fLine = line;
      - 57:         }
      -
      - 59:         @Override
      - 60:         public boolean equals(Object obj) {
      - 61:             return baseEquals(obj) && (fLine.equals(((BreakpointDMContext) obj).fLine));
      - 62:         }
      -
      - 64:         @Override
      - 65:         public int hashCode() {
      - 66:             return baseHashCode() + fLine.hashCode();
      - 67:         }
      -
      - 69:         @Override
      - 70:         public String toString() {
      - 71:             return baseToString() + ".breakpoint(" + fLine + ")";  //$NON-NLS-1$//$NON-NLS-2$*/
      - 72:         }
      - 73:     }
      -
      - 75:     /**
      - 76:      * Context representing a watch point.  In PDA debugger, a watchpoint is 
      - 77:      * uniquely identified using the function and variable.
      - 78:      */
      - 79:     @Immutable
      - 80:     private static class WatchpointDMContext extends AbstractDMContext implements IBreakpointDMContext {
      - 81:         final String fFunction;
      - 82:         final String fVariable; 
      -
      - 84:         public WatchpointDMContext(String sessionId, PDAProgramDMContext commandControlCtx, String function, 
      - 85:             String variable) 
      - 86:         {
      - 87:             super(sessionId, new IDMContext[] { commandControlCtx });
      - 88:             fFunction = function;
      - 89:             fVariable = variable;
      - 90:         }
      -
      - 92:         @Override
      - 93:         public boolean equals(Object obj) {
      - 94:             if (baseEquals(obj)) {
      - 95:                 WatchpointDMContext watchpointCtx = (WatchpointDMContext)obj;
      - 96:                 return fFunction.equals(watchpointCtx.fFunction) && fVariable.equals(watchpointCtx.fVariable);
      - 97:             }
      - 98:             return false;
      - 99:         }
      -
      -101:         @Override
      -102:         public int hashCode() {
      -103:             return baseHashCode() + fFunction.hashCode() + fVariable.hashCode();
      -104:         }
      -
      -106:         @Override
      -107:         public String toString() {
      -108:             return baseToString() + ".watchpoint(" + fFunction + "::" + fVariable + ")";
      -109:         }
      -110:     }
      -
      -112:     // Attribute names
      -113:     public static final String ATTR_BREAKPOINT_TYPE = PDAPlugin.PLUGIN_ID + ".pdaBreakpointType";      //$NON-NLS-1$
      -114:     public static final String PDA_LINE_BREAKPOINT = "breakpoint";                 //$NON-NLS-1$
      -115:     public static final String PDA_WATCHPOINT = "watchpoint";                 //$NON-NLS-1$
      -116:     public static final String ATTR_PROGRAM_PATH = PDAPlugin.PLUGIN_ID + ".pdaProgramPath";      //$NON-NLS-1$
      -
      -118:     // Services
      -119:     private PDACommandControl fCommandControl;
      -
      -121:     // Breakpoints currently installed
      -122:     private Set<IBreakpointDMContext> fBreakpoints = new HashSet<IBreakpointDMContext>();
      -
      -124:     /**
      -125:      * The service constructor
      -126:      * 
      -127:      * @param session The debugging session this service belongs to.
      -128:      */
      -129:     public PDABreakpoints(DsfSession session) {
      -130:         super(session);
      -131:     }
      -
      -133:     @Override
      -134:     public void initialize(final RequestMonitor rm) {
      -135:         super.initialize(new RequestMonitor(getExecutor(), rm) {
      -136:             @Override
      -137:             protected void handleOK() {
      -138:                 doInitialize(rm);
      -139:             }
      -140:         });
      -141:     }
      -
      -143:     private void doInitialize(final RequestMonitor rm) {
      -144:         // Get the services references
      -145:         fCommandControl = getServicesTracker().getService(PDACommandControl.class);
      -
      -147:         // Register this service
      -148:         register(new String[] { IBreakpoints.class.getName(), PDABreakpoints.class.getName() },
      -149:             new Hashtable<String, String>());
      -
      -151:         rm.done();
      -152:     }
      -
      -154:     @Override
      -155:     public void shutdown(final RequestMonitor rm) {
      -156:         unregister();
      -157:         rm.done();
      -158:     }
      -
      -160:     @Override
      -161:     protected BundleContext getBundleContext() {
      -162:         return PDAPlugin.getBundleContext();
      -163:     }
      -
      -165:     public void getBreakpoints(final IBreakpointsTargetDMContext context, final DataRequestMonitor<IBreakpointDMContext[]> rm) {
      -166:         // Validate the context
      -167:         if (!fCommandControl.getProgramDMContext().equals(context)) {
      -168:             PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid breakpoints target context");
      -169:             return;
      -170:         }
      -
      -172:         rm.setData(fBreakpoints.toArray(new IBreakpointDMContext[fBreakpoints.size()]));
      -173:         rm.done();
      -174:     }
      -
      -176:     public void getBreakpointDMData(IBreakpointDMContext dmc, DataRequestMonitor<IBreakpointDMData> rm) {
      -177:         PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Retrieving breakpoint data is not supported");
      -178:     }
      -
      -180:     public void insertBreakpoint(IBreakpointsTargetDMContext context, Map<String, Object> attributes, 
      -181:         DataRequestMonitor<IBreakpointDMContext> rm) 
      -182:     {
      -183:         Boolean enabled = (Boolean)attributes.get(IBreakpoint.ENABLED);
      -184:         if (enabled != null && !enabled.booleanValue()) {
      -185:             // If the breakpoint is disabled, just fail the request. 
      -186:             PDAPlugin.failRequest(rm, REQUEST_FAILED, "Breakpoint is disabled");
      -187:         } else {
      -188:             String type = (String) attributes.get(ATTR_BREAKPOINT_TYPE);
      -
      -190:             if (PDA_LINE_BREAKPOINT.equals(type)) {
      -191:                 // Retrieve the PDA program context from the context given in the 
      -192:                 // argument.  This service is typically only called by the 
      -193:                 // breakpoints mediator, which was called with the program context
      -194:                 // in the services initialization sequence.  So checking if 
      -195:                 // programCtx != null is mostly a formality.
      -196:                 PDAProgramDMContext programCtx = DMContexts.getAncestorOfType(context, PDAProgramDMContext.class);
      -197:                 if (programCtx != null) {
      -198:                     doInsertBreakpoint(programCtx, attributes, rm);
      -199:                 } else {
      -200:                     PDAPlugin.failRequest(rm, INVALID_HANDLE, "Unknown breakpoint type");
      -201:                 }
      -202:             }
      -203:             else if (PDA_WATCHPOINT.equals(type)) {
      -204:                 doInsertWatchpoint(attributes, rm);
      -205:             }
      -206:             else {
      -207:                 PDAPlugin.failRequest(rm, REQUEST_FAILED, "Unknown breakpoint type");
      -208:             }
      -209:         }
      -210:     }
      -
      -212:     private void doInsertBreakpoint(PDAProgramDMContext programCtx, final Map<String, Object> attributes, final DataRequestMonitor<IBreakpointDMContext> rm) 
      -213:     {
      -214:         // Compare the program path in the breakpoint with the path in the PDA 
      -215:         // program context. Only insert the breakpoint if the program matches. 
      -216:         String program = (String)attributes.get(ATTR_PROGRAM_PATH);
      -217:         if (!programCtx.getProgram().equals(program)) {
      -218:             PDAPlugin.failRequest(rm, REQUEST_FAILED, "Invalid file name");
      -219:             return;
      -220:         }
      -
      -222:         // Retrieve the line.
      -223:         Integer line = (Integer)attributes.get(IMarker.LINE_NUMBER);
      -224:         if (line == null) {
      -225:             PDAPlugin.failRequest(rm, REQUEST_FAILED, "No breakpoint line specified");
      -226:             return;
      -227:         }
      -
      -229:         // Create a new breakpoint context object and check that it's not 
      -230:         // installed already. PDA can only track a single breakpoint at a 
      -231:         // given line, attempting to set the second breakpoint should fail.
      -232:         final BreakpointDMContext breakpointCtx = 
      -233:             new BreakpointDMContext(getSession().getId(), fCommandControl.getProgramDMContext(), line);
      -234:         if (fBreakpoints.contains(breakpointCtx)) {
      -235:             PDAPlugin.failRequest(rm, REQUEST_FAILED, "Breakpoint already set");
      -236:             return;
      -237:         }
      -
      -239:         // Add the new breakpoint context to the list of known breakpoints.  
      -240:         // Adding it here, before the set command is completed will prevent 
      -241:         // a possibility of a second breakpoint being installed in the same 
      -242:         // location while this breakpoint is being processed.  It will also
      -243:         // allow the breakpoint to be removed or updated even while it is 
      -244:         // still being processed here.
      -245:         fBreakpoints.add(breakpointCtx);
      -246:         fCommandControl.queueCommand(
      -247:             new PDASetBreakpointCommand(fCommandControl.getProgramDMContext(), line), 
      -248:             new DataRequestMonitor<PDACommandResult>(getExecutor(), rm) {
      -249:                 @Override
      -250:                 protected void handleOK() {
      -251:                     rm.setData(breakpointCtx);
      -252:                     rm.done();
      -253:                 }
      -
      -255:                 @Override
      -256:                 protected void handleErrorOrCancel() {
      -257:                     // If inserting of the breakpoint failed, remove it from
      -258:                     // the set of installed breakpoints.
      -259:                     fBreakpoints.remove(breakpointCtx);
      -260:                     super.handleErrorOrCancel();
      -261:                 }
      -262:             });
      -263:     }
      -
      -265:     private void doInsertWatchpoint(final Map<String, Object> attributes, final DataRequestMonitor<IBreakpointDMContext> rm) 
      -266:     {
      -267:         String function = (String)attributes.get(PDAWatchpoint.FUNCTION_NAME);
      -268:         if (function == null) {
      -269:             PDAPlugin.failRequest(rm, REQUEST_FAILED, "No function specified");
      -270:             return;
      -271:         }
      -
      -273:         String variable = (String)attributes.get(PDAWatchpoint.VAR_NAME);
      -274:         if (variable == null) {
      -275:             PDAPlugin.failRequest(rm, REQUEST_FAILED, "No variable specified");
      -276:             return;
      -277:         }
      -
      -279:         Boolean isAccess = (Boolean)attributes.get(PDAWatchpoint.ACCESS);
      -280:         isAccess = isAccess != null ? isAccess : Boolean.FALSE; 
      -
      -282:         Boolean isModification = (Boolean)attributes.get(PDAWatchpoint.MODIFICATION);
      -283:         isModification = isModification != null ? isModification : Boolean.FALSE; 
      -
      -285:         // Create a new watchpoint context object and check that it's not 
      -286:         // installed already. PDA can only track a single watchpoint for a given
      -287:         // function::variable, attempting to set the second breakpoint should fail.
      -288:         final WatchpointDMContext watchpointCtx = 
      -289:             new WatchpointDMContext(getSession().getId(), fCommandControl.getProgramDMContext(), function, variable);
      -290:         if (fBreakpoints.contains(watchpointCtx)) {
      -291:             PDAPlugin.failRequest(rm, REQUEST_FAILED, "Watchpoint already set");
      -292:             return;
      -293:         }
      -
      -295:         // Determine the watch operation to perform.
      -296:         PDAWatchCommand.WatchOperation watchOperation = PDAWatchCommand.WatchOperation.NONE;
      -297:         if (isAccess && isModification) {
      -298:             watchOperation = PDAWatchCommand.WatchOperation.BOTH;
      -299:         } else if (isAccess) {
      -300:             watchOperation = PDAWatchCommand.WatchOperation.READ;
      -301:         } else if (isModification) {
      -302:             watchOperation = PDAWatchCommand.WatchOperation.WRITE;
      -303:         }
      -
      -305:         // Add the new breakpoint context to the list of known breakpoints.  
      -306:         // Adding it here, before the set command is completed will prevent 
      -307:         // a possibility of a second breakpoint being installed in the same 
      -308:         // location while this breakpoint is being processed.  It will also
      -309:         // allow the breakpoint to be removed or updated even while it is 
      -310:         // still being processed here.
      -311:         fBreakpoints.add(watchpointCtx);
      -312:         fCommandControl.queueCommand(
      -313:             new PDAWatchCommand(fCommandControl.getProgramDMContext(), function, variable, watchOperation), 
      -314:             new DataRequestMonitor<PDACommandResult>(getExecutor(), rm) {
      -315:                 @Override
      -316:                 protected void handleOK() {
      -317:                     rm.setData(watchpointCtx);
      -318:                     rm.done();
      -319:                 }
      -
      -321:                 @Override
      -322:                 protected void handleErrorOrCancel() {
      -323:                     // Since the command failed, we need to remove the breakpoint from 
      -324:                     // the existing breakpoint set.
      -325:                     fBreakpoints.remove(watchpointCtx);
      -326:                     super.handleErrorOrCancel();
      -327:                 }
      -328:             });
      -329:     }
      -
      -331:     public void removeBreakpoint(IBreakpointDMContext bpCtx, RequestMonitor rm) {
      -332:         if (!fBreakpoints.contains(bpCtx)) {
      -333:             PDAPlugin.failRequest(rm, REQUEST_FAILED, "Breakpoint already removed");
      -334:             return;
      -335:         }
      -
      -337:         if (bpCtx instanceof BreakpointDMContext) {
      -338:             doRemoveBreakpoint((BreakpointDMContext)bpCtx, rm);
      -339:         } else if (bpCtx instanceof WatchpointDMContext) {
      -340:             doRemoveWatchpoint((WatchpointDMContext)bpCtx, rm);
      -341:         } else {
      -342:             PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid breakpoint");
      -343:         }
      -344:     }
      -
      -346:     private void doRemoveBreakpoint(BreakpointDMContext bpCtx, RequestMonitor rm) {
      -347:         // Remove the breakpoint from the table right away, so that even when 
      -348:         // the remove is being processed, a new breakpoint can be created at the same 
      -349:         // location.
      -350:         fBreakpoints.remove(bpCtx);
      -
      -352:         fCommandControl.queueCommand(
      -353:             new PDAClearBreakpointCommand(fCommandControl.getProgramDMContext(), bpCtx.fLine), 
      -354:             new DataRequestMonitor<PDACommandResult>(getExecutor(), rm));        
      -355:     }
      -
      -357:     private void doRemoveWatchpoint(WatchpointDMContext bpCtx, RequestMonitor rm) {
      -358:         fBreakpoints.remove(bpCtx);
      -
      -360:         // Watchpoints are cleared using the same command, but with a "no watch" operation
      -361:         fCommandControl.queueCommand(
      -362:             new PDAWatchCommand(
      -363:                 fCommandControl.getProgramDMContext(), bpCtx.fFunction, bpCtx.fVariable, PDAWatchCommand.WatchOperation.NONE), 
      -364:                 new DataRequestMonitor<PDACommandResult>(getExecutor(), rm));        
      -365:     }
      -
      -367:     public void updateBreakpoint(final IBreakpointDMContext bpCtx, Map<String, Object> attributes, final RequestMonitor rm) {
      -368:         if (!fBreakpoints.contains(bpCtx)) {
      -369:             PDAPlugin.failRequest(rm, REQUEST_FAILED, "Breakpoint not installed");
      -370:             return;
      -371:         }
      -
      -373:         if (bpCtx instanceof BreakpointDMContext) {
      -374:             PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Modifying PDA breakpoints is not supported");
      -375:         } else if (bpCtx instanceof WatchpointDMContext) {
      -376:             WatchpointDMContext wpCtx = (WatchpointDMContext)bpCtx;
      -377:             if (!wpCtx.fFunction.equals(attributes.get(PDAWatchpoint.FUNCTION_NAME)) || 
      -378:                 !wpCtx.fVariable.equals(attributes.get(PDAWatchpoint.VAR_NAME)) )
      -379:             {
      -380:                 PDAPlugin.failRequest(rm, REQUEST_FAILED, "Cannot modify watchpoint function or variable");
      -381:                 return;
      -382:             }
      -383:             
      -384:             // PDA debugger can only track one watchpoint in the same location, 
      -385:             // so we can simply remove the existing context from the set and 
      -386:             // call insert again.  
      -387:             fBreakpoints.remove(bpCtx);
      -388:             doInsertWatchpoint(
      -389:                 attributes, 
      -390:                 new DataRequestMonitor<IBreakpointDMContext>(getExecutor(), rm) {
      -391:                     @Override
      -392:                     protected void handleOK() {
      -393:                         // The inserted watchpoint context will equal the 
      -394:                         // current context.
      -395:                         assert bpCtx.equals(getData());
      -396:                         rm.done();
      -397:                     }
      -398:                 });
      -399:         } else {
      -400:             PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid breakpoint");
      -401:         }
      -402:     }
      -403: }
      -
      - - - diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java.html deleted file mode 100644 index 556bfa472ed..00000000000 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java.html +++ /dev/null @@ -1,547 +0,0 @@ - - - -PDACommandControl.java - - - - - -
        1: package org.eclipse.dd.examples.pda.service;
      -
      -  3: import java.io.BufferedReader;
      -  4: import java.io.IOException;
      -  5: import java.io.InputStreamReader;
      -  6: import java.io.PrintWriter;
      -  7: import java.net.Socket;
      -  8: import java.net.UnknownHostException;
      -  9: import java.util.ArrayList;
      - 10: import java.util.Hashtable;
      - 11: import java.util.Iterator;
      - 12: import java.util.LinkedList;
      - 13: import java.util.List;
      - 14: import java.util.concurrent.BlockingQueue;
      - 15: import java.util.concurrent.LinkedBlockingQueue;
      - 16: import java.util.concurrent.RejectedExecutionException;
      -
      - 18: import org.eclipse.core.runtime.IProgressMonitor;
      - 19: import org.eclipse.core.runtime.IStatus;
      - 20: import org.eclipse.core.runtime.Status;
      - 21: import org.eclipse.core.runtime.jobs.Job;
      - 22: import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
      - 23: import org.eclipse.dd.dsf.concurrent.DsfRunnable;
      - 24: import org.eclipse.dd.dsf.concurrent.RequestMonitor;
      - 25: import org.eclipse.dd.dsf.concurrent.ThreadSafe;
      - 26: import org.eclipse.dd.dsf.debug.service.command.ICommand;
      - 27: import org.eclipse.dd.dsf.debug.service.command.ICommandControl;
      - 28: import org.eclipse.dd.dsf.debug.service.command.ICommandListener;
      - 29: import org.eclipse.dd.dsf.debug.service.command.ICommandResult;
      - 30: import org.eclipse.dd.dsf.debug.service.command.IEventListener;
      - 31: import org.eclipse.dd.dsf.service.AbstractDsfService;
      - 32: import org.eclipse.dd.dsf.service.DsfSession;
      - 33: import org.eclipse.dd.examples.pda.PDAPlugin;
      - 34: import org.eclipse.dd.examples.pda.service.commands.AbstractPDACommand;
      - 35: import org.eclipse.dd.examples.pda.service.commands.PDACommandResult;
      - 36: import org.eclipse.dd.examples.pda.service.commands.PDAExitCommand;
      - 37: import org.osgi.framework.BundleContext;
      -
      -
      - 40: /**
      - 41:  * Service that handles communication with a PDA debugger back end.  
      - 42:  */
      - 43: public class PDACommandControl extends AbstractDsfService implements ICommandControl {
      -
      - 45:     // Structure used to store command information in services internal queues.
      - 46:     private static class CommandHandle {
      - 47:         final private AbstractPDACommand<PDACommandResult> fCommand;
      - 48:         final private DataRequestMonitor<PDACommandResult> fRequestMonitor;
      - 49:         
      - 50:         CommandHandle(AbstractPDACommand<PDACommandResult> c, DataRequestMonitor<PDACommandResult> rm) {
      - 51:             fCommand = c; 
      - 52:             fRequestMonitor = rm;
      - 53:         }
      - 54:     }
      -
      - 56:     // Parameters that the command control is created with.
      - 57:     final private String fProgram;
      - 58:     final private int fRequestPort;
      - 59:     final private int fEventPort;
      -
      - 61:     // Queue of commands waiting to be sent to the debugger.  As long as commands
      - 62:     // are in this queue, they can still be removed by clients. 
      - 63:     private final List<CommandHandle> fCommandQueue = new LinkedList<CommandHandle>();
      - 64:     
      - 65:     // Queue of commands that are being sent to the debugger.  This queue is read
      - 66:     // by the send job, so as soon as commands are inserted into this queue, they can
      - 67:     // be considered as sent.
      - 68:     @ThreadSafe
      - 69:     private final BlockingQueue<CommandHandle> fTxCommands = new LinkedBlockingQueue<CommandHandle>();
      - 70:     
      - 71:     // Flag indicating that the PDA debugger started
      - 72:     private boolean fStarted = false;
      - 73:     
      - 74:     // Flag indicating that the PDA debugger has been disconnected 
      - 75:     @ThreadSafe
      - 76:     private boolean fTerminated = false;
      - 77:     
      - 78:     //  Data Model context of this command control. 
      - 79:     private PDAProgramDMContext fDMContext;
      -
      - 81:     // Synchronous listeners for commands and events.
      - 82:     private final List<ICommandListener> fCommandListeners = new ArrayList<ICommandListener>();
      - 83:     private final List<IEventListener>   fEventListeners = new ArrayList<IEventListener>();
      - 84:     
      - 85:     // Sockets for communicating with PDA debugger 
      - 86:     @ThreadSafe
      - 87:     private Socket fRequestSocket;
      - 88:     @ThreadSafe
      - 89:     private PrintWriter fRequestWriter;
      - 90:     @ThreadSafe
      - 91:     private BufferedReader fRequestReader;
      - 92:     @ThreadSafe
      - 93:     private Socket fEventSocket;
      - 94:     @ThreadSafe
      - 95:     private BufferedReader fEventReader;
      -
      - 97:     // Jobs servicing the sockets.
      - 98:     private EventDispatchJob fEventDispatchJob;
      - 99:     private CommandSendJob fCommandSendJob;
      -100:     
      -101:     /**
      -102:      * Command control constructor. 
      -103:      * @param session The DSF session that this service is a part of. 
      -104:      * @param requestPort Port number for sending PDA commands.
      -105:      * @param eventPort Port for listening to PDA events.
      -106:      */
      -107:     public PDACommandControl(DsfSession session, String program, int requestPort, int eventPort) {
      -108:         super(session);
      -109:         fProgram = program;
      -110:         fRequestPort = requestPort;
      -111:         fEventPort = eventPort;
      -112:     }
      -113:     
      -114:     @Override
      -115:     public void initialize(final RequestMonitor rm) {
      -116:         // Call the super-class to perform initialization first.
      -117:         super.initialize( new RequestMonitor(getExecutor(), rm) {
      -118:             @Override
      -119:             protected void handleOK() {
      -120:                 doInitialize(rm);
      -121:             }
      -122:         });
      -123:     }
      -
      -125:     private void doInitialize(final RequestMonitor rm) {
      -126:         // Create the control's data model context.
      -127:         fDMContext = new PDAProgramDMContext(getSession().getId(), fProgram);
      -
      -129:         // Add a listener for PDA events to track the started/terminated state.
      -130:         addEventListener(new IEventListener() {
      -131:             public void eventReceived(Object output) {
      -132:                 if ("started".equals(output)) {
      -133:                     setStarted();
      -134:                 } else if ("terminated".equals(output)) {
      -135:                     setTerminated();
      -136:                 }
      -137:             }
      -138:         });
      -139:         
      -140:         // Request monitor that will be invoked when the socket initialization is
      -141:         // completed.  
      -142:         final RequestMonitor socketsInitializeRm = new RequestMonitor(getExecutor(), rm) {
      -143:             @Override
      -144:             protected void handleOK() {
      -145:                 // Register the service with OSGi as the last step in initialization of 
      -146:                 // the service.
      -147:                 register(
      -148:                     new String[]{ ICommandControl.class.getName(), PDACommandControl.class.getName() }, 
      -149:                     new Hashtable<String,String>());
      -150:                 rm.done();
      -151:             }
      -152:         };
      -153:         
      -154:         // To avoid blocking the DSF dispatch thread use a job to initialize communication sockets.  
      -155:         new Job("PDA Initialize") {
      -156:             @Override
      -157:             protected IStatus run(IProgressMonitor monitor) {
      -158:                 try {
      -159:                     // give interpreter a chance to start
      -160:                     try {
      -161:                         Thread.sleep(1000);
      -162:                     } catch (InterruptedException e) {
      -163:                     }
      -164:                     fRequestSocket = new Socket("localhost", fRequestPort);
      -165:                     fRequestWriter = new PrintWriter(fRequestSocket.getOutputStream());
      -166:                     fRequestReader = new BufferedReader(new InputStreamReader(fRequestSocket.getInputStream()));
      -167:                     // give interpreter a chance to open next socket
      -168:                     try {
      -169:                         Thread.sleep(1000);
      -170:                     } catch (InterruptedException e) {
      -171:                     }
      -172:                     fEventSocket = new Socket("localhost", fEventPort);
      -173:                     fEventReader = new BufferedReader(new InputStreamReader(fEventSocket.getInputStream()));
      -
      -175:                     fEventDispatchJob = new EventDispatchJob();
      -176:                     fEventDispatchJob.schedule();
      -177:                     
      -178:                     fCommandSendJob = new CommandSendJob();
      -179:                     fCommandSendJob.schedule();
      -
      -181:                     socketsInitializeRm.done();
      -182:                 } catch (UnknownHostException e) {
      -183:                     socketsInitializeRm.setStatus(new Status(
      -184:                         IStatus.ERROR, PDAPlugin.PLUGIN_ID, REQUEST_FAILED, "Unable to connect to PDA VM", e));
      -185:                     socketsInitializeRm.done();
      -186:                 } catch (IOException e) {
      -187:                     socketsInitializeRm.setStatus(new Status(
      -188:                         IStatus.ERROR, PDAPlugin.PLUGIN_ID, REQUEST_FAILED, "Unable to connect to PDA VM", e));
      -189:                     socketsInitializeRm.done();
      -190:                 }
      -191:                 return Status.OK_STATUS;
      -192:             }
      -193:         }.schedule();
      -194:     }
      -
      -196:     @Override
      -197:     public void shutdown(final RequestMonitor requestMonitor) {
      -198:         // Unregister the service first, so that clients may no longer gain access to it.
      -199:         unregister();
      -200:         
      -201:         if (!isTerminated()) {
      -202:             // If the debugger is still connected, send it the exit command.
      -203:             terminate(new RequestMonitor(getExecutor(), requestMonitor) {
      -204:                 @Override
      -205:                 protected void handleCompleted() {
      -206:                     // Mark the command control as terminated.
      -207:                     setTerminated();
      -
      -209:                     // Ignore any error resulting from the exit command.  
      -210:                     // Errors will most likely result if the PDA process is 
      -211:                     // already terminated.
      -212:                     requestMonitor.done();
      -213:                 }
      -214:             });
      -215:         } else {
      -216:             requestMonitor.done();
      -217:         }
      -218:     }        
      -
      -220:     @Override
      -221:     protected BundleContext getBundleContext() {
      -222:         return PDAPlugin.getBundleContext();
      -223:     }
      -224:     
      -225:     /**
      -226:      *  Job that services the send command queue. 
      -227:      */
      -228:     private class CommandSendJob extends Job {
      -229:         CommandSendJob() {
      -230:             super("PDA Command Send");
      -231:             setSystem(true);
      -232:         }
      -233:         
      -234:         @Override
      -235:         protected IStatus run(IProgressMonitor monitor) {
      -236:             while (!isTerminated()) {
      -237:                 synchronized(fTxCommands) {
      -238:                     try {
      -239:                         // Remove comamnd from send queue.
      -240:                         final CommandHandle commandHandle = fTxCommands.take();
      -241:                         
      -242:                         // Send the request to PDA
      -243:                         fRequestWriter.println(commandHandle.fCommand.getRequest());
      -244:                         fRequestWriter.flush();
      -245:                         
      -246:                         try {
      -247:                             // wait for reply
      -248:                             final String response = fRequestReader.readLine();
      -249:                             
      -250:                             // Process the reply in the executor thread.
      -251:                             try {
      -252:                                 getExecutor().execute(new DsfRunnable() {
      -253:                                     public void run() {
      -254:                                         processCommandDone(commandHandle, response);
      -255:                                     }
      -256:                                 });
      -257:                             } catch (RejectedExecutionException e) {
      -258:                                 // Acceptable race condition may see the session shut down
      -259:                                 // while we're waiting for command response.  Still complete
      -260:                                 // the request monitor.
      -261:                                 assert isTerminated();
      -262:                                 assert isTerminated();
      -263:                                 PDAPlugin.failRequest(commandHandle.fRequestMonitor, REQUEST_FAILED, "Command control shut down.");
      -264:                             }
      -265:                         } catch (final IOException e) {
      -266:                             // Process error it in the executor thread
      -267:                             try {
      -268:                                 getExecutor().execute(new DsfRunnable() {
      -269:                                     public void run() {
      -270:                                         processCommandException(commandHandle, e);
      -271:                                     }
      -272:                                 });
      -273:                             } catch (RejectedExecutionException re) {
      -274:                                 // Acceptable race condition... see above
      -275:                                 assert isTerminated();
      -276:                                 PDAPlugin.failRequest(commandHandle.fRequestMonitor, REQUEST_FAILED, "Command control shut down.");
      -277:                             }
      -278:                         }
      -279:                     } catch (InterruptedException e) {
      -280:                         break;  // Shutting down.
      -281:                     }
      -282:                 }
      -283:             }
      -284:             return Status.OK_STATUS;
      -285:         }        
      -286:         
      -287:     }
      -288:     
      -289:     /**
      -290:      * Job that services the PDA event socket.
      -291:      */
      -292:     class EventDispatchJob extends Job {
      -293:         
      -294:         public EventDispatchJob() {
      -295:             super("PDA Event Listner");
      -296:             setSystem(true);
      -297:         }
      -
      -299:         @Override
      -300:         protected IStatus run(IProgressMonitor monitor) {
      -301:             while (!isTerminated()) {
      -302:                 try {
      -303:                     // Wait for an event.
      -304:                     final String event = fEventReader.readLine();
      -305:                     if (event != null) {
      -306:                         try {
      -307:                             // Process the event in executor thread.
      -308:                             getExecutor().execute(new DsfRunnable() {
      -309:                                 public void run() {
      -310:                                     processEventReceived(event);
      -311:                                 }
      -312:                             });
      -313:                         } catch (RejectedExecutionException e) {}                
      -314:                     } else {
      -315:                         break;
      -316:                     }
      -317:                 } catch (IOException e) {
      -318:                     break;
      -319:                 }
      -320:             }
      -321:             if (!isTerminated()) {
      -322:                 // Exception from the event socket is an indicator that the PDA debugger
      -323:                 // has exited.  Call setTerminated() in executor thread.
      -324:                 try {
      -325:                     getExecutor().execute(new DsfRunnable() {
      -326:                         public void run() {
      -327:                             setTerminated();
      -328:                         }
      -329:                     });
      -330:                 } catch (RejectedExecutionException e) {}                
      -331:             }
      -332:             return Status.OK_STATUS;
      -333:         }
      -334:         
      -335:     }
      -336:     
      -337:     public <V extends ICommandResult> void queueCommand(ICommand<V> command, DataRequestMonitor<V> rm) {
      -338:         if (command instanceof AbstractPDACommand<?>) {
      -339:             // Cast from command with "<V extends ICommandResult>" to a more concrete
      -340:             // type to use internally in the command control.
      -341:             @SuppressWarnings("unchecked")
      -342:             AbstractPDACommand<PDACommandResult> pdaCommand = (AbstractPDACommand<PDACommandResult>)command;
      -343:             
      -344:             // Similarly, cast the request monitor to a more concrete type.
      -345:             @SuppressWarnings("unchecked")
      -346:             DataRequestMonitor<PDACommandResult> pdaRM = (DataRequestMonitor<PDACommandResult>)rm;
      -
      -348:             // Add the command to the queue and notify command listeners.
      -349:             fCommandQueue.add( new CommandHandle(pdaCommand, pdaRM) );
      -350:             for (ICommandListener listener : fCommandListeners) {
      -351:                 listener.commandQueued(command);
      -352:             }
      -353:             
      -354:             // In a separate dispatch cycle.  This allows command listeners to repond to the 
      -355:             // command queued event.  
      -356:             getExecutor().execute(new DsfRunnable() {
      -357:                 public void run() {
      -358:                     processQueues();
      -359:                 }
      -360:             });
      -361:             
      -362:         } else {
      -363:             PDAPlugin.failRequest(rm, INTERNAL_ERROR, "Unrecognized command: " + command);
      -364:         }
      -365:     }
      -
      -367:     public void cancelCommand(ICommand<? extends ICommandResult> command) {
      -368:         // This debugger is unable of canceling commands once they have 
      -369:         // been sent.
      -370:     }
      -
      -372:     public void removeCommand(ICommand<? extends ICommandResult> command) {
      -373:         // Removes given command from the queue and notify the listeners
      -374:         for (Iterator<CommandHandle> itr = fCommandQueue.iterator(); itr.hasNext();) {
      -375:             CommandHandle handle = itr.next();
      -376:             if (command.equals(handle.fCommand)) {
      -377:                 itr.remove();
      -378:                 for (ICommandListener listener : fCommandListeners) {
      -379:                     listener.commandRemoved(command);
      -380:                 }                
      -381:             }
      -382:         }
      -383:     }
      -384:     
      -385:     public void addCommandListener(ICommandListener processor) { 
      -386:         fCommandListeners.add(processor); 
      -387:     }
      -388:     
      -389:     public void removeCommandListener(ICommandListener processor) { 
      -390:         fCommandListeners.remove(processor); 
      -391:     }
      -392:     
      -393:     public void addEventListener(IEventListener processor) { 
      -394:         fEventListeners.add(processor); 
      -395:     }
      -396:     
      -397:     public void removeEventListener(IEventListener processor) { 
      -398:         fEventListeners.remove(processor); 
      -399:     }
      -
      -401:     private void processCommandDone(CommandHandle handle, String response) {
      -402:         // Trace to debug output.
      -403:         PDAPlugin.debug("R: " + response);
      -404:         
      -405:         // Given the PDA response string, create the result using the command
      -406:         // that was sent.
      -407:         PDACommandResult result = handle.fCommand.createResult(response);
      -408:         
      -409:         // Set the result to the request monitor and return to sender.
      -410:         // Note: as long as PDA sends some response, a PDA command will never
      -411:         // return an error.
      -412:         handle.fRequestMonitor.setData(result);
      -413:         handle.fRequestMonitor.done();
      -
      -415:         // Notify listeners of the response
      -416:         for (ICommandListener listener : fCommandListeners) {
      -417:             listener.commandDone(handle.fCommand, result);
      -418:         }
      -419:         
      -420:         // Process next command in queue.
      -421:         processQueues();
      -422:     }
      -
      -424:     
      -425:     private void processCommandException(CommandHandle handle, Throwable exception) {
      -426:         
      -427:         // If sending a command resulted in an exception, notify the client.
      -428:         handle.fRequestMonitor.setStatus(new Status(
      -429:             IStatus.ERROR, PDAPlugin.PLUGIN_ID, REQUEST_FAILED, "Exception reading request response", exception));
      -430:         handle.fRequestMonitor.done();                            
      -
      -432:         // Notify listeners also.
      -433:         for (ICommandListener listener : fCommandListeners) {
      -434:             listener.commandDone(handle.fCommand, null);
      -435:         }
      -436:     }
      -
      -438:     private void processEventReceived(String event) {
      -439:         // Notify the listeners only.
      -440:         PDAPlugin.debug("E: " + event);
      -441:         for (IEventListener listener : fEventListeners) {
      -442:             listener.eventReceived(event);
      -443:         }
      -444:     }
      -445:     
      -446:     private synchronized void processQueues() {
      -447:         if (isTerminated()) {
      -448:             // If the PDA debugger is terminated.  Return all submitted commands 
      -449:             // with an error.
      -450:             for (CommandHandle handle : fCommandQueue) {
      -451:                 handle.fRequestMonitor.setStatus(new Status(
      -452:                     IStatus.ERROR, PDAPlugin.PLUGIN_ID, INVALID_STATE, "Command control is terminated", null));
      -453:                 handle.fRequestMonitor.done();
      -454:             }
      -455:             fCommandQueue.clear();
      -456:         } else if (fStarted && fTxCommands.isEmpty() && !fCommandQueue.isEmpty()) {
      -457:             // Process the queues if:
      -458:             // - the PDA debugger has started,
      -459:             // - there are no pending commands in the send queue,
      -460:             // - and there are commands waiting to be sent.
      -461:             CommandHandle handle = fCommandQueue.remove(0); 
      -462:             fTxCommands.add(handle);
      -463:             PDAPlugin.debug("C: " + handle.fCommand.getRequest());
      -464:             for (ICommandListener listener : fCommandListeners) {
      -465:                 listener.commandSent(handle.fCommand);
      -466:             }            
      -467:         }
      -468:     }
      -469:     
      -470:     /**
      -471:      * Return the PDA Debugger top-level Data Model context. 
      -472:      * @see PDAProgramDMContext
      -473:      */
      -474:     @ThreadSafe
      -475:     public PDAProgramDMContext getProgramDMContext() {
      -476:         return fDMContext;
      -477:     }
      -
      -479:     private void setStarted() {
      -480:         // Mark the command control as started and ready to process commands.
      -481:         fStarted = true;
      -482:         
      -483:         // Process any commands which may have been queued before the 
      -484:         processQueues();
      -
      -486:         // Issue a data model event.
      -487:         getSession().dispatchEvent(new PDAStartedEvent(getProgramDMContext()), getProperties());
      -488:     }
      -489:     
      -490:     /**
      -491:      * Returns whether the PDA debugger has started and is processing commands.
      -492:      */
      -493:     public boolean isStarted() {
      -494:         return fStarted;
      -495:     }
      -496:     
      -497:     @ThreadSafe
      -498:     private synchronized void setTerminated() {
      -499:         // Set terminated may be called more than once: by event listener thread, 
      -500:         // by the terminate command, etc, so protect against sending events multiple
      -501:         // times.
      -502:         if (!fTerminated) {
      -503:             fTerminated = true;
      -504:             
      -505:             // Process any waiting commands, they all should return with an error.
      -506:             processQueues();
      -507:             
      -508:             // Issue a data model event.
      -509:             getSession().dispatchEvent(new PDATerminatedEvent(getProgramDMContext()), getProperties());
      -510:         }
      -511:     }
      -
      -513:     /**
      -514:      * Returns whether the PDA debugger has been terminated.
      -515:      */
      -516:     @ThreadSafe
      -517:     public synchronized boolean isTerminated() {
      -518:         return fTerminated;
      -519:     }
      -
      -521:     /**
      -522:      * Sends a command to PDA debugger to terminate.
      -523:      */
      -524:     public void terminate(RequestMonitor rm) {
      -525:         if (!isTerminated()) {
      -526:             queueCommand(
      -527:                 new PDAExitCommand(fDMContext),
      -528:                 new DataRequestMonitor<PDACommandResult>(getExecutor(), rm));
      -529:         } else {
      -530:             // If already terminated, indicate success.
      -531:             rm.done();
      -532:         }
      -533:     }    
      -534: }
      -
      - - - diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAExpressions.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAExpressions.java.html deleted file mode 100644 index 8292629dd69..00000000000 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAExpressions.java.html +++ /dev/null @@ -1,386 +0,0 @@ - - - -PDAExpressions.java - - - - - -
        1: /*******************************************************************************
      -  2:  * Copyright (c) 2008 Wind River Systems and others.
      -  3:  * All rights reserved. This program and the accompanying materials
      -  4:  * are made available under the terms of the Eclipse Public License v1.0
      -  5:  * which accompanies this distribution, and is available at
      -  6:  * http://www.eclipse.org/legal/epl-v10.html
      -  7:  * 
      -  8:  * Contributors:
      -  9:  *     Wind River Systems - initial API and implementation
      - 10:  *******************************************************************************/
      - 11: package org.eclipse.dd.examples.pda.service;
      -
      - 13: import java.util.Hashtable;
      - 14: import java.util.Map;
      -
      - 16: import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
      - 17: import org.eclipse.dd.dsf.concurrent.Immutable;
      - 18: import org.eclipse.dd.dsf.concurrent.RequestMonitor;
      - 19: import org.eclipse.dd.dsf.datamodel.AbstractDMContext;
      - 20: import org.eclipse.dd.dsf.datamodel.AbstractDMEvent;
      - 21: import org.eclipse.dd.dsf.datamodel.DMContexts;
      - 22: import org.eclipse.dd.dsf.datamodel.IDMContext;
      - 23: import org.eclipse.dd.dsf.debug.service.IExpressions;
      - 24: import org.eclipse.dd.dsf.debug.service.IStack;
      - 25: import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext;
      - 26: import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent;
      - 27: import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent;
      - 28: import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason;
      - 29: import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext;
      - 30: import org.eclipse.dd.dsf.debug.service.command.CommandCache;
      - 31: import org.eclipse.dd.dsf.service.AbstractDsfService;
      - 32: import org.eclipse.dd.dsf.service.DsfServiceEventHandler;
      - 33: import org.eclipse.dd.dsf.service.DsfSession;
      - 34: import org.eclipse.dd.examples.pda.PDAPlugin;
      - 35: import org.eclipse.dd.examples.pda.service.commands.PDACommandResult;
      - 36: import org.eclipse.dd.examples.pda.service.commands.PDASetVarCommand;
      - 37: import org.eclipse.dd.examples.pda.service.commands.PDAVarCommand;
      - 38: import org.osgi.framework.BundleContext;
      -
      - 40: /**
      - 41:  * 
      - 42:  */
      - 43: public class PDAExpressions extends AbstractDsfService implements IExpressions {
      -
      - 45:     @Immutable
      - 46:     private static class ExpressionDMContext extends AbstractDMContext implements IExpressionDMContext {
      -
      - 48:         final private String fExpression;
      - 49:         
      - 50:         ExpressionDMContext(String sessionId, IFrameDMContext frameDmc, String expressin) {
      - 51:             super(sessionId, new IDMContext[] { frameDmc });
      - 52:             fExpression = expressin;
      - 53:         }
      -
      - 55:         public String getExpression() { 
      - 56:             return fExpression;
      - 57:         }
      - 58:         
      - 59:         @Override
      - 60:         public boolean equals(Object other) {
      - 61:             return super.baseEquals(other) && ((ExpressionDMContext)other).fExpression.equals(fExpression);
      - 62:         }
      - 63:         
      - 64:         @Override
      - 65:         public int hashCode() {
      - 66:             return super.baseHashCode() + fExpression.hashCode();
      - 67:         }
      - 68:         
      - 69:         @Override
      - 70:         public String toString() { 
      - 71:             return baseToString() + ".expression(" + fExpression + ")";  
      - 72:         }
      - 73:     }
      -
      - 75:     /**
      - 76:      * PDA expressions are simply variables.  Only the variable name 
      - 77:      * is relevant for its data.
      - 78:      */
      - 79:     @Immutable
      - 80:     private static class ExpressionDMData implements IExpressionDMData {
      -
      - 82:         final private String fExpression;
      - 83:         
      - 84:         public ExpressionDMData(String expression) {
      - 85:             fExpression = expression;
      - 86:         }
      - 87:         
      - 88:         public BasicType getBasicType() {
      - 89:             return BasicType.basic;
      - 90:         }
      -
      - 92:         public String getEncoding() {
      - 93:             return null;
      - 94:         }
      -
      - 96:         public Map<String, Integer> getEnumerations() {
      - 97:             return null;
      - 98:         }
      -
      -100:         public String getName() {
      -101:             return fExpression;
      -102:         }
      -
      -104:         public IRegisterDMContext getRegister() {
      -105:             return null;
      -106:         }
      -
      -108:         public String getStringValue() {
      -109:             return null;
      -110:         }
      -
      -112:         public String getTypeId() {
      -113:             return null;
      -114:         }
      -
      -116:         public String getTypeName() {
      -117:             return null;
      -118:         }
      -
      -120:     }
      -
      -122:     // @see #createExpression()
      -123:     @Immutable
      -124:     private static class InvalidExpressionDMContext extends AbstractDMContext implements IExpressionDMContext {
      -125:         final private String fExpression;
      -126:     
      -127:         public InvalidExpressionDMContext(String sessionId, IDMContext parent, String expr) {
      -128:             super(sessionId, new IDMContext[] { parent });
      -129:             fExpression = expr;
      -130:         }
      -131:     
      -132:         @Override
      -133:         public boolean equals(Object other) {
      -134:             return super.baseEquals(other) && 
      -135:                 fExpression == null 
      -136:                     ? ((InvalidExpressionDMContext) other).getExpression() == null 
      -137:                     : fExpression.equals(((InvalidExpressionDMContext) other).getExpression());
      -138:         }
      -139:     
      -140:         @Override
      -141:         public int hashCode() {
      -142:             return fExpression == null ? super.baseHashCode() : super.baseHashCode() ^ fExpression.hashCode();
      -143:         }
      -144:     
      -145:         @Override
      -146:         public String toString() {
      -147:             return baseToString() + ".invalid_expr[" + fExpression + "]"; 
      -148:         }
      -149:     
      -150:         public String getExpression() {
      -151:             return fExpression;
      -152:         }
      -153:     }
      -154:     
      -155:     @Immutable
      -156:     private static class ExpressionChangedDMEvent extends AbstractDMEvent<IExpressionDMContext> 
      -157:         implements IExpressionChangedDMEvent 
      -158:     {
      -159:         ExpressionChangedDMEvent(IExpressionDMContext expression) {
      -160:             super(expression);
      -161:         }
      -162:     }
      -
      -164:     
      -165:     private PDACommandControl fCommandControl;
      -166:     private IStack fStack;
      -
      -168:     private CommandCache fCommandCache;
      -
      -170:     public PDAExpressions(DsfSession session) {
      -171:         super(session);
      -172:     }
      -
      -174:     @Override
      -175:     protected BundleContext getBundleContext() {
      -176:         return PDAPlugin.getBundleContext();
      -177:     }
      -
      -179:     @Override
      -180:     public void initialize(final RequestMonitor rm) {
      -181:         super.initialize(
      -182:             new RequestMonitor(getExecutor(), rm) { 
      -183:                 @Override
      -184:                 protected void handleOK() {
      -185:                     doInitialize(rm);
      -186:                 }});
      -187:     }
      -
      -189:     private void doInitialize(final RequestMonitor rm) {
      -190:         fCommandControl = getServicesTracker().getService(PDACommandControl.class);
      -191:         fStack = getServicesTracker().getService(IStack.class);
      -192:         fCommandCache = new CommandCache(fCommandControl);
      -
      -194:         getSession().addServiceEventListener(this, null);
      -195:         
      -196:         register(new String[]{IExpressions.class.getName(), PDAExpressions.class.getName()}, new Hashtable<String,String>());
      -197:         
      -198:         rm.done();
      -199:     }
      -
      -201:     @Override
      -202:     public void shutdown(final RequestMonitor rm) {
      -203:         getSession().removeServiceEventListener(this);
      -204:         fCommandCache.reset();
      -205:         super.shutdown(rm);
      -206:     }
      -
      -208:     public void canWriteExpression(IExpressionDMContext expressionContext, DataRequestMonitor<Boolean> rm) {
      -209:         rm.setData(true);
      -210:         rm.done();
      -211:     }
      -
      -213:     public IExpressionDMContext createExpression(IDMContext ctx, String expression) {
      -214:         // Create an expression based on the given context and string expression.  
      -215:         // The PDA debugger can only evaluate variables as expressions and only
      -216:         // in context of a frame.  
      -217:         IFrameDMContext frameCtx = DMContexts.getAncestorOfType(ctx, IFrameDMContext.class);
      -218:         if (frameCtx != null) {
      -219:             return new ExpressionDMContext(getSession().getId(), frameCtx, expression);
      -220:         } else {
      -221:             // If a frame cannot be found in context, return an "invalid" 
      -222:             // expression context, because a null return value is not allowed.
      -223:             // Evaluating an invalid expression context will always yield an 
      -224:             // error.
      -225:             return new InvalidExpressionDMContext(getSession().getId(), ctx, expression);
      -226:         }
      -227:     }
      -
      -229:     public void getBaseExpressions(IExpressionDMContext exprContext, DataRequestMonitor<IExpressionDMContext[]> rm) {
      -230:         PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Not supported");
      -231:     }
      -
      -233:     public void getExpressionAddressData(IExpressionDMContext dmc, DataRequestMonitor<IExpressionDMAddress> rm) {
      -234:         PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Not supported");
      -235:     }
      -
      -237:     public void getExpressionData(final IExpressionDMContext exprCtx, final DataRequestMonitor<IExpressionDMData> rm) {
      -238:         // Since expression data doesn't contain any more information than the 
      -239:         // context, it doesn't require any debugger commmands.
      -240:         if (exprCtx instanceof ExpressionDMContext) {
      -241:             rm.setData(new ExpressionDMData(exprCtx.getExpression()));
      -242:             rm.done();
      -243:         } else {
      -244:             PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid expression context " + exprCtx);
      -245:         }
      -246:     }
      -
      -248:     public void getSubExpressionCount(IExpressionDMContext exprCtx, DataRequestMonitor<Integer> rm) {
      -249:         PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Not supported");
      -250:     }
      -
      -252:     public void getSubExpressions(IExpressionDMContext exprCtx, DataRequestMonitor<IExpressionDMContext[]> rm) {
      -253:         PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Not supported");
      -254:     }
      -
      -256:     public void getSubExpressions(IExpressionDMContext exprCtx, int startIndex, int length,
      -257:         DataRequestMonitor<IExpressionDMContext[]> rm) 
      -258:     {
      -259:         PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Not supported");
      -260:     }
      -
      -262:     public void getAvailableFormats(IFormattedDataDMContext dmc, DataRequestMonitor<String[]> rm) {
      -263:         // PDA debugger doesn't support formatting the expression.  Natural 
      -264:         // formatting is the only available option.
      -265:         rm.setData(new String[] { NATURAL_FORMAT });
      -266:         rm.done();
      -267:     }
      -
      -269:     public FormattedValueDMContext getFormattedValueContext(IFormattedDataDMContext exprCtx, String formatId) {
      -270:         // Creates a context that can be used to retrieve a formatted value.
      -271:         return new FormattedValueDMContext(this, exprCtx, formatId);
      -272:     }
      -
      -274:     public void getFormattedExpressionValue(FormattedValueDMContext formattedCtx, 
      -275:         final DataRequestMonitor<FormattedValueDMData> rm) 
      -276:     {
      -277:         final ExpressionDMContext exprCtx = DMContexts.getAncestorOfType(formattedCtx, ExpressionDMContext.class);
      -278:         if (exprCtx != null) {
      -279:             final IFrameDMContext frameCtx = DMContexts.getAncestorOfType(exprCtx, IFrameDMContext.class);
      -280:             
      -281:             // First retrieve the stack depth, needed to properly calculate
      -282:             // the frame index that is used by the PDAVarCommand. 
      -283:             fStack.getStackDepth(
      -284:                 frameCtx, 0,
      -285:                 new DataRequestMonitor<Integer>(getExecutor(), rm) {
      -286:                     @Override
      -287:                     protected void handleOK() {
      -288:                         // Calculate the frame index.
      -289:                         int frameId = getData() - frameCtx.getLevel() - 1;
      -290:                         
      -291:                         // Send the command to evaluate the variable.
      -292:                         fCommandCache.execute(
      -293:                             new PDAVarCommand(fCommandControl.getProgramDMContext(), frameId, exprCtx.getExpression()), 
      -294:                             new DataRequestMonitor<PDACommandResult>(getExecutor(), rm) {
      -295:                                 @Override
      -296:                                 protected void handleOK() {
      -297:                                     rm.setData(new FormattedValueDMData(getData().fResponseText));
      -298:                                     rm.done();
      -299:                                 }
      -300:                             });        
      -301:                     }
      -302:                 });
      -303:         } else {
      -304:             PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid expression context " + formattedCtx);
      -305:             rm.done();
      -306:         }
      -307:     }
      -
      -309:     public void writeExpression(final IExpressionDMContext exprCtx, final String exprValue, String formatId, 
      -310:         final RequestMonitor rm) 
      -311:     {
      -312:         if (exprCtx instanceof ExpressionDMContext) {
      -313:             final IFrameDMContext frameCtx = DMContexts.getAncestorOfType(exprCtx, IFrameDMContext.class);
      -314:             
      -315:             // Similarly to retrieving the variable, retrieve the 
      -316:             // stack depth first.
      -317:             fStack.getStackDepth(
      -318:                 frameCtx, 0,
      -319:                 new DataRequestMonitor<Integer>(getExecutor(), rm) {
      -320:                     @Override
      -321:                     protected void handleOK() {
      -322:                         // Calculate the frame index.
      -323:                         int frameId = getData() - frameCtx.getLevel() - 1;
      -324:                         
      -325:                         // Send the "write" command to PDA debugger
      -326:                         fCommandCache.execute(
      -327:                             new PDASetVarCommand(fCommandControl.getProgramDMContext(), frameId, exprCtx.getExpression(), exprValue), 
      -328:                             new DataRequestMonitor<PDACommandResult>(getExecutor(), rm) {
      -329:                                 @Override
      -330:                                 protected void handleOK() {
      -331:                                     getSession().dispatchEvent(new ExpressionChangedDMEvent(exprCtx), getProperties());
      -332:                                     rm.done();
      -333:                                 }
      -334:                             });
      -335:                     }
      -336:                 });
      -337:         } else {
      -338:             PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid expression context " + exprCtx);
      -339:             rm.done();
      -340:         }
      -341:     }
      -
      -343:     @SuppressWarnings("unchecked")
      -344:     @Deprecated
      -345:     public void getModelData(IDMContext dmc, DataRequestMonitor<?> rm) {
      -346:         if (dmc instanceof IExpressionDMContext) {
      -347:             getExpressionData((IExpressionDMContext) dmc, (DataRequestMonitor<IExpressionDMData>) rm);
      -348:         } else if (dmc instanceof FormattedValueDMContext) {
      -349:             getFormattedExpressionValue((FormattedValueDMContext) dmc, (DataRequestMonitor<FormattedValueDMData>) rm);
      -350:         } else {
      -351:             PDAPlugin.failRequest(rm, INVALID_HANDLE, "Unknown DMC type");
      -352:             rm.done();
      -353:         }
      -354:     }
      -
      -356:     @DsfServiceEventHandler 
      -357:     public void eventDispatched(IResumedDMEvent e) {
      -358:         // Mark the cache as not available, so that data retrieval commands 
      -359:         // will fail.  Also reset the cache unless it was a step command.
      -360:         fCommandCache.setTargetAvailable(false);
      -361:         if (!e.getReason().equals(StateChangeReason.STEP)) {
      -362:             fCommandCache.reset();
      -363:         }
      -364:     }    
      -
      -
      -367:     @DsfServiceEventHandler 
      -368:     public void eventDispatched(ISuspendedDMEvent e) {
      -369:         // Enable sending commands to target and clear the cache.
      -370:         fCommandCache.setTargetAvailable(true);
      -371:         fCommandCache.reset();
      -372:     }
      -373: }
      -
      - - - diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java.html deleted file mode 100644 index 00690033f51..00000000000 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java.html +++ /dev/null @@ -1,330 +0,0 @@ - - - -PDARunControl.java - - - - - -
        1: /*******************************************************************************
      -  2:  * Copyright (c) 2006 Wind River Systems and others.
      -  3:  * All rights reserved. This program and the accompanying materials
      -  4:  * are made available under the terms of the Eclipse Public License v1.0
      -  5:  * which accompanies this distribution, and is available at
      -  6:  * http://www.eclipse.org/legal/epl-v10.html
      -  7:  * 
      -  8:  * Contributors:
      -  9:  *     Wind River Systems - initial API and implementation
      - 10:  *     Ericsson        AB                  - Modified for handling of multiple threads
      - 11:  *******************************************************************************/
      - 12: package org.eclipse.dd.examples.pda.service;
      -
      - 14: import java.util.Hashtable;
      -
      - 16: import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
      - 17: import org.eclipse.dd.dsf.concurrent.Immutable;
      - 18: import org.eclipse.dd.dsf.concurrent.RequestMonitor;
      - 19: import org.eclipse.dd.dsf.datamodel.AbstractDMEvent;
      - 20: import org.eclipse.dd.dsf.datamodel.IDMContext;
      - 21: import org.eclipse.dd.dsf.datamodel.IDMEvent;
      - 22: import org.eclipse.dd.dsf.debug.service.IRunControl;
      - 23: import org.eclipse.dd.dsf.debug.service.command.IEventListener;
      - 24: import org.eclipse.dd.dsf.service.AbstractDsfService;
      - 25: import org.eclipse.dd.dsf.service.DsfServiceEventHandler;
      - 26: import org.eclipse.dd.dsf.service.DsfSession;
      - 27: import org.eclipse.dd.dsf.service.IDsfService;
      - 28: import org.eclipse.dd.examples.pda.PDAPlugin;
      - 29: import org.eclipse.dd.examples.pda.service.commands.PDACommandResult;
      - 30: import org.eclipse.dd.examples.pda.service.commands.PDAResumeCommand;
      - 31: import org.eclipse.dd.examples.pda.service.commands.PDAStepCommand;
      - 32: import org.eclipse.dd.examples.pda.service.commands.PDASuspendCommand;
      - 33: import org.osgi.framework.BundleContext;
      -
      -
      - 36: /**
      - 37:  * Service for monitoring and controlling execution state of the DPA 
      - 38:  * program.
      - 39:  * <p>
      - 40:  * This service depends on the {@link PDACommandControl} service.
      - 41:  * It must be initialized before this service is initialized.
      - 42:  * </p>
      - 43:  */
      - 44: public class PDARunControl extends AbstractDsfService 
      - 45:     implements IRunControl, IEventListener
      - 46: {
      - 47:     // Implementation note about tracking execution state:
      - 48:     // This class implements event handlers for the events that are generated by 
      - 49:     // this service itself.  When the event is dispatched, these handlers will
      - 50:     // be called first, before any of the clients.  These handlers update the 
      - 51:     // service's internal state information to make them consistent with the 
      - 52:     // events being issued.  Doing this in the handlers as opposed to when 
      - 53:     // the events are generated, guarantees that the state of the service will
      - 54:     // always be consistent with the events.
      - 55:     // The purpose of this pattern is to allow clients that listen to service 
      - 56:     // events and track service state, to be perfectly in sync with the service
      - 57:     // state.
      - 58:     
      - 59:     @Immutable 
      - 60:     private static class ExecutionDMData implements IExecutionDMData {
      - 61:         private final StateChangeReason fReason;
      - 62:         ExecutionDMData(StateChangeReason reason) {
      - 63:             fReason = reason;
      - 64:         }
      - 65:         public StateChangeReason getStateChangeReason() { return fReason; }
      - 66:     }
      - 67:     
      - 68:     @Immutable 
      - 69:     private static class ResumedEvent extends AbstractDMEvent<IExecutionDMContext> 
      - 70:         implements IResumedDMEvent
      - 71:     {
      - 72:         private final String fPDAEvent;
      -
      - 74:         ResumedEvent(IExecutionDMContext ctx, String pdaEvent) { 
      - 75:             super(ctx);
      - 76:             fPDAEvent = pdaEvent;
      - 77:         }
      - 78:         
      - 79:         public StateChangeReason getReason() {
      - 80:             if (fPDAEvent.startsWith("resumed breakpoint") || fPDAEvent.startsWith("suspended watch")) {
      - 81:                 return StateChangeReason.BREAKPOINT;
      - 82:             } else if (fPDAEvent.equals("resumed step") || fPDAEvent.equals("resumed drop")) {
      - 83:                 return StateChangeReason.STEP;
      - 84:             } else if (fPDAEvent.equals("resumed client")) {
      - 85:                 return StateChangeReason.USER_REQUEST;
      - 86:             } else {
      - 87:                 return StateChangeReason.UNKNOWN;
      - 88:             } 
      - 89:         }
      - 90:     }
      - 91:     
      - 92:     @Immutable
      - 93:     private static class SuspendedEvent extends AbstractDMEvent<IExecutionDMContext> 
      - 94:         implements ISuspendedDMEvent
      - 95:     {
      - 96:         private final String fPDAEvent;
      - 97:         
      - 98:         SuspendedEvent(IExecutionDMContext ctx, String pdaEvent) { 
      - 99:             super(ctx);
      -100:             fPDAEvent = pdaEvent;
      -101:         }
      -102:         
      -103:         public StateChangeReason getReason() {
      -104:             if (fPDAEvent.startsWith("suspended breakpoint") || fPDAEvent.startsWith("suspended watch")) {
      -105:                 return StateChangeReason.BREAKPOINT;
      -106:             } else if (fPDAEvent.equals("suspended step") || fPDAEvent.equals("suspended drop")) {
      -107:                 return StateChangeReason.STEP;
      -108:             } else if (fPDAEvent.equals("suspended client")) {
      -109:                 return StateChangeReason.USER_REQUEST;
      -110:             } else {
      -111:                 return StateChangeReason.UNKNOWN;
      -112:             } 
      -113:         }
      -114:     }
      -
      -116:     // Services 
      -117:     private PDACommandControl fCommandControl;
      -118:     
      -119:     // State flags
      -120:         private boolean fSuspended = true;
      -121:     private boolean fResumePending = false;
      -122:         private boolean fStepping = false;
      -123:         private StateChangeReason fStateChangeReason;
      -124:         
      -125:     public PDARunControl(DsfSession session) {
      -126:         super(session);
      -127:     }
      -128:     
      -129:     @Override
      -130:     protected BundleContext getBundleContext() {
      -131:         return PDAPlugin.getBundleContext();
      -132:     }
      -133:     
      -134:     @Override
      -135:     public void initialize(final RequestMonitor rm) {
      -136:         super.initialize(
      -137:             new RequestMonitor(getExecutor(), rm) { 
      -138:                 @Override
      -139:                 protected void handleOK() {
      -140:                     doInitialize(rm);
      -141:                 }});
      -142:     }
      -
      -144:     private void doInitialize(final RequestMonitor rm) {
      -145:         fCommandControl = getServicesTracker().getService(PDACommandControl.class);
      -
      -147:         // Add ourselves as a listener to PDA events, to catch suspended/resumed 
      -148:         // events.
      -149:         fCommandControl.addEventListener(this);
      -150:         
      -151:         // Add ourselves as a listener to service events, in order to process
      -152:         // our own suspended/resumed events.
      -153:         getSession().addServiceEventListener(this, null);
      -154:         
      -155:         // Register the service with OSGi
      -156:         register(new String[]{IRunControl.class.getName(), PDARunControl.class.getName()}, new Hashtable<String,String>());
      -157:         
      -158:         rm.done();
      -159:     }
      -
      -161:     @Override
      -162:     public void shutdown(final RequestMonitor rm) {
      -163:         fCommandControl.removeEventListener(this);
      -164:         getSession().removeServiceEventListener(this);
      -165:         super.shutdown(rm);
      -166:     }
      -167:     
      -168:     @Deprecated
      -169:     @SuppressWarnings("unchecked")
      -170:     public void getModelData(IDMContext dmc, DataRequestMonitor<?> rm) {
      -171:         // The getModelData() is deprecated and clients are expected to switch
      -172:         // to getExecutionData() and other data retrieve methods directly.
      -173:         // However the UI cache still uses it for now.
      -174:         if (dmc instanceof IExecutionDMContext) {
      -175:             getExecutionData((IExecutionDMContext)dmc, (DataRequestMonitor<IExecutionDMData>)rm); 
      -176:         } else {
      -177:             PDAPlugin.failRequest(rm, INVALID_HANDLE, "Unknown DMC type");
      -178:         }
      -179:     }
      -180:     
      -181:     public void eventReceived(Object output) {
      -182:         if (!(output instanceof String)) return;
      -183:         String event = (String)output;
      -184:         
      -185:         // Handle PDA debugger suspended/resumed events and issue the 
      -186:         // corresponding Data Model events.  Do not update the state
      -187:         // information until we start dispatching the service events.
      -188:         if (event.startsWith("suspended")) {
      -189:             IDMEvent<?> dmEvent = new SuspendedEvent(fCommandControl.getProgramDMContext(), event);
      -190:             getSession().dispatchEvent(dmEvent, getProperties());
      -191:         } else if (event.startsWith("resumed")) {
      -192:             IDMEvent<?> dmEvent = new ResumedEvent(fCommandControl.getProgramDMContext(), event);
      -193:             getSession().dispatchEvent(dmEvent, getProperties());
      -194:         }
      -195:     }
      -196:     
      -197:     
      -198:     @DsfServiceEventHandler 
      -199:     public void eventDispatched(ResumedEvent e) {
      -200:         // This service should be the first to receive the ResumedEvent, 
      -201:         // (before any other listeners are called).  Here, update the
      -202:         // service state information based on the the resumed event.
      -203:         fSuspended = false;
      -204:         fResumePending = false;
      -205:         fStateChangeReason = e.getReason();
      -206:         fStepping = e.getReason().equals(StateChangeReason.STEP);
      -207:     }    
      -
      -
      -210:     @DsfServiceEventHandler 
      -211:     public void eventDispatched(SuspendedEvent e) {
      -212:         // This service should be the first to receive the SuspendedEvent also, 
      -213:         // (before any other listeners are called).  Here, update the
      -214:         // service state information based on the the suspended event.
      -215:         fStateChangeReason = e.getReason();
      -216:         fResumePending = false;
      -217:         fSuspended = true;
      -218:         fStepping = false;
      -219:     }
      -220:     
      -221:     
      -222:         public boolean canResume(IExecutionDMContext context) {
      -223:         return isSuspended(context) && !fResumePending;
      -224:         }
      -
      -226:         public boolean canSuspend(IExecutionDMContext context) {
      -227:         return !isSuspended(context);
      -228:         }
      -
      -230:         public boolean isSuspended(IExecutionDMContext context) {
      -231:                 return fSuspended;
      -232:         }
      -
      -234:         public boolean isStepping(IExecutionDMContext context) {
      -235:             return !isSuspended(context) && fStepping;
      -236:     }
      -
      -238:         public void resume(IExecutionDMContext context, final RequestMonitor rm) {
      -239:                 assert context != null;
      -
      -241:                 if (canResume(context)) { 
      -242:             fResumePending = true;
      -243:             fCommandControl.queueCommand(
      -244:                     new PDAResumeCommand(fCommandControl.getProgramDMContext()),
      -245:                     new DataRequestMonitor<PDACommandResult>(getExecutor(), rm) { 
      -246:                     @Override
      -247:                     protected void handleErrorOrCancel() {
      -248:                         // If the resume command failed, we no longer
      -249:                         // expect to receive a resumed event.
      -250:                         fResumePending = false;
      -251:                     }
      -252:                     }
      -253:             );
      -254:         }else {
      -255:             PDAPlugin.failRequest(rm, INVALID_STATE, "Given context: " + context + ", is already running.");
      -256:         }
      -257:         }
      -258:         
      -259:         public void suspend(IExecutionDMContext context, final RequestMonitor rm){
      -260:                 assert context != null;
      -
      -262:                 if (canSuspend(context)) {
      -263:             fCommandControl.queueCommand(
      -264:                 new PDASuspendCommand(fCommandControl.getProgramDMContext()),
      -265:                 new DataRequestMonitor<PDACommandResult>(getExecutor(), rm));
      -266:             
      -267:         } else {
      -268:             PDAPlugin.failRequest(rm, IDsfService.INVALID_STATE, "Given context: " + context + ", is already suspended."); 
      -269:         }
      -270:     }
      -271:     
      -272:     public boolean canStep(IExecutionDMContext context) {
      -273:         return canResume(context);
      -274:     }
      -275:     
      -276:     public void step(IExecutionDMContext context, StepType stepType, final RequestMonitor rm) {
      -277:             assert context != null;
      -278:             
      -279:             if (canResume(context)) {
      -280:             fResumePending = true;
      -281:             fStepping = true;
      -
      -283:             fCommandControl.queueCommand(
      -284:                 new PDAStepCommand(fCommandControl.getProgramDMContext()),
      -285:                 new DataRequestMonitor<PDACommandResult>(getExecutor(), rm) {
      -286:                     @Override
      -287:                     protected void handleErrorOrCancel() {
      -288:                         // If the step command failed, we no longer
      -289:                         // expect to receive a resumed event.
      -290:                         fResumePending = false;
      -291:                         fStepping = false;
      -292:                     }
      -293:                 });
      -
      -295:             } else {
      -296:             PDAPlugin.failRequest(rm, INVALID_STATE, "Cannot resume context"); 
      -297:             return;
      -298:         }
      -299:     }
      -
      -301:     public boolean canInstructionStep(IExecutionDMContext context) {
      -302:         return false;
      -303:     }
      -304:     
      -305:     public void instructionStep(IExecutionDMContext context, StepType stepType, RequestMonitor rm) {
      -306:         PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Operation not implemented"); 
      -307:     }
      -
      -309:     public void getExecutionContexts(final IContainerDMContext containerDmc, final DataRequestMonitor<IExecutionDMContext[]> rm) {
      -310:         PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Operation not implemented"); 
      -311:     }
      -312:     
      -313:         public void getExecutionData(IExecutionDMContext dmc, DataRequestMonitor<IExecutionDMData> rm){
      -314:         rm.setData( new ExecutionDMData(fStateChangeReason) );
      -315:         rm.done();
      -316:     }
      -317: }
      -
      - - - diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java.html deleted file mode 100644 index efa44c42c84..00000000000 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java.html +++ /dev/null @@ -1,393 +0,0 @@ - - - -PDAStack.java - - - - - -
        1: /*******************************************************************************
      -  2:  * Copyright (c) 2008 Wind River Systems and others.
      -  3:  * All rights reserved. This program and the accompanying materials
      -  4:  * are made available under the terms of the Eclipse Public License v1.0
      -  5:  * which accompanies this distribution, and is available at
      -  6:  * http://www.eclipse.org/legal/epl-v10.html
      -  7:  * 
      -  8:  * Contributors:
      -  9:  *     Wind River Systems - initial API and implementation
      - 10:  *******************************************************************************/
      - 11: package org.eclipse.dd.examples.pda.service;
      -
      - 13: import java.util.Hashtable;
      -
      - 15: import org.eclipse.cdt.core.IAddress;
      - 16: import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
      - 17: import org.eclipse.dd.dsf.concurrent.Immutable;
      - 18: import org.eclipse.dd.dsf.concurrent.RequestMonitor;
      - 19: import org.eclipse.dd.dsf.datamodel.AbstractDMContext;
      - 20: import org.eclipse.dd.dsf.datamodel.DMContexts;
      - 21: import org.eclipse.dd.dsf.datamodel.IDMContext;
      - 22: import org.eclipse.dd.dsf.debug.service.IRunControl;
      - 23: import org.eclipse.dd.dsf.debug.service.IStack;
      - 24: import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
      - 25: import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent;
      - 26: import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent;
      - 27: import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason;
      - 28: import org.eclipse.dd.dsf.debug.service.command.CommandCache;
      - 29: import org.eclipse.dd.dsf.service.AbstractDsfService;
      - 30: import org.eclipse.dd.dsf.service.DsfServiceEventHandler;
      - 31: import org.eclipse.dd.dsf.service.DsfSession;
      - 32: import org.eclipse.dd.dsf.service.IDsfService;
      - 33: import org.eclipse.dd.examples.pda.PDAPlugin;
      - 34: import org.eclipse.dd.examples.pda.service.commands.PDAFrame;
      - 35: import org.eclipse.dd.examples.pda.service.commands.PDAStackCommand;
      - 36: import org.eclipse.dd.examples.pda.service.commands.PDAStackCommandResult;
      - 37: import org.osgi.framework.BundleContext;
      -
      - 39: /**
      - 40:  * Service for retrieving PDA debugger stack data. 
      - 41:  * <p>
      - 42:  * This service depends on the {@link PDACommandControl} service and the 
      - 43:  * {@link IRunControl} service.  These services must be initialized before 
      - 44:  * this service is initialized.
      - 45:  * </p>
      - 46:  */
      - 47: public class PDAStack extends AbstractDsfService implements IStack {
      -
      - 49:     /**
      - 50:      * PDA stack frame contains only the stack frame level.  It is only 
      - 51:      * used as an index into the frame data returned by the PDA debugger.
      - 52:      */
      - 53:     @Immutable
      - 54:     private static class FrameDMContext extends AbstractDMContext implements IFrameDMContext {
      -
      - 56:         final private int fLevel;
      -
      - 58:         FrameDMContext(String sessionId, IExecutionDMContext execDmc, int level) {
      - 59:             super(sessionId, new IDMContext[] { execDmc });
      - 60:             fLevel = level;
      - 61:         }
      -
      - 63:         public int getLevel() { return fLevel; }
      -
      - 65:         @Override
      - 66:         public boolean equals(Object other) {
      - 67:             return super.baseEquals(other) && ((FrameDMContext)other).fLevel == fLevel;
      - 68:         }
      -
      - 70:         @Override
      - 71:         public int hashCode() {
      - 72:             return super.baseHashCode() ^ fLevel;
      - 73:         }
      -
      - 75:         @Override
      - 76:         public String toString() { 
      - 77:             return baseToString() + ".frame[" + fLevel + "]";  //$NON-NLS-1$ //$NON-NLS-2$
      - 78:         }
      - 79:     }
      -
      - 81:     /**
      - 82:      * Frame data based on the PDAFrame object returned by the PDA debugger.
      - 83:      */
      - 84:     @Immutable
      - 85:     private static class FrameDMData implements IFrameDMData {
      -
      - 87:         final private PDAFrame fFrame;
      -
      - 89:         FrameDMData(PDAFrame frame) {
      - 90:             fFrame = frame;
      - 91:         }
      -
      - 93:         public String getFile() {
      - 94:             return fFrame.fFilePath.lastSegment();
      - 95:         }
      -
      - 97:         public String getFunction() {
      - 98:             return fFrame.fFunction;
      - 99:         }
      -
      -101:         public int getLine() {
      -102:             return fFrame.fLine + 1;
      -103:         }
      -
      -105:         public int getColumn() {
      -106:             return 0;
      -107:         }
      -
      -109:         public IAddress getAddress() {
      -110:             return null;
      -111:         }
      -112:     }
      -
      -114:     /**
      -115:      * Context representing a variable in a given stack frame.
      -116:      */
      -117:     @Immutable
      -118:     private static class VariableDMContext extends AbstractDMContext implements IVariableDMContext {
      -
      -120:         final private String fVariable;
      -
      -122:         VariableDMContext(String sessionId, IFrameDMContext frameCtx, String variable) {
      -123:             super(sessionId, new IDMContext[] { frameCtx });
      -124:             fVariable = variable;
      -125:         }
      -
      -127:         String getVariable() { return fVariable; }
      -
      -129:         @Override
      -130:         public boolean equals(Object other) {
      -131:             return super.baseEquals(other) && ((VariableDMContext)other).fVariable.equals(fVariable);
      -132:         }
      -
      -134:         @Override
      -135:         public int hashCode() {
      -136:             return super.baseHashCode() + fVariable.hashCode();
      -137:         }
      -
      -139:         @Override
      -140:         public String toString() { 
      -141:             return baseToString() + ".variable(" + fVariable + ")";  //$NON-NLS-1$ //$NON-NLS-2$
      -142:         }
      -143:     }
      -
      -145:     /**
      -146:      * PDA variable data, only supports returning the variable name.
      -147:      */
      -148:     @Immutable
      -149:     private static class VariableDMData implements IVariableDMData {
      -
      -151:         final private String fVariable;
      -
      -153:         VariableDMData(String variable) {
      -154:             fVariable = variable;
      -155:         }
      -
      -157:         public String getName() {
      -158:             return fVariable;
      -159:         }
      -
      -161:         public String getValue() {
      -162:             return null;
      -163:         }
      -164:     }
      -
      -166:     // Services that this service depends on.
      -167:     private PDACommandControl fCommandControl;
      -168:     private IRunControl fRunControl;
      -
      -170:     // Command cache 
      -171:     private CommandCache fCommandCache;
      -
      -173:     public PDAStack(DsfSession session) {
      -174:         super(session);
      -175:     }
      -
      -177:     @Override
      -178:     protected BundleContext getBundleContext() {
      -179:         return PDAPlugin.getBundleContext();
      -180:     }
      -
      -182:     @Override
      -183:     public void initialize(final RequestMonitor rm) {
      -184:         super.initialize(
      -185:             new RequestMonitor(getExecutor(), rm) { 
      -186:                 @Override
      -187:                 protected void handleOK() {
      -188:                     doInitialize(rm);
      -189:                 }});
      -190:     }
      -
      -192:     private void doInitialize(final RequestMonitor rm) {
      -193:         // Initialize service references that stack service depends on
      -194:         fCommandControl = getServicesTracker().getService(PDACommandControl.class);
      -195:         fRunControl = getServicesTracker().getService(IRunControl.class);
      -
      -197:         // Create the commands cache
      -198:         fCommandCache = new CommandCache(fCommandControl);
      -
      -200:         // Register to listen for run control events, to clear cache accordingly.
      -201:         getSession().addServiceEventListener(this, null);
      -
      -203:         // Register stack service with OSGi
      -204:         register(new String[]{IStack.class.getName(), PDAStack.class.getName()}, new Hashtable<String,String>());
      -
      -206:         rm.done();
      -207:     }
      -
      -209:     @Override
      -210:     public void shutdown(final RequestMonitor rm) {
      -211:         getSession().removeServiceEventListener(this);
      -212:         fCommandCache.reset();
      -213:         super.shutdown(rm);
      -214:     }
      -
      -
      -217:     public void getArguments(IFrameDMContext frameCtx, DataRequestMonitor<IVariableDMContext[]> rm) {
      -218:         PDAPlugin.failRequest(rm, IDsfService.NOT_SUPPORTED, "PDA debugger does not support function arguments.");
      -219:     }
      -
      -221:     public void getFrameData(final IFrameDMContext frameCtx, final DataRequestMonitor<IFrameDMData> rm) {
      -222:         // Execute the PDA stack command, or retrieve the result from cache if already available.
      -223:         fCommandCache.execute(
      -224:             new PDAStackCommand(fCommandControl.getProgramDMContext()),
      -225:             new DataRequestMonitor<PDAStackCommandResult>(getExecutor(), rm) {
      -226:                 @Override
      -227:                 protected void handleOK() {
      -228:                     // PDAFrame array is ordered highest to lowest.  We need to 
      -229:                     // calculate the index based on frame level.
      -230:                     int frameId = getData().fFrames.length - frameCtx.getLevel() - 1;
      -231:                     if (frameId < 0) {
      -232:                         PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid frame level " + frameCtx);
      -233:                         return;
      -234:                     }
      -
      -236:                     // Create the frame data object based on the corresponding PDAFrame
      -237:                     rm.setData(new FrameDMData(getData().fFrames[frameId]));
      -238:                     rm.done();
      -239:                 }
      -240:             });
      -241:     }
      -
      -
      -244:     public void getFrames(IDMContext context, final DataRequestMonitor<IFrameDMContext[]> rm) {
      -245:         // Can only create stack frames for an execution context as a parent, 
      -246:         // however the argument context is a generic context type, so it could 
      -247:         // be an execution context, a frame, a variable, etc. Search the 
      -248:         // hierarchy of the argument context to find the execution one.
      -249:         final IExecutionDMContext execCtx = DMContexts.getAncestorOfType(context, IExecutionDMContext.class);
      -250:         if (execCtx == null) {
      -251:             PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid context " + context);
      -252:             return;
      -253:         }
      -
      -255:         // Execute the stack command and create the corresponding frame contexts.
      -256:         fCommandCache.execute(
      -257:             new PDAStackCommand(fCommandControl.getProgramDMContext()),
      -258:             new DataRequestMonitor<PDAStackCommandResult>(getExecutor(), rm) {
      -259:                 @Override
      -260:                 protected void handleOK() {
      -261:                     IFrameDMContext[] frameCtxs = new IFrameDMContext[getData().fFrames.length];
      -262:                     for (int i = 0; i < getData().fFrames.length; i++) {
      -263:                         frameCtxs[i] = new FrameDMContext(getSession().getId(), execCtx, i);
      -264:                     }
      -265:                     rm.setData(frameCtxs);
      -266:                     rm.done();
      -267:                 }
      -268:             });
      -269:     }
      -
      -271:     public void getLocals(final IFrameDMContext frameCtx, final DataRequestMonitor<IVariableDMContext[]> rm) {
      -272:         // Execute the stack command again.
      -273:         fCommandCache.execute(
      -274:             new PDAStackCommand(fCommandControl.getProgramDMContext()),
      -275:             new DataRequestMonitor<PDAStackCommandResult>(getExecutor(), rm) {
      -276:                 @Override
      -277:                 protected void handleOK() {
      -278:                     // Find the correct PDAFrame
      -279:                     int frameId = getData().fFrames.length - frameCtx.getLevel() - 1;
      -280:                     if (frameId < 0) {
      -281:                         PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid frame level " + frameCtx);
      -282:                         return;
      -283:                     }
      -284:                     PDAFrame pdaFrame = getData().fFrames[frameId];
      -
      -286:                     // Create variable contexts for all variables in frame.
      -287:                     IVariableDMContext[] variableCtxs = new IVariableDMContext[pdaFrame.fVariables.length];
      -288:                     for (int i = 0; i < pdaFrame.fVariables.length; i++) {
      -289:                         variableCtxs[i] = new VariableDMContext(getSession().getId(), frameCtx, pdaFrame.fVariables[i]);
      -290:                     }
      -291:                     rm.setData(variableCtxs);
      -292:                     rm.done();
      -293:                 }
      -294:             });
      -
      -296:     }
      -
      -298:     public void getStackDepth(IDMContext context, int maxDepth, final DataRequestMonitor<Integer> rm) {
      -299:         // Execute stack command and return the data's size.
      -300:         fCommandCache.execute(
      -301:             new PDAStackCommand(fCommandControl.getProgramDMContext()),
      -302:             new DataRequestMonitor<PDAStackCommandResult>(getExecutor(), rm) {
      -303:                 @Override
      -304:                 protected void handleOK() {
      -305:                     rm.setData(getData().fFrames.length);
      -306:                     rm.done();
      -307:                 }
      -308:             });
      -309:     }
      -
      -311:     public void getTopFrame(IDMContext context, final DataRequestMonitor<IFrameDMContext> rm) {
      -312:         // Can only create stack frames for an execution context as a parent, 
      -313:         // however the argument context is a generic context type, so it could 
      -314:         // be an execution context, a frame, a variable, etc. Search the 
      -315:         // hierarchy of the argument context to find the execution one.
      -316:         final IExecutionDMContext execCtx = DMContexts.getAncestorOfType(context, IExecutionDMContext.class);
      -317:         if (execCtx == null) {
      -318:             PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid context " + context);
      -319:             return;
      -320:         }
      -
      -322:         // Since the frame context only contain the level, there's no need to 
      -323:         // call the PDA debugger.  Simply create a context for level 0. 
      -324:         rm.setData(new FrameDMContext(getSession().getId(), execCtx, 0));
      -325:         rm.done();
      -326:     }
      -
      -328:     public void getVariableData(IVariableDMContext variableCtx, DataRequestMonitor<IVariableDMData> rm) {
      -329:         if ( !(variableCtx instanceof VariableDMContext) ) {
      -330:             PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid context " + variableCtx);
      -331:             return;
      -332:         }
      -
      -334:         // The variable data doen't contain a value.  So there's no need to 
      -335:         // go to the back end to retrieve it.
      -336:         String variable = ((VariableDMContext)variableCtx).getVariable();
      -
      -338:         rm.setData(new VariableDMData(variable));
      -339:         rm.done();
      -340:     }
      -
      -342:     public boolean isStackAvailable(IDMContext context) {
      -343:         // Stack is available if the program is suspended or stepping.
      -344:         IExecutionDMContext execCtx = DMContexts.getAncestorOfType(context, IExecutionDMContext.class);
      -345:         return execCtx != null && (fRunControl.isSuspended(execCtx) || (fRunControl.isStepping(execCtx)));
      -346:     }
      -
      -348:     @SuppressWarnings("unchecked")
      -349:     @Deprecated
      -350:     public void getModelData(IDMContext dmc, DataRequestMonitor<?> rm) {
      -351:         // The getModelData() is deprecated and clients are expected to switch
      -352:         // to getExecutionData() and other data retrieve methods directly.
      -353:         // However the UI cache still uses it for now.
      -354:         if (dmc instanceof IFrameDMContext) {
      -355:             getFrameData((IFrameDMContext)dmc, (DataRequestMonitor<IFrameDMData>)rm);
      -356:         } else if (dmc instanceof IVariableDMContext) {
      -357:             getVariableData((IVariableDMContext)dmc, (DataRequestMonitor<IVariableDMData>)rm);
      -358:         } else {
      -359:             PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Unknown context type");
      -360:         }
      -361:     }
      -
      -363:     @DsfServiceEventHandler 
      -364:     public void eventDispatched(IResumedDMEvent e) {
      -365:         // Mark the cache as not available, so that stack commands will
      -366:         // fail.  Also reset the cache unless it was a step command.
      -367:         fCommandCache.setTargetAvailable(false);
      -368:         if (!e.getReason().equals(StateChangeReason.STEP)) {
      -369:             fCommandCache.reset();
      -370:         }
      -371:     }    
      -
      -
      -374:     @DsfServiceEventHandler 
      -375:     public void eventDispatched(ISuspendedDMEvent e) {
      -376:         // Enable sending commands to target and clear the cache.
      -377:         fCommandCache.setTargetAvailable(true);
      -378:         fCommandCache.reset();
      -379:     }
      -380: }
      -
      - - - diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommand.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommand.java.html deleted file mode 100644 index 311cbceb6b0..00000000000 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommand.java.html +++ /dev/null @@ -1,46 +0,0 @@ - - - -PDADataCommand.java - - - - - -
        1: /*******************************************************************************
      -  2:  * Copyright (c) 2008 Wind River Systems and others.
      -  3:  * All rights reserved. This program and the accompanying materials
      -  4:  * are made available under the terms of the Eclipse Public License v1.0
      -  5:  * which accompanies this distribution, and is available at
      -  6:  * http://www.eclipse.org/legal/epl-v10.html
      -  7:  * 
      -  8:  * Contributors:
      -  9:  *     Wind River Systems - initial API and implementation
      - 10:  *******************************************************************************/
      - 11: package org.eclipse.dd.examples.pda.service.commands;
      -
      - 13: import org.eclipse.dd.examples.pda.service.PDAProgramDMContext;
      -
      - 15: /**
      - 16:  * Retrieves data stack information 
      - 17:  * 
      - 18:  * <pre>
      - 19:  *    C: data
      - 20:  *    R: {value 1}|{value 2}|{value 3}|...|
      - 21:  * </pre>
      - 22:  */
      - 23: public class PDADataCommand extends AbstractPDACommand<PDADataCommandResult> {
      -
      - 25:     public PDADataCommand(PDAProgramDMContext context) {
      - 26:         super(context, "data");
      - 27:     }
      - 28:     
      - 29:     @Override
      - 30:     public PDADataCommandResult createResult(String resultText) {
      - 31:         return new PDADataCommandResult(resultText);
      - 32:     }
      - 33: }
      -
      - - - diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommandResult.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommandResult.java.html deleted file mode 100644 index b5f3ae2cb46..00000000000 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommandResult.java.html +++ /dev/null @@ -1,55 +0,0 @@ - - - -PDADataCommandResult.java - - - - - -
        1: /*******************************************************************************
      -  2:  * Copyright (c) 2008 Wind River Systems and others.
      -  3:  * All rights reserved. This program and the accompanying materials
      -  4:  * are made available under the terms of the Eclipse Public License v1.0
      -  5:  * which accompanies this distribution, and is available at
      -  6:  * http://www.eclipse.org/legal/epl-v10.html
      -  7:  * 
      -  8:  * Contributors:
      -  9:  *     Wind River Systems - initial API and implementation
      - 10:  *******************************************************************************/
      - 11: package org.eclipse.dd.examples.pda.service.commands;
      -
      - 13: import java.util.ArrayList;
      - 14: import java.util.List;
      - 15: import java.util.StringTokenizer;
      -
      -
      - 18: /**
      - 19:  * @see PDADataCommand
      - 20:  */
      - 21: public class PDADataCommandResult extends PDACommandResult {
      - 22:     
      - 23:     final public String[] fValues;
      - 24:     
      - 25:     PDADataCommandResult(String response) {
      - 26:         super(response);
      - 27:         StringTokenizer st = new StringTokenizer(response, "|");
      - 28:         List<String> valuesList = new ArrayList<String>();
      - 29:         
      - 30:         while (st.hasMoreTokens()) {
      - 31:             String token = st.nextToken();
      - 32:             if (token.length() != 0) {
      - 33:                 valuesList.add(st.nextToken());
      - 34:             }
      - 35:         }
      - 36:         
      - 37:         fValues = new String[valuesList.size()];
      - 38:         for (int i = 0; i < valuesList.size(); i++) {
      - 39:             fValues[i] = valuesList.get(i);
      - 40:         }
      - 41:     }
      - 42: }
      -
      - - - diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAResumeCommand.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAResumeCommand.java.html deleted file mode 100644 index ae563692a2f..00000000000 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAResumeCommand.java.html +++ /dev/null @@ -1,47 +0,0 @@ - - - -PDAResumeCommand.java - - - - - -
        1: /*******************************************************************************
      -  2:  * Copyright (c) 2008 Wind River Systems and others.
      -  3:  * All rights reserved. This program and the accompanying materials
      -  4:  * are made available under the terms of the Eclipse Public License v1.0
      -  5:  * which accompanies this distribution, and is available at
      -  6:  * http://www.eclipse.org/legal/epl-v10.html
      -  7:  * 
      -  8:  * Contributors:
      -  9:  *     Wind River Systems - initial API and implementation
      - 10:  *******************************************************************************/
      - 11: package org.eclipse.dd.examples.pda.service.commands;
      -
      - 13: import org.eclipse.dd.examples.pda.service.PDAProgramDMContext;
      -
      - 15: /**
      - 16:  * Resumes the execution  
      - 17:  * 
      - 18:  * <pre>
      - 19:  *    C: resume
      - 20:  *    R: ok
      - 21:  *    E: resumed client
      - 22:  * </pre>
      - 23:  */
      - 24: public class PDAResumeCommand extends AbstractPDACommand<PDACommandResult> {
      -
      - 26:     public PDAResumeCommand(PDAProgramDMContext context) {
      - 27:         super(context, "resume");
      - 28:     }
      - 29:     
      - 30:     @Override
      - 31:     public PDACommandResult createResult(String resultText) {
      - 32:         return new PDACommandResult(resultText);
      - 33:     }
      - 34: }
      -
      - - - From ab668f8755537fe261b7ae92d39546e1815bf080 Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Thu, 13 Mar 2008 18:18:03 +0000 Subject: [PATCH 302/834] Some typo's. --- .../eclipse/dd/examples/pda/service/PDACommandControl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java index e7b77ceeb0d..60d37deb922 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java @@ -236,7 +236,7 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon while (!isTerminated()) { synchronized(fTxCommands) { try { - // Remove comamnd from send queue. + // Remove command from send queue. final CommandHandle commandHandle = fTxCommands.take(); // Send the request to PDA @@ -351,7 +351,7 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon listener.commandQueued(command); } - // In a separate dispatch cycle. This allows command listeners to repond to the + // In a separate dispatch cycle. This allows command listeners to respond to the // command queued event. getExecutor().execute(new DsfRunnable() { public void run() { From 1e1e66689e2f0ddc0fffb41649f32fcd3c78d96c Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 13 Mar 2008 19:04:07 +0000 Subject: [PATCH 303/834] [220446] Updated the timers example. --- .../eclipse/dd/examples/dsf/timers/AlarmService.java | 10 +++++----- .../eclipse/dd/examples/dsf/timers/AlarmsVMNode.java | 8 ++++---- .../eclipse/dd/examples/dsf/timers/TimerService.java | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmService.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmService.java index 830580c4e57..1a48ba43113 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmService.java +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmService.java @@ -107,8 +107,8 @@ public class AlarmService extends AbstractDsfService /** * Event indicating that an alarm has been triggered by a timer. */ - public class AlarmTriggeredEvent extends AbstractDMEvent { - public AlarmTriggeredEvent(AlarmDMContext context) { + public class AlarmTriggeredDMEvent extends AbstractDMEvent { + public AlarmTriggeredDMEvent(AlarmDMContext context) { super(context); } } @@ -123,7 +123,7 @@ public class AlarmService extends AbstractDsfService @Override protected BundleContext getBundleContext() { - return DsfExamplesPlugin.getBundleContext(); + return DsfExamplesPlugin.getDefault().getBundle().getBundleContext(); } @Override @@ -179,7 +179,7 @@ public class AlarmService extends AbstractDsfService AlarmDMContext alarmCtx = new AlarmDMContext( getSession().getId(), timerContext, entry.getKey()); getSession().dispatchEvent( - new AlarmTriggeredEvent(alarmCtx), getProperties()); + new AlarmTriggeredDMEvent(alarmCtx), getProperties()); } } } @@ -201,7 +201,7 @@ public class AlarmService extends AbstractDsfService } /** Returns the alarm context for given timer and trigger contexts. */ - public AlarmDMContext getAlarmS(TriggerDMContext alarmCtx, TimerDMContext timerCtx) { + public AlarmDMContext getAlarm(TriggerDMContext alarmCtx, TimerDMContext timerCtx) { return new AlarmDMContext(getSession().getId(), timerCtx, alarmCtx); } diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmsVMNode.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmsVMNode.java index 3f86a7825c3..3cc08f4ce3c 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmsVMNode.java +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmsVMNode.java @@ -60,7 +60,7 @@ class AlarmsVMNode extends AbstractDMVMNode // Get the alarm context then check the triggered value. final AlarmDMContext alarmStatusDmc = getServicesTracker().getService(AlarmService.class). - getAlarmS(alarmDmc, timerDmc); + getAlarm(alarmDmc, timerDmc); boolean triggered = getServicesTracker().getService(AlarmService.class). isAlarmTriggered(alarmStatusDmc); @@ -84,7 +84,7 @@ class AlarmsVMNode extends AbstractDMVMNode public int getDeltaFlags(Object e) { - if (e instanceof AlarmService.AlarmTriggeredEvent) { + if (e instanceof AlarmService.AlarmTriggeredDMEvent) { return IModelDelta.ADDED | IModelDelta.SELECT | IModelDelta.EXPAND; } return IModelDelta.NO_CHANGE; @@ -93,10 +93,10 @@ class AlarmsVMNode extends AbstractDMVMNode public void buildDelta(Object e, VMDelta parentDelta, int nodeOffset, RequestMonitor requestMonitor) { // The alarm element is added when and selected upon a triggered event. // Parent element is also expanded allow the alarm to be selected. - if (e instanceof AlarmService.AlarmTriggeredEvent) { + if (e instanceof AlarmService.AlarmTriggeredDMEvent) { parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.EXPAND); parentDelta.addNode( - createVMContext( ((AlarmService.AlarmTriggeredEvent)e).getDMContext() ), + createVMContext( ((AlarmService.AlarmTriggeredDMEvent)e).getDMContext() ), 0, IModelDelta.ADDED | IModelDelta.SELECT); } diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimerService.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimerService.java index 1ab01d63d93..ab2ab106d4c 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimerService.java +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimerService.java @@ -100,7 +100,7 @@ public class TimerService extends AbstractDsfService @Override protected BundleContext getBundleContext() { - return DsfExamplesPlugin.getBundleContext(); + return DsfExamplesPlugin.getDefault().getBundle().getBundleContext(); } @Override From ec063f4c8b9f143a6c2e4d14edb3b1b909e237f3 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 13 Mar 2008 20:46:24 +0000 Subject: [PATCH 304/834] [220446] Updated the tutorials. --- .../docs/{common => intro}/data_model_1.dia | Bin .../docs/{common => intro}/data_model_1.png | Bin .../docs/{common => intro}/data_model_2.dia | Bin .../docs/{common => intro}/data_model_2.png | Bin .../dsf_programming_intro.html} | 206 +++++--- .../docs/{common => intro}/query_1.dia | Bin .../docs/{common => intro}/query_1.png | Bin .../{common => intro}/request_monitor_1.dia | Bin .../{common => intro}/request_monitor_1.png | Bin .../{common => intro}/synchronization_1.dia | Bin .../{common => intro}/synchronization_1.png | Bin .../{common => intro}/synchronization_2.dia | Bin .../{common => intro}/synchronization_2.png | Bin .../docs/{common => intro}/timers_1.png | Bin ...l_outline.html => dsf_debugger_howto.html} | 479 +++++++++++------- 15 files changed, 432 insertions(+), 253 deletions(-) rename plugins/org.eclipse.dd.doc.dsf/docs/{common => intro}/data_model_1.dia (100%) rename plugins/org.eclipse.dd.doc.dsf/docs/{common => intro}/data_model_1.png (100%) rename plugins/org.eclipse.dd.doc.dsf/docs/{common => intro}/data_model_2.dia (100%) rename plugins/org.eclipse.dd.doc.dsf/docs/{common => intro}/data_model_2.png (100%) rename plugins/org.eclipse.dd.doc.dsf/docs/{common/dsf_common_patterns.html => intro/dsf_programming_intro.html} (94%) rename plugins/org.eclipse.dd.doc.dsf/docs/{common => intro}/query_1.dia (100%) rename plugins/org.eclipse.dd.doc.dsf/docs/{common => intro}/query_1.png (100%) rename plugins/org.eclipse.dd.doc.dsf/docs/{common => intro}/request_monitor_1.dia (100%) rename plugins/org.eclipse.dd.doc.dsf/docs/{common => intro}/request_monitor_1.png (100%) rename plugins/org.eclipse.dd.doc.dsf/docs/{common => intro}/synchronization_1.dia (100%) rename plugins/org.eclipse.dd.doc.dsf/docs/{common => intro}/synchronization_1.png (100%) rename plugins/org.eclipse.dd.doc.dsf/docs/{common => intro}/synchronization_2.dia (100%) rename plugins/org.eclipse.dd.doc.dsf/docs/{common => intro}/synchronization_2.png (100%) rename plugins/org.eclipse.dd.doc.dsf/docs/{common => intro}/timers_1.png (100%) rename plugins/org.eclipse.dd.doc.dsf/docs/pda/{pda_tutorial_outline.html => dsf_debugger_howto.html} (91%) diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/common/data_model_1.dia b/plugins/org.eclipse.dd.doc.dsf/docs/intro/data_model_1.dia similarity index 100% rename from plugins/org.eclipse.dd.doc.dsf/docs/common/data_model_1.dia rename to plugins/org.eclipse.dd.doc.dsf/docs/intro/data_model_1.dia diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/common/data_model_1.png b/plugins/org.eclipse.dd.doc.dsf/docs/intro/data_model_1.png similarity index 100% rename from plugins/org.eclipse.dd.doc.dsf/docs/common/data_model_1.png rename to plugins/org.eclipse.dd.doc.dsf/docs/intro/data_model_1.png diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/common/data_model_2.dia b/plugins/org.eclipse.dd.doc.dsf/docs/intro/data_model_2.dia similarity index 100% rename from plugins/org.eclipse.dd.doc.dsf/docs/common/data_model_2.dia rename to plugins/org.eclipse.dd.doc.dsf/docs/intro/data_model_2.dia diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/common/data_model_2.png b/plugins/org.eclipse.dd.doc.dsf/docs/intro/data_model_2.png similarity index 100% rename from plugins/org.eclipse.dd.doc.dsf/docs/common/data_model_2.png rename to plugins/org.eclipse.dd.doc.dsf/docs/intro/data_model_2.png diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/common/dsf_common_patterns.html b/plugins/org.eclipse.dd.doc.dsf/docs/intro/dsf_programming_intro.html similarity index 94% rename from plugins/org.eclipse.dd.doc.dsf/docs/common/dsf_common_patterns.html rename to plugins/org.eclipse.dd.doc.dsf/docs/intro/dsf_programming_intro.html index 96a68ec621e..f7344d741ea 100644 --- a/plugins/org.eclipse.dd.doc.dsf/docs/common/dsf_common_patterns.html +++ b/plugins/org.eclipse.dd.doc.dsf/docs/intro/dsf_programming_intro.html @@ -1,16 +1,21 @@ - DSF Common Patterns + Introduction to Programming with DSF -

      DSF Common Patterns
      -

      -
    • +
    • 9 Next Steps
    • -

      1 Introduction

      -This document contains a tutorial for the basic features of the -Debugger Services Framework (DSF), created by the DSDP Device Debugging -project.
      -

      2 Examples
      -

      -Running example code is and performing included exercises is very +

      Copyright

      +Copyright (c) 2008 Wind River Systems and others. All rights +reserved. This program and the accompanying materials are made +available under the terms of the Eclipse Public License v1.0 which +accompanies this distribution, and is available at +http://www.eclipse.org/legal/epl-v10.html
      +
      +Contributors:
      +
        +
      • Wind River Systems - initial content
        +
      • +
      +
      +

      1 Examples
      +

      +Running example code and performing included exercises is very helpful in following this tutorial.  In order to run the examples in this tutorial the following is needed:
        -
      1. Download and install Eclipse development environment, either the Eclipse Classic 3.4 or Eclipse IDE for C/C++ Developers
        +
      2. Download and install the Eclipse SDK 3.4 (http://download.eclipse.org/eclipse/downloads)
      3. +
      4. nstall the Eclipse IDE for C/C++ 5.0:
      5. +
          +
        1. Using Update Manager, install the C and C++ Development SDK, found in +the Ganymede +Discovery Site.
        2. +
      6. Install the DSF SDK feature to build against, by performing either:
      7. @@ -87,7 +108,7 @@ Discovery Site under Remote Access and Device Development.
      8. Check out org.eclipse.dd.dsf and org.eclipse.dd.dsf.ui plugins, found in the /cvsroot/dsdp repository under /cvsroot/dsdp repository in the org.eclipse.dd.dsf/plugins directory.
      @@ -118,7 +139,7 @@ requires an Eclipse Application to be launched (see the -

      3 Asynchronous Methods

      +

      2 Asynchronous Methods

      One of the central features of DSF is that it relies very heavily on the use of asynchronous methods.  Asynchronous methods here mean @@ -129,7 +150,7 @@ is composed of asynchronous methods, a higher level system which uses those methods also has to have asynchronous methods in its interface (or risk blocking its calling thread).
      -

      3.1 Request Monitor

      +

      2.1 Request Monitor

      There is a standard callback object used in DSF, the request monitor.  A request monitor has the following features:
        @@ -146,15 +167,18 @@ invoked when the callback is invoked: handleCompleted(), handleOK(), handleError(), etc.  The users may override these methods as needed to perform additional processing upon asynchronous method completion. -
      • Parent Request Monitor +
      • Parent Request +Monitor - If the method calling an asynchronous method is itself asynchronous, it may set its argument request monitor as the parent of the request -monitor it is creating.  The parent request monitor will be
        +monitor it is creating.  The parent request monitor will be automatically invoked when the lower level request monitor is completed.
      Following is the snippet from a the "hello world" example of using a request monitor:
      +
      @@ -241,8 +265,8 @@ module.


      -

      3.2 Data Request -Monitor

      +

      2.2 Data Request +Monitor

      The base request monitor is useful for returning status of the asynchronous method, but they do not have an option of returning a @@ -292,8 +316,8 @@ methods. the calculation to the console.
      -

      3. 4 Multi-Request -Monitor

      +

      2.3 Multi-Request +Monitor

      A common problem when using asynchronous is that several asynchronous methods need to be called in parallel, so the calling method needs to somehow manage the completion of several request monitors.  @@ -336,21 +360,39 @@ example of using the CountingRequestMonitor:
        -
      • Line 50 creates the CountingRequestMonitor.  Note that the -parent request monitor is set to the request monitor from the +
      • Line 51 creates the CountingRequestMonitor.  Its parent +request monitor is set to the request monitor from the asyncQuicksort() argument.  This parent request monitor is -automatically called when the counting request monitor is completed.
      • -
      • Lines 51 and 52, use the same instance of counting request +automatically called when the counting request monitor is completed. +(see note)
        +
      • +
      • Lines 52 and 53, use the same instance of counting request monitor when calling the sub-routine.  Each sub-routine will call done() on the counting request monitor.
      • -
      • Line 53 sets the count to the number of sub-routines called with +
      • Line 54 sets the count to the number of sub-routines called with the counting request monitor.  Note that the done count can be set after calling the sub-routines, because the counting request monitor will not be completed until the count is set.
      • -
      • Line 55 Don't forget to complete the request monitor in all +
      • Line 55: Don't forget to complete the request monitor in all execution paths!
      + + + + + + +
      Note: The use of a parent request +monitor can simplify the code when implementing nested asynchronous +methods, since the parent requrest monitor is automatically completed +when the child requrest monitor is completed.  Unfortunately, +failing to specify a parent request monitor when it is expected can +sometimes lead to bugs.
      +
      +
      @@ -360,7 +402,7 @@ execution paths! style="text-align: left; background-color: rgb(255, 204, 204);">Exercise 2: Converting a synchronous method into an asynchronous one is another common task in -DSF.  This excercise converts the AsyncQuicksort.partition() +DSF.  This exercise converts the AsyncQuicksort.partition() method into asynchronous AsyncQuicksort.asyncPartition(). 

      Look for comments preceeded with "// TODO Exercise 2" in the @@ -370,7 +412,7 @@ module.

      -

      4 Concurrency

      +

      3 Concurrency

      The simple examples in previous section used asynchronous method signatures, however no real asynchronous work was performed since all execution was performed in the main thread.  This section examines @@ -422,7 +464,7 @@ synchronous IStructuredContentProvider interface.
    • AsyncDataViewer - Table-based viewer which implements an asynchronous ILazyContentProvider interface.
    • -

      4.1 Query

      +

      3.1 Query

      DSF is designed to facilitate use of asynchronous APIs.  However, sometimes there are situations where a synchronous method has to be implemented to call an asynchronous method.  One utility used to @@ -519,7 +561,7 @@ for completion of the asynchronous methods called by execute().

      -

      4.2 Synchronization

      +

      3.2 Synchronization

      Managing race conditions and deadlocks is one of the most challanging problems of large multi-threaded systems.  DSF uses a single-threaded executor as the primary mechanism for safe-guarding @@ -602,7 +644,7 @@ DSF executor thread.

      -Comparing other parts of the two data generator implementation shows +Comparing other parts of the two data generator implementations shows that using the synchronization mechanism above is the principal difference between the two implementations.  One notable exception is the principal processing loop in each data generator.  In the @@ -659,7 +701,7 @@ of the generator's thread:
      • Line 141 creates the loop that runs continuously until the break statement on line 159.
      • -
      • Line 149 implements the artcificial processing delay that is +
      • Line 149 implements the artificial processing delay that is executed for each request.

      In contrast the executor-based generator uses a dedicated method for @@ -720,7 +762,7 @@ that the queue servicing runnable is not scheduled too often.

    • Line 212 calls the ExecutorService.schedule() method to run the queue servicing runnable, with a delay that simulates the request processing time.
    • -
    • Line 224, after servicing runnableis finished, calls +
    • Line 224, after servicing runnable is finished, calls serviceQueue() again to process the next item in the queue.
    • the single-threaded executor concurrency model is that as long as a method is guaranteed to run in the executor thread, this method may access and modify any of the variables protected by this -executor.  This excercise demonstrates performing a somewhat more +executor.  This exercise demonstrates performing a somewhat more complicated operation on protected state data.

      Look for comments preceeded with "// TODO Exercise 3" in the @@ -761,7 +803,7 @@ module.

      -

      4.3 Annotations

      +

      3.3 Annotations

      In any multi-threaded system it can become very difficult to determine what are the rules governing access to the various data objects.  In a DSF system, it is even more important to identify which data @@ -778,7 +820,7 @@ org.eclipse.dd.dsf.concurrent
    • ThreadSafe - Indicates that the given element can be accessed on any thread.  Typically, if this annotation is used, the given member or class uses -syncrhonized or atomic objects to protect its data.
    • +synchronized or atomic objects to protect its data.
    • Immutable - Immutable objects cannot be modified after they are created, thus they are also thread-safe.  The easiest way to make an object @@ -822,7 +864,7 @@ add them.

      Exercise 4: -This excercise adds the appropriate synchronization annotations to the +This exercise adds the appropriate synchronization annotations to the methods and fields of DataProviderWithExecutor.

      Look @@ -843,7 +885,7 @@ module.

      Exercise 5: It is all too -easy to get into a deadlock situation.  This excercise +easy to get into a deadlock situation.  This exercise purposefully puts the data viewer system into a deadlock.  The deadlock first renders the data viewer unusable, but the main thread also gets deadlocked when attempting to exit the program.
      @@ -855,8 +897,8 @@ module.

      -

      5 Timers Example

      +

      4 Timers Example

      The Timers example, found in the org.eclipse.dd.examples.dsf.timers @@ -886,7 +928,7 @@ Returns the array of contexts for existing timers.
    • getTimerValue() method - Returns the current value for the given timer context.
    • -
    • TimerTickEvent event +
    • TimerTickDMEvent event class - An event that is generated for every timer, every time its value changes (once per second).  The event contains the timer's context.
      @@ -965,8 +1007,8 @@ editor - changes the value of the selected trigger.
    • -

      6 Services

      -

      6.1 OSGi

      +

      5 Services

      +

      5.1 OSGi

      DSF builds on top of OSGi services APIs.   OSGi offers a rich API for managing services and it is important to understand some of the OSGi service API basics in order to use DSF
      @@ -1018,10 +1060,10 @@ down the debugger.

      -

      6.2 Session

      +

      5.2 Session

      DSF-based debugger integrations can register many services and there can be multiple instances of debuggers registering services with the -same interfaces.  To help coordinate services in a give debugger +same interfaces.  To help coordinate services in a given debugger instance and distinguish the services between the instances of debuggers, DSF services are organized into sessions.

      DSF Session features include:
      @@ -1049,7 +1091,7 @@ type.  More information about Data Model is described in the Data Model section.
      -

      6.3 Executor

      +

      5.3 Executor

      All the services registered with the same session share a single DSF Executor.  By convention, all public service interfaces should be restricted to being called in this executor thread.  This point @@ -1068,7 +1110,7 @@ should be called using the session's DSF executor.
      -

      6.4 Tracker

      +

      5.4 Tracker

      Using the OSGi APIs for accessing services directly can be very cumbersome.  A client retrieving a service reference is responsible for retaining the ServiceReference object and for calling @@ -1167,8 +1209,8 @@ service reference leak.
      -

      6.5 Initialization / -Shutdown

      +

      5.5 Initialization / +Shutdown

      Every DSF service must implement the IDsfService.initialize() and IDsfService.shutdown() methods.  These methods can only be called in the session executor @@ -1195,7 +1237,7 @@ Timers example:
      org.eclipse.dd.examples.dsf.timers.ServicesStartupSequence
      + style="font-family: monospace; font-weight: bold;">org.eclipse.dd.examples.dsf.timers.ServicesShutdownSequence

      @@ -1329,7 +1371,7 @@ custom request monitor to be invoked at the completion of the sequence.

      -

      6.6 Events

      +

      5.6 Events

      DSF provides a somewhat unusual event mechanism, where event listeners do not implement any particular listener interface.  Instead, event listeners use the DsfServiceEventHandler @@ -1385,16 +1427,16 @@ listeners are called after the services.
      -

      7 Data Model

      +

      6 Data Model

      The term Data Model refers to the natural structure of data that is being retrieved by the DSF services.  One of the great challenges of creating an user -interface for a debugger is that the amount of of data that is +interface for a debugger is that the amount of data that is available on the target is much greater than what can be practically presented to the user.  Therefore the debugger services need to break up the data into chunks with appropriate granularity to achieve maximum performance and usability.
      -

      7.1 IDMContext

      +

      6.1 IDMContext

      The IDMContext represents a handle to a chunk of data in the Data Model.  This interface is a minimal, yet central feature of the Data Model API.
      @@ -1453,7 +1495,7 @@ use is optional.
      -

      7.2 Context Hierarchy

      +

      6.2 Context Hierarchy

      One of the most powerful features of the IDMContext interface is that is is hierarchical.  The IDMContext.getParents() method returns the immediate ancestors of a given context and following @@ -1535,7 +1577,7 @@ between service interfaces.
      -

      7.3 DMContexts

      +

      6.3 DMContexts

      Searching the context hierarchy can be tedious to implement, the DMContexts utility class contains a few static methods to simplify this task:
      @@ -1550,14 +1592,14 @@ the other. Converts all the contexts in a hierarchy of the give context into a list. -

      8 View Model

      +

      7 View Model

      View Model refers to the ideal user-presentable structure of the data.  This is in contrast to the Data Model, which refers to the natural data structure, although the two often end up being the same.  Never the less, the needs of the user presentation often change so the central feature of the View Model is the ability to customize it.
      -

      8.1 Flexible Hierarchy

      +

      7.1 Flexible Hierarchy

      View Model builds on the flexible hierarchy API introduced by Debug Platform team in release 3.2.  The flexible hierarchy API has a @@ -1589,8 +1631,8 @@ related to packaging.
      -

      8.2 Adapter Problem
      -

      +

      7.2 Adapter Problem
      +

      The number two feature of flexible hierarchy API is implemented using the adapter pattern.  One down-side of the adapter pattern is that there can only be one instance of an adapter of a particular type @@ -1638,7 +1680,7 @@ element, for use with different views.
      -

      8.4 API

      +

      7.3 API

      The View Model uses four principal types of elements when processing adapter requests from flexible hierarchy viewers.  These are:
        @@ -1663,7 +1705,7 @@ element that is being wrapped, as well as to the VM Node and VM Adapter that it originated from.
      -

      8.5 Content Provider

      +

      7.4 Content Provider

      The most important job of the View Model is to supply the content, in form of element wrappers, to the viewers.  The flexible hierarchy interface for this provider is listed below:
      @@ -1844,7 +1886,7 @@ array, and sets those VM Contexts to the update.
    • Line 94 completes the update.
    • -

      8.6 Model Event Proxy

      +

      7.5 Model Event Proxy

      Another important job of the View Model is to translate the events that originate from the Data Model into generic events (deltas) that the viewer can @@ -1875,9 +1917,11 @@ factory is implemented using abstract base classes in the org.eclipse.dd.dsf.ui.viewmodel package.  Instead, a typical DSF application only has to implement two interfaces in order to support event proxying:
      -

      Event handling in VM -Provider
      -
      The following listing from the Timers example shows the handling +

      Event handling in VM +Provider

      +

      +

      The following +listing from the Timers example shows the handling of a model event:

      @@ -1920,7 +1964,7 @@ their own single-threaded executor which is used to protect its state. method which continues the event processing.
      -Processing events in VM Nodes
      +

      Processing events in VM Nodes

      The following listing shows how the nodes translate the events into model delta components:

      @@ -1981,9 +2025,9 @@ They add a flag to the parent delta element, instructing it to refresh all the elements managed by this node.
      -

      8.7 Property Provider +

      7.6 Property Provider / Label Provider
      -

      + The IElementPropertyProvider interface is not actually part of the Flexible Hierarchy API, but an extension interface added by DSF.  View Model implementers can use @@ -2093,8 +2137,12 @@ expected VM Context class.  Then extracting the model object from the VM Context wrapper.
    • Line 127 retrieves element data from the service.
    • Lines 136-137 write the element properties into the property -update.
      -
    • +update. +

      8 Next Steps

      +The DSF framework is (as its name implies) designed for integrating a +debugger into Eclipse.  The follow up tutorial is How to write a DSF-based debugger +and it walks through the steps of implementing a debugger integration.
      diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/common/query_1.dia b/plugins/org.eclipse.dd.doc.dsf/docs/intro/query_1.dia similarity index 100% rename from plugins/org.eclipse.dd.doc.dsf/docs/common/query_1.dia rename to plugins/org.eclipse.dd.doc.dsf/docs/intro/query_1.dia diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/common/query_1.png b/plugins/org.eclipse.dd.doc.dsf/docs/intro/query_1.png similarity index 100% rename from plugins/org.eclipse.dd.doc.dsf/docs/common/query_1.png rename to plugins/org.eclipse.dd.doc.dsf/docs/intro/query_1.png diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/common/request_monitor_1.dia b/plugins/org.eclipse.dd.doc.dsf/docs/intro/request_monitor_1.dia similarity index 100% rename from plugins/org.eclipse.dd.doc.dsf/docs/common/request_monitor_1.dia rename to plugins/org.eclipse.dd.doc.dsf/docs/intro/request_monitor_1.dia diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/common/request_monitor_1.png b/plugins/org.eclipse.dd.doc.dsf/docs/intro/request_monitor_1.png similarity index 100% rename from plugins/org.eclipse.dd.doc.dsf/docs/common/request_monitor_1.png rename to plugins/org.eclipse.dd.doc.dsf/docs/intro/request_monitor_1.png diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/common/synchronization_1.dia b/plugins/org.eclipse.dd.doc.dsf/docs/intro/synchronization_1.dia similarity index 100% rename from plugins/org.eclipse.dd.doc.dsf/docs/common/synchronization_1.dia rename to plugins/org.eclipse.dd.doc.dsf/docs/intro/synchronization_1.dia diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/common/synchronization_1.png b/plugins/org.eclipse.dd.doc.dsf/docs/intro/synchronization_1.png similarity index 100% rename from plugins/org.eclipse.dd.doc.dsf/docs/common/synchronization_1.png rename to plugins/org.eclipse.dd.doc.dsf/docs/intro/synchronization_1.png diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/common/synchronization_2.dia b/plugins/org.eclipse.dd.doc.dsf/docs/intro/synchronization_2.dia similarity index 100% rename from plugins/org.eclipse.dd.doc.dsf/docs/common/synchronization_2.dia rename to plugins/org.eclipse.dd.doc.dsf/docs/intro/synchronization_2.dia diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/common/synchronization_2.png b/plugins/org.eclipse.dd.doc.dsf/docs/intro/synchronization_2.png similarity index 100% rename from plugins/org.eclipse.dd.doc.dsf/docs/common/synchronization_2.png rename to plugins/org.eclipse.dd.doc.dsf/docs/intro/synchronization_2.png diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/common/timers_1.png b/plugins/org.eclipse.dd.doc.dsf/docs/intro/timers_1.png similarity index 100% rename from plugins/org.eclipse.dd.doc.dsf/docs/common/timers_1.png rename to plugins/org.eclipse.dd.doc.dsf/docs/intro/timers_1.png diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/pda/pda_tutorial_outline.html b/plugins/org.eclipse.dd.doc.dsf/docs/pda/dsf_debugger_howto.html similarity index 91% rename from plugins/org.eclipse.dd.doc.dsf/docs/pda/pda_tutorial_outline.html rename to plugins/org.eclipse.dd.doc.dsf/docs/pda/dsf_debugger_howto.html index 18f154334d6..a8597f2ee79 100644 --- a/plugins/org.eclipse.dd.doc.dsf/docs/pda/pda_tutorial_outline.html +++ b/plugins/org.eclipse.dd.doc.dsf/docs/pda/dsf_debugger_howto.html @@ -6,96 +6,114 @@

      How to write a DSF-based debugger

      -

      Summary

      +

      Summary

      This tutorial describes the process of integrating a debugger with Eclipse using the Debugger Services Framework (DSF) developed by the DSDP Device Debugging project.
      -

      Table of Contents
      -

      +

      Table of Contents

      +

      Copyright

      +Copyright (c) 2005, 2008 IBM Corporation and others. All rights +reserved. This program and the accompanying materials are made +available under the terms of the Eclipse Public License v1.0 which +accompanies this distribution, and is available at +http://www.eclipse.org/legal/epl-v10.html
      +
      +Contributors:
      +
        +
      • IBM Corporation - initial content
      • +
      • Wind River Systems - adapted article to use with DSF
        +
      • +

      -

      i. Push Down Automata (PDA)
      +

      1 Push Down Automata +(PDA)

      The Push Down Automata (PDA) debugger example is used as the basis for this tutorial.  Before starting the tutorial it is best to familiarize with the features of the debugger.
      -

      Running the Example

      +

      1.1 Running the +Example

      Launch the PDA debugger with these twelve "easy" steps:
      1. Download and install Eclipse development environment, either the http://www.indigostar.com/ -

        Language

        +

        1.2 Language

        To demonstrate how to write a debugger for Eclipse, we need a language and a run time to debug. For this example, we chose an enhanced push down automata (PDA) assembly language and a simple @@ -242,11 +260,12 @@ line):

      -

      Debug Protocol

      +

      1.3 Debug Protocol

      Our PDA assembly language interpreter can be started in either run mode or debug mode. When started in debug mode, the interpreter listens -for debug commands on a specified local TCP socket and sends debug -events to a separate local TCP socket.  A detailed description of +for debug commands on a specified local TCP/IP socket and sends debug +events to a separate local TCP/IP socket.  A detailed description +of the protocol can be found in org.eclipse.dd.examples.pda/pdavm/docs/protocol.html, but the lists below show a quick overview.

      @@ -287,7 +306,7 @@ instruction was encountered
    • no such label X – a branch or call to an unknown label was encountered
    • -

      Step 1 - Launching
      +

      2 Step 1 - Launching

      The first task in integrating a debugger in Eclipse is creating and managing the debugger process.  The Eclipse Platform provides an @@ -296,7 +315,7 @@ extensive API for this purpose, which is nicely presented in the article.  This section (as this tutorial) concentrates on the DSF-specific tasks of launching the PDA debugger.
      -

      Launch Delegate

      +

      2.1 Launch Delegate

      At first glance, there's nothing unusual about the PDA debugger launch delegate.  Just like the Debug Platform version it:
        @@ -329,7 +348,7 @@ extension interface, in order to create a custom launch object:
        color="#4169e1"> public ILaunch getLaunch(ILaunchConfiguration configuration, String mode)
        throws CoreException {

        52: // Need to configure the source locator before creating the launch
        53: // because once the launch is created and added to launch manager,
        53: // because once the launch is created and added to launch manager,
        54: // the adapters will be created for the whole session, including
        55: // the source lookup adapter.
        56: ISourceLocator locator = getSourceLocator(configuration);

        -

        PDALaunch

        +

        2.2 PDALaunch

        The PDALaunch object plays two main roles:
        1. Serve as the root element of the PDA View Model hierarchy
        2. @@ -469,9 +488,11 @@ with this race condition.
            -
          • Line 88 declares the initializeServices() to be invoked only +
          • Line 90 declares the initializeServices() +to be invoked only within the session executor thread.  This is to protect access to -the fInitializationSequence variable and to allow the call on line 107 +the fInitializationSequence +variable and to allow the call on line 112 to be made without use of another runnable.
          Due to race conditions between debugger events and user commands, the +

          + +
          202:     @ConfinedToDsfExecutor("getSession().getExecutor()")
          203: public void shutdownServices(final RequestMonitor rm) {
          name="line244">244: rm.setStatus(getStatus());
          245: rm.done();
          246: }
          247: }) );
          248: }

          - -
          + name="line248">248: }
          -

          Launch/Shutdown +

          2.3 Launch/Shutdown Sequence

          The actual task of calling the asynchronous IDsfService's -

          Step 2 - +

          3 Step 2 - Connecting 

          With the launch framework in place, the debugger back end is running and the DSF session and executor are started.  The next step is to @@ -632,7 +655,8 @@ target state change events.
          -

          Synchronization

          +

          3.1 Synchronization

          Since there are several threads being used by the PDA Command Control protecting state data becomes very important.

          @@ -651,6 +675,9 @@ executing in the session executor's thread:
          +

          + +
           56:     // Parameters that the command control is created with.
          57: final private String fProgram;
          58: final private int fRequestPort;
          name="line94"> 94: @ThreadSafe
          95: private BufferedReader fEventReader;

          97: // Jobs servicing the sockets.
          98: private EventDispatchJob fEventDispatchJob;
          99: private CommandSendJob fCommandSendJob;
          - -
          + name="line99"> 99: private CommandSendJob fCommandSendJob; @@ -773,7 +798,8 @@ thread. -

          Command/Event +

          3.2 Command/Event Listeners

          As mentioned before there are two types of listeners that can be registered with the commands control: event @@ -797,8 +823,16 @@ an inconsistent state.
          - queueCommand()
          - -
          337:     public <V extends ICommandResult> void queueCommand(ICommand<V> command, DataRequestMonitor<V> rm) {

          + + + + + + - + + +
          +
          337:     public <V extends ICommandResult> void queueCommand(ICommand<V> command, DataRequestMonitor<V> rm) {
          338: if (command instanceof AbstractPDACommand<?>) {
          339: // Cast from command with "<V extends ICommandResult>" to a more concrete
          340: // type to use internally in the command control.
          color="#4169e1">else {
          363: PDAPlugin.failRequest(rm, INTERNAL_ERROR, "Unrecognized command: " + command);
          364: }
          365: }
          -

          +
          @@ -838,7 +874,8 @@ new command. send commands to the debugger.  The separate runnable is used to allow the command listeners to modify the queue as well. -

          PDAProgramDMContext

          +

          3.3 PDAProgramDMContext

          Finally the command control also declares a Data Model context, which is a parent to all other contexts for a given PDA debugger session.  Each command used with the command control has to @@ -858,12 +895,14 @@ stateless, which means that any command acts independently of any commands that came before it.  For debuggers which do have protocol state, e.g. GDB/MI, the command control needs to check the context of each command and set the protocol by preceding the command -being processed with other commands.
          +being processed with other commands (such as -thread-select in GDB/MI).
        -

        PDA Commands

        -To increase type safely and make the code more readable the plain text +

        3.4 PDA Commands

        +To increase type safety and make the code more readable the plain text PDA commands are abstracted using specific command objects.  Below is an example of a command class:

        @@ -903,10 +942,10 @@ is an example of a command class:
          -
        • Line 23 declares the class, using the Line 24 declares the class, using the PDADataCommandResult class as the type for the result which has to be generated by this command.
        • -
        • Line 31 creates and returns the PDADataCommandResult object, +
        • Line 32 creates and returns the PDADataCommandResult object, which parses the command result string.
        Here is the corresponding data result class:
        @@ -962,22 +1001,22 @@ immutable helps guard the integrity of these caches. -

        -

        Step +

        4 Step 3 - View Model

        -

        Adapter Glue
        -

        +

        4.1 Adapter Glue

        - @@ -1093,6 +1133,9 @@ object.
        + - @@ -1144,7 +1185,9 @@ views for the given PDA debugger instance.
      1. Line 94-95 register the source display adapter (the "MI" prefix is a historical left over).
      2. -
      3. Lines 98-109 register handlers for common debug commands.
      4. +
      5. Lines 98-109 register handlers for common debug commands.  +(See note below)
        +
      6. Lines 112 -116 Register an adapter to provide debug model ID.  It is used by Debug Platform to enable custom keyboard shortcuts for the debugger.
      7. @@ -1153,6 +1196,24 @@ elements.  This enables some actions in debug view which access the launch (such as Edit Source Lookup). +
        The adapter mechanism is something -like the glue of Eclipse APIs, since it allows object to be associated -with each without having any -explicit dependencies.  Just like glue it works best when the +like the glue of Eclipse APIs. It allows objects to be associated +together without having any +explicit dependencies between each other.  Just like glue it works +best when the mating parts are clean and closely fitted together, where just a little glue does the job.  If too much glue is used to put together many @@ -1007,9 +1046,10 @@ the custom PDALaunch object:
        -
           <extension
        point="org.eclipse.core.runtime.adapters">
        <factory
        class="org.eclipse.dd.examples.pda.ui.PDAAdapterFactory"
        adaptableType="org.eclipse.dd.examples.pda.launch.PDALaunch">
        <adapter type="org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider"/>
        <adapter type="org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory"/>
        </factory>
        </extension>
        +


        +
        +
           <extension
        point="org.eclipse.core.runtime.adapters">
        <factory
        class="org.eclipse.dd.examples.pda.ui.PDAAdapterFactory"
        adaptableType="org.eclipse.dd.examples.pda.launch.PDALaunch">
        <adapter type="org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider"/>
        <adapter type="org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory"/>
        </factory>
        </extension>
        +

        +
         85:         LaunchAdapterSet(PDALaunch launch) {
        86: // Initialize launch and session.
        87: fLaunch = launch;
        name="line120">120: // and debug model ID will be associated with all DMContexts from this
        121: // session.
        122: session.registerModelAdapter(ILaunch.class, fLaunch);
        123: }
        -

        + name="line123">123: }
        + + + + + +
        Note: Most of the common debug +actions, such as the resume/suspend/step commands in Debug view, have +been converted into re-targetable commands.  This means that the +given action uses the adapter mechanism to retrieve the command handler +from the selected element.  For a DSF-based debugger integration +these command handlers must be explicitly created and registered with +the session so that they are returned by the Data Model +IDMContext.getAdapter() implementation.
        +
        +
        Each adapter set is created new for each PDA debug session.  They also need to be disposed when they are no longer needed.  It could be expected that the adapters should be disposed when the PDA debugger @@ -1192,8 +1253,10 @@ PDA launch is removed:
        -

        PDA View Model

        -The PDAVMAdapter creates the VM Providers on demand for each debugger +

        4.2 PDA View Model

        +The PDAVMAdapter creates the +VM Providers on demand for each debugger view it supports:

        @@ -1233,10 +1296,36 @@ provider is created custom for the PDA debugger. style="font-style: italic;">Expressions views respectively.  These providers are implemented in the org.eclipse.dd.dsf.debug.ui plugin -and are reused here without modification.
        - +and are reused here without modification. -

        Launch VM Provider

        + + + + + + +
        Note: The VM Adapter is responsible +for creating providers for all debugger views supported by the given +debugger.  In case of PDA, the registers and modules views are not +supported, therefore the corresponding VM Providers are not created.
        +
        + + + + + + +
        Note: The Memory view is not a +Flexible Hierarchy view and so is not supported by the View +Model.  For an example of integrating a memory view, see the +DSF-based GDB debugger integration.
        +
        +

        4.3 Launch VM Provider

        "Launch" actually refers to the internal name of the Debug view.  The PDA debugger has a somewhat simpler presentation in Debug view than most debuggers because it does not support multiple threads so it has @@ -1258,7 +1347,8 @@ the thread node shown directly below the launch node.
        -The PDALaunchVMProvider constructor creates the VM Nodes and arranges +The PDALaunchVMProvider +constructor creates the VM Nodes and arranges them in a hierarchy that mirrors the screen-shot in Image 2.

        @@ -1316,15 +1406,16 @@ debug model events.  These events are used by the StandardProcessVMNode to update the processes' state.
        -
      8. Line 69 add the Launch VM Provider as a listener to the launch +
      9. Line 69 adds the Launch VM Provider as a listener to the launch events.  These events are used by the LaunchVMRootNode to update the state and content of the launch if it has been changed or terminated.
      10. -

        PDA Program VM Node

        +

        4.4 PDA Program VM Node

        -

        Elements

        +

        Elements

        The PDA Program Node is the most complex component of the PDA View Model.  It supplies an element representing the PDA program and it operates in three modes:
        @@ -1349,7 +1440,7 @@ wrapper element is used which does not have an underlying Data Model element.

      The following two methods implement the logic of supplying the elements -of the above modes:
      +for the above modes:

      + - @@ -1416,7 +1508,7 @@ However if the session is in the process of shutting down, this call may be caught in a race condition, therefore a check if service is available is necessary. -

      Label

      +

      Label

      Calculating the label for the PDA program element is also split into two parts depending on whether the program is terminated.  Similarly as when calculating the element, if the program is @@ -1514,7 +1606,7 @@ representative of what all label providers must do.
      name="line194">194: } else {
      195: imageKey = IDebugUIConstants.IMG_OBJS_THREAD_RUNNING;
      196: }
      197: update.setImageDescriptor(DebugUITools.getImageDescriptor(imageKey), 0);

      199: // Retrieve the last state chagne reason
      199: // Retrieve the last state change reason
      200: runControl.getExecutionData(
      201: programCtx,
      202: new DataRequestMonitor<IExecutionDMData>(ImmediateExecutor.getInstance(), null)
      203: {
      204: @Override
    • Line 174 declares the routine as to be called only on the session thread.  Accessing services on a different thread is a violation of their API contract.
    • -
    • Lines 177-184 retrieve the IRunControl +
    • Lines 177-181 retrieve the IRunControl service, always checking that the service is actually available.
    • Lines 184,185 retrieve the PDAProgramDMContext from the update.  This context can actually be expected to be in the 0 as the column index.
    • -

      Delta

      +

      Delta

      Translating the Data Model events into IModelDelta objects that can be processed by the Flexible Hierarchy views, is the most complicated task @@ -1613,6 +1705,9 @@ Model events is already implemented in the + - @@ -1639,7 +1732,7 @@ Model events is already implemented in the
      • Line 84 calls the base class handleEvent() -method which does the hard work care of calling the VM Nodes to build +method which does the hard work of calling the VM Nodes to build and send the delta to the views.
      The PDA program node implements methods to add the delta nodes for its @@ -1651,7 +1744,7 @@ elements:
      @@ -1687,10 +1780,12 @@ elements:
      +

      +
      119:     @Override
      120: public void update(IChildrenUpdate[] updates) {
      121: for (IChildrenUpdate update : updates) {
      name="line145">145: return;
      146: }
      147:
      148: update.setChild(createVMContext(commandControl.getProgramDMContext()), 0);
      149: update.done();
      150: }
      -

      + name="line149">149: update.done();
      150: }
      +

      +
       73:     public void handleDebugEvents(final DebugEvent[] events) {
      74: if (isDisposed()) return;
      75:
      87: } catch (RejectedExecutionException e) {
      88: // Ignore. This exception could be thrown if the view model is being
      89: // shut down.
      90: }
      91: }
      -

      + name="line90"> 90: }
      91: }
      org.eclipse.dd.examples.pda.ui.viewmodel.launch.PDALaunchVMNode + style="font-family: monospace; font-weight: bold;">org.eclipse.dd.examples.pda.ui.viewmodel.launch.PDAProgramVMNode - buildDelta()
        -
      • Lines 265-273 implement the synchronous -IVMNode.getDeltaFlags().  This method only needs to return what +
      • Lines 265-273 implement the synchronous IVMNode.getDeltaFlags().  +This method only needs to return what flags this node may create -for the given event and it is used optimize the logic of building the +for the given event and it is used to optimize the logic of building +the model deltas.
      • Line 270 tells the View Model logic that this node may add the IModelDelta.EXPAND and IModelDelta.SELECT flags.  These flags are @@ -1726,24 +1821,27 @@ Nodes in a given view. -

        Step 4 - Run Control

        +

        5 Step 4 - Run Control

        Up to this point most of the work in creating the new PDA debugger has gone into infrastructure.  Now it is time to start adding functionality to do some actual debugging.  The work needed to get run control functionality implemented is all encapsulated in the PDARunControl service.
        -

        State Tracking
        -

        -The primary function of the run control system is to track the current +

        5.1 State Tracking

        +The primary function of the +run control system is to track the current execution state of the program and to issue the corresponding events to the run control service clients.  Both of these tasks are -accomplished by the ICommandControl's IEventListner.eventReceived() +accomplished by the ICommandControl's IEventListner.eventReceived() implementation in combination with service event handlers for -IRunControl.IResumedDMEvent and IRunControl.ISuspendedDMEvent.  It +IRunControl.IResumedDMEvent +and IRunControl.ISuspendedDMEvent.  +It may seem odd that the run control service is listening to its own events in order to change its internal state, but doing so guarantees that the execution state reported by the service is consistent with the -events it sends out.
        +events it sends out.

      • Lines 211-219 update the state flags based on the stopped event.
      • +
        + + + + + +
        Note: Much of the sublety in the +above logic has to do with preventing race conditions.  Although, +while executing in the session executor thread, the state of the system +is guaranteed to remain unchanged by other agents, any time a runnable +is submitted to the session executor, by the time that runnable is +executed, the state of the system may completely change. 
        +
        +In the above example, a runnable is submitted to the session executor +when the DsfSession.dispatchEvent() is called on line 193.  +Between the time that the eventReceived() method is completed, and the +eventDispatched() methods are called, many clients may query the state +of the service.  By delaying the changing of the state until when +in the eventDispatch() handlers, the clients are guaranteed to observe +the state of the system be consistent with the events received by these +clients.
        +
        +
        One remarkable aspect of the state tracking logic is the use of the fResumePending flag.  This flag is set to true when a resume or step command is sent to the PDA debugger.  It is then used by the canResume() method to disallow sending another resume command.  This kind of predictive state -logic an improve the efficiency of the IDE commands.
        +logic can improve the efficiency of the IDE commands.

        -

        Commands

        -The command control commands all follow the same patter shown below by +

        5.2 Commands

        +  +All run control commands follow the same pattern shown below, by example of the resume() command:

        @@ -1892,7 +2016,7 @@ example of the resume() command:
        not, the command fails immediately.
      • Line 242 updates the fResumePending state flag.
      • -
      • Lines 244-253 send the resume command to the PDA debugger.
        +
      • Lines 243-253 send the resume command to the PDA debugger.
      • Lines 247-252 adds error handling in case the result command fails.  It restores the service state.
      • @@ -1906,7 +2030,7 @@ request monitor and completes it.
      • Tracking program running state
      -

      IExecutionDMData

      +

      5.3 IExecutionDMData

      There is very little data that the run control service interface returns for a given execution context.  The intention behind this is to @@ -1917,37 +2041,40 @@ extensions.  IExpressionDMData is the only object which is retrieved asynchronously from the run control service, and it only contains the state change reason for the last debugger state change. 
      -

      Step 5 - Breakpoints

      +

      6 Step 5 - Breakpoints

      Managing breakpoints is one of the complicated tasks that need to be implemented by Eclipse debuggers.  The source of this complexity is the fact that Eclipse breakpoints (IDE breakpoints) are managed independently of breakpoints that are installed in the debugger (target-side breakpoints).  The Eclipse debugger integration has to keep these two sets of breakpoints synchronized. 
      -

      IDE Breakpoints

      +

      6.1 IDE Breakpoints

      Eclipse breakpoints are based on markers, which are special tags in the -Eclispe resource system and are associated with files and +Eclipse resource system and are associated with files and folders.  By using markers, breakpoints gain the benefit of the resource system synchronization mechanism and the automatic persistence.  Also some other cool features such as adjusting the breakpoint line number when the source file is edited, are also automatically gained by using markers. 
      -

      An eclipse breakpoint declaration comes in three parts:
      +

      An Eclipse breakpoint declaration comes in three parts:

        -
      1. org.eclipse.core.resources.markers extension - A debugger must +
      2. org.eclipse.core.resources.markers +extension - A debugger must use this extension to declare a marker type for the new breakpoint.  Markers are hierarchical and a breakpoint should have one of the platform breakpoint objects as a super type.
      3. -
      4. org.eclipse.debug.core.breakpoints extension - A breakpoint must +
      5. org.eclipse.debug.core.breakpoints +extension - A breakpoint must be declared using this extension point, which requires a valid marker type.
      6. -
      7. org.eclipse.debug.core.model.IBreakpoint implementation - A +
      8. org.eclipse.debug.core.model.IBreakpoint +implementation - A breakpoint object must implement this interface.
      -Finally, in order to have breakpoints to appear in the Breakpoints +Finally, in order to have breakpoints appear in the Breakpoints view, they need to be registered with the breakpoint manager, which is -represented by the org.eclipse.debug.core.IBreakpointManager +represented by the org.eclipse.debug.core.IBreakpointManager interface.  The breakpoint manager also relays events for notifying of breakpoint changes and for a debugger it is the central object used to find the IDE breakpoints that need to be installed on @@ -1958,7 +2085,7 @@ is described in fine detail the How to write an Eclipse debugger article.

      -

      Target-Side +

      6.2 Target-Side Breakpoints

      DSF defines the IBreakpoints interface for a service which the functions @@ -1972,7 +2099,7 @@ include:
    • listing installed breakpoints
    • retrieving breakpoint detailed data
    • -

      Breakpoint Context
      +

      Breakpoint Context

      It is expected that primary client of this service is going to be another service which reads IDE Breakpoints, however under certain @@ -2034,7 +2161,7 @@ represents a "breakpoint space" must implement an IBreakpointDMContext object instances.
      -

      Inserting a Breakpoint

      +

      Inserting a Breakpoint

      PDA debugger supports two types of breakpoints.  The IBreakpoints.insertBreakpoint() implementation performs the task of what type of breakpoint should be installed and delegates to the proper @@ -2165,11 +2292,11 @@ The doInserBreakpoint() subroutine is listed next:
      -

      Removing a Breakpoint

      +

      Removing a Breakpoint

      The PDABreakpoints.removeBreakpoint() command takes the IBreakpointDMContext as an argument, but otherwise follows the same general logic as the insertBreakpoint() implementation.
      -

      Updating a Breakpoint

      +

      Updating a Breakpoint

      Updating a breakpoint involves modifying some of the attributes of an existing breakpoint.  Not all debuggers may support this functionality and for debuggers that do, not all types of breakpoints @@ -2243,16 +2370,18 @@ watchpoint were modified.
    • Lines 387 -398 re-insert the watchpoint which effectively updates the watchpoint attributes.
    • -

      Listing Breakpoints

      +

      Listing Breakpoints

      The PDA Breakpoints service tracks the inserted breakpoints using the fBreakpoints field.  Returning the list of breakpoints only requires returning the current state of this field.
      -

      Retrieving Breakpoint Detailed Data

      +

      Retrieving Breakpoint +Detailed Data

      The simple PDA debugger does not track detailed breakpoint data, such has hit counts, addresses etc.  So this function simply returns an error.
      -

      Breakpoints Mediator

      +

      6.4 Breakpoints +Mediator

      With the APIs for managing IDE and Target-Side breakpoints clearly defined, there is a need for a component which will keep the two sets of breakpoint objects synchronized.  DSF provides a standard -

      Step 6 - Stack

      -

      Command Cache

      +

      7 Step 6 - Stack

      +

      7.1 Command Cache

      A new feature introduced in this service is the command cache.  The command cache is a surprisingly simple mechanism for caching service data which otherwise would need to be retrieved repeatedly from @@ -2429,7 +2558,7 @@ and send it to the debugger.
      creates an array of FrameDMContext objects and returns it to the client.
      -

      Frame Context

      +

      7.2 Frame Context

      The primary object type managed by the stack service a stack frame.  It is implemented by the FrameDMContext object listed below:
      @@ -2520,7 +2649,7 @@ is based on information parsed from the result of the PDA debugger -

      Step 7 - Source +

      8 Step 7 - Source Display

      Integrating source display is relatively simple task, even though the Eclipse APIs for looking up and displaying source are rather @@ -2557,7 +2686,7 @@ This has actually already been accomplished in Step 3 - View Model, when registering the View Model adapters.

      -

      Step 8 - Variables

      +

      9 Step 8 - Variables

      At this point we almost have a fully functional PDA debugger.  The only thing that is left is to populate the Variables and Expressions views. 
      @@ -2573,7 +2702,7 @@ order to retrieve full type and value information for the given variables.
      -

      Variable Contexts

      +

      9.1 Variable Contexts

      The stack service allows clients to retrieve two types of variables through two methods
        @@ -2687,7 +2816,8 @@ The IStack interface also defines an IVariableDMData interface which returns information about the variable.  However, the only method from this interface used by the Variables view is the getName() method and it is the only method implemented by the PDA debugger integration:
        -

        Expression Contexts

        +

        9.2 Expression +Contexts

        The IExpressions interface uses a somewhat unusual way of managing contexts.  A client can create an IExpressionDMContext @@ -2731,7 +2861,7 @@ PDAExpressions.createExpression() implementation reflects this:

        -

        Expression Data
        +

        9.3 Expression Data

        The IExpressions interface allows for retrieving data in two stages:
          @@ -2742,7 +2872,7 @@ The implementation of the IExpressions.IExpressionDMData interface is required by the Variables views, however for the PDA debugger the IExpressionDMData does not carry any additional information beyond the expression string.
          -

          Formatted Value +

          9.4 Formatted Value Context

          The IExpressions service allows expression values to be retrieved in @@ -2782,7 +2912,7 @@ method is just a formality.

          -Only when the formatted vlaue context is evaluated, the var command is sent to the PDA debugger:

          @@ -2841,7 +2971,7 @@ debugger:
          style="font-style: italic;">formattedCtx argument.  If the expression context is not found, the evaluation is failed.
        1. Line 283 calls the stack service to retrieve the stack -depth.  This step is reqiured because the DPA debugger var command requires a stack frame number which is counted from the bottom.  Where as the stack frame level returned in the IFrameDMCotnext.getLevel() @@ -2852,9 +2982,10 @@ is counted at the top of the stack.
        2. expression and return the result to the client.
      -

      Additional Resources
      +

      10 Additional +Resources

      -

      Debug Platform

      +

      10.1 Debug Platform

      The platform team has evolved and improved the debug APIs over many releases.  Before starting a debugger integration using DSF, it would be very helpful to familiarize yourself with materials in these @@ -2873,14 +3004,14 @@ Platform: The Basics EclipseCon tutorial. Platform: Custom Integration EclipseCon tutorial.
      -

      GDB

      +

      10.2 GDB

      The DSDP Device Debugging project is developing a DSF-based debugger integration with GDB as the main reference implementation of the DSF APIs.  In comparison with PDA, GDB is a much more complex and feature rich debugger integration.  The GDB debugger integration is also being continually developed and improve features and performance.
      -

      TCF

      +

      10.3 TCF

      The Target Communication Framework which is being developed as part of the DSDP Target Management project includes a reference debugger agent implementation. This From 737a61b178056c8aab3feb571f2de08082e12a20 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 13 Mar 2008 20:49:41 +0000 Subject: [PATCH 305/834] [220446] Got rid of an unused extension point. --- plugins/org.eclipse.dd.examples.pda.ui/plugin.xml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/plugins/org.eclipse.dd.examples.pda.ui/plugin.xml b/plugins/org.eclipse.dd.examples.pda.ui/plugin.xml index 4247cf66b16..f7447fbd842 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/plugin.xml +++ b/plugins/org.eclipse.dd.examples.pda.ui/plugin.xml @@ -93,15 +93,6 @@ menubarPath="additions" id="org.eclipse.dd.examples.pda.editor.context.runToLineAction"/> - - - Date: Thu, 13 Mar 2008 20:50:12 +0000 Subject: [PATCH 306/834] [220446] Fixed a warning about JRE version in class path. --- plugins/org.eclipse.dd.examples.pda.ui/.classpath | 2 +- .../.settings/org.eclipse.jdt.core.prefs | 7 ++++++- plugins/org.eclipse.dd.examples.pda/.classpath | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/plugins/org.eclipse.dd.examples.pda.ui/.classpath b/plugins/org.eclipse.dd.examples.pda.ui/.classpath index b7464f3ca24..304e86186aa 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/.classpath +++ b/plugins/org.eclipse.dd.examples.pda.ui/.classpath @@ -1,7 +1,7 @@ + - diff --git a/plugins/org.eclipse.dd.examples.pda.ui/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.dd.examples.pda.ui/.settings/org.eclipse.jdt.core.prefs index 14a59416048..74e18eb9b7c 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.eclipse.dd.examples.pda.ui/.settings/org.eclipse.jdt.core.prefs @@ -1,9 +1,13 @@ -#Mon Jan 24 20:23:44 CST 2005 +#Thu Mar 13 10:58:13 PDT 2008 eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.deprecation=warning org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled org.eclipse.jdt.core.compiler.problem.emptyStatement=warning +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore org.eclipse.jdt.core.compiler.problem.finalParameterBound=ignore org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning @@ -35,3 +39,4 @@ org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=di org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/plugins/org.eclipse.dd.examples.pda/.classpath b/plugins/org.eclipse.dd.examples.pda/.classpath index b7464f3ca24..304e86186aa 100644 --- a/plugins/org.eclipse.dd.examples.pda/.classpath +++ b/plugins/org.eclipse.dd.examples.pda/.classpath @@ -1,7 +1,7 @@ + - From c643667feca869d3a3e2d132092233b35dda4ada Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 13 Mar 2008 20:50:35 +0000 Subject: [PATCH 307/834] [220446] Fixed a warning in manifest file. --- plugins/org.eclipse.dd.examples.pda.ui/META-INF/MANIFEST.MF | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.examples.pda.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.examples.pda.ui/META-INF/MANIFEST.MF index db3421c8f05..962fb9c560a 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.examples.pda.ui/META-INF/MANIFEST.MF @@ -18,7 +18,7 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.dd.dsf.ui;bundle-version="1.0.0", org.eclipse.dd.dsf.debug;bundle-version="1.0.0", org.eclipse.dd.dsf.debug.ui;bundle-version="1.0.0" -Eclipse-LazyStart: true +Bundle-ActivationPolicy: lazy Export-Package: org.eclipse.dd.examples.pda.ui, org.eclipse.dd.examples.pda.ui.breakpoints, org.eclipse.dd.examples.pda.ui.editor, From 63abb2b2c747189ff1eb07f19edb91238a3f49ce Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 13 Mar 2008 20:52:01 +0000 Subject: [PATCH 308/834] [220446] Clean up. --- .../org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java index 0fe04f06fc6..b8b2f9866d0 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java @@ -21,9 +21,6 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentati import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.ui.IDebugUIConstants; -/* - * - */ @ThreadSafe @SuppressWarnings("restriction") public class PDAVMAdapter extends AbstractDMVMAdapter From 9c5201ef984841406b0411f7ba3c0f9b47ba1520 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 13 Mar 2008 23:10:35 +0000 Subject: [PATCH 309/834] [220446] Minor clean up. --- .../examples/dsf/timers/TimersVMProvider.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersVMProvider.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersVMProvider.java index a19d6e31528..6f7a136e7dc 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersVMProvider.java +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersVMProvider.java @@ -56,21 +56,21 @@ public class TimersVMProvider extends AbstractDMVMProvider { clearNodes(); if (layout == ViewLayout.TRIGGERS_AT_TOP) { IRootVMNode root = new TimersRootVMNode(this); - IVMNode alarmsNode = new TriggersVMNode(this, getSession()); - addChildNodes(root, new IVMNode[] { alarmsNode }); + IVMNode triggersNode = new TriggersVMNode(this, getSession()); + addChildNodes(root, new IVMNode[] { triggersNode }); IVMNode timersNode = new TimersVMNode(this, getSession()); - addChildNodes(alarmsNode, new IVMNode[] { timersNode }); - IVMNode alarmStatusNode = new AlarmsVMNode(this, getSession()); - addChildNodes(timersNode, new IVMNode[] { alarmStatusNode }); + addChildNodes(triggersNode, new IVMNode[] { timersNode }); + IVMNode alarmNode = new AlarmsVMNode(this, getSession()); + addChildNodes(timersNode, new IVMNode[] { alarmNode }); setRootNode(root); } else if (layout == ViewLayout.TIMERS_AT_TOP) { IRootVMNode root = new TimersRootVMNode(this); IVMNode timersNode = new TimersVMNode(this, getSession()); addChildNodes(root, new IVMNode[] { timersNode }); - IVMNode alarmsNode = new TriggersVMNode(this, getSession()); - addChildNodes(timersNode, new IVMNode[] { alarmsNode }); - IVMNode alarmStatusNode = new AlarmsVMNode(this, getSession()); - addChildNodes(alarmsNode, new IVMNode[] { alarmStatusNode }); + IVMNode triggersNode = new TriggersVMNode(this, getSession()); + addChildNodes(timersNode, new IVMNode[] { triggersNode }); + IVMNode alarmNode = new AlarmsVMNode(this, getSession()); + addChildNodes(triggersNode, new IVMNode[] { alarmNode }); setRootNode(root); } From 0c602b6de889b15922e1218810aa1cefd129d35f Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Fri, 14 Mar 2008 15:44:20 +0000 Subject: [PATCH 310/834] Bug 222764 Use of the GDB command -environment-directory based on how the CDT used it. --- .../gdb/launch/launching/LaunchSequence.java | 17 ++--- .../eclipse/dd/mi/service/CSourceLookup.java | 62 ++++++++++++++++++- .../commands/MIEnvironmentDirectory.java | 47 ++++++++++++++ 3 files changed, 118 insertions(+), 8 deletions(-) create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIEnvironmentDirectory.java diff --git a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/LaunchSequence.java b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/LaunchSequence.java index 6a7676d65a1..8575b06d410 100644 --- a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/LaunchSequence.java +++ b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/LaunchSequence.java @@ -92,11 +92,11 @@ public class LaunchSequence extends Sequence { }}, new Step() { @Override public void execute(RequestMonitor requestMonitor) { - new MIMemory(fSession).initialize(requestMonitor); + new MIMemory(fSession).initialize(requestMonitor); }}, new Step() { @Override public void execute(RequestMonitor requestMonitor) { - new MIModules(fSession).initialize(requestMonitor); + new MIModules(fSession).initialize(requestMonitor); }}, new Step() { @Override public void execute(RequestMonitor requestMonitor) { @@ -113,10 +113,11 @@ public class LaunchSequence extends Sequence { }}, new Step() { @Override public void execute(RequestMonitor requestMonitor) { - fSourceLookup.setSourceLookupDirector( - fCommandControl.getGDBDMContext(), - ((CSourceLookupDirector)fLaunch.getSourceLocator())); - requestMonitor.done(); + CSourceLookupDirector locator = (CSourceLookupDirector)fLaunch.getSourceLocator(); + + fSourceLookup.setSourceLookupDirector(fCommandControl.getGDBDMContext(), locator); + fSourceLookup.setSourceLookupPath(fCommandControl.getGDBDMContext(), + locator.getSourceContainers(), requestMonitor); }}, new Step() { @Override public void execute(final RequestMonitor requestMonitor) { @@ -222,7 +223,9 @@ public class LaunchSequence extends Sequence { } }, - /* Start tracking the breakpoints once we know we are connected to the target (necessary for remote debugging) */ + /* + * Start tracking the breakpoints once we know we are connected to the target (necessary for remote debugging) + */ new Step() { @Override public void execute(final RequestMonitor requestMonitor) { fBpmService.startTrackingBreakpoints(fCommandControl.getGDBDMContext(), requestMonitor); diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/CSourceLookup.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/CSourceLookup.java index f13439a23fc..7390c09f05a 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/CSourceLookup.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/CSourceLookup.java @@ -10,24 +10,37 @@ *******************************************************************************/ package org.eclipse.dd.mi.service; +import java.io.File; +import java.util.ArrayList; import java.util.HashMap; import java.util.Hashtable; +import java.util.List; import java.util.Map; import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector; +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.debug.service.ISourceLookup; +import org.eclipse.dd.dsf.debug.service.command.ICommandControl; import org.eclipse.dd.dsf.service.AbstractDsfService; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.mi.internal.MIPlugin; +import org.eclipse.dd.mi.service.command.commands.MIEnvironmentDirectory; +import org.eclipse.dd.mi.service.command.output.MIInfo; +import org.eclipse.debug.core.sourcelookup.ISourceContainer; +import org.eclipse.debug.core.sourcelookup.containers.DirectorySourceContainer; +import org.eclipse.debug.core.sourcelookup.containers.FolderSourceContainer; +import org.eclipse.debug.core.sourcelookup.containers.ProjectSourceContainer; import org.osgi.framework.BundleContext; /** @@ -37,6 +50,8 @@ public class CSourceLookup extends AbstractDsfService implements ISourceLookup { private Map fDirectors = new HashMap(); + ICommandControl fConnection; + public CSourceLookup(DsfSession session) { super(session); } @@ -51,6 +66,48 @@ public class CSourceLookup extends AbstractDsfService implements ISourceLookup { fDirectors.put(ctx, director); } + public void setSourceLookupPath(ISourceLookupDMContext ctx, ISourceContainer[] containers, RequestMonitor rm) { + List pathList = getSourceLookupPath(containers); + String[] paths = pathList.toArray(new String[pathList.size()]); + + fConnection.queueCommand( + new MIEnvironmentDirectory(ctx, paths, false), + new DataRequestMonitor(getExecutor(), rm)); + } + + private List getSourceLookupPath(ISourceContainer[] containers) { + ArrayList list = new ArrayList(containers.length); + + for (int i = 0; i < containers.length; ++i) { + if (containers[i] instanceof ProjectSourceContainer) { + IProject project = ((ProjectSourceContainer)containers[i]).getProject(); + if (project != null && project.exists()) + list.add(project.getLocation().toPortableString()); + } + if (containers[i] instanceof FolderSourceContainer) { + IContainer container = ((FolderSourceContainer)containers[i]).getContainer(); + if (container != null && container.exists()) + list.add(container.getLocation().toPortableString()); + } + if (containers[i] instanceof DirectorySourceContainer) { + File dir = ((DirectorySourceContainer)containers[i]).getDirectory(); + if (dir != null && dir.exists()) { + IPath path = new Path( dir.getAbsolutePath()); + list.add(path.toPortableString()); + } + } + if (containers[i].isComposite()) { + try { + list.addAll(getSourceLookupPath(containers[i].getSourceContainers())); + } catch (CoreException e) { + } + } + } + + return list; + } + + @Override public void initialize(final RequestMonitor requestMonitor) { super.initialize( @@ -62,8 +119,11 @@ public class CSourceLookup extends AbstractDsfService implements ISourceLookup { } private void doInitialize(final RequestMonitor requestMonitor) { - // Register this service + fConnection = getServicesTracker().getService(ICommandControl.class); + + // Register this service register(new String[] { CSourceLookup.class.getName(), ISourceLookup.class.getName() }, new Hashtable()); + requestMonitor.done(); } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIEnvironmentDirectory.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIEnvironmentDirectory.java new file mode 100644 index 00000000000..ca3de1ed31d --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIEnvironmentDirectory.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005, 2008 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * ERicsson - Updated + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; + +/** + * + * -environment-directory [-r] PATHDIR + * + * Add directory PATHDIR to beginning of search path for source files. + * -r will first reset the path to its default + * + */ +public class MIEnvironmentDirectory extends MICommand { + + public MIEnvironmentDirectory(IDMContext ctx, String[] paths, boolean reset) { + super(ctx, "-environment-directory"); //$NON-NLS-1$ + + String[] options; + if (reset) { + if (paths == null) { + options = new String[] {"-r"}; //$NON-NLS-1$ + } else { + options = new String[paths.length + 1]; + options[0] = "-r"; //$NON-NLS-1$ + for (int i = 1; i < options.length; i++) { + options[i] = paths[i-1]; + } + } + } else { + options = paths; + } + + setOptions(options); + } +} \ No newline at end of file From 4f501b788f31bca3d7806bcce6ca0c7b70621b98 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 14 Mar 2008 20:56:49 +0000 Subject: [PATCH 311/834] [222568] Applied fix to prevent escaping of backslashes in C-Strings. --- .../src/org/eclipse/dd/mi/service/command/output/MIParser.java | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIParser.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIParser.java index dd18a64d4d2..e738cff18d3 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIParser.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIParser.java @@ -401,6 +401,7 @@ public class MIParser { char c = buffer.charAt(index); if (c == '\\') { if (escape) { + sb.append(c); sb.append(c); escape = false; } else { From a7c5da0b08ebe413c67599fc1ed543f72a67814b Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Tue, 18 Mar 2008 14:54:09 +0000 Subject: [PATCH 312/834] Print the token when printing the debug traces for the inserted thread-select and stack-select. --- .../org/eclipse/dd/mi/service/command/AbstractMIControl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java index 5772bbb3fb9..a2d3b3741f0 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java @@ -239,7 +239,7 @@ public abstract class AbstractMIControl extends AbstractDsfService CommandHandle cmdHandle = new CommandHandle( new MIThreadSelect(handle.fCommand.getContext(), fCurrentThreadId), null); fTxCommands.add(cmdHandle); - MIPlugin.debug(MIPlugin.getDebugTime() + " " + cmdHandle.getCommand()); //$NON-NLS-1$ + MIPlugin.debug(MIPlugin.getDebugTime() + " " + cmdHandle.getToken() + cmdHandle.getCommand()); //$NON-NLS-1$ } // Before the command is sent, Check the Stack level and send it to @@ -252,7 +252,7 @@ public abstract class AbstractMIControl extends AbstractDsfService CommandHandle cmdHandle = new CommandHandle( new MIStackSelectFrame(handle.fCommand.getContext(), fCurrentStackLevel), null); fTxCommands.add(cmdHandle); - MIPlugin.debug(MIPlugin.getDebugTime() + " " + cmdHandle.getCommand()); //$NON-NLS-1$ + MIPlugin.debug(MIPlugin.getDebugTime() + " " + cmdHandle.getToken() + cmdHandle.getCommand()); //$NON-NLS-1$ } fTxCommands.add(handle); } From a7fa912306cb424a95b8e329280b4b22fdb6cb11 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Tue, 18 Mar 2008 16:47:34 +0000 Subject: [PATCH 313/834] Bug 223025 Used to check for MIList twice instead of checking for MITuple. --- .../dd/mi/service/command/output/MIStackListArgumentsInfo.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIStackListArgumentsInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIStackListArgumentsInfo.java index 4d7f84cec84..2c82922f5c9 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIStackListArgumentsInfo.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIStackListArgumentsInfo.java @@ -37,7 +37,7 @@ public class MIStackListArgumentsInfo extends MIInfo { MIValue val = results[i].getMIValue(); if (val instanceof MIList) { parseStack((MIList)val, aList); - } else if (val instanceof MIList) { + } else if (val instanceof MITuple) { parseStack((MITuple)val, aList); } } From 89f4a41f0e91e813f237cf02337edd181e06fc3b Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Wed, 19 Mar 2008 13:24:30 +0000 Subject: [PATCH 314/834] Merge the GdbRemoteLaunchDelegate and the GdbLocalLaunchDelegate into a single GdbLaunchDelegate --- plugins/org.eclipse.dd.gdb.launch/plugin.xml | 4 +- .../dd/gdb/launch/launching/GdbLaunch.java | 4 +- ...chDelegate.java => GdbLaunchDelegate.java} | 31 +- .../launching/GdbRemoteLaunchDelegate.java | 292 ------------------ .../dd/gdb/internal/ui/GdbAdapterFactory.java | 6 +- .../CBreakpointGdbThreadFilterPage.java | 4 +- 6 files changed, 32 insertions(+), 309 deletions(-) rename plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/{GdbLocalLaunchDelegate.java => GdbLaunchDelegate.java} (90%) delete mode 100644 plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/GdbRemoteLaunchDelegate.java diff --git a/plugins/org.eclipse.dd.gdb.launch/plugin.xml b/plugins/org.eclipse.dd.gdb.launch/plugin.xml index cc2a0d580d0..0b49da90602 100644 --- a/plugins/org.eclipse.dd.gdb.launch/plugin.xml +++ b/plugins/org.eclipse.dd.gdb.launch/plugin.xml @@ -4,7 +4,7 @@ cliProcessRef = new AtomicReference(); - final AtomicReference inferiorProcessRef = new AtomicReference(); - try { - launch.getDsfExecutor().submit( new Callable() { - public Object call() throws CoreException { - DsfServicesTracker tracker = new DsfServicesTracker(GdbLaunchPlugin.getBundleContext(), launch.getSession().getId()); - GDBControl gdb = tracker.getService(GDBControl.class); - if (gdb != null) { - cliProcessRef.set(gdb.getCLIProcess()); - inferiorProcessRef.set(gdb.getInferiorProcess()); - } - tracker.dispose(); - return null; - } - }).get(); - launch.addProcess(DebugPlugin.newProcess(launch, cliProcessRef.get(), "gdb")); //$NON-NLS-1$ - launch.addProcess(DebugPlugin.newProcess(launch, inferiorProcessRef.get(), exePath.lastSegment())); - } catch (InterruptedException e) { - throw new CoreException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, 0, "Interrupted while waiting for get process callable.", e)); //$NON-NLS-1$ - } catch (ExecutionException e) { - throw (CoreException)e.getCause(); - } catch (RejectedExecutionException e) { - throw new CoreException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, 0, "Debugger shut down before launch was completed.", e)); //$NON-NLS-1$ - } - - // Create a memory retrieval and register it with session - try { - launch.getDsfExecutor().submit( new Callable() { - public Object call() throws CoreException { - DsfServicesTracker tracker = new DsfServicesTracker(GdbLaunchPlugin.getBundleContext(), launch.getSession().getId()); - GDBControl gdbControl = tracker.getService(GDBControl.class); - if (gdbControl != null) { - IMemoryBlockRetrieval memRetrieval = new DsfMemoryBlockRetrieval( - GDB_DEBUG_MODEL_ID, config, (IMemoryDMContext)gdbControl.getControlDMContext()); - launch.getSession().registerModelAdapter(IMemoryBlockRetrieval.class, memRetrieval); - ((DsfMemoryBlockRetrieval) memRetrieval).initialize(); - } - tracker.dispose(); - return null; - } - }).get(); - } catch (InterruptedException e) { - throw new CoreException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, 0, "Interrupted while waiting for get process callable.", e)); //$NON-NLS-1$ - } catch (ExecutionException e) { - throw (CoreException)e.getCause(); - } catch (RejectedExecutionException e) { - throw new CoreException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, 0, "Debugger shut down before launch was completed.", e)); //$NON-NLS-1$ - } - } - - - /* (non-Javadoc) - * @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#getPluginID() - */ - @Override - protected String getPluginID() { - return LaunchUIPlugin.getUniqueIdentifier(); - } - - /** - * Performs a runtime exec on the given command line in the context of the - * specified working directory, and returns the resulting process. If the - * current runtime does not support the specification of a working - * directory, the status handler for error code - * ERR_WORKING_DIRECTORY_NOT_SUPPORTED is queried to see if - * the exec should be re-executed without specifying a working directory. - * - * @param cmdLine - * the command line - * @param workingDirectory - * the working directory, or null - * @return the resulting process or null if the exec is - * cancelled - * @see Runtime - */ - protected Process exec( String[] cmdLine, String[] environ, File workingDirectory, boolean usePty ) throws CoreException { - Process p = null; - try { - if ( workingDirectory == null ) { - p = ProcessFactory.getFactory().exec( cmdLine, environ ); - } - else { - if ( usePty && PTY.isSupported() ) { - p = ProcessFactory.getFactory().exec( cmdLine, environ, workingDirectory, new PTY() ); - } - else { - p = ProcessFactory.getFactory().exec( cmdLine, environ, workingDirectory ); - } - } - } - catch( IOException e ) { - if ( p != null ) { - p.destroy(); - } - abort( "Error starting process.", e, ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR ); //$NON-NLS-1$ - } - catch( NoSuchMethodError e ) { - // attempting launches on 1.2.* - no ability to set working - // directory - IStatus status = new Status( IStatus.ERROR, LaunchUIPlugin.getUniqueIdentifier(), ICDTLaunchConfigurationConstants.ERR_WORKING_DIRECTORY_NOT_SUPPORTED, LaunchMessages.getString( "LocalDsfLaunchDelegate.9" ), e ); //$NON-NLS-1$ - IStatusHandler handler = DebugPlugin.getDefault().getStatusHandler( status ); - if ( handler != null ) { - Object result = handler.handleStatus( status, this ); - if ( result instanceof Boolean && ((Boolean)result).booleanValue() ) { - p = exec( cmdLine, environ, null, usePty ); - } - } - } - return p; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#preLaunchCheck(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.core.runtime.IProgressMonitor) - */ - @Override - public boolean preLaunchCheck( ILaunchConfiguration config, String mode, IProgressMonitor monitor ) throws CoreException { - // no pre launch check for core file - if ( mode.equals( ILaunchManager.DEBUG_MODE ) ) { - if ( ICDTLaunchConfigurationConstants.DEBUGGER_MODE_CORE.equals( config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN ) ) ) - return true; - } - return super.preLaunchCheck( config, mode, monitor ); - } - - /////////////////////////////////////////////////////////////////////////// - // ILaunchConfigurationDelegate2 - @Override - public boolean buildForLaunch(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException { - return false; - } - - @Override - public boolean finalLaunchCheck(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException { - return true; - } - - @Override - public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) throws CoreException { - // Need to configure the source locator before creating the launch - // because once the launch is created and added to launch manager, - // the adapters will be created for the whole session, including - // the source lookup adapter. - ISourceLocator locator = getSourceLocator(configuration); - - return new GdbLaunch(configuration, mode, locator); - } - - private ISourceLocator getSourceLocator(ILaunchConfiguration configuration) throws CoreException { - String type = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_ID, (String)null); - if (type == null) { - type = configuration.getType().getSourceLocatorId(); - } - if (type != null) { - IPersistableSourceLocator locator = DebugPlugin.getDefault().getLaunchManager().newSourceLocator(type); - String memento = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_MEMENTO, (String)null); - if (memento == null) { - locator.initializeDefaults(configuration); - } else { - if(locator instanceof IPersistableSourceLocator2) - ((IPersistableSourceLocator2)locator).initializeFromMemento(memento, configuration); - else - locator.initializeFromMemento(memento); - } - return locator; - } - return null; - } -} diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java index c38adc21aff..0a8e25f346b 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java @@ -28,8 +28,7 @@ import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.gdb.internal.ui.actions.DsfTerminateCommand; import org.eclipse.dd.gdb.internal.ui.viewmodel.GdbViewModelAdapter; import org.eclipse.dd.gdb.launch.launching.GdbLaunch; -import org.eclipse.dd.gdb.launch.launching.GdbLocalLaunchDelegate; -import org.eclipse.dd.gdb.launch.launching.GdbRemoteLaunchDelegate; +import org.eclipse.dd.gdb.launch.launching.GdbLaunchDelegate; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchesListener2; @@ -102,8 +101,7 @@ public class GdbAdapterFactory fDebugModelProvider = new IDebugModelProvider() { // @see org.eclipse.debug.core.model.IDebugModelProvider#getModelIdentifiers() public String[] getModelIdentifiers() { - return new String[] { GdbLocalLaunchDelegate.GDB_DEBUG_MODEL_ID, - GdbRemoteLaunchDelegate.GDB_DEBUG_MODEL_ID}; + return new String[] { GdbLaunchDelegate.GDB_DEBUG_MODEL_ID }; } }; session.registerModelAdapter(IDebugModelProvider.class, fDebugModelProvider); diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/CBreakpointGdbThreadFilterPage.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/CBreakpointGdbThreadFilterPage.java index 29ff31a6c1d..994ba97c6e0 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/CBreakpointGdbThreadFilterPage.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/CBreakpointGdbThreadFilterPage.java @@ -13,7 +13,7 @@ package org.eclipse.dd.gdb.internal.ui.breakpoints; import org.eclipse.cdt.debug.core.model.ICBreakpoint; import org.eclipse.core.runtime.CoreException; import org.eclipse.dd.gdb.breakpoints.CBreakpointGdbThreadsFilterExtension; -import org.eclipse.dd.gdb.launch.launching.GdbLocalLaunchDelegate; +import org.eclipse.dd.gdb.launch.launching.GdbLaunchDelegate; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; @@ -50,7 +50,7 @@ public class CBreakpointGdbThreadFilterPage extends PropertyPage { try { CBreakpointGdbThreadsFilterExtension filter = (CBreakpointGdbThreadsFilterExtension) bp.getExtension( - GdbLocalLaunchDelegate.GDB_DEBUG_MODEL_ID, CBreakpointGdbThreadsFilterExtension.class); + GdbLaunchDelegate.GDB_DEBUG_MODEL_ID, CBreakpointGdbThreadsFilterExtension.class); filter.initialize(bp); return filter; } catch (CoreException e) {} From 3cc3d633da84c3bf056c11fdc9578da2595c4c01 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Thu, 20 Mar 2008 13:00:11 +0000 Subject: [PATCH 315/834] Bug 223196 Removing the guard since it was wrong (== instead of !=) and it not useful --- .../src/org/eclipse/dd/gdb/service/command/GDBControl.java | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControl.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControl.java index 0e33727fc38..e0f495eda4b 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControl.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControl.java @@ -456,7 +456,6 @@ public class GDBControl extends AbstractMIControl { new Job("Terminating GDB process.") { //$NON-NLS-1$ @Override protected IStatus run(IProgressMonitor monitor) { - if (fProcess == null) fProcess.destroy(); int attempts = 0; From bff2486202e73038c6e73bb154f307ce2d59c032 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Thu, 20 Mar 2008 18:03:01 +0000 Subject: [PATCH 316/834] Bug 223200 Removal of commandCache --- .../dd/gdb/service/command/GDBControl.java | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControl.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControl.java index e0f495eda4b..ef6b93238d0 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControl.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControl.java @@ -35,7 +35,6 @@ import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.concurrent.Sequence; import org.eclipse.dd.dsf.datamodel.AbstractDMEvent; -import org.eclipse.dd.dsf.debug.service.command.CommandCache; import org.eclipse.dd.dsf.debug.service.command.ICommandControl; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfSession; @@ -48,9 +47,7 @@ import org.eclipse.dd.mi.service.command.MIControlDMContext; import org.eclipse.dd.mi.service.command.MIInferiorProcess; import org.eclipse.dd.mi.service.command.MIRunControlEventProcessor; import org.eclipse.dd.mi.service.command.commands.MIGDBExit; -import org.eclipse.dd.mi.service.command.commands.MIGDBShowExitCode; import org.eclipse.dd.mi.service.command.commands.MIInterpreterExecConsole; -import org.eclipse.dd.mi.service.command.output.MIGDBShowExitCodeInfo; import org.eclipse.dd.mi.service.command.output.MIInfo; import org.eclipse.debug.core.DebugException; import org.osgi.framework.BundleContext; @@ -98,8 +95,6 @@ public class GDBControl extends AbstractMIControl { private Process fProcess; private int fGDBExitValue; final private int fGDBLaunchTimeout; - - private CommandCache fCommandCache; private MIRunControlEventProcessor fMIEventProcessor; private CLIEventProcessor fCLICommandProcessor; @@ -263,18 +258,6 @@ public class GDBControl extends AbstractMIControl { } public IPath getExecutablePath() { return fExecPath; } - - public void getInferiorExitCode(final DataRequestMonitor rm) { - fCommandCache.execute( - new MIGDBShowExitCode(fControlDmc), - new DataRequestMonitor(getExecutor(), rm) { - @Override - protected void handleOK() { - rm.setData(getData().getCode()); - rm.done(); - } - }); - } public void getInferiorProcessId(DataRequestMonitor rm) { } @@ -559,7 +542,6 @@ public class GDBControl extends AbstractMIControl { fInferiorProcess = new GDBInferiorProcess(GDBControl.this, fProcess.getOutputStream()); fCLICommandProcessor = new CLIEventProcessor(GDBControl.this, fControlDmc, fInferiorProcess); fMIEventProcessor = new MIRunControlEventProcessor(GDBControl.this, fControlDmc); - fCommandCache = new CommandCache(GDBControl.this); requestMonitor.done(); } From 391048a4f0b31948c81bbb8119422d533e913817 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Sun, 23 Mar 2008 14:36:46 +0000 Subject: [PATCH 317/834] Launch should not be visible to the user. --- plugins/org.eclipse.dd.tests.gdb/plugin.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.tests.gdb/plugin.xml b/plugins/org.eclipse.dd.tests.gdb/plugin.xml index e2b5a7c5bfd..0ee16f5f708 100644 --- a/plugins/org.eclipse.dd.tests.gdb/plugin.xml +++ b/plugins/org.eclipse.dd.tests.gdb/plugin.xml @@ -5,7 +5,7 @@ Date: Mon, 24 Mar 2008 16:22:34 +0000 Subject: [PATCH 318/834] [219841] Fixed an NPE in BreakpointsMediator related to breakpoints that failed to plant. --- .../dd/dsf/debug/service/BreakpointsMediator.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/BreakpointsMediator.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/BreakpointsMediator.java index 8b011e0a79f..9b00519853f 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/BreakpointsMediator.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/BreakpointsMediator.java @@ -420,13 +420,15 @@ public class BreakpointsMediator extends AbstractDsfService implements IBreakpoi new DataRequestMonitor(getExecutor(), installRM) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + List list = breakpointIDs.get(breakpoint); + if (list == null) { + list = new LinkedList(); + breakpointIDs.put(breakpoint, list); + } + + if (getStatus().isOK()) { // Add the breakpoint back-end mapping - List list = breakpointIDs.get(breakpoint); - if (list == null) - list = new LinkedList(); list.add(getData()); - breakpointIDs.put(breakpoint, list); } else { // TODO (bug 219841): need to add breakpoint error status tracking // in addition to fBreakpointDMContexts. From 0b3ad17747c3ec891ba97f402cd302df7421a1ff Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Mon, 24 Mar 2008 16:23:53 +0000 Subject: [PATCH 319/834] [220446] Fixed typos. --- .../docs/intro/dsf_programming_intro.html | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/intro/dsf_programming_intro.html b/plugins/org.eclipse.dd.doc.dsf/docs/intro/dsf_programming_intro.html index f7344d741ea..6021e16ced9 100644 --- a/plugins/org.eclipse.dd.doc.dsf/docs/intro/dsf_programming_intro.html +++ b/plugins/org.eclipse.dd.doc.dsf/docs/intro/dsf_programming_intro.html @@ -16,8 +16,7 @@ more advanced features.
      • 1 Introduction
      • -
      • 2 Examples -
      • +
      • 2 Examples
      • 3 Asynchronous Methods
        • 3.1 Request Monitor
        • @@ -56,14 +55,12 @@ Shutdown
        • 8 View Model
        • 9 Next Steps
        • @@ -89,7 +86,7 @@ in this tutorial the following is needed:
          1. Download and install the Eclipse SDK 3.4 (http://download.eclipse.org/eclipse/downloads)
          2. -
          3. nstall the Eclipse IDE for C/C++ 5.0:
            +
          4. Install the Eclipse IDE for C/C++ 5.0:
            1. Using Update Manager, install the Date: Mon, 24 Mar 2008 16:34:37 +0000 Subject: [PATCH 320/834] [220446][219907] Updated the doc plugin to point to the new DSF tutorials. --- .../docs/dsf_concurrency_model-1.png | Bin 6256 -> 0 bytes .../docs/dsf_concurrency_model.html | 432 ------------------ .../docs/dsf_data_model.html | 286 ------------ .../docs/dsf_mi_instructions.html | 135 ------ .../docs/dsf_services_model-1.png | Bin 2224 -> 0 bytes .../docs/dsf_services_model-2.png | Bin 1761 -> 0 bytes .../docs/dsf_services_model.html | 363 --------------- plugins/org.eclipse.dd.doc.dsf/toc.xml | 16 +- 8 files changed, 9 insertions(+), 1223 deletions(-) delete mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/dsf_concurrency_model-1.png delete mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/dsf_concurrency_model.html delete mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/dsf_data_model.html delete mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/dsf_mi_instructions.html delete mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/dsf_services_model-1.png delete mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/dsf_services_model-2.png delete mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/dsf_services_model.html diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/dsf_concurrency_model-1.png b/plugins/org.eclipse.dd.doc.dsf/docs/dsf_concurrency_model-1.png deleted file mode 100644 index 1bb373447d7bd0f17cd54f8298fc6f65658c8420..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6256 zcmb7IXH-*Nvra<5D1dv zrDzaB2SJe=-}hVJk9&XJv(_nlpPAWn=FB{MX5x(vb)nZ-t^oi5s2=RL2><{JBR)q! zK*TG%I*&f_26odh&;S7HQ^J1TODB%6`ogRN0045@zb6p4_~kZU?c` z%=YG5e(+_`D3-r6fDIHE_W)^gCW$PQFC;a=@elm|^<$>?@g6w@0OSOKBLLKv5nWXH zuZ+|HkUHS+WE~*#F~iRY@_*kFXID-uUE1vI_LNpR85OSoOC&)Rc?+XF1{C3l?i$-z zDSAL7^jE-&0$3gUG1Jqri*qr4rAOxPTv3}H8NK?-nFfh3aYS4qG8ke%@iKNNI7E5M)_@JV>mW2sXncXP&W*nXvO^PVoj0 z+-Ks*L|JKDTDj2NVY?GM?wTIzQ7!D*nS`0@aDnFAB}Q(f|B#N#}f z{RaI?y}2?TknigAm8Q42&nfojJASl~d7;k45sY_`sai_+a48AbX4N`j-{B~olEKj% zx5{7JxgX+?Z`#)TiG?T)>8plI)WCj_5IwAsYnwESad$}*duu9867zDg$RTW!y=Y|Z zCc-J$B~99-EZpUnm)#0e)7y5%jp$fE!+lB~BsBnE(|raL--4{Ly}pqA+-+bXCfPK% zb0cHKYMLJQ=05ZJ!Jy;peY!7jTxMt)RwTsRU8mpbi^R$Ck!X`~D+|l}B>4f#CiXE9 z1J;o4&mc9+<}L7V3{s?HYp?joiH?7ff3iAG^u};Q`qDIoGQR(SLO2Vj;fcFC*^*(!7tR1a`o;)cS$F(@l`552e3Gj*|)pUeJ>#AGsSJPHqeYg3vLGa73 zjbM1t$GLayiDTQ_C-t3V-@*^trD;F(*MIr8CeEjpgao)6j!f!0#d zS=VKFEN3Cy02~w)6g98PV{cH(juXA*0-ssd?A@Z``F6a{61Lg@IKgElOut0uD;S?r zbn3Sls?+u2ZXTwxLupgD@!S3DqaNe3Kb^HhYuHx8ymx-5MWHS%5&Xe_SADZp()_t% z3<@fke~H}7ebGbnA@Y#Mg@u9^qYPQep4w#wBBe6z3R?O$O8ngU*4_(Ax027SNGm5^ z?2vrBK+3Rl!Gdn|j#94&QvR%+>=_#P6N$zVZaSWlWv zCD0%heIfOn&z%MBmY@{a*#X^%wTclFPb#$H**i5&`J`uvR-9%OCsQ&@N|*#D=iKV^ z2mfdW7^AAOw*3{HSIR5hB0;&(xpOq@)76p$SssVAgP1Zk=9bQ?cUPWbDbjZpLHI|t zrS8nK@^^F|qJD@LP9e%vFs3Hq<$S$25HM_FS->n?q4@f)Zf5QGD`%+;+0*T9E)G;v zuBizw1B8PdbfZvAkHQ!w#R(k|boic}$(kZCLowNsL+dA|Ut+hJZwo&5wT4zqTotRO zqlR@C%`S5J(Km+HCt} z00qwFSFEja>2on&IXMoe2Qhk2vB;D^mYx;n`dxn>_7FTU!oo0{avf|%)=h2Zo!0_- zGjf(4(6U|K9E3v1b*{(MM1YJ+Xi}QA!xqN?2^0K6 zMiMdtS0vyif}7rTfjvJzZO!Q0-kiH~W?PKVGUDB(jR@f?e?tNK4yRh%ZltPbBZfS| z_^E+YonAJLTY%}Si7am>m*IifrrPxc3;CzYMXcfEQohL_6+L=#yDF$nMe8U zm{m2W&$U|Xi&dGr%^ux|@#|b;Q1Npe$iMDoKHV}0#4nler-TvxTrd}>swY--&<_YL zuBZ#QsDPCTzTZ~ITE*9ex2yp~7)SJjgI9cKBLT1$lBzGaZz+N%8Dj)J{<}@un11nTO5e@UL@Lw&!u>2oI+p3pC-?#_h9%DmTl>*A9y&arSCc=Bw-b)MI z%!gQ$C^s%mt&!yRaUvLP3g-zWmgnaYCa_yyw3*}AtE?O3 zM?3aKHTQ!$iJIg>NK-_BxFi2yp+0s?*)G-Fn|$dnD#=W9b@9j8)H3)Iw6|}ciKh|{ z=d=C*%>KX{)&)8wj`Rlsj!88{d?kC>%UZay4?_lvGQ=moHgP`g)aT0dMuckvD-u~60Gedr}qAH z0TQZEHt8L}w9K_=Yy4d*&Ezd(GR)b(eoKExdj{c`LOwRym@TD&U6WP)+_S9)mvpGr z%a>H>ALM=BzM}WWP&B4y)`S}`b-;(G)O4a~5QF6G*~6QW)5|8adRVw8Ev3sc3-FMB zaiN%1`-m~6aJchw436S*%^Vzgs;E>_6#GH(HQGR6678jfqc3`d99c*bWZdKS4I=n4n;9w}*-|e0x@= ztrosDie|dPdFe^dlC7%!BlB@hHgOtsQjZk#k!^LQRVPz}t@w%ns{?bdFnK+T4frvE zCoiI&X5u;5)a)H@ZRDF5)tQAf)o&v`1n$j{ZEA~9qoIu!A*jd+iq7VD-isId;wng45%l9U*cAACz)7wq&(u)=I*n7O znU!wl(d-+^;xySGJzq;s7B~?MXurW(xU0ON=R9|9QiO$J4-rCENdJKlyKbvMp>I^J zag}#%TdU-Q7hekqo(y4rc)qm!*w-lc{;fiqB3#7w#oEEnVB?*K!U8>MvDaJlA79!N zIhD+^^Zj?T!GhUPvZi#@&c^N0uwz$yaOYK|gberPiPRTJsIv03n`HIUtXOvE6=!AB zlk->P45gLm49Vv@l-WvmokSNi{f9{#mx{sj#ToVb+7IaTABp~O{d_E6FmItV7Jxnf zb$R%TtgC8geBdf3apJ%XjD9dKJIj)L&JRmBhWbN)pjYX{9$3~3t3XJ;v4#LJp<0h?7HDK4k_cR{N9w0+$>4) z*e%pIhj;u)x6+J856qDBPaxf8YQcKHX7tl-XmRHHNc5CKiOVl0g?+!5ypSmxz^FXx z3T(z~Lz${q)k;~qNw1~tlMBbJn!eSvWg0WHseg62c{MZZ`z=sj4U&79#{XpX#)#KL0;D|-3mgI>EH!bA3Qw^28AAgJD zkCLC?DloJRY)0KO%zx>)yV)?dQ_Waocg8X*t89@jw#a0{@C4c#b`w*z$r|sFOdvYO z9{3-}NRl)V*F$XVc~Tm7uHhAUPW!gYl)eZaAH$TQJd1%iGtP?R`e?OEiV-C*USFf> zQ)d>W#6KI@oqj8|ZJ}6OerGs)$anuOx4unH6~c^Dca({~Ebkk)gD{`C#0~O6*@Tz( zV)_*+v4=80iV_VbcL!w16!zj*rz@xKU{PL06Zw?#uBI1T^@q2I)UxTn=R5a|&{%)X zu)~PG=EY~bik3Adjlh!Y0ov+cjkPlM831!y^HP7r;QNkD%<;G-j)md@HNkWEmBXrlHxU=oVx5f*#(hmb5OS zDsvE63(?+pGF+_Q;cQJbWGSABMWpe6Y0cjwwP=JZvbKhd3yI(ey!*SD*9_b2$9 zM2EDnsI}~%qMku1l~jVTE*@SsLgVY<7{?0nj8{MGo5S2;RLCRq2z^yAKByfWeJK!o zChwEUHkaTo-q*ZrokEr=C-0d`$kO$iDSE+UKhs6SNUcB%JnoxAa)cjRt=(+Sz3%Y} zo1p^l$%=+6bbQdmmF`E+XDdiBj#RmO7EEr_TdI60tvq*W|5RPyz&7_DqI4CQ>P?#} zK?1ggtn|INSF#mIM~&^|1n|^0-PhL<)S9m=_M? zj=|Pfc)Fr!og>s4Kni|VFoLIB9BL;p-772OZ2hQgyO`E4;H`5v?7$UVYLbB!96S$9 z6HBxuO)*hUsZ|s*Kf|c9ggv)s)() zH+D;3zj9U^8^aw4xA}3Q$DCIq^Y#C7D&Se}a4qgojHWuGR-F=>!ta&P83CF$a4Cat z)0BC3v3fA)$-GEw`s0zvGC@g@ihu?g#F;CCF8k^FDEcd=HNZShloXg0LC@p>hA7Z< z#Rq@_8<}9I-w#Hh>^$~j9d(r8KRN(@LQD#=J7m0JpTY#xSSca{YZ8@zYOj3vDkjvj z+dL+brjFL@Cx~bi`6B@AG)Cx3KpzAGx+2R-tqI^41AlSQ=UnW))+}Y46p{I$myx_+|SdY)$LjthE7D?%jw&8y?fW_p&*9!`(hL+Ye|bK!84^s?`jQZi{@VXhxh8v>2V6F=WL=l+t> zJu&`ceqOu}Go>;!&Uc~kxJl~3+}W3GUEW`HE}QhWSUT{yMW{`v6SsZswxRP)jK_I= zhG6JHUit>1$};ot{?|q5?%W)I3Lw+xdxrDjOQ@7wHnKIYVq;$uYO-{oA})0|ZOV@C zdoVXiIj|%~D6&GaX}=aY^zlk?C*qerR9&;IB51=fR7cc6`lmHN)3(~f6*{8@`}@_1{;i*QPQ zyHjVNec=`GxQThO(@}p{bWM^_p7&n(*H9gd34mN70Q8;)Wm@1nx!-a z;n~gWGFKhJRkv9?A^?U9P*nh~{ncRi4N1_GE)6Ioni$aJ-RK-z*lFF9Y6?akd*1my z(!XneCw~3kGAfRS8cgY-&KV6bw1qVHW~gIhuY0<@V*(0)juGdKpbOHXia`04`%CC1 zMR58WlYqF0+?sW4rC^+DmA!CpKg2R#E(}P-?*C?Lj$m+P6bm(kh-ZvXb|iRH2@a$- z%wjrS`i-mPM0{EtC*fRVt++8v!@~)=F&Uu_A#ziD#tPywzYgg;BLF&G4rR=%>?r`( zQC`Tn+Qr4?M8Eid+wk^4BHWO2_LBamQy;lZbc)Yc{_V#DzzoEHfdI=a0D%8;{N!*+ W(|ar%1~vi^4?S(e+clc@PyPove1psY diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/dsf_concurrency_model.html b/plugins/org.eclipse.dd.doc.dsf/docs/dsf_concurrency_model.html deleted file mode 100644 index 9ef49c39f64..00000000000 --- a/plugins/org.eclipse.dd.doc.dsf/docs/dsf_concurrency_model.html +++ /dev/null @@ -1,432 +0,0 @@ - - - - - DSF Concurrency Model - - -

              DSF Concurrency Model

              -

              -

              -

              Version -1.0
              -Pawel Piech
              -© 2006, Wind River Systems.  Release -under EPL version 1.0.

              -

              Introduction

              -Providing a solution to concurrency problems is the primary design goal -of DSF.  To that end DSF imposes a rather draconian -restriction on services that use it: 1) -All service interface methods must be called using a single designated -dispatch thread, unless explicitly stated otherwise, 2) The dispatch -thread should never be used to make a blocking call (a call that waits -on I/O or a call that makes a long-running computation).  What -the first restriction effectively means, is that the dispatch thread -becomes a global "lock" that all DSF services in a given session -share with each other, and which controls access to most of services' -shared data.  It's important to note that multi-threading is still allowed -within individual service implementation. but when crossing the service -interface boundaries, only the dispatch thread can be used.  The -second restriction just ensures that the performance of the whole -system is not killed by one service that needs to read a huge file over -the network.  Another way of looking at it is that the -service implementations practice co-operative multi-threading using the -single dispatch thread.
              -
              -There are a couple of obvious side effects that result from this rule:
              -
                -
              1. When executing within the dispatch thread, the state of the -services is guaranteed not to change.  This means that -thread-defensive programming techniques, such as making duplicates of -lists before iterating over them, are not necessary.  Also it's -possible to implement much more complicated logic which polls the state -of many objects, without the worry about dead-locks.
              2. -
              3. Whenever a blocking operation needs to be performed, it must be -done using an asynchronous method.  By the time the operation is -completed, and the caller regains the dispatch thread, this caller may -need to retest the relevant state of the system, because it could -change completely while the asynchronous operation was executing.
              4. -
              -

              The Mechanics

              -

              java.util.concurrent.ExecutorService
              -

              -DSF builds on the vast array of tools added in Java 5.0's -java.util.concurrent package (see http://java.sun.com/j2se/1.5.0/docs/guide/concurrency/index.html -for details), where the most important is the ExecutorService -interface.  ExecutorService -is a formal interface for submitting Runnable objects that will be -executed according to executor's rules, which could be to execute the -Runnable immediately, -within a thread pool, using a display thread, -etc.  For DSF, the main rule for executors is that they have -to use a single thread to execute the runnable and that the runnables -be executed in the order that they were submitted.  To give the -DSF clients and services a method for checking whether they are -being called on the dispatch thread, we extended the ExecutorService -interface as such:
              -
              public interface DsfExecutor extends ScheduledExecutorService
              {
              /**
              * Checks if the thread that this method is called in is the same as the
              * executor's dispatch thread.
              * @return true if in DSF executor's dispatch thread
              */
              public boolean isInExecutorThread();
              }
              -

              java.lang.concurrent.Future -vs org.eclipse.dd.dsf.concurrent.Done

              -The Done object -encapsulates the return value of an asynchronous call in DSF.  It -is actually merely a Runnable with -an attached org.eclipse.core.runtime.IStatus -object , but it can be extended by the services or clients to hold -whatever additional data is needed.   Typical pattern in how -the Done object is used, -is as follows:
              -
              Service:
              public class Service {
              void asyncMethod(Done done) {
              new Job() {
              public void run() {
              // perform calculation
              ...
              done.setStatus(new Status(IStatus.ERROR, ...));
              fExecutor.execute(done);
              }
              }.schedule();
              }
              }

              Client:
              ...
              Service service = new Service();
              final String clientData = "xyz";
              ...
              service.asynMethod(new Done() {
              public void run() {
              if (getStatus().isOK()) {
              // Handle return data
              ...
              } else {
              // Handle error
              ...
              }
              }
              }
              -The service performs the asynchronous operation a background thread, -but -it can still submit the Done runnable -with the executor.  In other words, the Done and other runnables can be -submitted from any thread, but will always execute in the single -dispatch thread.  Also if the implementation of the asyncMethod() is non-blocking, -it does not need to start a job, it could just perform the operation in -the dispatch thread.  On the client side, care has to be taken to -save appropriate state before the asynchronous method is called, -because by the time the Done is -executed, the client state may change.
              -
              -The java.lang.concurrent -package -doesn't already have a Done, -because the generic concurrent -package is geared more towards large thread pools, where clients submit -tasks to be run in a style similar to Eclipse's Jobs, rather than using -the single dispatch thread model of DSF.  To this end, the -concurrent package does have an equivalent object, Future.  -Future has methods that -allows the client to call the get() -method, and block while waiting for a result, and for this reason it -cannot -be used from the dispatch thread.  But it can be used, in a -limited way, by clients which are running on background thread that -still -need to retrieve data from synchronous -DSF methods.  In this case the code might look like the -following:
              -
              Service:
              public class Service {
              int syncMethod() {
              // perform calculation
              ...
              return result;
              }
              }

              Client:
              ...
              DsfExecutor executor = new DsfExecutor();
              final Service service = new Service(executor);
              Future<Integer> future = executor.submit(new Callable<Integer>() {
              Integer call() {
              return service.syncMethod();
              }
              });
              int result = future.get();
              -The biggest drawback to using Future -with DSF services, is that it does not work with -asynchronous methods.  This is because the Callable.call() -implementation -has to return a value within a single dispatch cycle.  To get -around this, DSF has an additional object called DsfQuery, which works like a Future combined with a Callable, but allows the -implementation to make multiple dispatches before setting the return -value to the client.  The DsfQuery object works as follows:
              -
              -
                -
              1. Client creates the query object with its own implementation of DsfQuery.execute().
                -
              2. -
              3. Client calls the DsfQuery.get() -method on non-dispatch thread, and blocks.
              4. -
              5. The query is queued with the executor, and eventually the DsfQuery.execute() method is -called on the dispatch thread.
              6. -
              7. The query DsfQuery.execute() -calls synchronous and asynchronous methods that are needed to do its -job.
              8. -
              9. The query code calls DsfQuery.done() -method with the result.
              10. -
              11. The DsfQuery.get() -method un-blocks and returns the result to the client.
                -
              12. -
              -

              Slow -Data Provider Example

              -The point of DSF concurrency can be most easily explained through -a practical example.  Suppose there is a viewer which needs to -show data that originates from a remote "provider".  There is a -considerable delay in transmitting the data to and from the provider, -and some delay in processing the data.  The viewer is a -lazy-loading table, which means that it request information only about -items that are visible on the screen, and as the table is scrolled, new -requests for data are generated.  The diagram below illustrates -the -logical relationship between components:
              -
              -.
              -

              In detail, these components look like this:

              -

              -Table Viewer
              -

              The table viewer is the standard -org.eclipse.jface.viewers.TableViewer, -created with SWT.VIRTUAL -flag.  It has an associated content -provider, SlowDataProviderContentProvider) which handles all the -interactions with the data provider.  The lazy content provider -operates in a very simple cycle:

              -
                -
              1. Table viewer tells content provider that the input has changed by -calling IContentProvider.inputChanged().  -This means that the content provider has to query initial state of the -data.
              2. -
              3. Next the content provider tells the viewer how many elements -there are, by calling TableViewer.setItemCount().
              4. -
              5. At this point, the table resizes, and it requests data values for -items that are visible.  So for each visible item it calls: ILazyContentProvider.updateElement().
              6. -
              7. After calculating the value, the content provider tells the table -what the value is, by calling TableViewer.replace().
              8. -
              9. If the data ever changes, the content provider tells the table to -rerequest the data, by calling TableViewer.clear().
              10. -
              -Table viewer operates in the -SWT display thread, which means that the content provider must switch -from the display thread to the DSF dispatch thread, whenever it is -called by the table viewer, as in the example below:
              -
                  public void updateElement(final int index) {
              assert fTableViewer != null;
              if (fDataProvider == null) return;

              fDataProvider.getExecutor().execute(
              new Runnable() { public void run() {
              // Must check again, in case disposed while redispatching.
              if (fDataProvider == null) return;

              queryItemData(index);
              }});
              }
              -Likewise, when the content provider calls the table viewer, it also has -to switch back into the display thread as in following example, when -the content provider receives an event from the data provider, that an -item value has changed.
              -
                  public void dataChanged(final Set<Integer> indexes) {
              // Check for dispose.
              if (fDataProvider == null) return;

              // Clear changed items in table viewer.
              if (fTableViewer != null) {
              final TableViewer tableViewer = fTableViewer;
              tableViewer.getTable().getDisplay().asyncExec(
              new Runnable() { public void run() {
              // Check again if table wasn't disposed when
              // switching to the display thread.
              if (tableViewer.getTable().isDisposed()) return; // disposed
              for (Integer index : indexes) {
              tableViewer.clear(index);
              }
              }});
              }
              }
              -All of this switching back and forth between threads makes the code -look a lot more complicated than it really is, and it takes some -getting used to, but this is the price to be paid for multi-threading. -Whether the participants use semaphores or the dispatch thread, the -logic is equally complicated, and we believe that using a single -dispatch thread, makes the synchronization very explicit and thus less -error-prone.
              -

              Data Provider Service

              -

              The data provider service interface, DataProvider, is very similar -to that of the lazy content provider.  It has methods to:

              -
                -
              • get item count
              • -
              • get a value for given item
              • -
              • register as listener for changes in data count and data values
              • -
              -But this is a DSF interface, and all methods must be called on the -service's dispatch thread.  For this reason, the DataProvider interface returns -an instance of DsfExecutor, -which must be used with the interface.
              -

              Slow Data Provider

              -

              The data provider is actually implemented as a thread which is an -inner class of SlowDataProvider -service.  The provider thread -communicates with the service by reading Request objects from a shared -queue, and by posting Runnable objects directly to the DsfExecutor but -with a simulated transmission delay.  Separately, an additional -flag is also used to control the shutdown of the provider thread.

              -To simulate a real back end, the data provider randomly invalidates a -set of items and notifies the listeners to update themselves.  It -also periodically invalidates the whole table and forces the clients to -requery all items.
              -

              Data and Control Flow
              -

              -This can be described in following steps:
              -
                -
              1. The table viewer requests data for an item at a given index (SlowDataProviderContentProvider.updateElement).
                -
              2. -
              3. The table viewer's content provider executes a Runnable in the DSF -dispatch thread and calls the data provider interface (SlowDataProviderContentProvider.queryItemData).
              4. -
              5. Data provider service creates a Request object, and files it in a -queue (SlowDataProvider.getItem).
              6. -
              7. Data provider thread de-queues the Request object and acts on it, -calculating the value (ProviderThread.processItemRequest).
              8. -
              9. Data provider thread schedules the calculation result to be -posted with DSF executor (SlowDataProvider.java:185).
              10. -
              11. The Done callback sets the result data in the table viewer (SlowDataProviderContentProvider.java:167).
                -
              12. -
              -

              Running the example and full sources

              -This example is implemented in the org.eclipse.dd.dsf.examples -plugin, in the org.eclipse.dd.dsf.examples.concurrent -package. 
              -
              -To run the example:
              -
                -
              1. Build the test plugin (along with the org.eclipse.dsdp.DSF plugin) -and launch the PDE. 
                -
              2. -
              3. Make sure to add the DSF -Tests action set to your current perspective.
              4. -
              5. From the main menu, select DSF -Tests -> Slow Data Provider.
              6. -
              7. A dialog will open and after a delay it will populate with data.
              8. -
              9. Scroll and resize dialog and observe the update behavior.
              10. -
              -

              Initial Notes
              -

              -This example is supposed to be representative of a typical embedded -debugger design problem.  Embedded debuggers are often slow in -retrieving and processing data, and can sometimes be accessed through a -relatively slow data channel, such as serial port or JTAG -connection.  But as such, this basic example presents a couple -of major usability problems
              -
                -
              1. The data provider service interface mirrors the table's content -provider interface, in that it has a method to retrieve a single piece -of data at a time.  The result of this is visible to the user as -lines of data are filled in one-by-one in the table.  However, -most debugger back ends are in fact capable of retrieving data in -batches and are much more efficient at it than retrieving data items -one-by-one.
              2. -
              3. When scrolling quickly through the table, the requests are -generated by the table viewer for items which are quickly scrolled out -of view, but the service still queues them up and calculates them in -the order they were received.  As a result, it takes a very long -time for the table to be populated with data at the location where the -user is looking. 
                -
              4. -
              -These two problems are very common in creating UI for embedded -debugging, and there are common patterns which can be used to solve -these problems in DSF services.
              -

              Coalescing

              -Coalescing many single-item requests into fewer multi-item requests is -the surest way to improve performance in communication with a remote -debugger, although it's not necessarily the simplest.  There are -two basic patterns in which coalescing is achieved:
              -
                -
              1. The back end provides an interface for retrieving data in large -chunks.  So when the service implementation receives a request for -a single item, it retrieves a whole chunk of data, returns the single -item, and stores the rest of the data in a local cache.
              2. -
              3. The back end providers an interface for retrieving data in -variable size chunks.  When the service implementation receives a -request for a single item, it buffers the request, and waits for other -requests to come in.  After a delay, the service clears the buffer -and submits a request for the combined items to the data provider.
              4. -
              -In practice, a combination of the two patterns is needed, but for -purpose of an example, we implemented the second pattern in the -"Input-Coalescing Slow Data Provider" (InputCoalescingSlowDataProvider.java).  -
              -

              Input Buffer

              -

              The main feature of this pattern is a buffer for holding the -requests before sending them to the data provider.  In this -example the user requests are buffered in two arrays: fGetItemIndexesBuffer and fGetItemDonesBuffer.  The -DataProvider.getItem() -implementation is changed as follows:

              -
                  public void getItem(final int index, final GetDataDone<String> done) {
              // Schedule a buffer-servicing call, if one is needed.
              if (fGetItemIndexesBuffer.isEmpty()) {
              fExecutor.schedule(
              new Runnable() { public void run() {
              fileBufferedRequests();
              }},
              COALESCING_DELAY_TIME,
              TimeUnit.MILLISECONDS);
              }

              // Add the call data to the buffer.
              // Note: it doesn't matter that the items were added to the buffer
              // after the buffer-servicing request was scheduled. This is because
              // the buffers are guaranteed not to be modified until this dispatch
              // cycle is over.
              fGetItemIndexesBuffer.add(index);
              fGetItemDonesBuffer.add(done);
              }

              -And method that services the buffer looks like this:
              -
                  public void fileBufferedRequests() { 
              // Remove a number of getItem() calls from the buffer, and combine them
              // into a request.
              int numToCoalesce = Math.min(fGetItemIndexesBuffer.size(), COALESCING_COUNT_LIMIT);
              final ItemRequest request = new ItemRequest(new Integer[numToCoalesce], new GetDataDone[numToCoalesce]);
              for (int i = 0; i < numToCoalesce; i++) {
              request.fIndexes[i] = fGetItemIndexesBuffer.remove(0);
              request.fDones[i] = fGetItemDonesBuffer.remove(0);
              }

              // Queue the coalesced request, with the appropriate transmission delay.
              fQueue.add(request);

              // If there are still calls left in the buffer, execute another
              // buffer-servicing call, but without any delay.
              if (!fGetItemIndexesBuffer.isEmpty()) {
              fExecutor.execute(new Runnable() { public void run() {
              fileBufferedRequests();
              }});
              }
              }
              -The most interesting feature of this implementation is the fact that -there are no semaphores anywhere to control access to the input -buffers.  Even though the buffers are serviced with a delay and -multiple clients can call the getItem() -method, the use of a single -dispatch thread prevents any race conditions that could corrupt the -buffer data.  In real-world implementations, the buffers and -caches that need to be used are far more sophisticated with much more -complicated logic, and this is where managing access to them using the -dispatch thread is ever more important.
              -

              Cancellability

              -

              Table Viewer

              -

              -Unlike coalescing, which can be implemented entirely within the -service, cancellability requires that the client be modified as well -to take advantage of this capability.  For the table viewer -content provider, this means that additional features have to be -added.  In CancellingSlowDataProviderContentProvider.java -ILazyContentProvider.updateElement() -was changes as follows:
              -
                  public void updateElement(final int index) {
              assert fTableViewer != null;
              if (fDataProvider == null) return;

              // Calculate the visible index range.
              final int topIdx = fTableViewer.getTable().getTopIndex();
              final int botIdx = topIdx + getVisibleItemCount(topIdx);

              fCancelCallsPending.incrementAndGet();
              fDataProvider.getExecutor().execute(
              new Runnable() { public void run() {
              // Must check again, in case disposed while redispatching.
              if (fDataProvider == null || fTableViewer.getTable().isDisposed()) return;
              if (index >= topIdx && index <= botIdx) {
              queryItemData(index);
              }
              cancelStaleRequests(topIdx, botIdx);
              }});
              }
              -Now the client keeps track of the requests it made to the service in fItemDataDones, and above, cancelStaleRequests() iterates -through all the outstanding requests and cancels the ones that are no -longer in the visible range.
              -

              Data Provider Service

              -

              -

              The data provider implementation -(CancellableInputCoalescingSlowDataProvider.java), -builds on top of the -coalescing data provider.  To make the canceling feature useful, -the data provider service has to limit the size of the request -queue.  This is because in this example which simulates -communication with a target and once requests are filed into the -request -queue, they cannot be canceled, just like a client can't cancel -request once it sends them over a socket.  So instead, if a flood -of getItem() -calls comes in, the service has to hold most of them in the coalescing -buffer in case the client decides to cancel them.  Therefore the -fileBufferedRequests() -method includes a simple check before servicing -the buffer, and if the request queue is full, the buffer servicing call -is delayed.

              -
                      if (fQueue.size() >= REQUEST_QUEUE_SIZE_LIMIT) {
              if (fGetItemIndexesBuffer.isEmpty()) {
              fExecutor.schedule(
              new Runnable() { public void run() {
              fileBufferedRequests();
              }},
              REQUEST_BUFFER_FULL_RETRY_DELAY,
              TimeUnit.MILLISECONDS);
              }
              return;
              }
              -Beyond this change, the only other significant change is that before -the requests are queued, they are checked for cancellation.
              -

              Final Notes
              -

              -The example given here is fairly simplistic, and chances are that the -same example could be implemented using semaphores and free threading -with perhaps fewer lines of code.  But what we have found is that -as the problem gets bigger, the amount of -features in the data provider increases, the state of the -communication protocol gets more complicated, and the number of modules -needed in the service layer increases, using free threading and -semaphores does not safely scale.  Using a dispatch thread for -synchronization certainly doesn't make the inherent problems of the -system less complicated, but it does help eliminate the race conditions -and deadlocks from the overall system.
              -

              Coalescing and Cancellability are both optimizations.  Neither -of these optimizations affected the original interface of the service, -and one of them only needed a service-side modification.  But as -with all optimizations, it is often better to first make sure that the -whole system is working correctly and then add optimizations where they -can make the biggest difference in user experience. 

              -

              The above examples of optimizations can take many forms, and as -mentioned with coalescing, caching data that is retrieved from the data -provider is the most common form of data coalescing.  For -cancellation, many services in DSF build on top of other services, -which means that even a low-level service can cause a higher -level service to retrieve data, while another event might cause it to -cancel those requests.  The perfect example of this is a Variables -service, which is responsible for calculating the value of expressions -shown in the Variables view.  The Variables service reacts to the -Run Control service, which issues a suspended event and then requests a -set of variables to be evaluated by the debugger back end.  But as -soon as a resumed event is issued by Run Control, the Variables service -needs to cancel  the pending evaluation requests.
              -

              -
              -
              - - diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/dsf_data_model.html b/plugins/org.eclipse.dd.doc.dsf/docs/dsf_data_model.html deleted file mode 100644 index bd1b40112e6..00000000000 --- a/plugins/org.eclipse.dd.doc.dsf/docs/dsf_data_model.html +++ /dev/null @@ -1,286 +0,0 @@ - - - - - DSF Data Model - - -

              DSF Data Model

              -Version -1.0
              -Pawel Piech
              -© 2006, Wind River Systems.  Release -under EPL version 1.0.
              -

              Overview

              -

              The data model aspect of DSF is only partially complete as compared -to the Concurrency and Services Models.  The goals for its design -are:
              -

              -
                -
              1. Separate the structure of the -data in the services from the model used for presentation in views.  -This seems like a basic model-viewer separation, which is something -that we theoretically have already.  But in reality the current -platform debug model APIs closely correspond to how the data is -laid out in debug views, and even with the flexible hierarchy views it -is -difficult to provide alternative layouts.
              2. -
              3. Allow for a modular -implementation of services that contribute to the data model.   -
                -
              4. -
              5. Perform well with large -data sets.
              6. -
              7. Make the data model interfaces -convenient to use by other services as well as by views.  -Some interim designs of DSF data model APIs were very well suited for -populating views (though asynchronous) content and label provider, but -were very difficult to use for other purposes, such as by another -service, or a client that creates a dialog.  This led to services -implementing two sets of interfaces for the same data, which was more -expensive to develop and maintain.
                -
              8. -
              9. Allow for easy changes to the -layout of data in views.  This is from the point of view of -a debugger implementer that would like to modify the standard layout of -debugger data.
                -
              10. -
              11. Allow the users to modify the -layout of data in views.  And this is a logical extension -of the previous goal.
              12. -
              -

              -That's a pretty ambitious set of goals to keep in mind, which partly -explains why the design is not fully complete yet.  In particular, -the last goal doesn't have any implementation at this point.  But -other than that the, we believe that our current design mostly -meets the other goals.  It remains to be seen how well it will -hold up -beyond a prototype implementation.
              -

              The DSF data model is divided into two parts: a non-UI part that -helps services expose data in a consistent form, and a UI part that -helps viewers present the data.  They are described separately in -the two sections below.
              -

              -

              Timers Example

              -

              A "timers -example" is included with the DSF plugins which -demonstrates the use of data model and view model -APIs.   It is probably much easier to digest this document -when referring to this example for usage.
              -

              -

              Data Model API (org.eclipse.dd.dsf.model)
              -

              -As stated before, the aim of this API is to allow services to provide -data with just enough common information, so that it can be easily -presented in the view, but with a simple enough design, so that the -data can be accessed by non-viewer clients.  The type of data in -services can vary greatly from service to service, some data for -example:
              -
                -
              • service data might be extremely large and thus may only be -retrieved from a back end process in small chunks, while some service -data might be always stored locally in the service
                -
              • -
              • data might take a very long time to retrieve, or it could be -instantaneous
                -
              • -
              • some services might support canceling of the request while it is -being processed, while other services might not
                -
              • -
              • some data may change very frequently, other data may not change -at all
                -
              • -
              -The data model API tries to find a common denominator for these -divergent properties and imposes the following restrictions:
              -
                -
              1. Each "chunk" of data that comes from a service has a -corresponding IDataModelContext (Data Model Context) -object.
                -
              2. -
              3. The DM-Context objects are to be generated by the data model services (IDataModelService) with either -synchronous or asynchronous methods, and taking whatever arguments are -needed.  Put differently, how DM-Contexts are created is up to the -service.
              4. -
              5. The service will provide a method for retrieving each "chunk" of -model data (IDataModelData) -using a method that requires no other arguments besides the DM-Contexts.
              6. -
              -

              DM-Context (IMContext)
              -

              -The DM-Contexts are the most -important part of this design, so they warrant a closer look.  The -interface is listed below:
              -
                  public interface IDataModelContext<V extends IDataModelData> extends IAdaptable {
              public String getSessionId();
              public String getServiceFilter();
              public IDataModelContext[] getParents();
              }
              -First of all the object extends IAdaptable, -which allows clients to use these objects as handles that are stored -with UI components.  However the implementation of IDataModelData.getAdapter()  -presents a particular challenge.  If the standard platform method -of retrieving an adapter is used (PlatformObject.getAdapter()), -then there can only be one adapter registered for a given DM-Context class, -which has to be shared by all the DSF sessions that are running -concurrently.  Thus one debugger that implements a IStack.IFrameDMContext, would have to -have the same instance of -IAsynchronousLabelAdapter as another debugger implementation -that is running at the same time.  To overcome this problem, DSF -provides a method for registering adapters with a session using DsfSession.registerModelAdapter(), -instead of with the platform (Platform.getAdapterManager().registerAdapters()).  -
              -

              The getSessionId() -method serves two purposes.  First, it allows the -IAdapter.getAdapter() -implementation to work as described above. Second, it allows clients to -access the correct dispatch thread (DsfSession.getSession(id).getExecutor()) -for calling the service that the DM-Context originated from. 
              -

              -

              The getServiceFilter() -method is actually included to allow future development.  It is -intended to allow the client to precisely identify the service that -the DM-Context originated from, without having to examine the exact class type -of the DM-Context.  But this functionality will not really be needed -until we start writing generic/data-driven clients.
              -

              -

              The getParents() -method allows the DM-Context to be connected together into something that can -be considered a "model".  Of course, most debugger data objects, -require the context of other objects in order to make sense: stack -frame is meaningless without the thread, debug symbols belong to a -module, which belongs to a process, etc.  In other words, there is -some natural hierarchy to the data in debug services which needs to be -accessible through the data model APIs.  This hierarchy may be the -same hierarchy that is to be shown in some debug views, but it doesn't -have to be.  More importantly, this hierarchy should allow for a -clean separation of debug services, and for a clear dependency graph -between these services.

              -

              View Model API (org.eclipse.dd.dsf.ui.model)
              -

              -This is the component which allows the DSF data model to be presented -in -the views with different/configurable layouts.  It is tightly -integrated with the recently added (and still provisional) -flexible-hierarchy viewers in the org.eclipse.debug.ui -plugin (see EclipseCon 2006 presentation -for more details).  Actually, the platform flexible hierarchy -framework already provides all the adapter interfaces needed to present -the DSF data model in the viewers, and it is possible to do -that.  However the flexible hierarchy views were not specifically -designed for DSF, and there are a few ugly patterns that emerge when -using them with DSF data model interfaces directly:
              -
                -
              • Because of the nature of IAdaptable pattern, the flexible -hierarchy label and content adapters have to have a single instance -that works for all views that the objects appear in.  This leads -to a lot of if-else statements, which make the implementation difficult -to follow.
                -
              • -
              • There is a single adapter for all DSF data model elements in the -tree (from the same session), so the adapters have even more if-else -statements to handle the different elements in the viewer.
              • -
              • Most of DSF adapter work needs to be performed in the dispatch -thread, so each handler starts with a re-dispatch call.
              • -
              • In all of this, the logic which determines the hierarchy of -elements in the viewer is very hard to follow.
              • -
              -The view model API tries to address these issues in the following way:
              -
                -
              1. It divides the adapter work for different views in separate ViewModelProvider objects.
              2. -
              3. It defines the view layout in an object-oriented manner using the - IViewModelLayoutNode -objects.
              4. -
              5. It consolidates the logic of switching to dispatch thread in one -place, and allows the ViewModelProvider -objects to work only in dispatch thread.
                -
              6. -
              -

              IViewModelLayoutNode

              -The core of the logic in this design lies in the implementation of the IViewModelLayoutNode objects. -This interface is listed below:
              -
              public interface IViewModelLayoutNode {
              public IViewModelLayoutNode[] getChildNodes();
              public void hasElements(IViewModelContext parentVmc, GetDataDone<Boolean> done);
              public void getElements(final IViewModelContext parentVmc, GetDataDone<IViewModelContext[]> done);
              public void retrieveLabel(IViewModelContext vmc, final ILabelRequestMonitor result);
              public boolean hasDeltaFlags(IDataModelEvent e);
              public void buildDelta(IDataModelEvent e, ViewModelDelta parent, Done done);
              public void sessionDispose();
              }
              -The getChildNodes() -method allows these layout nodes to be combined into a tree structure, -which mimics the layout of elements in the view.  What the -children are depends on the implementation, some may be configurable -and -some may be fixed.
              -
              -The hasElements() -and getElements() -methods generate the actual elements that will appear in the -view.  The methods are analogous to the flexible hierarchy API -methods: IAsynchronousContentAdapter.isContainer() -and IAsynchronousContentAdapter.retrieveChildren() -and are pretty straightforward to implement. Also retrieveLabel() -is directly analogous to -IAsynchronousLabelAdapter.retrieveLabel(). 
              -
              -The hasDeltaFlags() -and buildDelta() -are used to generate model deltas in response to service events. These -are discussed in the next section.
              -
              -Finally, in most cases the elements in the views correspond -directly to an IDataModelContext -(DM-Context) objects of a specific type.  In those cases, the DMContextVMLayoutNode -abstract class implements the common functionality in that pattern.
              -

              Model deltas

              -The hasDeltaFlags() and buildDelta() methods are used -to implement the IModelProxy adapter, -and are the most tricky aspect of this design.  The difficulty is -that the flexible hierarchy views require that the IModelProxy translate data -model-specific events, into generic model deltas that can be -interpreted by the viewer.  The deltas (IModelDelta) are tree -structures which are supposed to mirror the structure of nodes in the -tree, and which contain flags that tell the viewer what has changed in -the view and how.*  This means that if the -model proxy receives an event for some IDataModelContext (DM-Context) object, -it needs to know if this object is in the viewer's tree, and what is -the full path (or paths) that leads to this object. 
              -

              The model delta is generated by first calling the top layout node's hasDeltaFlags() with the -received event, which then can either return true or ask any of its -children if they have deltas (which in turn returns true or calls its -children, etc).  If a node returns true for hasDeltaFlags(), then the -asynchronous buildDelta() -is called with the event and a parent delta node, to generate the delta -elements and flags for its node.  Once the layout node generates -its delta objects, it still needs to call its children, which in turn -add their delta information, and so on.
              -

              -

              * It's not strictly true that a full path to -an element always has to be present for model delta's to work.  If -the full path is not present, the viewer will try to find the element -using an internal map that it keeps of all of the elements it -knows.  -But since the viewer is lazy loading, it is possible (and likely) that -the element affected by an event is not even known to the viewer at -time of the event, and for some delta actions, IModelDelta.SELECT and IModelDelta.EXPAND, this is not -acceptable.
              -

              - - diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/dsf_mi_instructions.html b/plugins/org.eclipse.dd.doc.dsf/docs/dsf_mi_instructions.html deleted file mode 100644 index 7d6e2b51153..00000000000 --- a/plugins/org.eclipse.dd.doc.dsf/docs/dsf_mi_instructions.html +++ /dev/null @@ -1,135 +0,0 @@ - - - - - GDB/MI Debugger on top of DSF - Instructions - - -

              GDB/MI Debugger implementation based on DSF

              -
              -
              -

              Buiding and Running Instructions
              -

              -

              To build:

              -
                -
              1. Install the latest milestone of Eclipse 3.3 SDK
              2. -
              3. Install the latest milestone of CDT 4.0
              4. -
              5. Install and configure gdb (cygwin on windows)
              6. -
              7. Check out following projects from - /cvsroot/dsdp/org.eclipse.dd.dsf/plugins -
              8. -
                  -
                • org.eclipse.dd.dsf
                • -
                • org.eclipse.dd.dsf.ui
                • -
                • org.eclipse.dd.dsf.debug
                • -
                • org.eclipse.dd.dsf.debug.ui
                • -
                • org.eclipse.dd.dsf.mi.core
                • -
                • org.eclipse.dd.dsf.mi.ui.
                • -
                -
              -

              To run:

              -
                -
              1. Create a new "Managed make build project" called "hello".
              2. -
              3. Create a simple hello.c source file:
              4. -
              -
              -
              #include <stdio.h>
              int main(void) {
              printf("Hello world");
              }
              -
              -
                -
              1. Build the project.
                -
              2. -
              3. Create a new "DSF C/C++ Local Application"  launch -configuration (one with the pink icon) and set the executable and entry -point to "main"
                -
              4. -
              5. Launch and step through.
              6. -
              7. If the "source not found" page appears, the a path mapping needs -to be created.  This is an issue with latest cygwin gdb.
                -
              8. -
                  -
                1. Click on the "Edit source lookup" button in the editor, or -right click on the launch node in Debug View and select "Edit source -lookup"
                2. -
                3. Click on the "Add..." button
                4. -
                5. Select "Path Mapping" and click OK.
                  -
                6. -
                7. Select the new "Path Mapping" source container and click the -"Edit..." button.
                8. -
                9. Once again, click the "Add..." button to create a mapping.
                10. -
                11. Enter the path to map from.  Look at the stack frame label -in Debug view, if the filename is something like -"/cygdrive/c/workspace/hello/hello.c", enter the path to the first real -directory "/cygdrive/c/workspace".
                12. -
                13. Enter the correct path to the directory entered above, in the -file system.  In example above, it would be "C:\workspace".
                14. -
                15. Click OK three times and you'll be back in Kansas.... ehm Debug -view that is.
                16. -
                17. If the source doesn't show up right away, try stepping once.
                18. -
                -
              -
              -

              Supported Platforms
              -

              -Currently only Windows with cygwin GDB is supported. -
              -
              -
              -

              Current Features
              -

              -
                -
              • Launching
              • -
                  -
                • The "DSF C/C++Local Application" is the standard CDT launch -configuration minus some of the features. 
                  -
                • -
                • What is NOT working here is
                  -
                • -
                    -
                  • Debugger tab: the selection of debugger back ends (gdb/mi, -Cygwin gdb debugger, etc.), tThe implementation is currently hard-wired -for Cygwin,
                  • -
                  • Debugger tab: Debugger Options section
                  • -
                  -
                -
              • Debug view
              • -
                  -
                • Single thread debugging only.
                • -
                • Terminating
                  -
                • -
                • Stepping
                  -
                • -
                • Resume/Suspend
                  -
                • -
                -
              • Console support
                -
              • -
                  -
                • GDB process output
                • -
                • NO user process console support
                  -
                • -
                -
              • Breakpoints
              • -
                  -
                • Basic CDT breakpoint support implemented
                • -
                    -
                  • no filtering support,
                    -
                  • -
                  • no advanced options (hardware, temporary, etc)
                  • -
                  • no watchpoints
                    -
                  • -
                  -
                -
              • Variables
              • -
                  -
                • not yet
                  -
                • -
                -
              -
              -
              Updated Aug 25th, 2006
              -
              - - diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/dsf_services_model-1.png b/plugins/org.eclipse.dd.doc.dsf/docs/dsf_services_model-1.png deleted file mode 100644 index b593371ee805527e885bd02a05399a15d30ac5a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2224 zcma)8eK^x=A0O%{VqH#NuF211tK@hqHpkoYHb&M&N%Bq^c}rWgmA4!=!dgXC^7c?V zNwkPfIu#QSerpO7t7leQ4vyJjdC9ZhuIK8X=X(D5e!lnpxv%@Wzu)WnUZ2mMw;zwy zP=l#KAP@~NPmCV~q6{ixtFnrMss1_nu_7rE{jjde&X3c&6q}9vaR=QMd3=0)ZEcOV z14jQ$p70DLLLllte-0(c)$4i?$OdOGjLX5({OR#O@Iw17KZQrt`%V5my(dz;{ARe$ zeM^LNkMALbQx4~Mgp=q&h#C`QW+CUiGU)4Qq>Io+na@tUJT+yiGAyPt>!%+9$Ubxo zx}?>Sa2{}0(LjRVfw@68^Jfx#>?Aj1;L{D&ZwCU8`yX(joqdKK1!XPiP*JNnV*@Fv zy|Qhp5Ydk^ebrS{o}2}Xo@GDSqgRbw>>6Z3^S9_%a52w3)?FfQP==3L%S|^k zD2H2qLindPJ@i5q=Y{o*ww=y9^GuVK{H;Qr-*i6Sm2l;&m)17@x2hjjjp`k~YxUz# zc}FX3h?T8c1WJxrH_sANIm>oDMAIn);9O6-1GaG&dNbJ>fzI@pG*SQsQrL6pD&X*- zn3`?^K|gYgcJV0(Zfn!hFO~wG+o~(BV8i^oRD@LrWgPSJqKw)Sjvyc!ULZF@olH7A$|?_6B_Ik!idZoJ7hOMCRc zajdhx(5`OA;IQ#-QO#4JJT!+~XD64&@q>EBZsfnr`=XkAtUa34dTaa6?tlM*e;FW? zFFZy^ri&teEvjKZ;mQr>2Dqj;CZ=ME==FU8ko-Q***I`;yf71yB zOfjv_f>bgM2W5!06g>4fUuh9xaH-QG__HBy)j zS3BZLxv)K-=WWzaTH#oMHZ@UXIZekGz{eS?KZ_-dkP0Ksjil1>JS-W8CENC@ET#9> zglq|MoqVesgqipS?COZi?;I)FLRPPIFX5Zt!6{p2hxj7S@6us3c<4et3+A}TMOnJhw)~Lf;`vmBz9@mf4x9kbH4uxwTt;Qzh)|J5?Pi#zx}5yvul=y+qh#{@>aPz1vJR2Tu2 zNiQ?S6L2Vl+T%89B;8D=v1cnQa<2iM_Nx&WP~Pqnu4cz*Nz=GSg;%rw`5U#I z1(7nv8isbGu;X(Hkw{7jFs3e^K1@C()1NGa7 zwND;Pya*f>3}5^BiH8fSNWbvf+MytQ_6|C}xmv%>BMaZ&7@yZHN zRsLRuuUSnbBzUlBHm$A>t5;sE2Aw+lK+k`Zr+X9q-a;Cjx<}AZ0X1~^>S8BYW8Q6;Of-* zg-i~TCB9i{;-((8U3^o|&G>0xNIz{>-F`m&tBuTRj{Dc2X%VDO05#=@VzciETAm>b zqF00hj%AfP z_@VnAmyi18)Vt6k$AEg~ld~Hk$qu@CF@$Xc$Rc#+7Y8rN{_KxtDnB^-4Ol}j5LUBZ g;|H5xS{7y)nhbBn-kA^o{=cytjBXo<(sU`1*Z&!C~In}D#Xz%h1_Eh=N(NU#R`Mx~McrJL% z8<`9M=o-zL8ld>bG5|mm?c)Ip#_}YBXNlMSjGsu=OxEl(*>Mnb;J`CP^qM1sCP8{r znGMuBosPqg5t9qcuZRp5n*$$RSC)gEFt3KC$@&4tebmTTyNIw%O+7O(iu2QpG^9A} zS>mrC5^iZV5c=b~5h+2#417+jc)Nx_1(tV+6Ke)0X!=h9zCmv;zA}Td=;xt{f7`L7aM~3ftJ{P#Hg2^e7l(@P3`vd6YQJ}+KQjf#q7(C0 z@yzzi&l3}*wx!@Fm6-dr56xeK$f3gzgb{j@j|~M@I(#x$|EAC3kk(5B3*x`@BI&<5 z=f_SQ?G?BfP5BO$9FqSzwlS6=4euMX@F7idJU3`cf<9Q#D6qJ()3>baeD=6aI3wJ} zjec<jPkCso2Oh*iAF{p{fRBrPESNcBKwwm4#?Z^cPU{rGE#gnI*z1~7!dROHCjn7*c^ z36)sWs0BVNdco2{DR`m~4fGB|AekLFEl6No{RLT43=n7x=@ZWBIbPY#Z2ZpFumS+2(aQ z`bYUhC=VGY;|7$V$&GnXl(F1oq4XCj12b*x;S#A?U%jD|sCE|M3s&ZXtFp?VxrVZI1v$X!FS!(eIH3KrXoRQ3fa#UH2C<+LtiOO%e`9Id}5w1ZKb^omvKU-5(PD>H1kLN)o_(xRep z3fG$S(UU~BUh>AWt6jaT6^z=vEyFNJd9l=J)-sHdDVoxvTg+a|XsTN5hD%qyoTeaD zJgQ2Uo75C!FO#>ercC$k`IAqd)cK{$ zJP5tbYiVyQDR-&9ZO^CmraQeHy~rs}rp$L;u6bb`n$T80X4ys-(AP<#4upLYuOFK5 z-a>Y8F=b}gfR2j26uDUXGpy{O1A=wQT0cb`<-QzZeQsIbeH`r`Rn%q2meg5h>|K(! zflHk3m=9Lf0kdVvbR^gP1$>rl@4w*GYb5M{ny6}-@f#Y)(RcWxu55s#D(1h+49iL}0{dHIXiJYrM)Vp$7$k;>~} zAZMN2)bo}xt2EQ%Z#eg6rD zUtnN>=8yAgUC)N>+&KegmZsX%<3V&>A-dnmYs>gZr|%SZJWF4YY+hgcPCw~PD*6s< zvMhXJ9ws!TX7JMv*Ud90M8%PaX@>K0xH!sRB%FVGc;L0~>>)M+!3Yy-3$XO=*BhDo zF3gGd!MKYd76N*Y3uneYjM27EQd|p%f=Kf8zT@I3iGY)PNTSK9uNKd^+Sy~MgLw2q z?VRvIo8YqGJ5@PhC2J8hRvqDe>n%t+nqbd67uS`|a{5;HQwwC4&G8U9;2(l7v+JrU m7HB~|*r(6@=O9qB#n7yhy{R`8i3O^O1n}_;@Tk}xo$(jIq)#UR diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/dsf_services_model.html b/plugins/org.eclipse.dd.doc.dsf/docs/dsf_services_model.html deleted file mode 100644 index 8380a0e4ae3..00000000000 --- a/plugins/org.eclipse.dd.doc.dsf/docs/dsf_services_model.html +++ /dev/null @@ -1,363 +0,0 @@ - - - - - DSF Services Model - - -

              DSF Services Model

              -
              -Version -1.0
              -Pawel Piech
              -
              © 2006, -Wind River Systems.  Release under EPL -version 1.0.
              -
              -

              Debugger Services Framework (DSF) is primarily a service framework -defining rules for how -services should be registered, discovered, organized into functional -groups, communicated with, and started/ended.  These rules help to -organize the services into a functional system that efficiently -abstracts various debugger back end capabilities. 

              -

              DSF services build on top of the OSGI services framework, so -it's important to understand OSGI services before looking at DSF -itself.  For an overview of OSGI including services, see the presentation -on OSGI from EclipseCon 2006.  For detailed information, see -OSGI javadocs, primarily: org.osgi.frameworkServiceRegistration, -BundleContext, ServiceReference, Filter, and ServiceTracker. -

              -

              Services
              -

              -In OSGI any class can be registered as a service.  In DSF, -Services must implement the IDsfService  -interface, which requires that the service -provide:
              -
                -
              1. Access to the DsfExecutor that -has to be used to access service methods.
              2. -
              3. Full list of properties used to uniquely identify the service in -OSGI.
              4. -
              5. Startup and shutdown methods.
              6. -
              -For the first two items, a service must use the data it received from -its constructor.  For the third item, a service must register and -unregister itself with OSGI.  But beyond that, this is all that -services have in common, everything else is up to the specific service -interface.
              -

              Sessions (org.eclipse.dd.dsf.service.DsfSession)
              -

              -DSF services are organized into logical groups, called -sessions.  Sessions are only necessary because we want multiple -instances of systems built with DSF services to run at the same -time  This is because there is only a single OSGI service -registry, so if multiple services are registered with a given class -name, OSGI will not be able to distinguish between the two based on the -class name alone.  So there is an additional property which is -used by every DSF service when registering with OSGI, IDsfService.PROP_SESSION_ID.  -
              -

              A Session object -(TODO: link javadoc) has the following data associated with it:
              -

              -
                -
              • Session ID - A String object that is unique -among all other sessions.  Its ID is used by services as the IDsfService.PROP_SESSION_ID -property, and it is used by the client to obtain the Session object instance.
              • -
              • DsfExecutor -- Each session has a single executor.  This means that all the -services in a single session share the same executor and dispatch -thread, and conversely it means that when operating in the dispatch -thread, the state of all the services in a session will remain the same -until the end of a dispatch.  Note: multiple sessions could share the same DsfExecutor.
              • -
              • Service startup counter -- An integer counter which is read and incremented by every service -that is started in a session.  This counter is used to determine -the dependency order among services, which is used by events.
              • -
              • Event listener list -- This will be covered in the "Events" section.
              • -
              • Adapter list - A -list of adapters, providing functionality analogous to runtime's org.eclipse.core.internal.runtime.AdapterManager.  -Sessions need to manage their own lists of adapters, so that IAdapter objects which -originate from DSF services can provider different adapters, based -on the session that they originate from.  This feature is covered -in detail in the "DSF Data Model" document.
                -
              • -
              -

              The Session class also has a number of static features used to -manage Session objects:

              -
                -
              • Session ID counter -- Used to generate new session IDs.
              • -
              • Methods for starting -and ending sessions
                -
              • -
              • Session started/ended -event listener list - This allows clients to be notified when -sessions are created or terminated, which is used mostly for clean-up -purposes.
                -
              • -
              -

              Startup/Shutdown

              -Managing the startup and shutdown process is often the most complicated -aspect of modular systems.  The details of how the startup and -shutdown processes should be performed are also highly dependent on the -specifics of the system and service implementations.  To help -with this, DSF provides two simple guidelines:
              -
                -
              1. There should be a clear -dependency tree of all services within a session - When the -dependencies between services are clearly defined, it is possible to -bring-up and bring-down the services in an order that guarantees each -running service can access all of the services that it depends on.
              2. -
              3. There needs to be a -single point of control, which brings up and shuts down all the -services. - In other words, services should not initialize or -shut-down themselves, based on some global event that they are all -listening to.  But rather an external piece of logic needs to be -in charge of performing this operation.
              4. -
              -The main implication of the first guideline, is that each service can -get and hold onto references to other services, without having to -repeatedly check, whether the service references are still valid.  -This is because if a given service is to be shut-down, all services -that depend on this service will already have been shut down.  The -second guideline, simply ensures that startup and shutdown procedures -are clear and easy to follow.
              -

              org.eclipse.dd.dsf.service.DsfServicesTracker -vs org.osgi.util.tracker.ServiceTracker

              -OSGI methods for obtaining and tracking services can be rather -complicated.  To obtain a reference to a service, the client has -to:
              -
                -
              1. Get a reference to a BundleContext - object, which can be retrieved from the plugin class.
              2. -
              3. Obtain a service reference object by calling BundleContext.getServiceReference();
              4. -
              5. Obtain an instance of the service by calling BundleContext.getService(ServiceReference).
              6. -
              -But worst of all, when the client is finished using the service, it has -to call BundleContext.ungetService(ServiceReference), -because the bundle context counts the used references to a given -service.  All this paperwork is useful for services which manage -their own life-cycle, and could be un-registered at any time.  To -make managing references to these kinds of services, OSGI provides a -utility class, called ServiceTracker.  -
              -

              For DSF services, the life cycle of the services is much more -predictable, but the process of obtaining a reference to a service is -just as onerous.  DSF provides its own utility, which is -separate from the ServiceTracker, -named DsfServicesTracker.  -The differences between the two are listed in table below:
              -

              - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
              Property
              -
              OSGI - ServiceTracker
              -
              DSF - DsfServicesTracker
              -
              Number -of services tracked
              -
              While -not strictly limited, it is optimized for tracking services of a single -class type, or more typically to track a single service reference.
              -
              Designed -to track services within a single DSF session. 
              -
              When -are service references obtained
              -
              Obtain -references automatically as the services register themselves.
              -
              Service -references are obtained as requested by the client, and cached.
              Synchronization
              -
              Multi-thread -accessible. 
              -
              Can -be accessed only on the session's dispatch thread.
              -
              Clean-up
              -
              Automatically -un-gets references for services that are shut down.
              -
              Client -must listen to session events, and clean up as needed.
              -
              -

              Both trackers are useful.  Service implementations that depend -on a number of other services are most likely to use DSF ServicesTracker, while some -clients, which use a single service may find OSGI ServiceTracker more suitable.
              -

              -

              Events

              -Events are the most un-conventional component of the services package -and probably most likely to need modifications to the design by the -community.  The design goal of -the event system is to allow a hierarchy of event classes, where a -listener could register itself for a specific event class or for all -events which derive from a base class.  The use case for this -behavior is in the data model, where we would like to have the ability -to capture all model-related events with a generic listener while at -the same time allowing for services to fully use class types. 
              -

              The event model is made up of the following components:
              -

              -
                -
              • DsfServiceEventHandler annotation -- This is the only indicator that a given method is an event -listener.  The class with the event handler doesn't have to -implement any interfaces, but it must be public, which is a big -drawback.
              • -
              • Session.addServiceEventListener, - Session.removeServiceEventListener -methods - These methods allow clients to register for an event -based on an event class and a service filter, where the filter can be -used to uniquely identify a service in case of services with multiple -instances of same class.
              • -
              • Session.dispatchEvent method - -This is the method that actually dispatches the event to the -listeners.  -The method must be called by a service that generates the event.
              • -
              -There are only a few more notes about the events mechanism:
              -
                -
              1. The event is always dispatched in its own Runnable submitted to -the session's DsfExecutor.
              2. -
              3. There is a slight convenience for clients not to have to register -for each type of event separately.
              4. -
              5. There is a slight inconvenience for clients, because anonymous -classes cannot be used as listeners, due to the public class -requirement.
              6. -
              -

              Debugger Services (org.eclipse.dd.dsf.debug)
              -

              -DSF framework includes a set of service interfaces for a typical -debugger implementation.  Functionally, they are pretty much -equivalent to the platform debug interfaces, but they are structured in -a way that allows a debugger to implement only some of them.  In -order for the startup and shutdown process to work effectively, the -dependencies between services need to be clearly defined.  The -dependencies between the main service interfaces are shown in the graph -below:
              -
              -

              It's also important to realize that it's unlikely that a single -hierarchy of interfaces will adequately fit all the various debugger -use cases, and it is likely that some interfaces will be needed which -partially duplicate functionality found in other interfaces.  -An example of this in the proposed interface set are the interfaces -which are used to initiate a debugging session.  The INativeProcesses service is -intended as the simple abstraction for native debuggers, where a -debugger only needs an existing host process ID or an executable image -name.  Based on this a INativeProcess -debugger implementation should be able to initiate a debugging session, -and return run-control, memory, and symbol contexts that are required -to carry out debugging operations.  By comparison, IOS and ITarget are generic interfaces -which allow clients to manage multiple target definitions, to -examine a wide array of OS objects, and to attach a debugger to a -process or some other debuggable entity. 
              -
              -

              -

              Disclaimer

              -Drafting large APIs that are intended to have many implementations and -by clients is a notoriously difficult task.  It is -impossible to expect that a first draft of such interfaces will not -require changes, and only time and multiple successful implementation -can validate them.  While we can draw upon many examples of -debugger -APIs in Eclipse in and our commercial debugger, this is a new API with -a -prototype that exercises only a small portion of its interfaces.
              -
              -
              -
              -
              -
              -
              -
              -
              -
              -
              - - diff --git a/plugins/org.eclipse.dd.doc.dsf/toc.xml b/plugins/org.eclipse.dd.doc.dsf/toc.xml index cdda79bb01c..0c117d28640 100644 --- a/plugins/org.eclipse.dd.doc.dsf/toc.xml +++ b/plugins/org.eclipse.dd.doc.dsf/toc.xml @@ -4,12 +4,14 @@ - - - - - - - + + + + + + + + + From 508a4a90b34f91b5a881238ed1dcbfcf2accb480 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Mon, 24 Mar 2008 20:00:43 +0000 Subject: [PATCH 321/834] Splitting the LaunchSequence into ServicesLaunchSequence and FinalLaunchSequence, as discussed in Bug 221505 comment #7 --- ...Sequence.java => FinalLaunchSequence.java} | 159 +++++------------- .../launch/launching/GdbLaunchDelegate.java | 21 ++- .../launching/ServicesLaunchSequence.java | 157 +++++++++++++++++ 3 files changed, 211 insertions(+), 126 deletions(-) rename plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/{LaunchSequence.java => FinalLaunchSequence.java} (63%) create mode 100644 plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/ServicesLaunchSequence.java diff --git a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/LaunchSequence.java b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/FinalLaunchSequence.java similarity index 63% rename from plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/LaunchSequence.java rename to plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/FinalLaunchSequence.java index 8575b06d410..321305a15a2 100644 --- a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/LaunchSequence.java +++ b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/FinalLaunchSequence.java @@ -1,45 +1,33 @@ /******************************************************************************* - * Copyright (c) 2006 Wind River Systems and others. + * Copyright (c) 2008 Ericsson 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 + * Ericsson - initial API and implementation *******************************************************************************/ package org.eclipse.dd.gdb.launch.launching; -import org.eclipse.cdt.debug.core.CDebugCorePlugin; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector; import org.eclipse.cdt.debug.mi.core.IGDBServerMILaunchConfigurationConstants; -import org.eclipse.cdt.debug.mi.core.IMILaunchConfigurationConstants; import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.concurrent.Sequence; -import org.eclipse.dd.dsf.debug.service.StepQueueManager; import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; -import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.gdb.launch.internal.GdbLaunchPlugin; -import org.eclipse.dd.gdb.service.GDBRunControl; import org.eclipse.dd.gdb.service.command.GDBControl; import org.eclipse.dd.gdb.service.command.GDBControl.SessionType; import org.eclipse.dd.mi.service.CSourceLookup; -import org.eclipse.dd.mi.service.ExpressionService; -import org.eclipse.dd.mi.service.MIBreakpoints; import org.eclipse.dd.mi.service.MIBreakpointsManager; -import org.eclipse.dd.mi.service.MIDisassembly; -import org.eclipse.dd.mi.service.MIMemory; -import org.eclipse.dd.mi.service.MIModules; -import org.eclipse.dd.mi.service.MIRegisters; -import org.eclipse.dd.mi.service.MIStack; import org.eclipse.dd.mi.service.command.commands.MIBreakInsert; import org.eclipse.dd.mi.service.command.commands.MICommand; import org.eclipse.dd.mi.service.command.commands.MIExecContinue; @@ -49,98 +37,36 @@ import org.eclipse.dd.mi.service.command.output.MIBreakInsertInfo; import org.eclipse.dd.mi.service.command.output.MIInfo; import org.eclipse.debug.core.DebugException; -public class LaunchSequence extends Sequence { +public class FinalLaunchSequence extends Sequence { Step[] fSteps = new Step[] { - // Create and initialize the Connection service. - new Step() { - @Override - public void execute(RequestMonitor requestMonitor) { - String debugMode = ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN; - try { - debugMode = fLaunch.getLaunchConfiguration().getAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, - ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN ); - } catch (CoreException e) { - } + /* + * Fetch the control service for later use + */ + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + DsfServicesTracker tracker = new DsfServicesTracker(GdbLaunchPlugin.getBundleContext(), fLaunch.getSession().getId()); + fCommandControl = tracker.getService(GDBControl.class); + tracker.dispose(); - if (debugMode.equals(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN)) { - fSessionType = SessionType.RUN; - } else if (debugMode.equals(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_ATTACH)) { - fSessionType = SessionType.ATTACH; - } else if (debugMode.equals(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_CORE)) { - fSessionType = SessionType.CORE; - } else if (debugMode.equals(IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE)) { - fSessionType = SessionType.REMOTE; - } else { - fSessionType = SessionType.RUN; - } + requestMonitor.done(); + }}, + /* + * Setup the source paths + */ + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + DsfServicesTracker tracker = new DsfServicesTracker(GdbLaunchPlugin.getBundleContext(), fLaunch.getSession().getId()); + CSourceLookup sourceLookup = tracker.getService(CSourceLookup.class); + tracker.dispose(); - // - // Create the connection. - // - fCommandControl = new GDBControl(fSession, getGDBPath(), fExecPath, fSessionType, 30); - fCommandControl.initialize(requestMonitor); - } - }, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - new GDBRunControl(fSession).initialize(requestMonitor); + CSourceLookupDirector locator = (CSourceLookupDirector)fLaunch.getSourceLocator(); + sourceLookup.setSourceLookupPath(fCommandControl.getGDBDMContext(), + locator.getSourceContainers(), requestMonitor); }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - new StepQueueManager(fSession).initialize(requestMonitor); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - new MIMemory(fSession).initialize(requestMonitor); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - new MIModules(fSession).initialize(requestMonitor); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - new MIStack(fSession).initialize(requestMonitor); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - new ExpressionService(fSession).initialize(requestMonitor); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - fSourceLookup = new CSourceLookup(fSession); - fSourceLookup.initialize(requestMonitor); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - CSourceLookupDirector locator = (CSourceLookupDirector)fLaunch.getSourceLocator(); - - fSourceLookup.setSourceLookupDirector(fCommandControl.getGDBDMContext(), locator); - fSourceLookup.setSourceLookupPath(fCommandControl.getGDBDMContext(), - locator.getSourceContainers(), requestMonitor); - }}, - new Step() { @Override - public void execute(final RequestMonitor requestMonitor) { - // Create the low-level breakpoint service - final MIBreakpoints bpService = new MIBreakpoints(fSession); - bpService.initialize(new RequestMonitor(getExecutor(), requestMonitor)); - }}, - new Step() { @Override - public void execute(final RequestMonitor requestMonitor) { - // Create high-level breakpoint service and install breakpoints - // for the GDB debug context. - fBpmService = new MIBreakpointsManager(fSession, CDebugCorePlugin.PLUGIN_ID); - fBpmService.initialize(new RequestMonitor(getExecutor(), requestMonitor)); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - new MIRegisters(fSession).initialize(requestMonitor); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - new MIDisassembly(fSession).initialize(requestMonitor); - }}, - /* If remote debugging, connect to target */ + /* + * If remote debugging, connect to target + */ new Step() { private boolean fTcpConnection; private String fRemoteTcpHost; @@ -228,7 +154,10 @@ public class LaunchSequence extends Sequence { */ new Step() { @Override public void execute(final RequestMonitor requestMonitor) { - fBpmService.startTrackingBreakpoints(fCommandControl.getGDBDMContext(), requestMonitor); + DsfServicesTracker tracker = new DsfServicesTracker(GdbLaunchPlugin.getBundleContext(), fLaunch.getSession().getId()); + MIBreakpointsManager bpmService = tracker.getService(MIBreakpointsManager.class); + tracker.dispose(); + bpmService.startTrackingBreakpoints(fCommandControl.getGDBDMContext(), requestMonitor); }}, /* * If needed, insert breakpoint at main and run to it. @@ -298,34 +227,22 @@ public class LaunchSequence extends Sequence { }, }; - DsfSession fSession; GdbLaunch fLaunch; - IPath fExecPath; SessionType fSessionType; GDBControl fCommandControl; - CSourceLookup fSourceLookup; - MIBreakpointsManager fBpmService; - public LaunchSequence(DsfSession session, GdbLaunch launch, IPath execPath) { - super(session.getExecutor()); - fSession = session; + public FinalLaunchSequence(DsfExecutor executor, GdbLaunch launch, SessionType type) { + super(executor); fLaunch = launch; - fExecPath = execPath; + fSessionType = type; } + @Override public Step[] getSteps() { return fSteps; } - - private IPath getGDBPath() { - IPath retVal = new Path("gdb.exe"); //$NON-NLS-1$ - try { - retVal = new Path( fLaunch.getLaunchConfiguration().getAttribute( IMILaunchConfigurationConstants.ATTR_DEBUG_NAME, IMILaunchConfigurationConstants.DEBUGGER_DEBUG_NAME_DEFAULT ) ); - } catch (CoreException e) { - } - return retVal; - } } + diff --git a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/GdbLaunchDelegate.java b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/GdbLaunchDelegate.java index 96acd7f0581..0258f116093 100644 --- a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/GdbLaunchDelegate.java +++ b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/GdbLaunchDelegate.java @@ -124,15 +124,15 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate // Create and invoke the launch sequence to create the debug control and services - final LaunchSequence launchSequence = - new LaunchSequence(launch.getSession(), launch, exePath); - launch.getSession().getExecutor().execute(launchSequence); + final ServicesLaunchSequence servicesLaunchSequence = + new ServicesLaunchSequence(launch.getSession(), launch, exePath); + launch.getSession().getExecutor().execute(servicesLaunchSequence); try { - launchSequence.get(); + servicesLaunchSequence.get(); } catch (InterruptedException e1) { throw new DebugException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, "Interrupted Exception in dispatch thread", e1)); //$NON-NLS-1$ } catch (ExecutionException e1) { - throw new DebugException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Error in launch sequence", e1.getCause())); //$NON-NLS-1$ + throw new DebugException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Error in services launch sequence", e1.getCause())); //$NON-NLS-1$ } launch.initializeControl(); @@ -163,6 +163,17 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate throw new CoreException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, 0, "Debugger shut down before launch was completed.", e)); //$NON-NLS-1$ } + // Create and invoke the final launch sequence to setup GDB + final FinalLaunchSequence finalLaunchSequence = + new FinalLaunchSequence(launch.getSession().getExecutor(), launch, fSessionType); + launch.getSession().getExecutor().execute(finalLaunchSequence); + try { + finalLaunchSequence.get(); + } catch (InterruptedException e1) { + throw new DebugException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, "Interrupted Exception in dispatch thread", e1)); //$NON-NLS-1$ + } catch (ExecutionException e1) { + throw new DebugException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Error in final launch sequence", e1.getCause())); //$NON-NLS-1$ + } // Create a memory retrieval and register it with session try { launch.getDsfExecutor().submit( new Callable() { diff --git a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/ServicesLaunchSequence.java b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/ServicesLaunchSequence.java new file mode 100644 index 00000000000..281448bf5aa --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/ServicesLaunchSequence.java @@ -0,0 +1,157 @@ +/******************************************************************************* + * 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.gdb.launch.launching; + +import org.eclipse.cdt.debug.core.CDebugCorePlugin; +import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; +import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector; +import org.eclipse.cdt.debug.mi.core.IMILaunchConfigurationConstants; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.concurrent.Sequence; +import org.eclipse.dd.dsf.debug.service.StepQueueManager; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.gdb.service.GDBRunControl; +import org.eclipse.dd.gdb.service.command.GDBControl; +import org.eclipse.dd.gdb.service.command.GDBControl.SessionType; +import org.eclipse.dd.mi.service.CSourceLookup; +import org.eclipse.dd.mi.service.ExpressionService; +import org.eclipse.dd.mi.service.MIBreakpoints; +import org.eclipse.dd.mi.service.MIBreakpointsManager; +import org.eclipse.dd.mi.service.MIDisassembly; +import org.eclipse.dd.mi.service.MIMemory; +import org.eclipse.dd.mi.service.MIModules; +import org.eclipse.dd.mi.service.MIRegisters; +import org.eclipse.dd.mi.service.MIStack; + +public class ServicesLaunchSequence extends Sequence { + + Step[] fSteps = new Step[] { + // Create and initialize the Connection service. + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + String debugMode = ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN; + try { + debugMode = fLaunch.getLaunchConfiguration().getAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, + ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN ); + } catch (CoreException e) { + } + + if (debugMode.equals(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN)) { + fSessionType = SessionType.RUN; + } else if (debugMode.equals(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_ATTACH)) { + fSessionType = SessionType.ATTACH; + } else if (debugMode.equals(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_CORE)) { + fSessionType = SessionType.CORE; + } else if (debugMode.equals(IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE)) { + fSessionType = SessionType.REMOTE; + } else { + fSessionType = SessionType.RUN; + } + + // + // Create the connection. + // + fCommandControl = new GDBControl(fSession, getGDBPath(), fExecPath, fSessionType, 30); + fCommandControl.initialize(requestMonitor); + } + }, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new GDBRunControl(fSession).initialize(requestMonitor); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new StepQueueManager(fSession).initialize(requestMonitor); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new MIMemory(fSession).initialize(requestMonitor); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new MIModules(fSession).initialize(requestMonitor); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new MIStack(fSession).initialize(requestMonitor); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new ExpressionService(fSession).initialize(requestMonitor); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + fSourceLookup = new CSourceLookup(fSession); + fSourceLookup.initialize(requestMonitor); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + fSourceLookup.setSourceLookupDirector(fCommandControl.getGDBDMContext(), (CSourceLookupDirector)fLaunch.getSourceLocator()); + requestMonitor.done(); + }}, + new Step() { @Override + public void execute(final RequestMonitor requestMonitor) { + // Create the low-level breakpoint service + final MIBreakpoints bpService = new MIBreakpoints(fSession); + bpService.initialize(new RequestMonitor(getExecutor(), requestMonitor)); + }}, + new Step() { @Override + public void execute(final RequestMonitor requestMonitor) { + // Create high-level breakpoint service and install breakpoints + // for the GDB debug context. + fBpmService = new MIBreakpointsManager(fSession, CDebugCorePlugin.PLUGIN_ID); + fBpmService.initialize(new RequestMonitor(getExecutor(), requestMonitor)); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new MIRegisters(fSession).initialize(requestMonitor); + }}, + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + new MIDisassembly(fSession).initialize(requestMonitor); + }}, + }; + + DsfSession fSession; + GdbLaunch fLaunch; + IPath fExecPath; + SessionType fSessionType; + + GDBControl fCommandControl; + CSourceLookup fSourceLookup; + MIBreakpointsManager fBpmService; + + public ServicesLaunchSequence(DsfSession session, GdbLaunch launch, IPath execPath) { + super(session.getExecutor()); + fSession = session; + fLaunch = launch; + fExecPath = execPath; + } + + @Override + public Step[] getSteps() { + return fSteps; + } + + private IPath getGDBPath() { + IPath retVal = new Path("gdb.exe"); //$NON-NLS-1$ + try { + retVal = new Path( fLaunch.getLaunchConfiguration().getAttribute( IMILaunchConfigurationConstants.ATTR_DEBUG_NAME, IMILaunchConfigurationConstants.DEBUGGER_DEBUG_NAME_DEFAULT ) ); + } catch (CoreException e) { + } + return retVal; + } + +} From 42eb4e884ea8d701f28bdbf3025e411d2204955c Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Tue, 25 Mar 2008 17:46:32 +0000 Subject: [PATCH 322/834] Bug 223684 Removes the dependency by moving IGDBLaunchConfigurationContants from the org.eclipse.dd.gdb.launch plugin to org.eclipse.dd.gdb --- .../gdb/launch/launching/GdbLaunchDelegate.java | 1 + .../IGDBLaunchConfigurationConstants.java | 7 ------- .../launching/ServicesLaunchSequence.java | 1 + plugins/org.eclipse.dd.gdb/META-INF/MANIFEST.MF | 3 ++- .../gdb/IGDBLaunchConfigurationConstants.java | 17 +++++++++++++++++ 5 files changed, 21 insertions(+), 8 deletions(-) delete mode 100644 plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/IGDBLaunchConfigurationConstants.java create mode 100644 plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/IGDBLaunchConfigurationConstants.java diff --git a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/GdbLaunchDelegate.java b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/GdbLaunchDelegate.java index 0258f116093..7dce245a668 100644 --- a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/GdbLaunchDelegate.java +++ b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/GdbLaunchDelegate.java @@ -34,6 +34,7 @@ import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.debug.model.DsfMemoryBlockRetrieval; import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryDMContext; import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.gdb.IGDBLaunchConfigurationConstants; import org.eclipse.dd.gdb.launch.internal.GdbLaunchPlugin; import org.eclipse.dd.gdb.service.command.GDBControl; import org.eclipse.dd.gdb.service.command.GDBControl.SessionType; diff --git a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/IGDBLaunchConfigurationConstants.java b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/IGDBLaunchConfigurationConstants.java deleted file mode 100644 index fff7667d916..00000000000 --- a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/IGDBLaunchConfigurationConstants.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.eclipse.dd.gdb.launch.launching; - -public class IGDBLaunchConfigurationConstants { - - public static final String DEBUGGER_MODE_REMOTE = "remote"; - -} diff --git a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/ServicesLaunchSequence.java b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/ServicesLaunchSequence.java index 281448bf5aa..62ef5d4c0d7 100644 --- a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/ServicesLaunchSequence.java +++ b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/ServicesLaunchSequence.java @@ -21,6 +21,7 @@ import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.concurrent.Sequence; import org.eclipse.dd.dsf.debug.service.StepQueueManager; import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.gdb.IGDBLaunchConfigurationConstants; import org.eclipse.dd.gdb.service.GDBRunControl; import org.eclipse.dd.gdb.service.command.GDBControl; import org.eclipse.dd.gdb.service.command.GDBControl.SessionType; diff --git a/plugins/org.eclipse.dd.gdb/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.gdb/META-INF/MANIFEST.MF index 4ed8a929be6..ef35582da38 100644 --- a/plugins/org.eclipse.dd.gdb/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.gdb/META-INF/MANIFEST.MF @@ -14,6 +14,7 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.cdt.debug.core Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: J2SE-1.5 -Export-Package: org.eclipse.dd.gdb.breakpoints, +Export-Package: org.eclipse.dd.gdb, + org.eclipse.dd.gdb.breakpoints, org.eclipse.dd.gdb.service, org.eclipse.dd.gdb.service.command diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/IGDBLaunchConfigurationConstants.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/IGDBLaunchConfigurationConstants.java new file mode 100644 index 00000000000..73f3801c151 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/IGDBLaunchConfigurationConstants.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2008 Ericsson 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: + * Ericsson - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.gdb; + +public class IGDBLaunchConfigurationConstants { + + public static final String DEBUGGER_MODE_REMOTE = "remote"; //$NON-NLS-1$ + +} From 7d6b83a35f170866b135bcb80bfea00db5927b87 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 25 Mar 2008 20:38:29 +0000 Subject: [PATCH 323/834] [179293] Added cancel listener to RequestMonitor. Added handleWarning() completion handler. --- .../dd/dsf/concurrent/RequestMonitor.java | 148 +++++++++++++++--- 1 file changed, 122 insertions(+), 26 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java index 3c281732e41..5b73616c4ee 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java @@ -14,10 +14,10 @@ import java.util.concurrent.Executor; import java.util.concurrent.RejectedExecutionException; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.ListenerList; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.internal.DsfPlugin; -import org.eclipse.dd.dsf.service.IDsfService; /** * Used to monitor the result of an asynchronous request. Because of the @@ -56,6 +56,22 @@ import org.eclipse.dd.dsf.service.IDsfService; */ @ConfinedToDsfExecutor("") public class RequestMonitor { + + /** + * Interface used by RequestMonitor to notify when a given request monitor + * is canceled. + * + * @see RequestMonitor + */ + public static interface ICanceledListener { + + /** + * Called when the given request monitor is canceled. + */ + public void requestCanceled(RequestMonitor rm); + } + + public static final IStatus STATUS_CANCEL = new Status(IStatus.CANCEL, DsfPlugin.PLUGIN_ID, "Request canceled"); //$NON-NLS-1$ /** @@ -70,6 +86,8 @@ public class RequestMonitor { */ private final RequestMonitor fParentRequestMonitor; + private ListenerList fCancelListeners; + /** * Status */ @@ -87,6 +105,18 @@ public class RequestMonitor { public RequestMonitor(Executor executor, RequestMonitor parentRequestMonitor) { fExecutor = executor; fParentRequestMonitor = parentRequestMonitor; + + // If the parent rm is not null, add ourselves as a listener so that + // this request monitor will automatically be canceled when the parent + // is canceled. + if (fParentRequestMonitor != null) { + fParentRequestMonitor.addCancelListener( + new ICanceledListener() { + public void requestCanceled(RequestMonitor rm) { + cancel(); + } + }); + } } /** @@ -101,16 +131,26 @@ public class RequestMonitor { } /** - * Sets this request as canceled. The operation may still be carried out - * as it is up to the implementation of the asynchronous operation - * to cancel the operation. - * @param canceled Flag indicating whether to cancel. + * Sets this request monitor as canceled and calls the cancel listeners if any. + * The operation may still be carried out as it is up to the implementation of + * the asynchronous operation to cancel the operation. Even after the request + * monitor is canceled, the done() method still has to be called. */ - public synchronized void setCanceled(boolean canceled) { - if (fParentRequestMonitor != null) { - fParentRequestMonitor.setCanceled(canceled); - } else { - fCanceled = canceled; + public void cancel() { + Object[] listeners = null; + synchronized (this) { + fCanceled = true; + if (fCancelListeners != null) { + listeners = fCancelListeners.getListeners(); + } + } + + // Call the listeners outsize of a synchronized section to reduce the + // risk of deadlocks. + if (listeners != null) { + for (Object listener : listeners) { + ((ICanceledListener)listener).requestCanceled(this); + } } } @@ -121,13 +161,31 @@ public class RequestMonitor { * of the request monitor. */ public synchronized boolean isCanceled() { - if (fParentRequestMonitor != null) { - return fParentRequestMonitor.isCanceled(); - } else { - return fCanceled; - } + return fCanceled; } + /** + * Adds the given listener to list of listeners that are notified when this + * request monitor is canceled. + */ + public synchronized void addCancelListener(ICanceledListener listener) { + if (fCancelListeners == null) { + fCancelListeners = new ListenerList(); + } + fCancelListeners.add(listener); + } + + /** + * Removes the given listener from the list of listeners that are notified + * when this request monitor is canceled. + */ + public synchronized void removeCancelListener(ICanceledListener listener) { + if (fCancelListeners == null) { + fCancelListeners = new ListenerList(); + } + fCancelListeners.remove(listener); + } + /** * Marks this request as completed. Once this method is called, the * monitor submits a runnable to the DSF Executor to call the @@ -165,7 +223,7 @@ public class RequestMonitor { /** * Default handler for the completion of a request. The implementation * calls {@link #handleOK()} if the request succeeded, and calls - * {@link #handleErrorOrCancel()} or cancel otherwise. + * {@link #handleCancelOrErrorOrWarning()} or cancel otherwise. *
              * Note: Sub-classes may override this method. */ @@ -173,7 +231,7 @@ public class RequestMonitor { if (getStatus().isOK()) { handleOK(); } else { - handleErrorOrCancel(); + handleCancelOrErrorOrWarning(); } } @@ -181,7 +239,7 @@ public class RequestMonitor { * Default handler for a successful the completion of a request. If this * monitor has a parent monitor that was configured by the constructor, that * parent monitor is notified. Otherwise this method does nothing. - * {@link #handleErrorOrCancel()} or cancel otherwise. + * {@link #handleCancelOrErrorOrWarning()} or cancel otherwise. *
              * Note: Sub-classes may override this method. */ @@ -194,27 +252,46 @@ public class RequestMonitor { /** * The default implementation of a cancellation or an error result of a * request. The implementation delegates to {@link #handleCancel()} and - * {@link #handleError()} as needed. + * {@link #handleErrorOrWarning()} as needed. *
              * Note: Sub-classes may override this method. */ - protected void handleErrorOrCancel() { + protected void handleCancelOrErrorOrWarning() { assert !getStatus().isOK(); if (isCanceled()) { handleCancel(); } else { - if (getStatus().getCode() == IStatus.CANCEL) { + if (getStatus().getSeverity() == IStatus.CANCEL) { DsfPlugin.getDefault().getLog().log(new Status( - IStatus.ERROR, DsfPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Request monitor: '" + this + "' resulted in a cancel status: " + getStatus() + ", even though the request is not set to cancel.", null)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + IStatus.ERROR, DsfPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Request monitor: '" + this + "' resulted in a cancel status: " + getStatus() + ", even though the request is not set to cancel.", null)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + if (getStatus().getSeverity() == IStatus.ERROR) { + handleError(); + } else { + handleWarning(); } - handleError(); } } + /** + * The default implementation of an error or warning result of a request. + * The implementation delegates to {@link #handleError()} and + * {@link #handleWarning()} as needed. + *
              + * Note: Sub-classes may override this method. + */ + protected void handleErrorOrWarning() { + if (getStatus().getSeverity() == IStatus.ERROR) { + handleError(); + } else { + handleWarning(); + } + } + /** * The default implementation of an error result of a request. If this * monitor has a parent monitor that was configured by the constructor, that - * parent monitor is configured with a new error status containing this error. + * parent monitor is configured with a new status containing this error. * Otherwise the error is logged. *
              * Note: Sub-classes may override this method. @@ -224,12 +301,31 @@ public class RequestMonitor { fParentRequestMonitor.setStatus(getStatus()); fParentRequestMonitor.done(); } else { - MultiStatus logStatus = new MultiStatus(DsfPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Request for monitor: '" + toString() + "' resulted in an error.", null); //$NON-NLS-1$ //$NON-NLS-2$ + MultiStatus logStatus = new MultiStatus(DsfPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Request for monitor: '" + toString() + "' resulted in an error.", null); //$NON-NLS-1$ //$NON-NLS-2$ logStatus.merge(getStatus()); DsfPlugin.getDefault().getLog().log(logStatus); } } + /** + * The default implementation of an error result of a request. If this + * monitor has a parent monitor that was configured by the constructor, that + * parent monitor is configured with a new status containing this warning. + * Otherwise the warning is logged. + *
              + * Note: Sub-classes may override this method. + */ + protected void handleWarning() { + if (fParentRequestMonitor != null) { + fParentRequestMonitor.setStatus(getStatus()); + fParentRequestMonitor.done(); + } else { + MultiStatus logStatus = new MultiStatus(DsfPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Request for monitor: '" + toString() + "' resulted in a warning.", null); //$NON-NLS-1$ //$NON-NLS-2$ + logStatus.merge(getStatus()); + DsfPlugin.getDefault().getLog().log(logStatus); + } + } + /** * Default handler for a canceled the completion of a request. If this * monitor has a parent monitor that was configured by the constructor, that @@ -250,7 +346,7 @@ public class RequestMonitor { * This usually happens only when the executor is shutting down. */ protected void handleRejectedExecutionException() { - MultiStatus logStatus = new MultiStatus(DsfPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Request for monitor: '" + toString() + "' resulted in a rejected execution exception.", null); //$NON-NLS-1$ //$NON-NLS-2$ + MultiStatus logStatus = new MultiStatus(DsfPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Request for monitor: '" + toString() + "' resulted in a rejected execution exception.", null); //$NON-NLS-1$ //$NON-NLS-2$ logStatus.merge(getStatus()); if (fParentRequestMonitor != null) { fParentRequestMonitor.setStatus(logStatus); From 03b5f689a4eb0e2d91bf75fea6af05fe2ad4240b Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 25 Mar 2008 20:41:20 +0000 Subject: [PATCH 324/834] [223774] Moved status error codes from IDsfService interface into IDsfStatusConstants interface. --- .../expression/AbstractExpressionVMNode.java | 10 +-- .../ExpressionVMProviderContentStragegy.java | 4 +- ...xpressionVMProviderModelProxyStrategy.java | 2 +- .../expression/VMExpressionUpdate.java | 4 +- .../ui/viewmodel/launch/LaunchRootVMNode.java | 4 +- .../viewmodel/launch/StackFramesVMNode.java | 6 +- .../viewmodel/modules/ModuleDetailPane.java | 4 +- .../ui/viewmodel/modules/ModulesVMNode.java | 6 +- .../register/RegisterBitFieldVMNode.java | 12 ++-- .../register/RegisterGroupVMNode.java | 10 +-- .../ui/viewmodel/register/RegisterVMNode.java | 10 +-- .../register/SyncRegisterDataAccess.java | 18 ++--- .../variable/SyncVariableDataAccess.java | 11 +-- .../ui/viewmodel/variable/VariableVMNode.java | 8 +-- .../debug/service/command/CommandCache.java | 4 +- .../DsfMISourceLookupParticipant.java | 6 +- .../ViewerCountingRequestMonitor.java | 2 +- .../concurrent/ViewerDataRequestMonitor.java | 2 +- .../dsf/ui/viewmodel/AbstractVMAdapter.java | 10 +-- .../dd/dsf/ui/viewmodel/AbstractVMNode.java | 4 +- .../dsf/ui/viewmodel/AbstractVMProvider.java | 10 +-- .../DefaultVMModelProxyStrategy.java | 4 +- .../dd/dsf/ui/viewmodel/VMChildrenUpdate.java | 4 +- .../viewmodel/datamodel/AbstractDMVMNode.java | 9 +-- .../PropertyBasedLabelProvider.java | 4 +- .../dsf/concurrent/IDsfStatusConstants.java | 48 +++++++++++++ .../dd/dsf/service/AbstractDsfService.java | 7 +- .../eclipse/dd/dsf/service/IDsfService.java | 32 +-------- .../examples/dsf/filebrowser/FileVMNode.java | 4 +- .../dsf/timers/ServicesShutdownSequence.java | 3 +- .../dsf/timers/TriggerCellModifier.java | 8 +-- .../dsf/dataviewer/AsyncDataViewer.java | 2 +- .../launch/PDAServicesShutdownSequence.java | 3 +- .../examples/pda/service/PDABreakpoints.java | 8 +-- .../examples/pda/service/PDARunControl.java | 10 +-- .../dd/examples/pda/service/PDAStack.java | 16 ++--- .../dd/gdb/launch/launching/GdbLaunch.java | 6 +- .../launch/launching/ShutdownSequence.java | 5 +- .../ui/breakpoints/GdbThreadFilterEditor.java | 18 ++--- .../ui/viewmodel/launch/ThreadVMNode.java | 8 +-- .../dd/gdb/service/command/GDBControl.java | 6 +- .../eclipse/dd/mi/service/CSourceLookup.java | 12 ++-- .../eclipse/dd/mi/service/MIBreakpoints.java | 71 +++++++++---------- .../org/eclipse/dd/mi/service/MIMemory.java | 18 ++--- .../eclipse/dd/mi/service/MIRegisters.java | 4 +- .../eclipse/dd/mi/service/MIRunControl.java | 19 +++-- .../org/eclipse/dd/mi/service/MIStack.java | 11 ++- .../dd/mi/service/MIVariableManager.java | 12 ++-- .../mi/service/command/AbstractMIControl.java | 5 +- .../mi/service/command/MIInferiorProcess.java | 4 +- .../tests/gdb/launching/ShutdownSequence.java | 5 +- 51 files changed, 267 insertions(+), 246 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/IDsfStatusConstants.java diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionVMNode.java index 86c6a6bf1da..924526a295c 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionVMNode.java @@ -16,11 +16,11 @@ 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.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.MultiRequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.concurrent.ViewerDataRequestMonitor; import org.eclipse.dd.dsf.ui.viewmodel.VMChildrenUpdate; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMNode; @@ -42,7 +42,7 @@ public abstract class AbstractExpressionVMNode extends AbstractDMVMNode public void update(final IExpressionUpdate update) { if (!canParseExpression(update.getExpression())) { - update.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Invalid expression", null)); //$NON-NLS-1$ + update.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Invalid expression", null)); //$NON-NLS-1$ update.done(); return; } @@ -53,7 +53,7 @@ public abstract class AbstractExpressionVMNode extends AbstractDMVMNode @Override protected void handleOK() { if (getData().size() == 0) { - update.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "No contexts", null)); //$NON-NLS-1$ + update.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "No contexts", null)); //$NON-NLS-1$ update.done(); } else { final List elements = getData(); @@ -73,7 +73,7 @@ public abstract class AbstractExpressionVMNode extends AbstractDMVMNode } } if (!foundMatchingContext) { - update.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Context not found", null)); //$NON-NLS-1$ + update.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Context not found", null)); //$NON-NLS-1$ } } else { update.setStatus(getStatus()); @@ -97,7 +97,7 @@ public abstract class AbstractExpressionVMNode extends AbstractDMVMNode } @Override - protected void handleErrorOrCancel() { + protected void handleCancelOrErrorOrWarning() { update.setStatus(getStatus()); update.done(); } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderContentStragegy.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderContentStragegy.java index 1488f99f368..ab1afc9f400 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderContentStragegy.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderContentStragegy.java @@ -12,8 +12,8 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.concurrent.ViewerDataRequestMonitor; import org.eclipse.dd.dsf.ui.viewmodel.DefaultVMContentProviderStrategy; @@ -40,7 +40,7 @@ public class ExpressionVMProviderContentStragegy extends DefaultVMContentProvide if (matchingNode != null) { updateExpressionWithNode(matchingNode, update); } else { - update.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, "Cannot parse expression", null)); //$NON-NLS-1$ + update.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, "Cannot parse expression", null)); //$NON-NLS-1$ update.done(); } } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderModelProxyStrategy.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderModelProxyStrategy.java index 6cc7480e085..4c7a5686ef9 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderModelProxyStrategy.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderModelProxyStrategy.java @@ -96,7 +96,7 @@ public class ExpressionVMProviderModelProxyStrategy extends DefaultVMModelProxyS } @Override - protected void handleError() { + protected void handleErrorOrWarning() { // Avoid propagating the error to avoid processing the delta by // all nodes. rm.done(); diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/VMExpressionUpdate.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/VMExpressionUpdate.java index beb74d991f4..6408819022a 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/VMExpressionUpdate.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/VMExpressionUpdate.java @@ -13,8 +13,8 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.internal.ui.DsfUIPlugin; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.VMViewerUpdate; import org.eclipse.debug.core.model.IExpression; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; @@ -72,7 +72,7 @@ class VMExpressionUpdate extends VMViewerUpdate implements IExpressionUpdate { if (fExpressionElement != null) { rm.setData(fExpressionElement); } else if (rm.getStatus().isOK()) { - rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, "Incomplete elements of updates", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, "Incomplete elements of updates", null)); //$NON-NLS-1$ } super.done(); } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/LaunchRootVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/LaunchRootVMNode.java index d3e1ea62a3c..bd39dd7271f 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/LaunchRootVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/LaunchRootVMNode.java @@ -16,8 +16,8 @@ import java.util.List; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.IRootVMNode; import org.eclipse.dd.dsf.ui.viewmodel.RootVMNode; @@ -89,7 +89,7 @@ public class LaunchRootVMNode extends RootVMNode @Override public void createRootDelta(Object rootObject, Object event, final DataRequestMonitor rm) { if (!(rootObject instanceof ILaunch)) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Invalid root element configured with launch root node.", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Invalid root element configured with launch root node.", null)); //$NON-NLS-1$ return; } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java index 9ffd46cff9e..79a1a044694 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java @@ -15,6 +15,7 @@ import java.util.concurrent.RejectedExecutionException; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.debug.service.IRunControl; @@ -28,7 +29,6 @@ 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.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.ModelProxyInstalledEvent; import org.eclipse.dd.dsf.ui.viewmodel.VMChildrenUpdate; @@ -191,8 +191,8 @@ public class StackFramesVMNode extends AbstractDMVMNode */ if (!getStatus().isOK()) { assert getStatus().isOK() || - getStatus().getCode() != IDsfService.INTERNAL_ERROR || - getStatus().getCode() != IDsfService.NOT_SUPPORTED; + getStatus().getCode() != IDsfStatusConstants.INTERNAL_ERROR || + getStatus().getCode() != IDsfStatusConstants.NOT_SUPPORTED; handleFailedUpdate(update); return; } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPane.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPane.java index f8a099b75a7..94db474de94 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPane.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPane.java @@ -24,6 +24,7 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.Query; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; @@ -34,7 +35,6 @@ import org.eclipse.dd.dsf.debug.service.IModules.IModuleDMContext; import org.eclipse.dd.dsf.debug.service.IModules.IModuleDMData; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext; import org.eclipse.debug.core.model.IDebugElement; import org.eclipse.debug.internal.ui.DebugUIPlugin; @@ -525,7 +525,7 @@ public class ModuleDetailPane extends AbstractDetailPane implements IAdaptable, DsfServicesTracker tracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), fDmc.getSessionId()); IModules service = tracker.getService(IModules.class); if (service == null) { - rm .setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ + rm .setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ rm.done(); return; } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMNode.java index 9cccf07505d..3d00a73fbb8 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMNode.java @@ -14,6 +14,7 @@ import java.util.concurrent.RejectedExecutionException; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.service.IModules; @@ -23,7 +24,6 @@ import org.eclipse.dd.dsf.debug.service.IModules.IModuleDMData; import org.eclipse.dd.dsf.debug.service.IModules.ISymbolDMContext; import org.eclipse.dd.dsf.debug.ui.IDsfDebugUIConstants; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMNode; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; @@ -99,8 +99,8 @@ public class ModulesVMNode extends AbstractDMVMNode */ if (!getStatus().isOK()) { assert getStatus().isOK() || - getStatus().getCode() != IDsfService.INTERNAL_ERROR || - getStatus().getCode() != IDsfService.NOT_SUPPORTED; + getStatus().getCode() != IDsfStatusConstants.INTERNAL_ERROR || + getStatus().getCode() != IDsfStatusConstants.NOT_SUPPORTED; handleFailedUpdate(update); return; } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java index bf368b39e59..fb47d5a9fa9 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java @@ -17,6 +17,7 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; @@ -39,7 +40,6 @@ import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValuePrefere import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValueVMContext; import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterBitFieldCellModifier.BitFieldEditorStyle; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; @@ -292,8 +292,8 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode */ if (!getStatus().isOK()) { assert getStatus().isOK() || - getStatus().getCode() != IDsfService.INTERNAL_ERROR || - getStatus().getCode() != IDsfService.NOT_SUPPORTED; + getStatus().getCode() != IDsfStatusConstants.INTERNAL_ERROR || + getStatus().getCode() != IDsfStatusConstants.NOT_SUPPORTED; handleFailedUpdate(update); return; } @@ -375,7 +375,7 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode regDmc, new DataRequestMonitor(getSession().getExecutor(), null) { @Override - protected void handleErrorOrCancel() { + protected void handleCancelOrErrorOrWarning() { handleFailedUpdate(update); } @@ -514,14 +514,14 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode @Override protected void testElementForExpression(Object element, IExpression expression, DataRequestMonitor rm) { if (!(element instanceof IDMVMContext)) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ rm.done(); return; } final IBitFieldDMContext dmc = DMContexts.getAncestorOfType(((IDMVMContext)element).getDMContext(), IBitFieldDMContext.class); if (dmc == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ rm.done(); return; } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java index 835a6e7731e..e7911b2c9f9 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java @@ -17,6 +17,7 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; @@ -30,7 +31,6 @@ import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.AbstractExpressionVMNode; import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionCellModifier; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; @@ -187,8 +187,8 @@ public class RegisterGroupVMNode extends AbstractExpressionVMNode */ if (!getStatus().isOK()) { assert getStatus().isOK() || - getStatus().getCode() != IDsfService.INTERNAL_ERROR || - getStatus().getCode() != IDsfService.NOT_SUPPORTED; + getStatus().getCode() != IDsfStatusConstants.INTERNAL_ERROR || + getStatus().getCode() != IDsfStatusConstants.NOT_SUPPORTED; handleFailedUpdate(update); return; } @@ -330,13 +330,13 @@ public class RegisterGroupVMNode extends AbstractExpressionVMNode @Override protected void testElementForExpression(Object element, IExpression expression, DataRequestMonitor rm) { if (!(element instanceof IDMVMContext)) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ rm.done(); return; } final IRegisterGroupDMContext dmc = DMContexts.getAncestorOfType(((IDMVMContext)element).getDMContext(), IRegisterGroupDMContext.class); if (dmc == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ rm.done(); return; } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java index 1a35a3efe39..3596e91412f 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java @@ -17,6 +17,7 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; @@ -35,7 +36,6 @@ import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.AbstractExpressionVMNode import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValuePreferenceStore; import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValueVMContext; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; @@ -292,8 +292,8 @@ public class RegisterVMNode extends AbstractExpressionVMNode */ if (!getStatus().isOK()) { assert getStatus().isOK() || - getStatus().getCode() != IDsfService.INTERNAL_ERROR || - getStatus().getCode() != IDsfService.NOT_SUPPORTED; + getStatus().getCode() != IDsfStatusConstants.INTERNAL_ERROR || + getStatus().getCode() != IDsfStatusConstants.NOT_SUPPORTED; handleFailedUpdate(update); return; } @@ -487,13 +487,13 @@ public class RegisterVMNode extends AbstractExpressionVMNode @Override protected void testElementForExpression(Object element, IExpression expression, DataRequestMonitor rm) { if (!(element instanceof IDMVMContext)) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ rm.done(); return; } final IRegisterDMContext dmc = DMContexts.getAncestorOfType(((IDMVMContext)element).getDMContext(), IRegisterDMContext.class); if (dmc == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ rm.done(); return; } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java index 8fecbdb88c5..4c53b877e9f 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java @@ -16,6 +16,7 @@ import java.util.concurrent.ExecutionException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.Query; import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.concurrent.ThreadSafeAndProhibitedFromDsfExecutor; @@ -35,7 +36,6 @@ import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMData; import org.eclipse.dd.dsf.service.DsfServices; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext; import org.osgi.framework.InvalidSyntaxException; import org.osgi.util.tracker.ServiceTracker; @@ -109,7 +109,7 @@ public class SyncRegisterDataAccess { IRegisters service = getService(); if (service == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service not available", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Service not available", null)); //$NON-NLS-1$ rm.done(); return; } @@ -211,7 +211,7 @@ public class SyncRegisterDataAccess { */ IRegisters service = getService(); if (service == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ rm.done(); return; } @@ -319,7 +319,7 @@ public class SyncRegisterDataAccess { */ IRegisters service = getService(); if (service == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ rm.done(); return; } @@ -446,7 +446,7 @@ public class SyncRegisterDataAccess { IRegisters service = getService(); if (service == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service not available", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Service not available", null)); //$NON-NLS-1$ rm.done(); return; } @@ -535,7 +535,7 @@ public class SyncRegisterDataAccess { IRegisters service = getService(); if (service == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service not available", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Service not available", null)); //$NON-NLS-1$ rm.done(); return; } @@ -629,7 +629,7 @@ public class SyncRegisterDataAccess { */ IRegisters service = getService(); if (service == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ rm.done(); return; } @@ -738,7 +738,7 @@ public class SyncRegisterDataAccess { */ IRegisters service = getService(); if (service == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ rm.done(); return; } @@ -843,7 +843,7 @@ public class SyncRegisterDataAccess { */ IRegisters service = getService(); if (service == null) { - rm .setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ + rm .setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ rm.done(); return; } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java index 0f715b36969..2cb64e637d1 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java @@ -12,6 +12,7 @@ import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.Query; import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.concurrent.ThreadSafeAndProhibitedFromDsfExecutor; @@ -119,7 +120,7 @@ public class SyncVariableDataAccess { IExpressions service = getService(); if (service == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service not available", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Service not available", null)); //$NON-NLS-1$ rm.done(); return; } @@ -220,7 +221,7 @@ public class SyncVariableDataAccess { */ IExpressions service = getService(); if (service == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ rm.done(); return; } @@ -331,7 +332,7 @@ public class SyncVariableDataAccess { */ IExpressions service = getService(); if (service == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ rm.done(); return; } @@ -430,7 +431,7 @@ public class SyncVariableDataAccess { */ IExpressions service = getService(); if (service == null) { - rm .setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ + rm .setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ rm.done(); return; } @@ -526,7 +527,7 @@ public class SyncVariableDataAccess { */ IExpressions service = getService(); if (service == null) { - rm .setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ + rm .setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ rm.done(); return; } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java index 077ed6ff17e..5f314eee20d 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java @@ -19,6 +19,7 @@ import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfExecutor; import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.MultiRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.DMContexts; @@ -42,7 +43,6 @@ import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.IExpressionUpdate; import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValuePreferenceStore; import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValueVMContext; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; @@ -228,8 +228,8 @@ public class VariableVMNode extends AbstractExpressionVMNode if (!getStatus().isOK()) { assert getStatus().isOK() || - getStatus().getCode() != IDsfService.INTERNAL_ERROR || - getStatus().getCode() != IDsfService.NOT_SUPPORTED; + getStatus().getCode() != IDsfStatusConstants.INTERNAL_ERROR || + getStatus().getCode() != IDsfStatusConstants.NOT_SUPPORTED; /* * Instead of just failing this outright we are going to attempt to do more here. @@ -473,7 +473,7 @@ public class VariableVMNode extends AbstractExpressionVMNode @Override protected void handleFailedUpdate(IViewerUpdate update) { if (update instanceof IExpressionUpdate) { - update.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Update failed", null)); //$NON-NLS-1$ + update.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Update failed", null)); //$NON-NLS-1$ update.done(); } else { super.handleFailedUpdate(update); diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java index f88c8be7480..db4208f08eb 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java @@ -22,10 +22,10 @@ import java.util.Map; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.debug.internal.DsfDebugPlugin; -import org.eclipse.dd.dsf.service.IDsfService; /** * This is a utility class for caching results of MI Commands. Return MIInfo @@ -268,7 +268,7 @@ public class CommandCache implements ICommandListener * Return an error if the target is available anymore. */ if (!fIsTargetAvailable) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Target not available.", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Target not available.", null)); //$NON-NLS-1$ rm.done(); return; } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java index 9c4b59b3549..a05d01e4cbc 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java @@ -25,6 +25,7 @@ import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.Query; import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.datamodel.IDMContext; @@ -34,7 +35,6 @@ import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMData; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.sourcelookup.ISourceContainer; import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector; @@ -204,7 +204,7 @@ public class DsfMISourceLookupParticipant implements ISourceLookupParticipant { @ConfinedToDsfExecutor("fExecutor") private void getSourceNameOnDispatchThread(IDMContext dmc, final DataRequestMonitor rm) { if (!(dmc instanceof IStack.IFrameDMContext)) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "No source for this object", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_HANDLE, "No source for this object", null)); //$NON-NLS-1$ rm.done(); return; } @@ -212,7 +212,7 @@ public class DsfMISourceLookupParticipant implements ISourceLookupParticipant { IStack stackService = fServicesTracker.getService(IStack.class); if (stackService == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Stack data not available", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_HANDLE, "Stack data not available", null)); //$NON-NLS-1$ rm.done(); return; } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/ViewerCountingRequestMonitor.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/ViewerCountingRequestMonitor.java index 674e83f5c60..884062638b1 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/ViewerCountingRequestMonitor.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/ViewerCountingRequestMonitor.java @@ -42,7 +42,7 @@ public class ViewerCountingRequestMonitor extends CountingRequestMonitor { } @Override - protected void handleError() { + protected void handleErrorOrWarning() { fUpdate.setStatus(getStatus()); fUpdate.done(); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/ViewerDataRequestMonitor.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/ViewerDataRequestMonitor.java index b20e3cc04b6..5e8a53a0c2a 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/ViewerDataRequestMonitor.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/ViewerDataRequestMonitor.java @@ -40,7 +40,7 @@ public class ViewerDataRequestMonitor extends DataRequestMonitor { } @Override - protected void handleError() { + protected void handleErrorOrWarning() { fUpdate.setStatus(getStatus()); fUpdate.done(); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java index 95de160fabb..f4b25c1432e 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java @@ -17,9 +17,9 @@ import java.util.concurrent.RejectedExecutionException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.internal.ui.DsfUIPlugin; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; @@ -97,7 +97,7 @@ abstract public class AbstractVMAdapter implements IVMAdapter updateProvider(provider, updates); } else { for (IViewerUpdate update : updates) { - update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, + update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "No model provider for update " + update, null)); //$NON-NLS-1$ } } @@ -109,7 +109,7 @@ abstract public class AbstractVMAdapter implements IVMAdapter updateProvider(provider, updates); } else { for (IViewerUpdate update : updates) { - update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, + update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "No model provider for update " + update, null)); //$NON-NLS-1$ } } @@ -121,7 +121,7 @@ abstract public class AbstractVMAdapter implements IVMAdapter updateProvider(provider, updates); } else { for (IViewerUpdate update : updates) { - update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, + update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "No model provider for update " + update, null)); //$NON-NLS-1$ } } @@ -142,7 +142,7 @@ abstract public class AbstractVMAdapter implements IVMAdapter }); } catch (RejectedExecutionException e) { for (IViewerUpdate update : updates) { - update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, + update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Display is disposed, cannot complete update " + update, null)); //$NON-NLS-1$ update.done(); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMNode.java index f8f67ed9be9..cb7ed0723ea 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMNode.java @@ -14,8 +14,8 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.internal.ui.DsfUIPlugin; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; @@ -52,7 +52,7 @@ abstract public class AbstractVMNode implements IVMNode { } public void getContextsForEvent(VMDelta parentDelta, Object event, DataRequestMonitor rm) { - rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.NOT_SUPPORTED, "", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.NOT_SUPPORTED, "", null)); //$NON-NLS-1$ rm.done(); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java index 495dc80c536..4fc1d2aa95a 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java @@ -20,7 +20,7 @@ import java.util.concurrent.RejectedExecutionException; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfExecutor; -import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.ui.concurrent.DisplayDsfExecutor; import org.eclipse.dd.dsf.ui.concurrent.ViewerDataRequestMonitor; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; @@ -336,8 +336,8 @@ abstract public class AbstractVMProvider implements IVMProvider } @Override - protected void handleError() { - if (getStatus().getCode() == IDsfService.NOT_SUPPORTED) { + protected void handleErrorOrWarning() { + if (getStatus().getCode() == IDsfStatusConstants.NOT_SUPPORTED) { updateNode( node, new VMChildrenUpdate( @@ -382,8 +382,8 @@ abstract public class AbstractVMProvider implements IVMProvider } @Override - protected void handleError() { - if (getStatus().getCode() == IDsfService.NOT_SUPPORTED) { + protected void handleErrorOrWarning() { + if (getStatus().getCode() == IDsfStatusConstants.NOT_SUPPORTED) { updateNode( node, new VMChildrenUpdate( diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMModelProxyStrategy.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMModelProxyStrategy.java index f51c807277a..b82c7ef4d58 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMModelProxyStrategy.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMModelProxyStrategy.java @@ -22,9 +22,9 @@ import org.eclipse.core.runtime.SafeRunner; import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.MultiRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelChangedListener; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; @@ -293,7 +293,7 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy { if (getStatus().isOK()) { assert getData() != null; buildChildDeltasForEventContext(getData(), node, event, parentDelta, nodeOffset, rm); - } else if (getStatus().getCode() == IDsfService.NOT_SUPPORTED) { + } else if (getStatus().getCode() == IDsfStatusConstants.NOT_SUPPORTED) { // The DMC for this node was not found in the event. Call the // super-class to resort to the default behavior which may add a // delta for every element in this node. diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMChildrenUpdate.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMChildrenUpdate.java index 13943a34ade..93954b441c0 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMChildrenUpdate.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMChildrenUpdate.java @@ -16,8 +16,8 @@ import java.util.List; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.internal.ui.DsfUIPlugin; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; @@ -129,7 +129,7 @@ public class VMChildrenUpdate extends VMViewerUpdate implements IChildrenUpdate */ rm.setData(fElements); if (rm.getStatus().isOK() && fLength != -1 && fElements.size() != fLength) { - rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, "Incomplete elements of updates", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, "Incomplete elements of updates", null)); //$NON-NLS-1$ } super.done(); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/datamodel/AbstractDMVMNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/datamodel/AbstractDMVMNode.java index d297215fb27..21ff0b60ac8 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/datamodel/AbstractDMVMNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/datamodel/AbstractDMVMNode.java @@ -17,6 +17,7 @@ import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; @@ -182,7 +183,7 @@ abstract public class AbstractDMVMNode extends AbstractVMNode implements IVMNode */ protected boolean checkDmc(IDMContext dmc, IViewerUpdate update) { if (dmc == null) { - update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, + update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "No valid context found.", null)); //$NON-NLS-1$ handleFailedUpdate(update); return false; @@ -200,7 +201,7 @@ abstract public class AbstractDMVMNode extends AbstractVMNode implements IVMNode */ protected boolean checkService(Class serviceClass, String filter, IViewerUpdate update) { if (getServicesTracker().getService(serviceClass, filter) == null) { - update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, + update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Service " + serviceClass.getName() + " not available.", null)); //$NON-NLS-1$ //$NON-NLS-2$ handleFailedUpdate(update); return false; @@ -226,7 +227,7 @@ abstract public class AbstractDMVMNode extends AbstractVMNode implements IVMNode @ConfinedToDsfExecutor("getSession().getExecutor()") protected void updateHasElementsInSessionThread(final IHasChildrenUpdate update) { - update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.NOT_SUPPORTED, "Not implemented, clients should call to update all children instead.", null)); //$NON-NLS-1$ + update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.NOT_SUPPORTED, "Not implemented, clients should call to update all children instead.", null)); //$NON-NLS-1$ update.done(); } @@ -248,7 +249,7 @@ abstract public class AbstractDMVMNode extends AbstractVMNode implements IVMNode @ConfinedToDsfExecutor("getSession().getExecutor()") protected void updateElementCountInSessionThread(final IChildrenCountUpdate update) { - update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.NOT_SUPPORTED, "Not implemented, clients should call to update all children instead.", null)); //$NON-NLS-1$ + update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.NOT_SUPPORTED, "Not implemented, clients should call to update all children instead.", null)); //$NON-NLS-1$ update.done(); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/PropertyBasedLabelProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/PropertyBasedLabelProvider.java index cf2d915942c..3791a7f3c5d 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/PropertyBasedLabelProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/PropertyBasedLabelProvider.java @@ -21,10 +21,10 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.ListenerList; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.internal.ui.DsfUIPlugin; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.VMViewerUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; @@ -81,7 +81,7 @@ public class PropertyBasedLabelProvider if (fProperties == null || fValues.size() >= fProperties.length) { rm.setData(fValues); } else { - rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, "Incomplete properties updated", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, "Incomplete properties updated", null)); //$NON-NLS-1$ } super.done(); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/IDsfStatusConstants.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/IDsfStatusConstants.java new file mode 100644 index 00000000000..9da092a2198 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/IDsfStatusConstants.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.concurrent; + +/** + * Interface that hold the codes used when reporting status using the DSF + * Request Monitor. + */ +public interface IDsfStatusConstants { + /** + * Error code indicating that the service is in a state which does not allow the + * request to be processed. For example if the client requested target information + * after target was disconnected. + */ + final static int INVALID_STATE = 10001; + + /** + * Error code indicating that client supplied an invalid handle to the service. + * A handle could become invalid after an object it represents is removed from + * the system. + */ + final static int INVALID_HANDLE = 10002; + + /** + * Error code indicating that the client request is not supported/implemented. + */ + final static int NOT_SUPPORTED = 10003; + + /** + * Error code indicating that the request to a sub-service or an external process + * failed. + */ + final static int REQUEST_FAILED = 10004; + + /** + * Error code indicating an unexpected condition in the service, i.e. programming error. + */ + final static int INTERNAL_ERROR = 10005; + +} diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java index 0c4bc5f8f2c..9392a9492ea 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/AbstractDsfService.java @@ -14,20 +14,21 @@ import java.util.Arrays; import java.util.Dictionary; import java.util.Enumeration; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; import org.osgi.framework.ServiceRegistration; /** - * Standard base implementation of the DSF service. This is a convinience + * Standard base implementation of the DSF service. This is a convenience * class that provides the basic functionality that all DSF services have * to implement. */ abstract public class AbstractDsfService - implements IDsfService + implements IDsfService, IDsfStatusConstants { /** Reference to the session that this service belongs to. */ private DsfSession fSession; diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java index be934f81ee1..16f6a7fb227 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/IDsfService.java @@ -43,37 +43,7 @@ public interface IDsfService { * all DSF services when they are registered with OSGI service framework. */ final static String PROP_SESSION_ID = "org.eclipse.dd.dsf.service.IService.session_id"; //$NON-NLS-1$ - - /** - * Error code indicating that the service is in a state which does not allow the - * request to be processed. For example if the client requested target information - * after target was disconnected. - */ - final static int INVALID_STATE = 10001; - - /** - * Error code indicating that client supplied an invalid handle to the service. - * A handle could become invalid after an object it represents is removed from - * the system. - */ - final static int INVALID_HANDLE = 10002; - - /** - * Error code indicating that the client request is not supported/implemented. - */ - final static int NOT_SUPPORTED = 10003; - - /** - * Error code indicating that the request to a sub-service or an external process - * failed. - */ - final static int REQUEST_FAILED = 10004; - - /** - * Error code indicating an unexpected condition in the service, i.e. programming error. - */ - final static int INTERNAL_ERROR = 10005; - + /** * Returns the DSF Session that this service belongs to. */ diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileVMNode.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileVMNode.java index eacebbe7b47..1d40f990503 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileVMNode.java +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileVMNode.java @@ -22,9 +22,9 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.internal.ui.DsfUIPlugin; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.IVMNode; import org.eclipse.dd.dsf.ui.viewmodel.IVMProvider; @@ -190,7 +190,7 @@ class FileVMNode } public void getContextsForEvent(VMDelta parentDelta, Object event, DataRequestMonitor rm) { - rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.NOT_SUPPORTED, "", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.NOT_SUPPORTED, "", null)); //$NON-NLS-1$ rm.done(); } diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/ServicesShutdownSequence.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/ServicesShutdownSequence.java index 0df9281a21d..ca306b8b5ff 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/ServicesShutdownSequence.java +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/ServicesShutdownSequence.java @@ -12,6 +12,7 @@ package org.eclipse.dd.examples.dsf.timers; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.concurrent.Sequence; import org.eclipse.dd.dsf.service.DsfServicesTracker; @@ -90,7 +91,7 @@ public class ServicesShutdownSequence extends Sequence { else { requestMonitor.setStatus(new Status( IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, - IDsfService.INTERNAL_ERROR, + IDsfStatusConstants.INTERNAL_ERROR, "Service '" + clazz.getName() + "' not found.", null)); requestMonitor.done(); } diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TriggerCellModifier.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TriggerCellModifier.java index 8b02fb5b788..ef49cd42742 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TriggerCellModifier.java +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TriggerCellModifier.java @@ -17,12 +17,12 @@ import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.Query; import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.concurrent.ThreadSafeAndProhibitedFromDsfExecutor; import org.eclipse.dd.dsf.service.DsfServices; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; import org.eclipse.dd.examples.dsf.timers.AlarmService.TriggerDMContext; import org.eclipse.jface.dialogs.MessageDialog; @@ -199,7 +199,7 @@ public class TriggerCellModifier implements ICellModifier { AlarmService service = getService(fDmc); if (service == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, + rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Service not available", null)); rm.done(); return; @@ -207,7 +207,7 @@ public class TriggerCellModifier implements ICellModifier { int value = service.getTriggerValue(fDmc); if (value == -1) { - rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, + rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_HANDLE, "Invalid context", null)); rm.done(); return; @@ -241,7 +241,7 @@ public class TriggerCellModifier implements ICellModifier { // Guard against a disposed service AlarmService service = getService(fDmc); if (service == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, + rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Service not available", null)); rm.done(); return; diff --git a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/AsyncDataViewer.java b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/AsyncDataViewer.java index b9e04d83d2b..da828939503 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/AsyncDataViewer.java +++ b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/AsyncDataViewer.java @@ -199,7 +199,7 @@ public class AsyncDataViewer if (item.fIndex < topIdx || item.fIndex > botIdx) { // Set the item to canceled status, so that the data provider // will ignore it. - item.setCanceled(true); + item.cancel(); // Add the item index to list of indexes that were canceled, // which will be sent to the table widget. diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java index 7404dbad668..f0056268c7e 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java @@ -13,6 +13,7 @@ package org.eclipse.dd.examples.pda.launch; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.concurrent.Sequence; import org.eclipse.dd.dsf.debug.service.BreakpointsMediator; @@ -133,7 +134,7 @@ public class PDAServicesShutdownSequence extends Sequence { } }); } else { - requestMonitor.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, + requestMonitor.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Service '" + clazz.getName() + "' not found.", null)); //$NON-NLS-1$//$NON-NLS-2$ requestMonitor.done(); } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpoints.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpoints.java index adfa26047b1..5e4b733ea96 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpoints.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpoints.java @@ -253,11 +253,11 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints } @Override - protected void handleErrorOrCancel() { + protected void handleCancelOrErrorOrWarning() { // If inserting of the breakpoint failed, remove it from // the set of installed breakpoints. fBreakpoints.remove(breakpointCtx); - super.handleErrorOrCancel(); + super.handleCancelOrErrorOrWarning(); } }); } @@ -319,11 +319,11 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints } @Override - protected void handleErrorOrCancel() { + protected void handleCancelOrErrorOrWarning() { // Since the command failed, we need to remove the breakpoint from // the existing breakpoint set. fBreakpoints.remove(watchpointCtx); - super.handleErrorOrCancel(); + super.handleCancelOrErrorOrWarning(); } }); } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java index bf4fbedf66b..02462870cbe 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java @@ -14,6 +14,7 @@ package org.eclipse.dd.examples.pda.service; import java.util.Hashtable; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.AbstractDMEvent; @@ -24,7 +25,6 @@ import org.eclipse.dd.dsf.debug.service.command.IEventListener; import org.eclipse.dd.dsf.service.AbstractDsfService; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.examples.pda.PDAPlugin; import org.eclipse.dd.examples.pda.service.commands.PDACommandResult; import org.eclipse.dd.examples.pda.service.commands.PDAResumeCommand; @@ -244,11 +244,11 @@ public class PDARunControl extends AbstractDsfService new PDAResumeCommand(fCommandControl.getProgramDMContext()), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleErrorOrCancel() { + protected void handleCancelOrErrorOrWarning() { // If the resume command failed, we no longer // expect to receive a resumed event. fResumePending = false; - super.handleErrorOrCancel(); + super.handleCancelOrErrorOrWarning(); } } ); @@ -266,7 +266,7 @@ public class PDARunControl extends AbstractDsfService new DataRequestMonitor(getExecutor(), rm)); } else { - PDAPlugin.failRequest(rm, IDsfService.INVALID_STATE, "Given context: " + context + ", is already suspended."); + PDAPlugin.failRequest(rm, IDsfStatusConstants.INVALID_STATE, "Given context: " + context + ", is already suspended."); } } @@ -285,7 +285,7 @@ public class PDARunControl extends AbstractDsfService new PDAStepCommand(fCommandControl.getProgramDMContext()), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleErrorOrCancel() { + protected void handleCancelOrErrorOrWarning() { // If the step command failed, we no longer // expect to receive a resumed event. fResumePending = false; diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java index 6aa231cc771..a54126b9c8d 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java @@ -14,6 +14,7 @@ import java.util.Hashtable; import org.eclipse.cdt.core.IAddress; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.AbstractDMContext; @@ -29,7 +30,6 @@ import org.eclipse.dd.dsf.debug.service.command.CommandCache; import org.eclipse.dd.dsf.service.AbstractDsfService; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.examples.pda.PDAPlugin; import org.eclipse.dd.examples.pda.service.commands.PDAFrame; import org.eclipse.dd.examples.pda.service.commands.PDAStackCommand; @@ -215,7 +215,7 @@ public class PDAStack extends AbstractDsfService implements IStack { public void getArguments(IFrameDMContext frameCtx, DataRequestMonitor rm) { - PDAPlugin.failRequest(rm, IDsfService.NOT_SUPPORTED, "PDA debugger does not support function arguments."); + PDAPlugin.failRequest(rm, IDsfStatusConstants.NOT_SUPPORTED, "PDA debugger does not support function arguments."); } public void getFrameData(final IFrameDMContext frameCtx, final DataRequestMonitor rm) { @@ -229,7 +229,7 @@ public class PDAStack extends AbstractDsfService implements IStack { // calculate the index based on frame level. int frameId = getData().fFrames.length - frameCtx.getLevel() - 1; if (frameId < 0) { - PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid frame level " + frameCtx); + PDAPlugin.failRequest(rm, IDsfStatusConstants.INVALID_HANDLE, "Invalid frame level " + frameCtx); return; } @@ -248,7 +248,7 @@ public class PDAStack extends AbstractDsfService implements IStack { // hierarchy of the argument context to find the execution one. final IExecutionDMContext execCtx = DMContexts.getAncestorOfType(context, IExecutionDMContext.class); if (execCtx == null) { - PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid context " + context); + PDAPlugin.failRequest(rm, IDsfStatusConstants.INVALID_HANDLE, "Invalid context " + context); return; } @@ -278,7 +278,7 @@ public class PDAStack extends AbstractDsfService implements IStack { // Find the correct PDAFrame int frameId = getData().fFrames.length - frameCtx.getLevel() - 1; if (frameId < 0) { - PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid frame level " + frameCtx); + PDAPlugin.failRequest(rm, IDsfStatusConstants.INVALID_HANDLE, "Invalid frame level " + frameCtx); return; } PDAFrame pdaFrame = getData().fFrames[frameId]; @@ -315,7 +315,7 @@ public class PDAStack extends AbstractDsfService implements IStack { // hierarchy of the argument context to find the execution one. final IExecutionDMContext execCtx = DMContexts.getAncestorOfType(context, IExecutionDMContext.class); if (execCtx == null) { - PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid context " + context); + PDAPlugin.failRequest(rm, IDsfStatusConstants.INVALID_HANDLE, "Invalid context " + context); return; } @@ -327,7 +327,7 @@ public class PDAStack extends AbstractDsfService implements IStack { public void getVariableData(IVariableDMContext variableCtx, DataRequestMonitor rm) { if ( !(variableCtx instanceof VariableDMContext) ) { - PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid context " + variableCtx); + PDAPlugin.failRequest(rm, IDsfStatusConstants.INVALID_HANDLE, "Invalid context " + variableCtx); return; } @@ -356,7 +356,7 @@ public class PDAStack extends AbstractDsfService implements IStack { } else if (dmc instanceof IVariableDMContext) { getVariableData((IVariableDMContext)dmc, (DataRequestMonitor)rm); } else { - PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Unknown context type"); + PDAPlugin.failRequest(rm, IDsfStatusConstants.INVALID_HANDLE, "Unknown context type"); } } diff --git a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/GdbLaunch.java b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/GdbLaunch.java index c864884cb40..3127d6c650e 100644 --- a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/GdbLaunch.java +++ b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/GdbLaunch.java @@ -21,6 +21,7 @@ import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor; import org.eclipse.dd.dsf.concurrent.DsfExecutor; import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.concurrent.Sequence; @@ -28,7 +29,6 @@ import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.gdb.launch.internal.GdbLaunchPlugin; import org.eclipse.dd.gdb.service.command.GDBControl; import org.eclipse.debug.core.DebugException; @@ -83,9 +83,9 @@ public class GdbLaunch extends Launch try { fExecutor.submit(initRunnable).get(); } catch (InterruptedException e) { - new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Error initializing launch", e); //$NON-NLS-1$ + new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Error initializing launch", e); //$NON-NLS-1$ } catch (ExecutionException e) { - new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Error initializing launch", e); //$NON-NLS-1$ + new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Error initializing launch", e); //$NON-NLS-1$ } } diff --git a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/ShutdownSequence.java b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/ShutdownSequence.java index 4ddab9e913f..f241dc1021e 100644 --- a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/ShutdownSequence.java +++ b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/ShutdownSequence.java @@ -13,6 +13,7 @@ package org.eclipse.dd.gdb.launch.launching; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.concurrent.Sequence; import org.eclipse.dd.dsf.service.DsfServicesTracker; @@ -98,7 +99,7 @@ public class ShutdownSequence extends Sequence { // } // }); // } else { -// requestMonitor.setStatus(new Status(IStatus.ERROR, DsfGdbLaunchPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, +// requestMonitor.setStatus(new Status(IStatus.ERROR, DsfGdbLaunchPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, // "Needed services not found.", null)); //$NON-NLS-1$ // requestMonitor.done(); // } @@ -171,7 +172,7 @@ public class ShutdownSequence extends Sequence { } }); } else { - requestMonitor.setStatus(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, + requestMonitor.setStatus(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Service '" + clazz.getName() + "' not found.", null)); //$NON-NLS-1$//$NON-NLS-2$ requestMonitor.done(); } diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/GdbThreadFilterEditor.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/GdbThreadFilterEditor.java index cec2b7a7564..23d5cc67026 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/GdbThreadFilterEditor.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/GdbThreadFilterEditor.java @@ -20,6 +20,7 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; import org.eclipse.dd.dsf.concurrent.Query; import org.eclipse.dd.dsf.datamodel.DMContexts; @@ -27,7 +28,6 @@ import org.eclipse.dd.dsf.debug.service.IRunControl; import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; 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.gdb.breakpoints.CBreakpointGdbThreadsFilterExtension; import org.eclipse.dd.gdb.internal.ui.GdbUIPlugin; import org.eclipse.dd.gdb.launch.launching.GdbLaunch; @@ -368,7 +368,7 @@ public class GdbThreadFilterEditor { @Override protected void execute(DataRequestMonitor rm) { if (!session.isActive()) { - rm.setStatus(getFailStatus(IDsfService.INVALID_STATE, "Launch's session not active.")); //$NON-NLS-1$ + rm.setStatus(getFailStatus(IDsfStatusConstants.INVALID_STATE, "Launch's session not active.")); //$NON-NLS-1$ rm.done(); return; } @@ -380,7 +380,7 @@ public class GdbThreadFilterEditor { if (gdbControl != null) { rm.setData(gdbControl.getGDBDMContext()); } else { - rm.setStatus(getFailStatus(IDsfService.INVALID_STATE, "GDB Control not accessible.")); //$NON-NLS-1$ + rm.setStatus(getFailStatus(IDsfStatusConstants.INVALID_STATE, "GDB Control not accessible.")); //$NON-NLS-1$ } rm.done(); tracker.close(); @@ -408,7 +408,7 @@ public class GdbThreadFilterEditor { @Override protected void execute(DataRequestMonitor rm) { if (!session.isActive()) { - rm.setStatus(getFailStatus(IDsfService.INVALID_STATE, "Container's session not active.")); //$NON-NLS-1$ + rm.setStatus(getFailStatus(IDsfStatusConstants.INVALID_STATE, "Container's session not active.")); //$NON-NLS-1$ rm.done(); return; } @@ -420,7 +420,7 @@ public class GdbThreadFilterEditor { if (runControl != null) { runControl.getExecutionContexts(container, rm); } else { - rm.setStatus(getFailStatus(IDsfService.INVALID_STATE, "GDB Control not accessible.")); //$NON-NLS-1$ + rm.setStatus(getFailStatus(IDsfStatusConstants.INVALID_STATE, "GDB Control not accessible.")); //$NON-NLS-1$ rm.done(); } tracker.close(); @@ -448,7 +448,7 @@ public class GdbThreadFilterEditor { @Override protected void execute(DataRequestMonitor rm) { if (!session.isActive()) { - rm.setStatus(getFailStatus(IDsfService.INVALID_STATE, "Container's session not active.")); //$NON-NLS-1$ + rm.setStatus(getFailStatus(IDsfStatusConstants.INVALID_STATE, "Container's session not active.")); //$NON-NLS-1$ rm.done(); return; } @@ -460,7 +460,7 @@ public class GdbThreadFilterEditor { if (gdbControl != null) { rm.setData(gdbControl.getExecutablePath().toOSString()); } else { - rm.setStatus(getFailStatus(IDsfService.INVALID_STATE, "GDB Control not accessible.")); //$NON-NLS-1$ + rm.setStatus(getFailStatus(IDsfStatusConstants.INVALID_STATE, "GDB Control not accessible.")); //$NON-NLS-1$ } rm.done(); tracker.close(); @@ -488,7 +488,7 @@ public class GdbThreadFilterEditor { @Override protected void execute(final DataRequestMonitor rm) { if (!session.isActive()) { - rm.setStatus(getFailStatus(IDsfService.INVALID_STATE, "Container's session not active.")); //$NON-NLS-1$ + rm.setStatus(getFailStatus(IDsfStatusConstants.INVALID_STATE, "Container's session not active.")); //$NON-NLS-1$ rm.done(); return; } @@ -513,7 +513,7 @@ public class GdbThreadFilterEditor { } }); } else { - rm.setStatus(getFailStatus(IDsfService.INVALID_STATE, "GDB Control not accessible.")); //$NON-NLS-1$ + rm.setStatus(getFailStatus(IDsfStatusConstants.INVALID_STATE, "GDB Control not accessible.")); //$NON-NLS-1$ rm.done(); } tracker.close(); diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ThreadVMNode.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ThreadVMNode.java index fefd36c28a9..2f2c15e0ae4 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ThreadVMNode.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ThreadVMNode.java @@ -18,6 +18,7 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; @@ -33,7 +34,6 @@ import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent; import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason; import org.eclipse.dd.dsf.internal.ui.DsfUIPlugin; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.ModelProxyInstalledEvent; import org.eclipse.dd.dsf.ui.viewmodel.VMChildrenUpdate; @@ -177,17 +177,17 @@ public class ThreadVMNode extends AbstractDMVMNode } else if (vmcIdx >= 0) { rm.setData(new VMContextInfo((IVMContext)getData().get(vmcIdx), vmcIdx, false)); } else { - rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, "No threads available", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, "No threads available", null)); //$NON-NLS-1$ } rm.done(); } else { - rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, "No threads available", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, "No threads available", null)); //$NON-NLS-1$ rm.done(); } } }); } catch (RejectedExecutionException e) { - rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.NOT_SUPPORTED, "", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.NOT_SUPPORTED, "", null)); //$NON-NLS-1$ rm.done(); } } diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControl.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControl.java index ef6b93238d0..c4e450184ef 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControl.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControl.java @@ -32,13 +32,13 @@ import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.concurrent.Sequence; import org.eclipse.dd.dsf.datamodel.AbstractDMEvent; import org.eclipse.dd.dsf.debug.service.command.ICommandControl; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.gdb.internal.GdbPlugin; import org.eclipse.dd.mi.service.command.AbstractCLIProcess; import org.eclipse.dd.mi.service.command.AbstractMIControl; @@ -458,7 +458,7 @@ public class GDBControl extends AbstractMIControl { attempts++; } requestMonitor.setStatus(new Status( - IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, "Process terminate failed", null)); //$NON-NLS-1$ + IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, "Process terminate failed", null)); //$NON-NLS-1$ requestMonitor.done(); return Status.OK_STATUS; } @@ -534,7 +534,7 @@ public class GDBControl extends AbstractMIControl { fCLIProcess = new GDBCLIProcess(GDBControl.this, fUseInterpreterConsole); } catch(IOException e) { - requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, "Failed to create CLI Process", e)); //$NON-NLS-1$ + requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, "Failed to create CLI Process", e)); //$NON-NLS-1$ requestMonitor.done(); return; } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/CSourceLookup.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/CSourceLookup.java index 7390c09f05a..333389f510b 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/CSourceLookup.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/CSourceLookup.java @@ -28,12 +28,12 @@ import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.debug.service.ISourceLookup; import org.eclipse.dd.dsf.debug.service.command.ICommandControl; import org.eclipse.dd.dsf.service.AbstractDsfService; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.mi.internal.MIPlugin; import org.eclipse.dd.mi.service.command.commands.MIEnvironmentDirectory; import org.eclipse.dd.mi.service.command.output.MIInfo; @@ -137,14 +137,14 @@ public class CSourceLookup extends AbstractDsfService implements ISourceLookup { { if (! (source instanceof String)) { // In future if needed other elements such as URIs could be supported. - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.NOT_SUPPORTED, "Only string source element is supported", null)); //$NON-NLS-1$); + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfStatusConstants.NOT_SUPPORTED, "Only string source element is supported", null)); //$NON-NLS-1$); rm.done(); return; } final String sourceString = (String) source; if (!fDirectors.containsKey(sourceLookupCtx) ){ - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "No source director configured for given context", null)); //$NON-NLS-1$); + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_HANDLE, "No source director configured for given context", null)); //$NON-NLS-1$); rm.done(); return; } @@ -170,7 +170,7 @@ public class CSourceLookup extends AbstractDsfService implements ISourceLookup { public void getSource(ISourceLookupDMContext sourceLookupCtx, final String debuggerPath, final DataRequestMonitor rm) { if (!fDirectors.containsKey(sourceLookupCtx) ){ - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "No source director configured for given context", null)); //$NON-NLS-1$); + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_HANDLE, "No source director configured for given context", null)); //$NON-NLS-1$); rm.done(); return; } @@ -183,12 +183,12 @@ public class CSourceLookup extends AbstractDsfService implements ISourceLookup { try { sources = director.findSourceElements(debuggerPath); if (sources == null || sources.length == 0) { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, "No sources found", null)); //$NON-NLS-1$); + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, "No sources found", null)); //$NON-NLS-1$); } else { rm.setData(sources[0]); } } catch (CoreException e) { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, "Source lookup failed", e)); //$NON-NLS-1$); + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, "Source lookup failed", e)); //$NON-NLS-1$); } finally { rm.done(); } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpoints.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpoints.java index 8f97eb51a53..5f6dfe7b801 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpoints.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpoints.java @@ -30,7 +30,6 @@ import org.eclipse.dd.dsf.debug.service.command.ICommandControl; import org.eclipse.dd.dsf.service.AbstractDsfService; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.mi.internal.MIPlugin; import org.eclipse.dd.mi.service.command.commands.MIBreakAfter; import org.eclipse.dd.mi.service.command.commands.MIBreakCondition; @@ -291,7 +290,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints { // Validate the context if (context == null) { - drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_EXECUTION_CONTEXT, null)); + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_EXECUTION_CONTEXT, null)); drm.done(); return; } @@ -338,7 +337,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints { // Validate the breakpoint context if (dmc == null) { - drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); drm.done(); return; } @@ -349,7 +348,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints breakpoint = (MIBreakpointDMContext) dmc; } else { - drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT_TYPE, null)); + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_TYPE, null)); drm.done(); return; } @@ -357,7 +356,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints // Validate the target context IBreakpointsTargetDMContext context = DMContexts.getAncestorOfType(breakpoint, IBreakpointsTargetDMContext.class); if (context == null) { - drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_EXECUTION_CONTEXT, null)); + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_EXECUTION_CONTEXT, null)); drm.done(); return; } @@ -365,7 +364,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints // Select the breakpoints context map Map contextBreakpoints = fBreakpoints.get(context); if (contextBreakpoints == null) { - drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); drm.done(); return; } @@ -387,7 +386,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints // Validate the context if (context == null) { - drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_EXECUTION_CONTEXT, null)); + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_EXECUTION_CONTEXT, null)); drm.done(); return; } @@ -402,7 +401,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints // Validate the breakpoint type String type = (String) attributes.get(BREAKPOINT_TYPE); if (type == null) { - drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT_TYPE, null)); + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_TYPE, null)); drm.done(); return; } @@ -415,7 +414,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints addWatchpoint(context, attributes, drm); } else { - drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT_TYPE, null)); + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_TYPE, null)); drm.done(); } } @@ -467,7 +466,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints // Select the context breakpoints map final Map contextBreakpoints = fBreakpoints.get(context); if (contextBreakpoints == null) { - drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); drm.done(); return; } @@ -489,7 +488,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints // With MI, an invalid location won't generate an error if (getData().getMIBreakpoints().length == 0) { - drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, BREAKPOINT_INSERTION_FAILURE, null)); + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, BREAKPOINT_INSERTION_FAILURE, null)); drm.done(); return; } @@ -498,7 +497,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints final MIBreakpointDMData newBreakpoint = new MIBreakpointDMData(getData().getMIBreakpoints()[0]); int reference = newBreakpoint.getNumber(); if (reference == -1) { - drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, BREAKPOINT_INSERTION_FAILURE, null)); + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, BREAKPOINT_INSERTION_FAILURE, null)); drm.done(); return; } @@ -520,7 +519,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints @Override protected void handleError() { - drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, BREAKPOINT_INSERTION_FAILURE, null)); + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, BREAKPOINT_INSERTION_FAILURE, null)); drm.done(); } }; @@ -542,7 +541,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints // Pick the context breakpoints map final Map contextBreakpoints = fBreakpoints.get(context); if (contextBreakpoints == null) { - drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); drm.done(); return; } @@ -560,7 +559,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints // With MI, an invalid location won't generate an error if (getData().getMIBreakpoints().length == 0) { - drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, WATCHPOINT_INSERTION_FAILURE, null)); + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, WATCHPOINT_INSERTION_FAILURE, null)); drm.done(); return; } @@ -569,7 +568,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints final MIBreakpointDMData newBreakpoint = new MIBreakpointDMData(getData().getMIBreakpoints()[0]); int reference = newBreakpoint.getNumber(); if (reference == -1) { - drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, WATCHPOINT_INSERTION_FAILURE, null)); + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, WATCHPOINT_INSERTION_FAILURE, null)); drm.done(); return; } @@ -593,7 +592,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints @Override protected void handleError() { - drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, WATCHPOINT_INSERTION_FAILURE, null)); + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, WATCHPOINT_INSERTION_FAILURE, null)); drm.done(); } }; @@ -613,7 +612,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints // Validate the breakpoint context if (dmc == null) { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); rm.done(); return; } @@ -624,7 +623,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints breakpointCtx = (MIBreakpointDMContext) dmc; } else { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT_TYPE, null)); + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_TYPE, null)); rm.done(); return; } @@ -632,7 +631,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints // Validate the target context IBreakpointsTargetDMContext context = DMContexts.getAncestorOfType(dmc, IBreakpointsTargetDMContext.class); if (context == null) { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_EXECUTION_CONTEXT, null)); + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_EXECUTION_CONTEXT, null)); rm.done(); return; } @@ -640,7 +639,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints // Pick the context breakpoints map final Map contextBreakpoints = fBreakpoints.get(context); if (contextBreakpoints == null) { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); rm.done(); return; } @@ -649,7 +648,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints final int reference = breakpointCtx.getReference(); MIBreakpointDMData breakpoint = contextBreakpoints.get(reference); if (breakpoint == null) { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); rm.done(); return; } @@ -680,7 +679,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints { // Validate the breakpoint context if (dmc == null) { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); rm.done(); return; } @@ -691,7 +690,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints breakpointCtx = (MIBreakpointDMContext) dmc; } else { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT_TYPE, null)); + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_TYPE, null)); rm.done(); return; } @@ -699,7 +698,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints // Validate the context IBreakpointsTargetDMContext context = DMContexts.getAncestorOfType(dmc, IBreakpointsTargetDMContext.class); if (context == null) { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_EXECUTION_CONTEXT, null)); + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_EXECUTION_CONTEXT, null)); rm.done(); return; } @@ -707,7 +706,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints // Pick the context breakpoints map final Map contextBreakpoints = fBreakpoints.get(context); if (contextBreakpoints == null) { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); rm.done(); return; } @@ -716,7 +715,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints final int reference = breakpointCtx.getReference(); MIBreakpointDMData breakpoint = contextBreakpoints.get(reference); if (breakpoint == null) { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); rm.done(); return; } @@ -814,7 +813,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints // Pick the context breakpoints map final Map contextBreakpoints = fBreakpoints.get(context); if (contextBreakpoints == null) { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); rm.done(); return; } @@ -827,7 +826,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints protected void handleCompleted() { MIBreakpointDMData breakpoint = contextBreakpoints.get(reference); if (breakpoint == null) { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); rm.done(); return; } @@ -835,7 +834,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints breakpoint.setCondition(condition); } else { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, INVALID_CONDITION, null)); + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, INVALID_CONDITION, null)); breakpoint.setCondition(NULL_STRING); } rm.done(); @@ -858,7 +857,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints // Pick the context breakpoints map final Map contextBreakpoints = fBreakpoints.get(context); if (contextBreakpoints == null) { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); rm.done(); return; } @@ -871,7 +870,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints protected void handleOK() { MIBreakpointDMData breakpoint = contextBreakpoints.get(reference); if (breakpoint == null) { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); rm.done(); return; } @@ -894,7 +893,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints // Pick the context breakpoints map final Map contextBreakpoints = fBreakpoints.get(context); if (contextBreakpoints == null) { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); rm.done(); return; } @@ -907,7 +906,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints protected void handleOK() { MIBreakpointDMData breakpoint = contextBreakpoints.get(reference); if (breakpoint == null) { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); rm.done(); return; } @@ -930,7 +929,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints // Pick the context breakpoints map final Map contextBreakpoints = fBreakpoints.get(context); if (contextBreakpoints == null) { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); rm.done(); return; } @@ -943,7 +942,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints protected void handleOK() { MIBreakpointDMData breakpoint = contextBreakpoints.get(reference); if (breakpoint == null) { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); rm.done(); return; } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIMemory.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIMemory.java index ef259a8ae72..b958bcdec73 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIMemory.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIMemory.java @@ -23,6 +23,7 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.AbstractDMEvent; import org.eclipse.dd.dsf.datamodel.DMContexts; @@ -38,7 +39,6 @@ import org.eclipse.dd.dsf.debug.service.command.ICommandControl; import org.eclipse.dd.dsf.service.AbstractDsfService; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.mi.internal.MIPlugin; import org.eclipse.dd.mi.service.ExpressionService.ExpressionChangedEvent; import org.eclipse.dd.mi.service.command.commands.MIDataReadMemory; @@ -173,14 +173,14 @@ public class MIMemory extends AbstractDsfService implements IMemory { // Validate the word size // NOTE: We only accept 1 byte words for this implementation if (word_size != 1) { - drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.NOT_SUPPORTED, "Word size not supported (!= 1)", null)); //$NON-NLS-1$ + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, "Word size not supported (!= 1)", null)); //$NON-NLS-1$ drm.done(); return; } // Validate the byte count if (count < 0) { - drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Invalid word count (< 0)", null)); //$NON-NLS-1$ + drm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Invalid word count (< 0)", null)); //$NON-NLS-1$ drm.done(); return; } @@ -205,21 +205,21 @@ public class MIMemory extends AbstractDsfService implements IMemory { // Validate the word size // NOTE: We only accept 1 byte words for this implementation if (word_size != 1) { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.NOT_SUPPORTED, "Word size not supported (!= 1)", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, "Word size not supported (!= 1)", null)); //$NON-NLS-1$ rm.done(); return; } // Validate the byte count if (count < 0) { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Invalid word count (< 0)", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Invalid word count (< 0)", null)); //$NON-NLS-1$ rm.done(); return; } // Validate the buffer size if (buffer.length < count) { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Buffer too short", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Buffer too short", null)); //$NON-NLS-1$ rm.done(); return; } @@ -244,21 +244,21 @@ public class MIMemory extends AbstractDsfService implements IMemory { // Validate the word size // NOTE: We only accept 1 byte words for this implementation if (word_size != 1) { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.NOT_SUPPORTED, "Word size not supported (!= 1)", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, "Word size not supported (!= 1)", null)); //$NON-NLS-1$ rm.done(); return; } // Validate the repeat count if (count < 0) { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Invalid repeat count (< 0)", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Invalid repeat count (< 0)", null)); //$NON-NLS-1$ rm.done(); return; } // Validate the pattern if (pattern.length < 1) { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Empty pattern", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Empty pattern", null)); //$NON-NLS-1$ rm.done(); return; } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRegisters.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRegisters.java index 56c17b4eb45..596a4b70ab2 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRegisters.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRegisters.java @@ -276,7 +276,7 @@ public class MIRegisters extends AbstractDsfService implements IRegisters { // If the list is empty just return empty handed. if (regValue.length == 0) { assert false : "Backend protocol error"; //$NON-NLS-1$ - //done.setStatus(new Status(IStatus.ERROR, IDsfService.INTERNAL_ERROR ,)); + //done.setStatus(new Status(IStatus.ERROR, IDsfStatusConstants.INTERNAL_ERROR ,)); rm.done(); return; } @@ -331,7 +331,7 @@ public class MIRegisters extends AbstractDsfService implements IRegisters { // If the list is empty just return empty handed. if (regValue.length == 0) { assert false : "Backend protocol error"; //$NON-NLS-1$ - //done.setStatus(new Status(IStatus.ERROR, IDsfService.INTERNAL_ERROR ,)); + //done.setStatus(new Status(IStatus.ERROR, IDsfStatusConstants.INTERNAL_ERROR ,)); rm.done(); return; } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java index 644182278e4..1e7fb7ea3ab 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java @@ -28,7 +28,6 @@ import org.eclipse.dd.dsf.debug.service.command.ICommandControl; import org.eclipse.dd.dsf.service.AbstractDsfService; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.mi.internal.MIPlugin; import org.eclipse.dd.mi.service.command.commands.MIExecContinue; import org.eclipse.dd.mi.service.command.commands.MIExecFinish; @@ -475,7 +474,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl else{ IMIExecutionDMContext dmc = DMContexts.getAncestorOfType(context, IMIExecutionDMContext.class); if (dmc == null){ - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Given context: " + context + " is not an execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$ + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_STATE, "Given context: " + context + " is not an execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$ rm.done(); return; } @@ -491,7 +490,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl } ); }else { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Given context: " + context + ", is already running.", null)); //$NON-NLS-1$ //$NON-NLS-2$ + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_STATE, "Given context: " + context + ", is already running.", null)); //$NON-NLS-1$ //$NON-NLS-2$ rm.done(); } } @@ -507,7 +506,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl else { IMIExecutionDMContext dmc = DMContexts.getAncestorOfType(context, IMIExecutionDMContext.class); if (dmc == null){ - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Given context: " + context + " is not an execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$ + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, "Given context: " + context + " is not an execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$ rm.done(); return; } @@ -523,7 +522,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl } ); } else { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Given context: " + context + ", is already suspended.", null)); //$NON-NLS-1$ //$NON-NLS-2$ + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, "Given context: " + context + ", is already suspended.", null)); //$NON-NLS-1$ //$NON-NLS-2$ rm.done(); } } @@ -537,7 +536,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl IMIExecutionDMContext dmc = DMContexts.getAncestorOfType(context, IMIExecutionDMContext.class); if (dmc == null){ - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Given context: " + context + " is not an execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$ + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, "Given context: " + context + " is not an execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$ rm.done(); return; } @@ -574,12 +573,12 @@ public class MIRunControl extends AbstractDsfService implements IRunControl fConnection.queueCommand( new MIExecFinish(topFrameDmc), new DataRequestMonitor(getExecutor(), rm) {}); } else { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Cannot create context for command, stack service not available.", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, "Cannot create context for command, stack service not available.", null)); //$NON-NLS-1$ rm.done(); } break; default: - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Given step type not supported", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INTERNAL_ERROR, "Given step type not supported", null)); //$NON-NLS-1$ rm.done(); } } @@ -643,7 +642,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl IMIExecutionDMContext dmc = DMContexts.getAncestorOfType(context, IMIExecutionDMContext.class); if (dmc == null){ - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Given context: " + context + " is not an execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$ + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, "Given context: " + context + " is not an execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$ rm.done(); return; } @@ -660,7 +659,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl } }); } else { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, "Cannot resume given DMC.", null)); //$NON-NLS-1$ rm.done(); } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIStack.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIStack.java index 59582892581..7baa34260f8 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIStack.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIStack.java @@ -34,7 +34,6 @@ import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason; import org.eclipse.dd.dsf.service.AbstractDsfService; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.mi.internal.MIPlugin; import org.eclipse.dd.mi.service.command.commands.MIStackInfoDepth; import org.eclipse.dd.mi.service.command.commands.MIStackListArguments; @@ -166,7 +165,7 @@ public class MIStack extends AbstractDsfService getVariableData((MIVariableDMC)dmc, (DataRequestMonitor)rm); // getVariablesData invokes rm } else { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ rm.done(); } } @@ -198,7 +197,7 @@ public class MIStack extends AbstractDsfService if (execDmc == null) { //rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, -1, "No frame context found in " + ctx, null)); //$NON-NLS-1$ - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context" + ctx, null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context" + ctx, null)); //$NON-NLS-1$ rm.done(); return; } @@ -216,7 +215,7 @@ public class MIStack extends AbstractDsfService public void getTopFrame(final IDMContext ctx, final DataRequestMonitor rm) { final IMIExecutionDMContext execDmc = DMContexts.getAncestorOfType(ctx, IMIExecutionDMContext.class); if (execDmc == null) { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context" + ctx, null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context" + ctx, null)); //$NON-NLS-1$ rm.done(); return; } @@ -258,7 +257,7 @@ public class MIStack extends AbstractDsfService public void getFrameData(final IFrameDMContext frameDmc, final DataRequestMonitor rm) { if (!(frameDmc instanceof MIFrameDMC)) { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context type " + frameDmc, null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context type " + frameDmc, null)); //$NON-NLS-1$ rm.done(); return; } @@ -267,7 +266,7 @@ public class MIStack extends AbstractDsfService IMIExecutionDMContext execDmc = DMContexts.getAncestorOfType(frameDmc, IMIExecutionDMContext.class); if (execDmc == null) { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "No execution context found in " + frameDmc, null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "No execution context found in " + frameDmc, null)); //$NON-NLS-1$ rm.done(); return; } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java index b445a0619d4..82390639728 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java @@ -24,6 +24,7 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.debug.service.IExpressions; @@ -44,7 +45,6 @@ import org.eclipse.dd.dsf.service.AbstractDsfService; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.mi.internal.MIPlugin; import org.eclipse.dd.mi.service.ExpressionService.ExpressionInfo; import org.eclipse.dd.mi.service.ExpressionService.MIExpressionDMC; @@ -822,7 +822,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon // If the variable is a complex structure (including an array), then we cannot write to it if (isComplex()) { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, "Cannot change the value of a complex expression", null)); //$NON-NLS-1$ rm.done(); return; @@ -849,7 +849,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon try { value = Integer.toString(Integer.parseInt(value, 2)); } catch (NumberFormatException e) { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_HANDLE, "Invalid binary number: " + value, e)); //$NON-NLS-1$ rm.done(); return; @@ -864,7 +864,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon // we do nothing for now and let the user have put in the proper value } else { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_HANDLE, "Unknown format: " + formatId, null)); //$NON-NLS-1$ rm.done(); return; @@ -874,7 +874,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon // Return a status info so that handleOK is not called and we don't send // an ExpressionChanged event if (value.equals(getValue(formatId))) { - rm.setStatus(new Status(IStatus.INFO, MIPlugin.PLUGIN_ID, IDsfService.NOT_SUPPORTED, + rm.setStatus(new Status(IStatus.INFO, MIPlugin.PLUGIN_ID, IDsfStatusConstants.NOT_SUPPORTED, "Setting to the same value of: " + value, null)); //$NON-NLS-1$ rm.done(); return; @@ -1607,7 +1607,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon // This does not use the variable objects but sends the command directly to the back-end fCommandControl.queueCommand(command, rm); } else { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Unexpected Expression Meta command", null)); //$NON-NLS-1$ rm.done(); } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java index a2d3b3741f0..62a6be29442 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java @@ -39,7 +39,6 @@ import org.eclipse.dd.dsf.debug.service.command.ICommandResult; import org.eclipse.dd.dsf.debug.service.command.IEventListener; import org.eclipse.dd.dsf.service.AbstractDsfService; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.mi.internal.MIPlugin; import org.eclipse.dd.mi.service.IMIExecutionDMContext; import org.eclipse.dd.mi.service.command.commands.MICommand; @@ -133,7 +132,7 @@ public abstract class AbstractMIControl extends AbstractDsfService */ private Status genStatus(String str) { - return new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, str, null); + return new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_STATE, str, null); } protected void stopCommandProcessing() { @@ -631,7 +630,7 @@ public abstract class AbstractMIControl extends AbstractDsfService if ( errorResult.equals(MIResultRecord.ERROR) ) { String status = getStatusString(commandHandle.getCommand(),response); - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, status, null)); + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, status, null)); } /* diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIInferiorProcess.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIInferiorProcess.java index 83bdc774da0..fbc80308ab4 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIInferiorProcess.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIInferiorProcess.java @@ -29,6 +29,7 @@ import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; import org.eclipse.dd.dsf.concurrent.Query; import org.eclipse.dd.dsf.debug.service.command.ICommand; @@ -36,7 +37,6 @@ import org.eclipse.dd.dsf.debug.service.command.ICommandListener; import org.eclipse.dd.dsf.debug.service.command.ICommandResult; import org.eclipse.dd.dsf.debug.service.command.IEventListener; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.mi.internal.MIPlugin; import org.eclipse.dd.mi.service.command.commands.CLICommand; import org.eclipse.dd.mi.service.command.commands.CLIExecAbort; @@ -231,7 +231,7 @@ public class MIInferiorProcess extends Process } else if (getState() != State.TERMINATED) { // This will cause ExecutionException to be thrown with a CoreException, // which will in turn contain the IllegalThreadStateException. - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "GDB is still running.", new IllegalThreadStateException())); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "GDB is still running.", new IllegalThreadStateException())); //$NON-NLS-1$ rm.done(); } else { getCommandControl().queueCommand( diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/ShutdownSequence.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/ShutdownSequence.java index 1a4ce69ad4f..14357c73502 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/ShutdownSequence.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/ShutdownSequence.java @@ -13,6 +13,7 @@ package org.eclipse.dd.tests.gdb.launching; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.concurrent.Sequence; import org.eclipse.dd.dsf.service.DsfServicesTracker; @@ -71,7 +72,7 @@ public class ShutdownSequence extends Sequence { if (bpm != null && commandControl != null) { bpm.stopTrackingBreakpoints(commandControl.getGDBDMContext(), requestMonitor); } else { - requestMonitor.setStatus(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, + requestMonitor.setStatus(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Needed services not found.", null)); //$NON-NLS-1$ requestMonitor.done(); } @@ -99,7 +100,7 @@ public class ShutdownSequence extends Sequence { service.shutdown(requestMonitor); } else { - requestMonitor.setStatus(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, + requestMonitor.setStatus(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Service '" + clazz.getName() + "' not found.", null)); //$NON-NLS-1$//$NON-NLS-2$ requestMonitor.done(); } From b927bcd241fc344347e134c33f3ee89ba6297de1 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 25 Mar 2008 21:48:36 +0000 Subject: [PATCH 325/834] Updated sanity test program with comments. --- tests/SanityTest/SanityTest.cpp | 36 ++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/tests/SanityTest/SanityTest.cpp b/tests/SanityTest/SanityTest.cpp index df1c81aa3e4..280fae77146 100644 --- a/tests/SanityTest/SanityTest.cpp +++ b/tests/SanityTest/SanityTest.cpp @@ -1,10 +1,13 @@ -//============================================================================ -// Name : HelloCDT.cpp -// Author : Francois Chouinard -// Version : -// Copyright : Ericsson Research Canada -// Description : Hello World in C++, Ansi-style -//============================================================================ +/******************************************************************************* + * Copyright (c) 2007 Ericsson 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: + * Ericsson - initial API and implementation + *******************************************************************************/ #include #include @@ -39,7 +42,7 @@ void test_threads(void) char *message2 = "Thread 3"; int iret1, iret2; - // Create independent threads each of which will execute function + // Create a method breakpoint for "thread_print" and resume. iret1 = pthread_create( &thread1, NULL, thread_print, (void*) message1); iret2 = pthread_create( &thread2, NULL, thread_print, (void*) message2); @@ -59,17 +62,18 @@ void test_threads(void) void test_stack2(int* k) { bool j = true; - int* l = k; + int l = *k; *k += 10; - // Modifying memory updates the monitors - // but not the Variables view :-( + // Modify *k in the memory view, Memory view and the Variables view + // should show the new value. printf("%d\n", *k); } void test_stack(void) { - // Add a memory monitor for 'j' + // Add a memory monitor for '&j' and verify that the memory changes + // with the following step. int j = 5; // Step into test_stack2(&j); @@ -81,6 +85,8 @@ void countdown(int m) { int x = m; if (x == 0) { + // Set a breakpoint at next line and resume. + // Verify that the stack shown has the correct number of frames. printf("We have a lift-off!\n"); return; } @@ -118,14 +124,16 @@ void test_overlap(void) /////////////////////////////////////////////////////////////////////////////// int main() { - // If we don't step this instruction then the initial content of cptr will - // be cached and the Variables view will display the wrong value. + // Step over the assignments and verify that the new values are displayed + // in the variables view. char* cptr = "Thread 1"; // char* interpreted as C-string in Variables view char* cp = (char*) malloc(1); *cp = 'a'; + // Set a line breakpiont at the start of each test. + // Run to and step into each test. test_stack(); test_threads(); test_recursion(); From fa8d487ab4135afd0a3ffbfb8e11727be30c6083 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 26 Mar 2008 04:32:53 +0000 Subject: [PATCH 326/834] [179293] Fixed a bug in handleErrorOrWarning() handling introduced by the last commit for bug 179293. --- .../expression/AbstractExpressionVMNode.java | 2 +- .../register/RegisterBitFieldVMNode.java | 2 +- .../dd/dsf/concurrent/RequestMonitor.java | 16 +++++++--------- .../ui/viewmodel/GdbViewModelAdapter.java | 3 +-- 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionVMNode.java index 924526a295c..9ead9f614a3 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionVMNode.java @@ -97,7 +97,7 @@ public abstract class AbstractExpressionVMNode extends AbstractDMVMNode } @Override - protected void handleCancelOrErrorOrWarning() { + protected void handleNotOK() { update.setStatus(getStatus()); update.done(); } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java index fb47d5a9fa9..32e16ae7b9e 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java @@ -375,7 +375,7 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode regDmc, new DataRequestMonitor(getSession().getExecutor(), null) { @Override - protected void handleCancelOrErrorOrWarning() { + protected void handleNotOK() { handleFailedUpdate(update); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java index 5b73616c4ee..727b3ff066c 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java @@ -223,15 +223,15 @@ public class RequestMonitor { /** * Default handler for the completion of a request. The implementation * calls {@link #handleOK()} if the request succeeded, and calls - * {@link #handleCancelOrErrorOrWarning()} or cancel otherwise. + * {@link #handleNotOK()} or cancel otherwise. *
              * Note: Sub-classes may override this method. */ protected void handleCompleted() { - if (getStatus().isOK()) { + if (getStatus().getSeverity() <= IStatus.INFO) { handleOK(); } else { - handleCancelOrErrorOrWarning(); + handleNotOK(); } } @@ -239,7 +239,7 @@ public class RequestMonitor { * Default handler for a successful the completion of a request. If this * monitor has a parent monitor that was configured by the constructor, that * parent monitor is notified. Otherwise this method does nothing. - * {@link #handleCancelOrErrorOrWarning()} or cancel otherwise. + * {@link #handleNotOK()} or cancel otherwise. *
              * Note: Sub-classes may override this method. */ @@ -256,7 +256,7 @@ public class RequestMonitor { *
              * Note: Sub-classes may override this method. */ - protected void handleCancelOrErrorOrWarning() { + protected void handleNotOK() { assert !getStatus().isOK(); if (isCanceled()) { handleCancel(); @@ -265,10 +265,8 @@ public class RequestMonitor { DsfPlugin.getDefault().getLog().log(new Status( IStatus.ERROR, DsfPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Request monitor: '" + this + "' resulted in a cancel status: " + getStatus() + ", even though the request is not set to cancel.", null)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } - if (getStatus().getSeverity() == IStatus.ERROR) { - handleError(); - } else { - handleWarning(); + if (getStatus().getSeverity() > IStatus.INFO) { + handleErrorOrWarning(); } } } diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java index a8f003eddf0..07f6ff34b33 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java @@ -10,7 +10,6 @@ *******************************************************************************/ package org.eclipse.dd.gdb.internal.ui.viewmodel; -import org.eclipse.cdt.debug.ui.ICDebugUIConstants; import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.ExpressionVMProvider; import org.eclipse.dd.dsf.debug.ui.viewmodel.modules.ModulesVMProvider; @@ -52,7 +51,7 @@ public class GdbViewModelAdapter extends AbstractDMVMAdapter return new RegisterVMProvider(this, context, getSession()); } else if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(context.getId()) ) { return new ExpressionVMProvider(this, context, getSession()); - } else if (ICDebugUIConstants.ID_MODULES_VIEW.equals(context.getId()) ) { + } else if (IDebugUIConstants.ID_MODULE_VIEW.equals(context.getId()) ) { return new ModulesVMProvider(this, context, getSession()); } return null; From 2eeb644c2fb0fe2213de10df5cc140a6653bcd03 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Wed, 26 Mar 2008 14:21:03 +0000 Subject: [PATCH 327/834] Fix compilation after commit for Bug 179293 --- .../eclipse/dd/examples/pda/service/PDABreakpoints.java | 8 ++++---- .../eclipse/dd/examples/pda/service/PDARunControl.java | 6 +++--- .../dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpoints.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpoints.java index 5e4b733ea96..6d56ff522fc 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpoints.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpoints.java @@ -253,11 +253,11 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints } @Override - protected void handleCancelOrErrorOrWarning() { + protected void handleNotOK() { // If inserting of the breakpoint failed, remove it from // the set of installed breakpoints. fBreakpoints.remove(breakpointCtx); - super.handleCancelOrErrorOrWarning(); + super.handleNotOK(); } }); } @@ -319,11 +319,11 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints } @Override - protected void handleCancelOrErrorOrWarning() { + protected void handleNotOK() { // Since the command failed, we need to remove the breakpoint from // the existing breakpoint set. fBreakpoints.remove(watchpointCtx); - super.handleCancelOrErrorOrWarning(); + super.handleNotOK(); } }); } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java index 02462870cbe..5457e57efb6 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java @@ -244,11 +244,11 @@ public class PDARunControl extends AbstractDsfService new PDAResumeCommand(fCommandControl.getProgramDMContext()), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleCancelOrErrorOrWarning() { + protected void handleNotOK() { // If the resume command failed, we no longer // expect to receive a resumed event. fResumePending = false; - super.handleCancelOrErrorOrWarning(); + super.handleNotOK(); } } ); @@ -285,7 +285,7 @@ public class PDARunControl extends AbstractDsfService new PDAStepCommand(fCommandControl.getProgramDMContext()), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleCancelOrErrorOrWarning() { + protected void handleNotOK() { // If the step command failed, we no longer // expect to receive a resumed event. fResumePending = false; diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java index 07f6ff34b33..a8f003eddf0 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.gdb.internal.ui.viewmodel; +import org.eclipse.cdt.debug.ui.ICDebugUIConstants; import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.ExpressionVMProvider; import org.eclipse.dd.dsf.debug.ui.viewmodel.modules.ModulesVMProvider; @@ -51,7 +52,7 @@ public class GdbViewModelAdapter extends AbstractDMVMAdapter return new RegisterVMProvider(this, context, getSession()); } else if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(context.getId()) ) { return new ExpressionVMProvider(this, context, getSession()); - } else if (IDebugUIConstants.ID_MODULE_VIEW.equals(context.getId()) ) { + } else if (ICDebugUIConstants.ID_MODULES_VIEW.equals(context.getId()) ) { return new ModulesVMProvider(this, context, getSession()); } return null; From 26ae2918f0c5673d3579f0d9d013dd5b54eabb04 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 27 Mar 2008 02:40:19 +0000 Subject: [PATCH 328/834] [179293] Refactor the handle*() methods of the RequestMoniotr. --- .../detail/NumberFormatDetailPane.java | 2 +- .../sourcelookup/MISourceDisplayAdapter.java | 2 +- .../expression/AbstractExpressionVMNode.java | 4 +- .../expression/ExpressionManagerVMNode.java | 2 +- .../ExpressionVMProviderContentStragegy.java | 4 +- ...xpressionVMProviderModelProxyStrategy.java | 4 +- .../viewmodel/launch/StackFramesVMNode.java | 10 +- .../viewmodel/modules/ModuleDetailPane.java | 4 +- .../ui/viewmodel/modules/ModulesVMNode.java | 4 +- .../register/RegisterBitFieldVMNode.java | 8 +- .../register/RegisterGroupVMNode.java | 4 +- .../ui/viewmodel/register/RegisterVMNode.java | 8 +- .../register/SyncRegisterDataAccess.java | 16 +- .../variable/SyncVariableDataAccess.java | 11 +- .../ui/viewmodel/variable/VariableVMNode.java | 8 +- .../dd/dsf/debug/model/DsfMemoryBlock.java | 2 +- .../debug/model/DsfMemoryBlockRetrieval.java | 2 +- .../debug/service/BreakpointsMediator.java | 12 +- .../dsf/debug/service/StepQueueManager.java | 2 +- .../debug/service/command/CommandCache.java | 2 +- .../DsfMISourceLookupParticipant.java | 2 +- .../ViewerCountingRequestMonitor.java | 2 +- .../concurrent/ViewerDataRequestMonitor.java | 2 +- .../dsf/ui/viewmodel/AbstractVMProvider.java | 10 +- .../DefaultVMContentProviderStrategy.java | 12 +- .../DefaultVMModelProxyStrategy.java | 12 +- .../PropertyBasedLabelProvider.java | 2 +- .../update/AbstractCachingVMProvider.java | 10 +- .../org/eclipse/dd/dsf/concurrent/Query.java | 2 +- .../dd/dsf/concurrent/RequestMonitor.java | 93 ++++++++--- .../eclipse/dd/dsf/concurrent/Sequence.java | 4 +- .../dsf/dataviewer/AsyncDataViewer.java | 2 +- .../ui/viewmodel/launch/PDAProgramVMNode.java | 2 +- .../dd/examples/pda/launch/PDALaunch.java | 2 +- .../pda/launch/PDAServicesInitSequence.java | 2 +- .../launch/PDAServicesShutdownSequence.java | 2 +- .../examples/pda/service/PDABreakpoints.java | 16 +- .../pda/service/PDACommandControl.java | 4 +- .../examples/pda/service/PDAExpressions.java | 10 +- .../examples/pda/service/PDARunControl.java | 8 +- .../dd/examples/pda/service/PDAStack.java | 10 +- .../launch/launching/FinalLaunchSequence.java | 2 +- .../dd/gdb/launch/launching/GdbLaunch.java | 2 +- .../launch/launching/ShutdownSequence.java | 2 +- .../ui/breakpoints/GdbThreadFilterEditor.java | 2 +- .../ui/viewmodel/launch/ContainerVMNode.java | 2 +- .../ui/viewmodel/launch/ThreadVMNode.java | 10 +- .../eclipse/dd/gdb/service/GDBRunControl.java | 6 +- .../dd/gdb/service/command/GDBControl.java | 8 +- .../eclipse/dd/mi/service/CSourceLookup.java | 2 +- .../dd/mi/service/ExpressionService.java | 20 +-- .../eclipse/dd/mi/service/MIBreakpoints.java | 20 +-- .../dd/mi/service/MIBreakpointsManager.java | 26 +-- .../eclipse/dd/mi/service/MIDisassembly.java | 10 +- .../org/eclipse/dd/mi/service/MIMemory.java | 20 +-- .../org/eclipse/dd/mi/service/MIModules.java | 6 +- .../eclipse/dd/mi/service/MIRegisters.java | 14 +- .../eclipse/dd/mi/service/MIRunControl.java | 10 +- .../org/eclipse/dd/mi/service/MIStack.java | 22 +-- .../dd/mi/service/MIVariableManager.java | 60 +++---- .../actions/MILogActionEnabler.java | 2 +- .../mi/service/command/MIInferiorProcess.java | 2 +- .../dd/tests/dsf/events/AbstractService.java | 2 +- .../eclipse/dd/tests/dsf/events/Service1.java | 2 +- .../eclipse/dd/tests/dsf/events/Service2.java | 2 +- .../eclipse/dd/tests/dsf/events/Service3.java | 2 +- .../dsf/service/MultiInstanceTestService.java | 2 +- .../tests/dsf/service/SimpleTestService.java | 2 +- .../dd/tests/gdb/ExpressionServiceTest.java | 150 +++++++++--------- .../dd/tests/gdb/GDBProcessesTest.java | 4 +- .../dd/tests/gdb/MIBreakpointsTest.java | 2 +- .../dd/tests/gdb/MIDisassemblyTest.java | 10 +- .../eclipse/dd/tests/gdb/MIMemoryTest.java | 6 +- .../eclipse/dd/tests/gdb/MIRegistersTest.java | 6 +- .../dd/tests/gdb/MIRunControlTest.java | 18 +-- .../dd/tests/gdb/framework/SyncUtil.java | 8 +- .../tests/gdb/launching/LaunchSequence.java | 8 +- 77 files changed, 417 insertions(+), 375 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/viewmodel/numberformat/detail/NumberFormatDetailPane.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/viewmodel/numberformat/detail/NumberFormatDetailPane.java index 4ef667d3b88..7008f75ebeb 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/viewmodel/numberformat/detail/NumberFormatDetailPane.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/viewmodel/numberformat/detail/NumberFormatDetailPane.java @@ -386,7 +386,7 @@ public class NumberFormatDetailPane implements IDetailPane, IAdaptable, IPropert final DataRequestMonitor getAvailableFormatsDone = new DataRequestMonitor(finalService.getSession().getExecutor(), null) { @Override - protected void handleOK() { + protected void handleSuccess() { /* * Now we have a set of formats for each one fire up an independent * asynchronous request to get the data in that format. We do not diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java index ce9154d8885..1f0ce0e2762 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java @@ -285,7 +285,7 @@ public class MISourceDisplayAdapter implements ISourceDisplay frameDmc, new DataRequestMonitor(fExecutor, rm) { @Override - public void handleOK() { + public void handleSuccess() { FramePositioningData clientData = new FramePositioningData(); clientData.fLevel = frameDmc.getLevel(); // Document line numbers are 0-based. While debugger line numbers are 1-based. diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionVMNode.java index 9ead9f614a3..4e198a6d113 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionVMNode.java @@ -51,7 +51,7 @@ public abstract class AbstractExpressionVMNode extends AbstractDMVMNode update, -1, -1, new ViewerDataRequestMonitor>(getExecutor(), update) { @Override - protected void handleOK() { + protected void handleSuccess() { if (getData().size() == 0) { update.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "No contexts", null)); //$NON-NLS-1$ update.done(); @@ -97,7 +97,7 @@ public abstract class AbstractExpressionVMNode extends AbstractDMVMNode } @Override - protected void handleNotOK() { + protected void handleFailure() { update.setStatus(getStatus()); update.done(); } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerVMNode.java index a25f962abdb..f9e67bd53f9 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerVMNode.java @@ -195,7 +195,7 @@ public class ExpressionManagerVMNode extends AbstractVMNode update, expression, new DataRequestMonitor(getVMProvider().getExecutor(), multiRm) { @Override - protected void handleOK() { + protected void handleSuccess() { update.setChild(getData(), childIndex); multiRm.done(); } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderContentStragegy.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderContentStragegy.java index ab1afc9f400..9b3eb6e0623 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderContentStragegy.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderContentStragegy.java @@ -52,7 +52,7 @@ public class ExpressionVMProviderContentStragegy extends DefaultVMContentProvide update, update.getExpression(), new ViewerDataRequestMonitor(getVMProvider().getExecutor(), update) { @Override - protected void handleOK() { + protected void handleSuccess() { // Check if the evaluated node has child expression nodes. // If it does, check if any of those nodes can evaluate the given // expression further. If they can, call the child node to further @@ -70,7 +70,7 @@ public class ExpressionVMProviderContentStragegy extends DefaultVMContentProvide new ViewerDataRequestMonitor(getVMProvider().getExecutor(), update) { @Override - protected void handleOK() { + protected void handleSuccess() { update.setExpressionElement(getData()); update.done(); } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderModelProxyStrategy.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderModelProxyStrategy.java index 4c7a5686ef9..187cec3fa88 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderModelProxyStrategy.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderModelProxyStrategy.java @@ -79,7 +79,7 @@ public class ExpressionVMProviderModelProxyStrategy extends DefaultVMModelProxyS expression, expressionElementIdx, event, parentDelta, path, new RequestMonitor(getVMProvider().getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { final IExpressionVMNode matchingNode = getExpressionVMProvider().findNodeToParseExpression(node, expression); if (matchingNode != null && !matchingNode.equals(node)) { @@ -90,7 +90,7 @@ public class ExpressionVMProviderModelProxyStrategy extends DefaultVMModelProxyS parentDelta, getVMProvider().getPresentationContext(), expression, new DataRequestMonitor(getVMProvider().getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { buildDeltaForExpressionElement( node, getData(), expressionElementIdx, event, parentDelta, path, rm); } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java index 79a1a044694..e057e5aa9df 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java @@ -85,7 +85,7 @@ public class StackFramesVMNode extends AbstractDMVMNode new DataRequestMonitor(getSession().getExecutor(), null) { @Override public void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { // 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. @@ -129,7 +129,7 @@ public class StackFramesVMNode extends AbstractDMVMNode new DataRequestMonitor(getExecutor(), null) { @Override public void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { handleFailedUpdate(update); return; } @@ -189,7 +189,7 @@ public class StackFramesVMNode extends AbstractDMVMNode * service changed during the request, but the view model * has not been updated yet. */ - if (!getStatus().isOK()) { + if (!isSuccess()) { assert getStatus().isOK() || getStatus().getCode() != IDsfStatusConstants.INTERNAL_ERROR || getStatus().getCode() != IDsfStatusConstants.NOT_SUPPORTED; @@ -294,7 +294,7 @@ public class StackFramesVMNode extends AbstractDMVMNode new DataRequestMonitor>(getExecutor(), null) { @Override public void handleCompleted() { - if (getStatus().isOK() && getData().size() != 0) { + if (isSuccess() && getData().size() != 0) { rm.setData(new IVMContext[] { (IVMContext)getData().get(0) }); } else { // In case of errors, return an empty set of frames. @@ -429,7 +429,7 @@ public class StackFramesVMNode extends AbstractDMVMNode new DataRequestMonitor>(getExecutor(), null) { @Override public void handleCompleted() { - if (getStatus().isOK() && getData().size() != 0) { + if (isSuccess() && getData().size() != 0) { parentDelta.addNode( getData().get(0), 0, IModelDelta.SELECT | IModelDelta.EXPAND); } rm.done(); diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPane.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPane.java index 94db474de94..3eeb02d9716 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPane.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPane.java @@ -382,7 +382,7 @@ public class ModuleDetailPane extends AbstractDetailPane implements IAdaptable, // final DataRequestMonitor modData = // new DataRequestMonitor(service.getSession().getExecutor(), null) { // @Override -// protected void handleOK() { +// protected void handleSuccess() { // detailComputed(getModuleDetail(getData())); // } // }; @@ -544,7 +544,7 @@ public class ModuleDetailPane extends AbstractDetailPane implements IAdaptable, } @Override - protected void handleOK() { + protected void handleSuccess() { /* * All good set return value. */ diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMNode.java index 3d00a73fbb8..cbad5058e92 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMNode.java @@ -52,7 +52,7 @@ public class ModulesVMNode extends AbstractDMVMNode new DataRequestMonitor(getSession().getExecutor(), null) { @Override public void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { update.done(); return; } @@ -97,7 +97,7 @@ public class ModulesVMNode extends AbstractDMVMNode * changed during the request, but the view model * has not been updated yet. */ - if (!getStatus().isOK()) { + if (!isSuccess()) { assert getStatus().isOK() || getStatus().getCode() != IDsfStatusConstants.INTERNAL_ERROR || getStatus().getCode() != IDsfStatusConstants.NOT_SUPPORTED; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java index 32e16ae7b9e..ec598d0d1b7 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java @@ -229,7 +229,7 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode new DataRequestMonitor(getSession().getExecutor(), null) { @Override public void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { handleFailedUpdate(update); return; } @@ -290,7 +290,7 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode * service changed during the request, but the view model * has not been updated yet. */ - if (!getStatus().isOK()) { + if (!isSuccess()) { assert getStatus().isOK() || getStatus().getCode() != IDsfStatusConstants.INTERNAL_ERROR || getStatus().getCode() != IDsfStatusConstants.NOT_SUPPORTED; @@ -375,12 +375,12 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode regDmc, new DataRequestMonitor(getSession().getExecutor(), null) { @Override - protected void handleNotOK() { + protected void handleFailure() { handleFailedUpdate(update); } @Override - protected void handleOK() { + protected void handleSuccess() { fillUpdateWithVMCs(update, getData()); update.done(); } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java index e7911b2c9f9..afed1987537 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java @@ -138,7 +138,7 @@ public class RegisterGroupVMNode extends AbstractExpressionVMNode new DataRequestMonitor(getSession().getExecutor(), null) { @Override public void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { update.done(); return; } @@ -185,7 +185,7 @@ public class RegisterGroupVMNode extends AbstractExpressionVMNode * service changed during the request, but the view model * has not been updated yet. */ - if (!getStatus().isOK()) { + if (!isSuccess()) { assert getStatus().isOK() || getStatus().getCode() != IDsfStatusConstants.INTERNAL_ERROR || getStatus().getCode() != IDsfStatusConstants.NOT_SUPPORTED; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java index 3596e91412f..bdabd600730 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java @@ -178,7 +178,7 @@ public class RegisterVMNode extends AbstractExpressionVMNode new DataRequestMonitor(getSession().getExecutor(), null) { @Override public void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { handleFailedUpdate(update); return; } @@ -228,7 +228,7 @@ public class RegisterVMNode extends AbstractExpressionVMNode new DataRequestMonitor(getSession().getExecutor(), null) { @Override public void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { handleFailedUpdate(update); return; } @@ -290,7 +290,7 @@ public class RegisterVMNode extends AbstractExpressionVMNode * service changed during the request, but the view model * has not been updated yet. */ - if (!getStatus().isOK()) { + if (!isSuccess()) { assert getStatus().isOK() || getStatus().getCode() != IDsfStatusConstants.INTERNAL_ERROR || getStatus().getCode() != IDsfStatusConstants.NOT_SUPPORTED; @@ -370,7 +370,7 @@ public class RegisterVMNode extends AbstractExpressionVMNode new DataRequestMonitor(getSession().getExecutor(), null) { @Override public void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { handleFailedUpdate(update); return; } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java index 4c53b877e9f..d044e909ee7 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java @@ -129,7 +129,7 @@ public class SyncRegisterDataAccess { } @Override - protected void handleOK() { + protected void handleSuccess() { /* * All good set return value. */ @@ -238,7 +238,7 @@ public class SyncRegisterDataAccess { } @Override - protected void handleOK() { + protected void handleSuccess() { /* * All good set return value. */ @@ -345,7 +345,7 @@ public class SyncRegisterDataAccess { } @Override - protected void handleOK() { + protected void handleSuccess() { /* * All good set return value. */ @@ -466,7 +466,7 @@ public class SyncRegisterDataAccess { } @Override - protected void handleOK() { + protected void handleSuccess() { /* * All good set return value. */ @@ -555,7 +555,7 @@ public class SyncRegisterDataAccess { } @Override - protected void handleOK() { + protected void handleSuccess() { /* * All good set return value. */ @@ -660,7 +660,7 @@ public class SyncRegisterDataAccess { } @Override - protected void handleOK() { + protected void handleSuccess() { /* * All good set return value. */ @@ -763,7 +763,7 @@ public class SyncRegisterDataAccess { } @Override - protected void handleOK() { + protected void handleSuccess() { /* * All good set return value. */ @@ -868,7 +868,7 @@ public class SyncRegisterDataAccess { } @Override - protected void handleOK() { + protected void handleSuccess() { /* * All good set return value. */ diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java index 2cb64e637d1..b58d7442220 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java @@ -134,13 +134,14 @@ public class SyncVariableDataAccess { */ if (!DsfSession.isSessionActive(session.getId())) { GetVariableValueQuery.this.cancel(false); + rm.done(); return; } super.handleCompleted(); } @Override - protected void handleOK() { + protected void handleSuccess() { /* * All good set return value. */ @@ -248,7 +249,7 @@ public class SyncVariableDataAccess { } @Override - protected void handleOK() { + protected void handleSuccess() { /* * All good set return value. */ @@ -357,7 +358,7 @@ public class SyncVariableDataAccess { } @Override - protected void handleOK() { + protected void handleSuccess() { /* * All good set return value. */ @@ -456,7 +457,7 @@ public class SyncVariableDataAccess { } @Override - protected void handleOK() { + protected void handleSuccess() { /* * All good set return value. */ @@ -546,7 +547,7 @@ public class SyncVariableDataAccess { } @Override - protected void handleOK() { + protected void handleSuccess() { /* * All good set return value. */ diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java index 5f314eee20d..a336d256762 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java @@ -226,7 +226,7 @@ public class VariableVMNode extends AbstractExpressionVMNode // fail if the state of the service changed during the request, but the view model // has not been updated yet. - if (!getStatus().isOK()) { + if (!isSuccess()) { assert getStatus().isOK() || getStatus().getCode() != IDsfStatusConstants.INTERNAL_ERROR || getStatus().getCode() != IDsfStatusConstants.NOT_SUPPORTED; @@ -380,7 +380,7 @@ public class VariableVMNode extends AbstractExpressionVMNode new DataRequestMonitor(getSession().getExecutor(), null) { @Override public void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { handleFailedUpdate(update); return; } @@ -567,7 +567,7 @@ public class VariableVMNode extends AbstractExpressionVMNode new DataRequestMonitor(dsfExecutor, null) { @Override public void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { handleFailedUpdate(update); return; } @@ -645,7 +645,7 @@ public class VariableVMNode extends AbstractExpressionVMNode // IExpressionDMContext object for each local variable name, saving them all // in an array. - if (!getStatus().isOK()) { + if (!isSuccess()) { handleFailedUpdate(update); return; } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java index b114acad5ce..3f6d22d3829 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java @@ -428,7 +428,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens fRetrieval.getContext(), address, 0, fWordSize, (int) length, new DataRequestMonitor(fRetrieval.getExecutor(), drm) { @Override - protected void handleOK() { + protected void handleSuccess() { drm.setData(getData()); drm.done(); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java index bd0c65652f2..6ec2b2b5938 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java @@ -481,7 +481,7 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl valueDmc, new DataRequestMonitor(getExecutor(), drm) { @Override - protected void handleOK() { + protected void handleSuccess() { // Store the result FormattedValueDMData data = getData(); String value = data.getFormattedValue().substring(2); // Strip the "0x" diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/BreakpointsMediator.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/BreakpointsMediator.java index 9b00519853f..2d696fe1b56 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/BreakpointsMediator.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/BreakpointsMediator.java @@ -135,7 +135,7 @@ public class BreakpointsMediator extends AbstractDsfService implements IBreakpoi super.initialize( new RequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { doInitialize(rm); }}); } @@ -426,7 +426,7 @@ public class BreakpointsMediator extends AbstractDsfService implements IBreakpoi breakpointIDs.put(breakpoint, list); } - if (getStatus().isOK()) { + if (isSuccess()) { // Add the breakpoint back-end mapping list.add(getData()); } else { @@ -619,7 +619,7 @@ public class BreakpointsMediator extends AbstractDsfService implements IBreakpoi context, attrs, new DataRequestMonitor(getExecutor(), countingRM) { @Override - protected void handleOK() { + protected void handleSuccess() { newBpContexts.add(getData()); countingRM.done(); } @@ -639,7 +639,7 @@ public class BreakpointsMediator extends AbstractDsfService implements IBreakpoi new DataRequestMonitor(getExecutor(), countingRM) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { newBpContexts.add(getData()); } else { // TODO (bug 219841): need to add breakpoint error status tracking @@ -658,7 +658,7 @@ public class BreakpointsMediator extends AbstractDsfService implements IBreakpoi oldBpContexts.get(i), newAttrsList.get(i), new RequestMonitor(getExecutor(), countingRM) { @Override - protected void handleOK() { + protected void handleSuccess() { newBpContexts.add(bpCtx); countingRM.done(); } @@ -807,7 +807,7 @@ public class BreakpointsMediator extends AbstractDsfService implements IBreakpoi @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { if (getStatus().getSeverity() == IStatus.ERROR) { DsfDebugPlugin.getDefault().getLog().log(getStatus()); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/StepQueueManager.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/StepQueueManager.java index e73bec79996..e15bbcb5040 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/StepQueueManager.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/StepQueueManager.java @@ -88,7 +88,7 @@ public class StepQueueManager extends AbstractDsfService super.initialize( new RequestMonitor(getExecutor(), requestMonitor) { @Override - protected void handleOK() { + protected void handleSuccess() { doInitialize(requestMonitor); }}); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java index db4208f08eb..2f27c08b22d 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java @@ -369,7 +369,7 @@ public class CommandCache implements ICommandListener fCachedContexts.put(context, map); } - if (!status.isOK()) { + if (!isSuccess()) { /* * We had some form of error with the original command. So notify the diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java index a05d01e4cbc..565ddfa6de3 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java @@ -220,7 +220,7 @@ public class DsfMISourceLookupParticipant implements ISourceLookupParticipant { stackService.getFrameData( frameDmc, new DataRequestMonitor(fExecutor, rm) { @Override - public void handleOK() { + public void handleSuccess() { rm.setData(getData().getFile()); rm.done(); }}); diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/ViewerCountingRequestMonitor.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/ViewerCountingRequestMonitor.java index 884062638b1..62b723df076 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/ViewerCountingRequestMonitor.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/ViewerCountingRequestMonitor.java @@ -37,7 +37,7 @@ public class ViewerCountingRequestMonitor extends CountingRequestMonitor { } @Override - protected void handleOK() { + protected void handleSuccess() { fUpdate.done(); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/ViewerDataRequestMonitor.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/ViewerDataRequestMonitor.java index 5e8a53a0c2a..f6250e2726c 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/ViewerDataRequestMonitor.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/concurrent/ViewerDataRequestMonitor.java @@ -35,7 +35,7 @@ public class ViewerDataRequestMonitor extends DataRequestMonitor { } @Override - protected void handleOK() { + protected void handleSuccess() { fUpdate.done(); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java index 4fc1d2aa95a..c6a14553935 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java @@ -203,7 +203,7 @@ abstract public class AbstractVMProvider implements IVMProvider new DataRequestMonitor(getExecutor(), null) { @Override public void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { proxyStrategy.fireModelChanged(getData()); } } @@ -330,7 +330,7 @@ abstract public class AbstractVMProvider implements IVMProvider update, new ViewerDataRequestMonitor(getExecutor(), updates[i]) { @Override - protected void handleOK() { + protected void handleSuccess() { update.setHasChilren(getData()); update.done(); } @@ -344,7 +344,7 @@ abstract public class AbstractVMProvider implements IVMProvider update, -1, -1, new ViewerDataRequestMonitor>(getExecutor(), update) { @Override - protected void handleOK() { + protected void handleSuccess() { update.setHasChilren( !getData().isEmpty() ); update.done(); } @@ -376,7 +376,7 @@ abstract public class AbstractVMProvider implements IVMProvider update, new ViewerDataRequestMonitor(getExecutor(), update) { @Override - protected void handleOK() { + protected void handleSuccess() { update.setChildCount(getData()); update.done(); } @@ -390,7 +390,7 @@ abstract public class AbstractVMProvider implements IVMProvider update, -1, -1, new ViewerDataRequestMonitor>(getExecutor(), update) { @Override - protected void handleOK() { + protected void handleSuccess() { update.setChildCount( getData().size() ); update.done(); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMContentProviderStrategy.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMContentProviderStrategy.java index b58052fe967..8793d5ddcf5 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMContentProviderStrategy.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMContentProviderStrategy.java @@ -125,10 +125,10 @@ public class DefaultVMContentProviderStrategy implements IElementContentProvider @Override protected void handleCompleted() { // Status is OK, only if all request monitors are OK. - if (getStatus().isOK()) { + if (isSuccess()) { boolean isContainer = false; for (DataRequestMonitor hasElementsDone : getRequestMonitors()) { - isContainer |= hasElementsDone.getStatus().isOK() && + isContainer |= hasElementsDone.isSuccess() && hasElementsDone.getData().booleanValue(); } update.setHasChilren(isContainer); @@ -178,7 +178,7 @@ public class DefaultVMContentProviderStrategy implements IElementContentProvider new DataRequestMonitor(getVMProvider().getExecutor(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { int numChildren = 0; for (Integer count : getData()) { numChildren += count.intValue(); @@ -216,7 +216,7 @@ public class DefaultVMContentProviderStrategy implements IElementContentProvider new DataRequestMonitor(getVMProvider().getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { update.done(); return; } @@ -251,7 +251,7 @@ public class DefaultVMContentProviderStrategy implements IElementContentProvider final MultiRequestMonitor childrenCountMultiReqMon = new MultiRequestMonitor(getVMProvider().getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { rm.setData(counts); rm.done(); } @@ -266,7 +266,7 @@ public class DefaultVMContentProviderStrategy implements IElementContentProvider childrenCountMultiReqMon.add( new DataRequestMonitor(getVMProvider().getExecutor(), null) { @Override - protected void handleOK() { + protected void handleSuccess() { counts[nodeIndex] = getData(); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMModelProxyStrategy.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMModelProxyStrategy.java index b82c7ef4d58..254cb123524 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMModelProxyStrategy.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMModelProxyStrategy.java @@ -250,7 +250,7 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy { getRootElement(), event, new DataRequestMonitor(getVMProvider().getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { // Find the root delta for the whole view to use when firing the delta. // Note: the view root is going to be different than the model root // in case when the view model provider is registered to populate only @@ -272,7 +272,7 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy { childNodesWithDeltaFlags, getData(), event, new RequestMonitor(getVMProvider().getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { rm.setData(viewRootDelta); rm.done(); } @@ -290,7 +290,7 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy { new DataRequestMonitor(getVMProvider().getExecutor(), rm) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { assert getData() != null; buildChildDeltasForEventContext(getData(), node, event, parentDelta, nodeOffset, rm); } else if (getStatus().getCode() == IDsfStatusConstants.NOT_SUPPORTED) { @@ -341,7 +341,7 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy { // Check for an empty list of elements. If it's empty then we // don't have to call the children nodes, so return here. // No need to propagate error, there's no means or need to display it. - if (!getStatus().isOK() || getData().isEmpty()) { + if (!isSuccess() || getData().isEmpty()) { requestMonitor.done(); return; } @@ -525,7 +525,7 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy { event, delta, nodeOffset, new RequestMonitor(getVMProvider().getExecutor(), multiRm) { @Override - protected void handleOK() { + protected void handleSuccess() { buildChildDeltas( childNode, event, delta, nodeOffset, new RequestMonitor(getVMProvider().getExecutor(), multiRm)); } @@ -568,7 +568,7 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy { super.handleCompleted(); } @Override - protected void handleOK() { + protected void handleSuccess() { Map data = new HashMap(); int offset = 0; for (int i = 0; i < childNodes.length; i++) { diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/PropertyBasedLabelProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/PropertyBasedLabelProvider.java index 3791a7f3c5d..08eff3de241 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/PropertyBasedLabelProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/PropertyBasedLabelProvider.java @@ -192,7 +192,7 @@ public class PropertyBasedLabelProvider new DataRequestMonitor>(ImmediateExecutor.getInstance(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { updateLabel(labelUpdate, getData()); } labelUpdate.done(); diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java index ae68fb748fb..fd564c17be6 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java @@ -298,7 +298,7 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa new VMHasChildrenUpdate(update, new DataRequestMonitor(getExecutor(), null) { @Override protected void handleCompleted() { - if(getStatus().isOK()) { + if(isSuccess()) { entry.fHasChildren = this.getData(); update.setHasChilren(getData()); } else { @@ -326,7 +326,7 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa IChildrenCountUpdate updateProxy = new VMChildrenCountUpdate(update, new DataRequestMonitor(getExecutor(), null) { @Override protected void handleCompleted() { - if(getStatus().isOK()) { + if(isSuccess()) { entry.fChildrenCount = this.getData(); update.setChildCount(getData()); } else { @@ -360,7 +360,7 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa // The viewer may request more children then there are at a given level. // This causes the update to return with an error. // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=202109 - // Instead of checking getStatus().isOK(), check getData() != null. + // Instead of checking isSuccess(), check getData() != null. if(getData() != null) { // Check if the udpate retrieved all children by specifying "offset = -1, length = -1" int updateOffset = update.getOffset(); @@ -578,7 +578,7 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa @Override public void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { proxyStrategy.fireModelChanged(getData()); } } @@ -731,7 +731,7 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa new DataRequestMonitor(executor, rm) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { entry.fDataOrStatus.put(dmc, getData()); rm.setData(getData()); } else { diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Query.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Query.java index 58ba79d0769..089fb10c4bc 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Query.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Query.java @@ -114,7 +114,7 @@ abstract public class Query extends DsfRunnable execute(new DataRequestMonitor(ImmediateExecutor.getInstance(), null) { @Override public void handleCompleted() { - if (getStatus().isOK()) fSync.doSet(getData()); + if (isSuccess()) fSync.doSet(getData()); else fSync.doSetException(new CoreException(getStatus())); } }); diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java index 727b3ff066c..8219ae9201e 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java @@ -33,12 +33,28 @@ import org.eclipse.dd.dsf.internal.DsfPlugin; * as an argument. *

              *

              - * This class handles an optional "parent" request monitor. If a parent monitor is - * specified, it will automatically be invoked by this monitor when the request is - * completed. The parent option is useful when implementing a method which is - * asynchronous (and accepts a request monitor as an argument) and which itself calls - * another asynchronous method to complete its operation. For example, in the request - * monitor implementation below, the implementation only needs to override + * The severity of the {@link IStatus> returned by #getStatus() can be used to + * determine the success or failure of the asynchronous operation. By convention + * the error codes returned by asynchronous method should be interpreted as follows: + *

                + *
              • OK and INFO - Result is a success. In DataRequestMonitor, getData() should + * return a value.
              • + *
              • WARNING - Acceptable error condition (getData() may return null). Where for + * example user tried to retrieve variable data, but the program resumed in the + * mean time and an event will be generated shortly which will clear the variables + * view.
              • + *
              • ERROR - An error condition that should probably be reported to the user.
              • + *
              • CANCEL - The request was canceled, and the asynchronous method was not + * completed.
              • + *
              + *

              + *

              + * The RequestMonitor constructor accepts an optional "parent" request monitor. If a + * parent monitor is specified, it will automatically be invoked by this monitor when + * the request is completed. The parent option is useful when implementing a method + * which is asynchronous (and accepts a request monitor as an argument) and which itself + * calls another asynchronous method to complete its operation. For example, in the + * request monitor implementation below, the implementation only needs to override * handleOK(), because the base implementation will handle notifying the * parent rm in case the getIngredients() call fails. *

              @@ -54,7 +70,7 @@ import org.eclipse.dd.dsf.internal.DsfPlugin;
                * 
              *

              */ -@ConfinedToDsfExecutor("") +@ThreadSafe public class RequestMonitor { /** @@ -132,9 +148,17 @@ public class RequestMonitor { /** * Sets this request monitor as canceled and calls the cancel listeners if any. - * The operation may still be carried out as it is up to the implementation of - * the asynchronous operation to cancel the operation. Even after the request - * monitor is canceled, the done() method still has to be called. + *

              + * Note: Calling cancel() does not automatically complete the RequestMonitor. + * The asynchronous call still has to call done(). + *

              + *

              + * Note: logically a request should only be canceled by the client that issued + * the request in the first place. After a request is canceled, the method + * that is fulfilling the request may call {@link #setStatus(IStatus)} with + * severity of IStatus.CANCEL to indicate that it recognized that + * the given request was canceled and it did not perform the given operation. + *

              */ public void cancel() { Object[] listeners = null; @@ -180,10 +204,9 @@ public class RequestMonitor { * when this request monitor is canceled. */ public synchronized void removeCancelListener(ICanceledListener listener) { - if (fCancelListeners == null) { - fCancelListeners = new ListenerList(); + if (fCancelListeners != null) { + fCancelListeners.remove(listener); } - fCancelListeners.remove(listener); } /** @@ -219,19 +242,29 @@ public class RequestMonitor { public String toString() { return "RequestMonitor (" + super.toString() + "): " + getStatus().toString(); //$NON-NLS-1$ //$NON-NLS-2$ } + + /** + * Checks whether the given request monitor completed with success or + * failure result. If the request monitor was canceled it is considered + * that it failed, regardless of the status. + */ + public boolean isSuccess() { + return !isCanceled() && getStatus().getSeverity() <= IStatus.INFO; + } /** * Default handler for the completion of a request. The implementation - * calls {@link #handleOK()} if the request succeeded, and calls - * {@link #handleNotOK()} or cancel otherwise. + * calls {@link #handleSuccess()} if the request succeeded, and calls + * {@link #handleFailure()} or cancel otherwise. *
              * Note: Sub-classes may override this method. */ + @ConfinedToDsfExecutor("fExecutor") protected void handleCompleted() { - if (getStatus().getSeverity() <= IStatus.INFO) { - handleOK(); + if (isSuccess()) { + handleSuccess(); } else { - handleNotOK(); + handleFailure(); } } @@ -239,11 +272,12 @@ public class RequestMonitor { * Default handler for a successful the completion of a request. If this * monitor has a parent monitor that was configured by the constructor, that * parent monitor is notified. Otherwise this method does nothing. - * {@link #handleNotOK()} or cancel otherwise. + * {@link #handleFailure()} or cancel otherwise. *
              * Note: Sub-classes may override this method. */ - protected void handleOK() { + @ConfinedToDsfExecutor("fExecutor") + protected void handleSuccess() { if (fParentRequestMonitor != null) { fParentRequestMonitor.done(); } @@ -256,7 +290,8 @@ public class RequestMonitor { *
              * Note: Sub-classes may override this method. */ - protected void handleNotOK() { + @ConfinedToDsfExecutor("fExecutor") + protected void handleFailure() { assert !getStatus().isOK(); if (isCanceled()) { handleCancel(); @@ -278,6 +313,7 @@ public class RequestMonitor { *
              * Note: Sub-classes may override this method. */ + @ConfinedToDsfExecutor("fExecutor") protected void handleErrorOrWarning() { if (getStatus().getSeverity() == IStatus.ERROR) { handleError(); @@ -294,6 +330,7 @@ public class RequestMonitor { *
              * Note: Sub-classes may override this method. */ + @ConfinedToDsfExecutor("fExecutor") protected void handleError() { if (fParentRequestMonitor != null) { fParentRequestMonitor.setStatus(getStatus()); @@ -313,14 +350,11 @@ public class RequestMonitor { *
              * Note: Sub-classes may override this method. */ + @ConfinedToDsfExecutor("fExecutor") protected void handleWarning() { if (fParentRequestMonitor != null) { fParentRequestMonitor.setStatus(getStatus()); fParentRequestMonitor.done(); - } else { - MultiStatus logStatus = new MultiStatus(DsfPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Request for monitor: '" + toString() + "' resulted in a warning.", null); //$NON-NLS-1$ //$NON-NLS-2$ - logStatus.merge(getStatus()); - DsfPlugin.getDefault().getLog().log(logStatus); } } @@ -331,9 +365,15 @@ public class RequestMonitor { *
              * Note: Sub-classes may override this method. */ + @ConfinedToDsfExecutor("fExecutor") protected void handleCancel() { if (fParentRequestMonitor != null) { - fParentRequestMonitor.setStatus(getStatus()); + if (getStatus().getSeverity() == IStatus.CANCEL && !fParentRequestMonitor.isCanceled()) { + fParentRequestMonitor.setStatus(new Status( + IStatus.ERROR, DsfPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Sub-request " + toString() + " was canceled and not handled.'", null)); //$NON-NLS-1$ //$NON-NLS-2$ + } else { + fParentRequestMonitor.setStatus(getStatus()); + } fParentRequestMonitor.done(); } } @@ -343,6 +383,7 @@ public class RequestMonitor { * rejects the runnable that is submitted invoke this request monitor. * This usually happens only when the executor is shutting down. */ + @ThreadSafe protected void handleRejectedExecutionException() { MultiStatus logStatus = new MultiStatus(DsfPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Request for monitor: '" + toString() + "' resulted in a rejected execution exception.", null); //$NON-NLS-1$ //$NON-NLS-2$ logStatus.merge(getStatus()); diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Sequence.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Sequence.java index 73e88c5a90f..3bca2cd6e60 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Sequence.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/Sequence.java @@ -275,7 +275,7 @@ abstract public class Sequence extends DsfRunnable implements Future { assert fStepIdx == fCurrentStepIdx; // Proceed to the next step. - if (getStatus().isOK()) { + if (isSuccess()) { fProgressMonitor.worked(getSteps()[fStepIdx].getTicks()); executeStep(fStepIdx + 1); } else { @@ -329,7 +329,7 @@ abstract public class Sequence extends DsfRunnable implements Future { assert fStepIdx == fCurrentStepIdx; // Proceed to the next step. - if (getStatus().isOK()) { + if (isSuccess()) { fProgressMonitor.worked(getSteps()[fStepIdx].getTicks()); rollBackStep(fStepIdx - 1); } else { diff --git a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/AsyncDataViewer.java b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/AsyncDataViewer.java index da828939503..d03fa2b6db6 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/AsyncDataViewer.java +++ b/plugins/org.eclipse.dd.examples.dsf/src_preprocess/org/eclipse/dd/examples/dsf/dataviewer/AsyncDataViewer.java @@ -171,7 +171,7 @@ public class AsyncDataViewer fItemDataRequestMonitors.remove(this); // Check if the request completed successfully, otherwise ignore it. - if (getStatus().isOK()) { + if (isSuccess()) { if (!fViewer.getTable().isDisposed()) { fViewer.replace(getData(), fIndex); } diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDAProgramVMNode.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDAProgramVMNode.java index b5ebe9f9544..33fc71780bd 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDAProgramVMNode.java +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDAProgramVMNode.java @@ -204,7 +204,7 @@ public class PDAProgramVMNode extends AbstractDMVMNode @Override public void handleCompleted(){ // If the request failed, fail the udpate. - if (!getStatus().isOK()) { + if (!isSuccess()) { handleFailedUpdate(update); return; } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunch.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunch.java index 99d726d6d2d..5db49e184bc 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunch.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunch.java @@ -230,7 +230,7 @@ implements ITerminate @Override public void handleCompleted() { fSession.removeServiceEventListener(PDALaunch.this); - if (!getStatus().isOK()) { + if (!isSuccess()) { PDAPlugin.getDefault().getLog().log(new MultiStatus( PDAPlugin.PLUGIN_ID, -1, new IStatus[]{getStatus()}, "Session shutdown failed", null)); //$NON-NLS-1$ } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java index 781e8c505e3..c13ff5b33be 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java @@ -76,7 +76,7 @@ public class PDAServicesInitSequence extends Sequence { fSession, new PDABreakpointAttributeTranslator()); bpmService.initialize(new RequestMonitor(getExecutor(), requestMonitor) { @Override - protected void handleOK() { + protected void handleSuccess() { bpmService.startTrackingBreakpoints(fCommandControl.getProgramDMContext(), requestMonitor); } }); diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java index f0056268c7e..4ca6df9cfe9 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java @@ -127,7 +127,7 @@ public class PDAServicesShutdownSequence extends Sequence { service.shutdown(new RequestMonitor(getExecutor(), requestMonitor) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { PDAPlugin.getDefault().getLog().log(getStatus()); } requestMonitor.done(); diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpoints.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpoints.java index 6d56ff522fc..01f3259de65 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpoints.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpoints.java @@ -134,7 +134,7 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints public void initialize(final RequestMonitor rm) { super.initialize(new RequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { doInitialize(rm); } }); @@ -247,17 +247,17 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints new PDASetBreakpointCommand(fCommandControl.getProgramDMContext(), line), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { rm.setData(breakpointCtx); rm.done(); } @Override - protected void handleNotOK() { + protected void handleFailure() { // If inserting of the breakpoint failed, remove it from // the set of installed breakpoints. fBreakpoints.remove(breakpointCtx); - super.handleNotOK(); + super.handleFailure(); } }); } @@ -313,17 +313,17 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints new PDAWatchCommand(fCommandControl.getProgramDMContext(), function, variable, watchOperation), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { rm.setData(watchpointCtx); rm.done(); } @Override - protected void handleNotOK() { + protected void handleFailure() { // Since the command failed, we need to remove the breakpoint from // the existing breakpoint set. fBreakpoints.remove(watchpointCtx); - super.handleNotOK(); + super.handleFailure(); } }); } @@ -389,7 +389,7 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints attributes, new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { // The inserted watchpoint context will equal the // current context. assert bpCtx.equals(getData()); diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java index 60d37deb922..8530ca85543 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java @@ -116,7 +116,7 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon // Call the super-class to perform initialization first. super.initialize( new RequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { doInitialize(rm); } }); @@ -141,7 +141,7 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon // completed. final RequestMonitor socketsInitializeRm = new RequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { // Register the service with OSGi as the last step in initialization of // the service. register( diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAExpressions.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAExpressions.java index 2995b3388d0..7e0e4236b32 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAExpressions.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAExpressions.java @@ -181,7 +181,7 @@ public class PDAExpressions extends AbstractDsfService implements IExpressions { super.initialize( new RequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { doInitialize(rm); }}); } @@ -284,7 +284,7 @@ public class PDAExpressions extends AbstractDsfService implements IExpressions { frameCtx, 0, new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { // Calculate the frame index. int frameId = getData() - frameCtx.getLevel() - 1; @@ -293,7 +293,7 @@ public class PDAExpressions extends AbstractDsfService implements IExpressions { new PDAVarCommand(fCommandControl.getProgramDMContext(), frameId, exprCtx.getExpression()), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { rm.setData(new FormattedValueDMData(getData().fResponseText)); rm.done(); } @@ -318,7 +318,7 @@ public class PDAExpressions extends AbstractDsfService implements IExpressions { frameCtx, 0, new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { // Calculate the frame index. int frameId = getData() - frameCtx.getLevel() - 1; @@ -327,7 +327,7 @@ public class PDAExpressions extends AbstractDsfService implements IExpressions { new PDASetVarCommand(fCommandControl.getProgramDMContext(), frameId, exprCtx.getExpression(), exprValue), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { getSession().dispatchEvent(new ExpressionChangedDMEvent(exprCtx), getProperties()); rm.done(); } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java index 5457e57efb6..6a0c0c59ed9 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java @@ -136,7 +136,7 @@ public class PDARunControl extends AbstractDsfService super.initialize( new RequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { doInitialize(rm); }}); } @@ -244,11 +244,11 @@ public class PDARunControl extends AbstractDsfService new PDAResumeCommand(fCommandControl.getProgramDMContext()), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleNotOK() { + protected void handleFailure() { // If the resume command failed, we no longer // expect to receive a resumed event. fResumePending = false; - super.handleNotOK(); + super.handleFailure(); } } ); @@ -285,7 +285,7 @@ public class PDARunControl extends AbstractDsfService new PDAStepCommand(fCommandControl.getProgramDMContext()), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleNotOK() { + protected void handleFailure() { // If the step command failed, we no longer // expect to receive a resumed event. fResumePending = false; diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java index a54126b9c8d..5f4648414dc 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java @@ -184,7 +184,7 @@ public class PDAStack extends AbstractDsfService implements IStack { super.initialize( new RequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { doInitialize(rm); }}); } @@ -224,7 +224,7 @@ public class PDAStack extends AbstractDsfService implements IStack { new PDAStackCommand(fCommandControl.getProgramDMContext()), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { // PDAFrame array is ordered highest to lowest. We need to // calculate the index based on frame level. int frameId = getData().fFrames.length - frameCtx.getLevel() - 1; @@ -257,7 +257,7 @@ public class PDAStack extends AbstractDsfService implements IStack { new PDAStackCommand(fCommandControl.getProgramDMContext()), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { IFrameDMContext[] frameCtxs = new IFrameDMContext[getData().fFrames.length]; for (int i = 0; i < getData().fFrames.length; i++) { frameCtxs[i] = new FrameDMContext(getSession().getId(), execCtx, i); @@ -274,7 +274,7 @@ public class PDAStack extends AbstractDsfService implements IStack { new PDAStackCommand(fCommandControl.getProgramDMContext()), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { // Find the correct PDAFrame int frameId = getData().fFrames.length - frameCtx.getLevel() - 1; if (frameId < 0) { @@ -301,7 +301,7 @@ public class PDAStack extends AbstractDsfService implements IStack { new PDAStackCommand(fCommandControl.getProgramDMContext()), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { rm.setData(getData().fFrames.length); rm.done(); } diff --git a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/FinalLaunchSequence.java b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/FinalLaunchSequence.java index 321305a15a2..1533ada87bc 100644 --- a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/FinalLaunchSequence.java +++ b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/FinalLaunchSequence.java @@ -216,7 +216,7 @@ public class FinalLaunchSequence extends Sequence { true, false, null, 0, fStopSymbol, 0), new DataRequestMonitor(getExecutor(), requestMonitor) { @Override - protected void handleOK() { + protected void handleSuccess() { // After the break-insert is done, execute the -exec-run or -exec-continue command. fCommandControl.queueCommand(execCommand, new DataRequestMonitor(getExecutor(), requestMonitor)); diff --git a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/GdbLaunch.java b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/GdbLaunch.java index 3127d6c650e..f9a6f5f97e7 100644 --- a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/GdbLaunch.java +++ b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/GdbLaunch.java @@ -144,7 +144,7 @@ public class GdbLaunch extends Launch @Override public void handleCompleted() { fSession.removeServiceEventListener(GdbLaunch.this); - if (!getStatus().isOK()) { + if (!isSuccess()) { GdbLaunchPlugin.getDefault().getLog().log(new MultiStatus( GdbLaunchPlugin.PLUGIN_ID, -1, new IStatus[]{getStatus()}, "Session shutdown failed", null)); //$NON-NLS-1$ } diff --git a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/ShutdownSequence.java b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/ShutdownSequence.java index f241dc1021e..53bbc04897c 100644 --- a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/ShutdownSequence.java +++ b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/ShutdownSequence.java @@ -165,7 +165,7 @@ public class ShutdownSequence extends Sequence { service.shutdown(new RequestMonitor(getExecutor(), requestMonitor) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { GdbLaunchPlugin.getDefault().getLog().log(getStatus()); } requestMonitor.done(); diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/GdbThreadFilterEditor.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/GdbThreadFilterEditor.java index 23d5cc67026..6b963f92b91 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/GdbThreadFilterEditor.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/GdbThreadFilterEditor.java @@ -501,7 +501,7 @@ public class GdbThreadFilterEditor { runControl.getThreadData((IMIExecutionDMContext) thread, new DataRequestMonitor( ImmediateExecutor.getInstance(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { final StringBuilder builder = new StringBuilder("Thread["); //$NON-NLS-1$ builder.append(((IMIExecutionDMContext)thread).getThreadId()); builder.append("] "); //$NON-NLS-1$ diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ContainerVMNode.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ContainerVMNode.java index 3cecaccba41..f0f3542e170 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ContainerVMNode.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ContainerVMNode.java @@ -93,7 +93,7 @@ public class ContainerVMNode extends AbstractDMVMNode new DataRequestMonitor(getExecutor(), null) { @Override public void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { update.done(); return; } diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ThreadVMNode.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ThreadVMNode.java index 2f2c15e0ae4..681bf305211 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ThreadVMNode.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ThreadVMNode.java @@ -74,7 +74,7 @@ public class ThreadVMNode extends AbstractDMVMNode new DataRequestMonitor(getSession().getExecutor(), null){ @Override public void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { handleFailedUpdate(update); return; } @@ -120,7 +120,7 @@ public class ThreadVMNode extends AbstractDMVMNode new DataRequestMonitor(getExecutor(), rm) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { rm.setData(new IVMContext[] { getData().fVMContext }); } else { rm.setData(new IVMContext[0]); @@ -149,7 +149,7 @@ public class ThreadVMNode extends AbstractDMVMNode parentDelta, getVMProvider().getPresentationContext(), -1, -1, new DataRequestMonitor>(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { try { getSession().getExecutor().execute(new DsfRunnable() { public void run() { @@ -231,7 +231,7 @@ public class ThreadVMNode extends AbstractDMVMNode new DataRequestMonitor(getSession().getExecutor(), null) { @Override public void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { update.done(); return; } @@ -294,7 +294,7 @@ public class ThreadVMNode extends AbstractDMVMNode new DataRequestMonitor(getExecutor(), rm) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { parentDelta.addNode( getData().fVMContext, nodeOffset + getData().fIndex, IModelDelta.EXPAND | (getData().fIsSuspended ? 0 : IModelDelta.SELECT)); diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/GDBRunControl.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/GDBRunControl.java index b6b3aabdd57..36ad19ce117 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/GDBRunControl.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/GDBRunControl.java @@ -90,7 +90,7 @@ public class GDBRunControl extends MIRunControl { super.initialize( new RequestMonitor(getExecutor(), requestMonitor) { @Override - public void handleOK() { + public void handleSuccess() { doInitialize(requestMonitor); }}); } @@ -132,7 +132,7 @@ public class GDBRunControl extends MIRunControl { DataRequestMonitor rm1 = new DataRequestMonitor( getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { raiseExitEvents(getData()); fOldExecutionCtxts = getData(); rm.setData(fOldExecutionCtxts); @@ -153,7 +153,7 @@ public class GDBRunControl extends MIRunControl { getCache().execute(new CLIInfoThreads(containerDmc), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { rm.setData( createThreadInfo(execDmc, getData()) ); rm.done(); } diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControl.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControl.java index c4e450184ef..c9656dfdd63 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControl.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControl.java @@ -120,7 +120,7 @@ public class GDBControl extends AbstractMIControl { public void initialize(final RequestMonitor requestMonitor) { super.initialize( new RequestMonitor(getExecutor(), requestMonitor) { @Override - protected void handleOK() { + protected void handleSuccess() { doInitialize(requestMonitor); } }); @@ -220,7 +220,7 @@ public class GDBControl extends AbstractMIControl { public void handleCompleted() { // Cancel the time out runnable (if it hasn't run yet). quitTimeoutFuture.cancel(false); - if (!getStatus().isOK() && !isGDBExited()) { + if (!isSuccess() && !isGDBExited()) { destroy(); } rm.done(); @@ -361,7 +361,7 @@ public class GDBControl extends AbstractMIControl { protected void handleCompleted() { if (!fGDBLaunchMonitor.fTimedOut) { fGDBLaunchMonitor.fLaunched = true; - if (!getStatus().isOK()) { + if (!isSuccess()) { requestMonitor.setStatus(getStatus()); } requestMonitor.done(); @@ -517,7 +517,7 @@ public class GDBControl extends AbstractMIControl { new DataRequestMonitor(getExecutor(), null) { @Override protected void handleCompleted() { - fUseInterpreterConsole = getStatus().isOK(); + fUseInterpreterConsole = isSuccess(); requestMonitor.done(); } } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/CSourceLookup.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/CSourceLookup.java index 333389f510b..02122aba680 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/CSourceLookup.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/CSourceLookup.java @@ -113,7 +113,7 @@ public class CSourceLookup extends AbstractDsfService implements ISourceLookup { super.initialize( new RequestMonitor(getExecutor(), requestMonitor) { @Override - protected void handleOK() { + protected void handleSuccess() { doInitialize(requestMonitor); }}); } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/ExpressionService.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/ExpressionService.java index d7e751cebef..5a085191629 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/ExpressionService.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/ExpressionService.java @@ -418,7 +418,7 @@ public class ExpressionService extends AbstractDsfService implements IExpression public void initialize(final RequestMonitor requestMonitor) { super.initialize(new RequestMonitor(getExecutor(), requestMonitor) { @Override - protected void handleOK() { + protected void handleSuccess() { doInitialize(requestMonitor); } }); @@ -588,7 +588,7 @@ public class ExpressionService extends AbstractDsfService implements IExpression new ExprMetaGetVar(dmc), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { rm.setData(new ExpressionDMData(getData().getExpr(), getData().getType(), getData().getNumChildren(), getData().getEditable())); rm.done(); @@ -630,7 +630,7 @@ public class ExpressionService extends AbstractDsfService implements IExpression new MIDataEvaluateExpression(addressDmc), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { String tmpAddrStr = getData().getValue(); // Deal with adresses of contents of a char* which is in @@ -643,7 +643,7 @@ public class ExpressionService extends AbstractDsfService implements IExpression new MIDataEvaluateExpression(sizeDmc), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { try { int size = Integer.parseInt(getData().getValue()); rm.setData(new ExpressionDMAddress(addrStr, size)); @@ -686,7 +686,7 @@ public class ExpressionService extends AbstractDsfService implements IExpression new ExprMetaGetValue(dmc), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { rm.setData(new FormattedValueDMData(getData().getValue())); rm.done(); } @@ -723,7 +723,7 @@ public class ExpressionService extends AbstractDsfService implements IExpression new ExprMetaGetChildren(dmc), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { ExpressionInfo[] childrenExpr = getData().getChildrenExpressions(); IExpressionDMContext[] childArray = new IExpressionDMContext[childrenExpr.length]; for (int i=0; i(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { rm.setData((IExpressionDMContext[])Arrays.asList(getData()).subList(startIndex, startIndex + length).toArray()); rm.done(); } @@ -790,7 +790,7 @@ public class ExpressionService extends AbstractDsfService implements IExpression new ExprMetaGetChildCount(dmc), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { rm.setData(getData().getChildNum()); rm.done(); } @@ -818,7 +818,7 @@ public class ExpressionService extends AbstractDsfService implements IExpression new ExprMetaGetAttributes(dmc), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { rm.setData(getData().getEditable()); rm.done(); } @@ -858,7 +858,7 @@ public class ExpressionService extends AbstractDsfService implements IExpression formatId, new RequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { // A value has changed, we should remove any references to that // value in our cache. Since we don't have such granularity, // we must clear the entire cache. diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpoints.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpoints.java index 5f6dfe7b801..5b456c20950 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpoints.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpoints.java @@ -207,7 +207,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints public void initialize(final RequestMonitor rm) { super.initialize(new RequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { doInitialize(rm); } }); @@ -309,7 +309,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints fConnection.queueCommand(new MIBreakList(context), new DataRequestMonitor(getExecutor(), drm) { @Override - protected void handleOK() { + protected void handleSuccess() { // Refresh the breakpoints map and format the result breakpointContext.clear(); MIBreakpoint[] breakpoints = getData().getMIBreakpoints(); @@ -484,7 +484,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints DataRequestMonitor addBreakpointDRM = new DataRequestMonitor(getExecutor(), drm) { @Override - protected void handleOK() { + protected void handleSuccess() { // With MI, an invalid location won't generate an error if (getData().getMIBreakpoints().length == 0) { @@ -555,7 +555,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints DataRequestMonitor addWatchpointDRM = new DataRequestMonitor(getExecutor(), drm) { @Override - protected void handleOK() { + protected void handleSuccess() { // With MI, an invalid location won't generate an error if (getData().getMIBreakpoints().length == 0) { @@ -659,7 +659,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints new DataRequestMonitor(getExecutor(), rm) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { getSession().dispatchEvent(new BreakpointRemovedEvent(dmc), getProperties()); contextBreakpoints.remove(reference); } @@ -746,7 +746,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints int numberOfChanges = 0; final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { if (generateUpdateEvent) getSession().dispatchEvent(new BreakpointUpdatedEvent(dmc), getProperties()); rm.done(); @@ -830,7 +830,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints rm.done(); return; } - if (getStatus().isOK()) { + if (isSuccess()) { breakpoint.setCondition(condition); } else { @@ -867,7 +867,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints new MIBreakAfter(context, reference, ignoreCount), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { MIBreakpointDMData breakpoint = contextBreakpoints.get(reference); if (breakpoint == null) { rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); @@ -903,7 +903,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints new MIBreakEnable(context, new int[] { reference }), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { MIBreakpointDMData breakpoint = contextBreakpoints.get(reference); if (breakpoint == null) { rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); @@ -939,7 +939,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints new MIBreakDisable(context, new int[] { reference }), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { MIBreakpointDMData breakpoint = contextBreakpoints.get(reference); if (breakpoint == null) { rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointsManager.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointsManager.java index 044e384a6e9..a13de5f8fce 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointsManager.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointsManager.java @@ -219,7 +219,7 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo super.initialize( new RequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { doInitialize(rm); }}); } @@ -412,7 +412,7 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo // Upon determining the debuggerPath, the breakpoint is installed determineDebuggerPath(dmc, attributes, new RequestMonitor(getExecutor(), countingRm) { @Override - protected void handleOK() { + protected void handleSuccess() { installBreakpoint(dmc, breakpoint, attributes, new RequestMonitor(getExecutor(), countingRm)); } }); @@ -549,7 +549,7 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo DataRequestMonitor drm = new DataRequestMonitor(getExecutor(), installRM) { @Override - protected void handleOK() { + protected void handleSuccess() { // Add the new back-end breakpoint to the map Vector list = breakpointIDs.get(breakpoint); if (list == null) @@ -684,7 +684,7 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo // Upon completion, update the mappings CountingRequestMonitor removeRM = new CountingRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { // Update the mappings platformBPs.remove(breakpoint); threadsIDs.remove(breakpoint); @@ -804,7 +804,7 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo // Update completion monitor final CountingRequestMonitor updateRM = new CountingRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { // Success: simply store the new attributes platformBPs.put(breakpoint, attributes); rm.done(); @@ -828,7 +828,7 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo final Vector newTargetBPs = new Vector(); final CountingRequestMonitor removeRM = new CountingRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { // All right! Save the new list and perform the final update Map> breakpointIDs = fBreakpointIDs.get(dmc); if (breakpointIDs == null) { @@ -852,7 +852,7 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo // In theory, we could have had a partial success and the original threads // list would be invalid. We think it is highly unlikely so we assume that // either everything went fine or else everything failed. - protected void handleOK() { + protected void handleSuccess() { // Get the list of new back-end breakpoints contexts newTargetBPs.addAll(getData()); threadsIDs.put(breakpoint, newThreads); @@ -908,7 +908,7 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo // Once we're done, return the new list of back-end breakpoints contexts final CountingRequestMonitor installRM = new CountingRequestMonitor(getExecutor(), drm) { @Override - protected void handleOK() { + protected void handleSuccess() { // Report whatever we have managed to install // It is very likely installation either succeeded or failed for all drm.setData(breakpointList); @@ -932,7 +932,7 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo fBreakpoints.insertBreakpoint(context, attrs, new DataRequestMonitor(getExecutor(), installRM) { @Override - protected void handleOK() { + protected void handleSuccess() { // Add the new back-end breakpoint context to the list breakpointList.add(getData()); try { @@ -1011,7 +1011,7 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo determineDebuggerPath(dmc, attrs, new RequestMonitor(getExecutor(), countingRm) { @Override - protected void handleOK() { + protected void handleSuccess() { installBreakpoint(dmc, (ICBreakpoint) breakpoint, attrs, new RequestMonitor(getExecutor(), countingRm)); } @@ -1064,7 +1064,7 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { if (getStatus().getSeverity() == IStatus.ERROR) { MIPlugin.getDefault().getLog().log(getStatus()); } @@ -1090,7 +1090,7 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo determineDebuggerPath(dmc, attrs, new RequestMonitor(getExecutor(), countingRm) { @Override - protected void handleOK() { + protected void handleSuccess() { modifyBreakpoint(dmc, (ICBreakpoint) breakpoint, attrs, delta, new RequestMonitor(getExecutor(), countingRm)); } }); @@ -1334,7 +1334,7 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo fSourceLookup.getDebuggerPath(srcDmc, hostPath, new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { attributes.put(ATTR_DEBUGGER_PATH, getData()); rm.done(); } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIDisassembly.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIDisassembly.java index b8cad253a70..c809a873daf 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIDisassembly.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIDisassembly.java @@ -54,7 +54,7 @@ public class MIDisassembly extends AbstractDsfService implements IDisassembly { public void initialize(final RequestMonitor rm) { super.initialize(new RequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { doInitialize(rm); } }); @@ -110,7 +110,7 @@ public class MIDisassembly extends AbstractDsfService implements IDisassembly { fConnection.queueCommand(new MIDataDisassemble(context, start, end, false), new DataRequestMonitor(getExecutor(), drm) { @Override - protected void handleOK() { + protected void handleSuccess() { IInstruction[] result = getData().getMIAssemblyCode(); drm.setData(result); drm.done(); @@ -135,7 +135,7 @@ public class MIDisassembly extends AbstractDsfService implements IDisassembly { fConnection.queueCommand(new MIDataDisassemble(context, filename, linenum, lines, false), new DataRequestMonitor(getExecutor(), drm) { @Override - protected void handleOK() { + protected void handleSuccess() { IInstruction[] result = getData().getMIAssemblyCode(); drm.setData(result); drm.done(); @@ -163,7 +163,7 @@ public class MIDisassembly extends AbstractDsfService implements IDisassembly { fConnection.queueCommand(new MIDataDisassemble(context, start, end, true), new DataRequestMonitor(getExecutor(), drm) { @Override - protected void handleOK() { + protected void handleSuccess() { IMixedInstruction[] result = getData().getMIMixedCode(); drm.setData(result); drm.done(); @@ -189,7 +189,7 @@ public class MIDisassembly extends AbstractDsfService implements IDisassembly { fConnection.queueCommand(new MIDataDisassemble(context, filename, linenum, lines, true), new DataRequestMonitor(getExecutor(), drm) { @Override - protected void handleOK() { + protected void handleSuccess() { IMixedInstruction[] result = getData().getMIMixedCode(); drm.setData(result); drm.done(); diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIMemory.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIMemory.java index b958bcdec73..0870b86f01a 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIMemory.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIMemory.java @@ -94,7 +94,7 @@ public class MIMemory extends AbstractDsfService implements IMemory { public void initialize(final RequestMonitor requestMonitor) { super.initialize(new RequestMonitor(getExecutor(), requestMonitor) { @Override - protected void handleOK() { + protected void handleSuccess() { doInitialize(requestMonitor); } }); @@ -304,7 +304,7 @@ public class MIMemory extends AbstractDsfService implements IMemory { expressionService.getExpressionAddressData(context, new DataRequestMonitor(getExecutor(), null) { @Override - protected void handleOK() { + protected void handleSuccess() { // Figure out which memory area was modified IExpressionDMAddress expression = getData(); final int count = expression.getSize(); @@ -694,7 +694,7 @@ public class MIMemory extends AbstractDsfService implements IMemory { final CountingRequestMonitor countingRM = new CountingRequestMonitor(getExecutor(), drm) { @Override - protected void handleOK() { + protected void handleSuccess() { // We received everything so read the result from the memory cache drm.setData(getMemoryBlockFromCache(address, count)); drm.done(); @@ -710,7 +710,7 @@ public class MIMemory extends AbstractDsfService implements IMemory { readMemoryBlock(memoryDMC, startAddress, 0, word_size, length, new DataRequestMonitor(getSession().getExecutor(), drm) { @Override - protected void handleOK() { + protected void handleSuccess() { MemoryByte[] block = new MemoryByte[count]; block = getData(); MemoryBlock memoryBlock = new MemoryBlock(startAddress, length, block); @@ -738,7 +738,7 @@ public class MIMemory extends AbstractDsfService implements IMemory { memoryDMC, address, offset, word_size, count, buffer, new RequestMonitor(getSession().getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { // Clear the command cache (otherwise we can't guarantee // that the subsequent memory read will be correct) fCommandCache.reset(); @@ -747,7 +747,7 @@ public class MIMemory extends AbstractDsfService implements IMemory { final DataRequestMonitor drm = new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { updateMemoryCache(address.add(offset), count, getData()); // Send the MemoryChangedEvent IAddress[] addresses = new IAddress[count]; @@ -764,7 +764,7 @@ public class MIMemory extends AbstractDsfService implements IMemory { readMemoryBlock(memoryDMC, address, offset, word_size, count, new DataRequestMonitor(getExecutor(), drm) { @Override - public void handleOK() { + protected void handleSuccess() { drm.setData(getData()); drm.done(); } @@ -809,7 +809,7 @@ public class MIMemory extends AbstractDsfService implements IMemory { fMemoryCache.readMemoryBlock(memoryDMC, address, 0, 1, count, new DataRequestMonitor(getExecutor(), rm) { @Override - public void handleOK() { + protected void handleSuccess() { MemoryByte[] oldBlock = fMemoryCache.getMemoryBlockFromCache(address, count); MemoryByte[] newBlock = getData(); boolean blocksDiffer = false; @@ -855,7 +855,7 @@ public class MIMemory extends AbstractDsfService implements IMemory { new MIDataReadMemory(memoryDMC, offset, address.toString(), mode, word_size, nb_rows, nb_cols, asChar), new DataRequestMonitor(getExecutor(), drm) { @Override - protected void handleOK() { + protected void handleSuccess() { // Retrieve the memory block drm.setData(getData().getMIMemoryBlock()); drm.done(); @@ -881,7 +881,7 @@ public class MIMemory extends AbstractDsfService implements IMemory { final CountingRequestMonitor countingRM = new CountingRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { rm.done(); } }; diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIModules.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIModules.java index 64a8a86b291..d013393fceb 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIModules.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIModules.java @@ -53,7 +53,7 @@ public class MIModules extends AbstractDsfService implements IModules { super.initialize( new RequestMonitor(getExecutor(), requestMonitor) { @Override - protected void handleOK() { + protected void handleSuccess() { doInitialize(requestMonitor); }}); } @@ -155,7 +155,7 @@ public class MIModules extends AbstractDsfService implements IModules { fModulesCache.execute(new CLIInfoSharedLibrary(symCtx), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { rm.setData(makeModuleContexts(symCtx, getData())); rm.done(); } @@ -184,7 +184,7 @@ public class MIModules extends AbstractDsfService implements IModules { fModulesCache.execute(new CLIInfoSharedLibrary(dmc), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { rm.setData( createSharedLibInfo((ModuleDMContext)dmc, getData()) ); rm.done(); } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRegisters.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRegisters.java index 596a4b70ab2..a7c658569ad 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRegisters.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRegisters.java @@ -162,7 +162,7 @@ public class MIRegisters extends AbstractDsfService implements IRegisters { super.initialize( new RequestMonitor(getExecutor(), requestMonitor) { @Override - protected void handleOK() { + protected void handleSuccess() { doInitialize(requestMonitor); }}); } @@ -269,7 +269,7 @@ public class MIRegisters extends AbstractDsfService implements IRegisters { new MIDataListRegisterValues(execDmc, MIFormat.HEXADECIMAL, regnos), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { // Retrieve the register value. MIRegisterValue[] regValue = getData().getMIRegisterValues(); @@ -324,7 +324,7 @@ public class MIRegisters extends AbstractDsfService implements IRegisters { new MIDataListRegisterValues(miExecDmc, NumberFormat, regnos), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { // Retrieve the register value. MIRegisterValue[] regValue = getData().getMIRegisterValues(); @@ -463,7 +463,7 @@ public class MIRegisters extends AbstractDsfService implements IRegisters { new MIDataListRegisterNames(containerDmc), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { // Retrieve the register names. String[] regNames = getData().getRegisterNames() ; @@ -515,18 +515,18 @@ public class MIRegisters extends AbstractDsfService implements IRegisters { final IExpressionDMContext exprCtxt = exprService.createExpression(regCtx, "$" + regName); //$NON-NLS-1$ exprService.getModelData(exprCtxt, new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { // Evaluate the expression - request HEX since it works in every case final FormattedValueDMContext valueDmc = exprService.getFormattedValueContext(exprCtxt, formatId); exprService.getModelData( valueDmc, new DataRequestMonitor(getExecutor(), null) { @Override - protected void handleOK() { + protected void handleSuccess() { if(! regValue.equals(getData().getFormattedValue()) || ! valueDmc.getFormatID().equals(formatId)){ exprService.writeExpression(exprCtxt, regValue, formatId, new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { generateRegisterChangedEvent(regDmc); } }); diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java index 1e7fb7ea3ab..a70af84f3be 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java @@ -291,7 +291,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl super.initialize( new RequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { doInitialize(rm); }}); } @@ -484,7 +484,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl cmd, new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { rm.done(); } } @@ -516,7 +516,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl cmd, new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { rm.done(); } } @@ -598,7 +598,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl new DataRequestMonitor( getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { rm.setData(makeExecutionDMCs(containerDmc, getData())); rm.done(); } @@ -654,7 +654,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl new DataRequestMonitor( getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { rm.done(); } }); diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIStack.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIStack.java index 7baa34260f8..c268e272d8d 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIStack.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIStack.java @@ -135,7 +135,7 @@ public class MIStack extends AbstractDsfService super.initialize( new RequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { doInitialize(rm); } }); @@ -205,7 +205,7 @@ public class MIStack extends AbstractDsfService new MIStackListFrames(execDmc), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { rm.setData(getFrames(execDmc, getData())); rm.done(); } @@ -236,7 +236,7 @@ public class MIStack extends AbstractDsfService ctx, new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { rm.setData(getData()[0]); rm.done(); } @@ -340,7 +340,7 @@ public class MIStack extends AbstractDsfService new MIStackListFrames(execDmc), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { // Find the index to the correct MI frame object. int idx = findFrameIndex(getData().getMIFrames(), miFrameDmc.fLevel); if (idx == -1) { @@ -384,7 +384,7 @@ public class MIStack extends AbstractDsfService new MIStackListArguments(execDmc, true), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { // Find the index to the correct MI frame object. // Note: this is a short-cut, but it won't work once we implement retrieving // partial lists of stack frames. @@ -464,7 +464,7 @@ public class MIStack extends AbstractDsfService new MIStackListArguments(execDmc, true), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { // Find the correct frame and argument if ( frameDmc.fLevel >= getData().getMIFrames().length || miVariableDmc.fIndex >= getData().getMIFrames()[frameDmc.fLevel].getArgs().length ) @@ -484,7 +484,7 @@ public class MIStack extends AbstractDsfService new MIStackListLocals(frameDmc, true), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { // Create the data object. rm.setData(new VariableData(getData().getLocals()[miVariableDmc.fIndex])); @@ -520,7 +520,7 @@ public class MIStack extends AbstractDsfService final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { rm.setData( localsList.toArray(new IVariableDMContext[localsList.size()]) ); rm.done(); } @@ -531,7 +531,7 @@ public class MIStack extends AbstractDsfService frameDmc, new DataRequestMonitor(getExecutor(), countingRm) { @Override - protected void handleOK() { + protected void handleSuccess() { localsList.addAll( Arrays.asList(getData()) ); countingRm.done(); } @@ -541,7 +541,7 @@ public class MIStack extends AbstractDsfService new MIStackListLocals(frameDmc, true), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { localsList.addAll( Arrays.asList( makeVariableDMCs(frameDmc, MIVariableDMC.Type.LOCAL, getData().getLocals().length)) ); countingRm.done(); @@ -560,7 +560,7 @@ public class MIStack extends AbstractDsfService depthCommand, new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { rm.setData(getData().getDepth()); rm.done(); } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java index 82390639728..dc3708d93dd 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java @@ -358,7 +358,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon protected void handleCompleted() { currentState = STATE_READY; - if (getStatus().isOK()) { + if (isSuccess()) { outOfScope = getRootToUpdate().isOutOfScope(); // This request monitor is the one that should re-create // the variable object if the old one was out-of-scope @@ -414,7 +414,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon new MIVarShowAttributes(fControlDmc, getGdbName()), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { editable = getData().isEditable(); rm.setData(editable); @@ -466,7 +466,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon addrCxt, new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { getData().getValue(formatCxt, rm); } @@ -485,7 +485,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon if (locked) { operationsPending.add(new RequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { getValue(dmc, rm); } }); @@ -503,7 +503,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon new DataRequestMonitor(getExecutor(), rm) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { setCurrentFormat(dmc.getFormatID()); // If set-format returned the value, no need to evaluate @@ -539,7 +539,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon new DataRequestMonitor(getExecutor(), rm) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { setValue(getCurrentFormat(), getData().getValue()); rm.setData(new FormattedValueDMData(getData().getValue())); rm.done(); @@ -576,7 +576,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon new DataRequestMonitor(getExecutor(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { setCurrentFormat(IFormattedValues.NATURAL_FORMAT); } unlock(); @@ -641,13 +641,13 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon new MIVarListChildren(fControlDmc, getGdbName()), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { MIVar[] children = getData().getMIVars(); final List realChildren = new ArrayList(); final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { // Store the children in our variable object cache setChildren(realChildren.toArray(new ExpressionInfo[realChildren.size()])); rm.setData(getChildren()); @@ -678,7 +678,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon final DataRequestMonitor childPathRm = new DataRequestMonitor(getExecutor(), countingRm) { @Override - protected void handleOK() { + protected void handleSuccess() { String childFullExpression = getData(); // For children that do not map to a real expression (such as f.public) @@ -729,7 +729,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon exprDmc, new DataRequestMonitor(getExecutor(), countingRm) { @Override - protected void handleOK() { + protected void handleSuccess() { ExpressionInfo[] vars = getData(); for (ExpressionInfo realChild : vars) { realChildren.add(realChild); @@ -759,7 +759,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon new DataRequestMonitor(getExecutor(), childPathRm) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { childPathRm.setData(getData().getFullExpression()); } else { // If we don't have var-info-path-expression @@ -874,7 +874,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon // Return a status info so that handleOK is not called and we don't send // an ExpressionChanged event if (value.equals(getValue(formatId))) { - rm.setStatus(new Status(IStatus.INFO, MIPlugin.PLUGIN_ID, IDsfStatusConstants.NOT_SUPPORTED, + rm.setStatus(new Status(IStatus.WARNING, MIPlugin.PLUGIN_ID, IDsfStatusConstants.NOT_SUPPORTED, "Setting to the same value of: " + value, null)); //$NON-NLS-1$ rm.done(); return; @@ -885,7 +885,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon new MIVarAssign(fControlDmc, getGdbName(), value), new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { // We must also mark all variable objects // as out-of-date. This is because some variable objects may be affected // by this one having changed. @@ -963,7 +963,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon new DataRequestMonitor(getExecutor(), rm) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { setGdbName(getData().getName()); setExpressionData( exprCtx.getExpression(), @@ -1062,7 +1062,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon protected void handleCompleted() { currentState = STATE_READY; - if (getStatus().isOK()) { + if (isSuccess()) { outOfDate = false; MIVarChange[] changes = getData().getMIVarChanges(); @@ -1201,7 +1201,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon execCtx, 0, new DataRequestMonitor(getExecutor(), rm) { @Override - public void handleOK() { + protected void handleSuccess() { fFrameId = new Integer(getData() - frameCtx.getLevel()); rm.done(); } @@ -1362,7 +1362,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon exprCtx, new RequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { getVariable(id, exprCtx, rm); } }); @@ -1383,7 +1383,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon // and if we should re-create it. varObj.update(new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { boolean shouldCreateNew = getData().booleanValue(); @@ -1444,7 +1444,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon newVarObj.create(exprCtx, new RequestMonitor(getExecutor(), rm) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { // Also store the object as a varObj that is up-to-date updatedRootList.add(newVarObj); @@ -1481,7 +1481,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon ctx, new DataRequestMonitor(getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { getData().writeValue(expressionValue, formatId, rm); } }); @@ -1504,7 +1504,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon exprCtx, new DataRequestMonitor(getExecutor(), drm) { @Override - protected void handleOK() { + protected void handleSuccess() { drm.setData( new ExprMetaGetVarInfo( exprCtx.getRelativeExpression(), @@ -1523,11 +1523,11 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon exprCtx, new DataRequestMonitor(getExecutor(), drm) { @Override - protected void handleOK() { + protected void handleSuccess() { getData().getAttributes( new DataRequestMonitor(getExecutor(), drm) { @Override - protected void handleOK() { + protected void handleSuccess() { drm.setData(new ExprMetaGetAttributesInfo(getData())); drm.done(); } @@ -1546,12 +1546,12 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon exprCtx, new DataRequestMonitor(getExecutor(), drm) { @Override - protected void handleOK() { + protected void handleSuccess() { getData().getValue( valueCtx, new DataRequestMonitor(getExecutor(), drm) { @Override - protected void handleOK() { + protected void handleSuccess() { drm.setData( new ExprMetaGetValueInfo(getData().getFormattedValue())); drm.done(); @@ -1569,12 +1569,12 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon exprCtx, new DataRequestMonitor(getExecutor(), drm) { @Override - protected void handleOK() { + protected void handleSuccess() { getData().getChildren( exprCtx, new DataRequestMonitor(getExecutor(), drm) { @Override - protected void handleOK() { + protected void handleSuccess() { drm.setData(new ExprMetaGetChildrenInfo(getData())); drm.done(); } @@ -1591,11 +1591,11 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon exprCtx, new DataRequestMonitor(getExecutor(), drm) { @Override - protected void handleOK() { + protected void handleSuccess() { getData().getChildrenCount( new DataRequestMonitor(getExecutor(), drm) { @Override - protected void handleOK() { + protected void handleSuccess() { drm.setData(new ExprMetaGetChildCountInfo(getData())); drm.done(); } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/breakpoint/actions/MILogActionEnabler.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/breakpoint/actions/MILogActionEnabler.java index 8b9c509bedb..fc96c6a26c1 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/breakpoint/actions/MILogActionEnabler.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/breakpoint/actions/MILogActionEnabler.java @@ -56,7 +56,7 @@ public class MILogActionEnabler implements ILogActionEnabler { @Override protected void handleCompleted() { String result = expression + ": evaluation failed."; //$NON-NLS-1$ - if (getStatus().isOK()) { + if (isSuccess()) { result = getData().getFormattedValue(); } drm.setData(result); diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIInferiorProcess.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIInferiorProcess.java index fbc80308ab4..b8ef43d869c 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIInferiorProcess.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIInferiorProcess.java @@ -238,7 +238,7 @@ public class MIInferiorProcess extends Process new MIGDBShowExitCode(getCommandControl().getControlDMContext()), new DataRequestMonitor(fSession.getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { rm.setData(getData().getCode()); rm.done(); } diff --git a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/AbstractService.java b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/AbstractService.java index 94a5fdc9de2..7831252c5d3 100644 --- a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/AbstractService.java +++ b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/AbstractService.java @@ -37,7 +37,7 @@ abstract public class AbstractService extends AbstractDsfService super.initialize( new RequestMonitor(getExecutor(), requestMonitor) { @Override - public void handleOK() { + public void handleSuccess() { doInitialize(requestMonitor); } }); diff --git a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/Service1.java b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/Service1.java index 34e3cd72bb2..01e132acc81 100644 --- a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/Service1.java +++ b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/Service1.java @@ -24,7 +24,7 @@ public class Service1 extends AbstractService { super.initialize( new RequestMonitor(getExecutor(), requestMonitor) { @Override - public void handleOK() { + public void handleSuccess() { doInitialize(requestMonitor); } }); diff --git a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/Service2.java b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/Service2.java index a466c03e295..076cfb9fd8d 100644 --- a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/Service2.java +++ b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/Service2.java @@ -24,7 +24,7 @@ public class Service2 extends AbstractService { super.initialize( new RequestMonitor(getExecutor(), requestMonitor) { @Override - public void handleOK() { + public void handleSuccess() { doInitialize(requestMonitor); } }); diff --git a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/Service3.java b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/Service3.java index 5069157e8d0..51064766187 100644 --- a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/Service3.java +++ b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/events/Service3.java @@ -30,7 +30,7 @@ public class Service3 extends AbstractService { super.initialize( new RequestMonitor(getExecutor(), requestMonitor) { @Override - public void handleOK() { + public void handleSuccess() { doInitialize(requestMonitor); } }); diff --git a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/service/MultiInstanceTestService.java b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/service/MultiInstanceTestService.java index 2addfb41af7..3e831ec29cb 100644 --- a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/service/MultiInstanceTestService.java +++ b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/service/MultiInstanceTestService.java @@ -38,7 +38,7 @@ public class MultiInstanceTestService extends AbstractDsfService { super.initialize( new RequestMonitor(getExecutor(), requestMonitor) { @Override - public void handleOK() { + public void handleSuccess() { doInitialize(requestMonitor); } }); diff --git a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/service/SimpleTestService.java b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/service/SimpleTestService.java index f0e29b2f309..6389c0dc059 100644 --- a/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/service/SimpleTestService.java +++ b/plugins/org.eclipse.dd.tests.dsf/src/org/eclipse/dd/tests/dsf/service/SimpleTestService.java @@ -34,7 +34,7 @@ public class SimpleTestService extends AbstractDsfService { super.initialize( new RequestMonitor(getExecutor(), requestMonitor) { @Override - public void handleOK() { + public void handleSuccess() { doInitialize(requestMonitor); } }); diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/ExpressionServiceTest.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/ExpressionServiceTest.java index 33ccdf3ae6b..7ea0742a50a 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/ExpressionServiceTest.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/ExpressionServiceTest.java @@ -354,7 +354,7 @@ public class ExpressionServiceTest extends BaseTestCase { .getExecutor(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { wait.setReturnInfo(getData()); } @@ -455,7 +455,7 @@ public class ExpressionServiceTest extends BaseTestCase { .getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else { if (getData().getFormattedValue().equals("28")) { @@ -474,7 +474,7 @@ public class ExpressionServiceTest extends BaseTestCase { .getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else { if (getData().getFormattedValue().equalsIgnoreCase("0x1c")) { @@ -523,7 +523,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { wait.setReturnInfo(getData()); } @@ -551,7 +551,7 @@ public class ExpressionServiceTest extends BaseTestCase { .getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else { if (getData().getFormattedValue().equals(actualAddrStr)) { @@ -569,7 +569,7 @@ public class ExpressionServiceTest extends BaseTestCase { fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else { IExpressionDMContext[] children = getData(); @@ -597,7 +597,7 @@ public class ExpressionServiceTest extends BaseTestCase { .getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else { if (getData().getFormattedValue().equals(actualAddrStr)) { @@ -645,7 +645,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { wait.setReturnInfo(getData()); } @@ -672,7 +672,7 @@ public class ExpressionServiceTest extends BaseTestCase { .getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else { if (getData().getFormattedValue().equals(actualAddrStr)) { @@ -690,7 +690,7 @@ public class ExpressionServiceTest extends BaseTestCase { null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else { int count = getData(); @@ -711,7 +711,7 @@ public class ExpressionServiceTest extends BaseTestCase { .getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else { if (getData().getFormattedValue().equals(actualAddrStr)) { @@ -761,7 +761,7 @@ public class ExpressionServiceTest extends BaseTestCase { .getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else { if (getData().getFormattedValue().equals("32")) { @@ -780,7 +780,7 @@ public class ExpressionServiceTest extends BaseTestCase { fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else { wait.waitFinished(); @@ -795,7 +795,7 @@ public class ExpressionServiceTest extends BaseTestCase { .getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else { if (getData().getFormattedValue().equals("0x38")) { @@ -850,7 +850,7 @@ public class ExpressionServiceTest extends BaseTestCase { .getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else { if (getData().getFormattedValue().equals("32")) { @@ -870,7 +870,7 @@ public class ExpressionServiceTest extends BaseTestCase { .getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else { if (getData().getFormattedValue().equals("0x20")) { @@ -889,7 +889,7 @@ public class ExpressionServiceTest extends BaseTestCase { null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else { if (getData() != 0) { @@ -907,7 +907,7 @@ public class ExpressionServiceTest extends BaseTestCase { fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else { if (getData().length != 0) { @@ -927,7 +927,7 @@ public class ExpressionServiceTest extends BaseTestCase { .getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else { if (getData().getFormattedValue().equals("040")) { @@ -986,7 +986,7 @@ public class ExpressionServiceTest extends BaseTestCase { .getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else { if (getData().getFormattedValue().equals("32")) { @@ -1005,7 +1005,7 @@ public class ExpressionServiceTest extends BaseTestCase { fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else { wait.waitFinished(); @@ -1022,7 +1022,7 @@ public class ExpressionServiceTest extends BaseTestCase { .getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else { if (getData().getFormattedValue().equals("070")) { @@ -1048,7 +1048,7 @@ public class ExpressionServiceTest extends BaseTestCase { .getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else { if (getData().getFormattedValue().equals("32")) { @@ -1080,7 +1080,7 @@ public class ExpressionServiceTest extends BaseTestCase { .getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else { if (getData().getFormattedValue().equals("56")) { @@ -1131,7 +1131,7 @@ public class ExpressionServiceTest extends BaseTestCase { .getExecutor(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { wait.setReturnInfo(getData()); } @@ -1282,7 +1282,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else if (getData().length != 2) { wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, @@ -1296,7 +1296,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else if (getData().getFormattedValue().equals(valueStr)) { wait.waitFinished(); @@ -1334,7 +1334,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else if (getData().length != 2) { wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, @@ -1348,7 +1348,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else if (getData().getFormattedValue().equals(valueStr)) { wait.waitFinished(); @@ -1386,7 +1386,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else if (getData().length != 2) { wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, @@ -1400,7 +1400,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else if (getData().getFormattedValue().equals(valueStr)) { wait.waitFinished(); @@ -1466,7 +1466,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else if (getData().length != 1) { wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, @@ -1480,7 +1480,7 @@ public class ExpressionServiceTest extends BaseTestCase { protected void handleCompleted() { final IExpressionDMContext[] childDmcs = getData(); - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else if (childDmcs.length != 2) { wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, @@ -1497,7 +1497,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else if (getData().getFormattedValue().equals(valueStr)) { wait.waitFinished(); @@ -1542,7 +1542,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else if (getData().length != 1) { wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, @@ -1556,7 +1556,7 @@ public class ExpressionServiceTest extends BaseTestCase { protected void handleCompleted() { final IExpressionDMContext[] childDmcs = getData(); - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else if (childDmcs.length != 2) { wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, @@ -1573,7 +1573,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else if (getData().getFormattedValue().equals(valueStr)) { wait.waitFinished(); @@ -1627,7 +1627,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else { if (getData().length != 5) { @@ -1645,7 +1645,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else { if (getData().length != 2) { @@ -1692,7 +1692,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else { wait.waitFinished(); @@ -1717,7 +1717,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else { wait.waitFinished(); @@ -1765,7 +1765,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else { if (getData().getFormattedValue().equals("1011")) { @@ -1801,7 +1801,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else { if (getData().getFormattedValue().equals("11")) { @@ -1864,7 +1864,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else { if (getData().getFormattedValue().equals("1.99")) { @@ -1885,7 +1885,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else { if (getData().getFormattedValue().equals("0x1")) { @@ -1922,7 +1922,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else { if (getData().getFormattedValue().equals("1.22")) { @@ -1981,7 +1981,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else if (getData().length != 1) { wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, @@ -1998,7 +1998,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else if (getData().getFormattedValue().equals(valueStr)) { wait.waitFinished(); @@ -2017,7 +2017,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else { if (getData().getFormattedValue().equals(valueStr)) { @@ -2055,7 +2055,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else { if (getData().getFormattedValue().equals("1.22")) { @@ -2101,7 +2101,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else if (getData().length != 1) { wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, @@ -2115,7 +2115,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else if (getData().getFormattedValue().equals(valueStr)) { wait.waitFinished(); @@ -2148,7 +2148,7 @@ public class ExpressionServiceTest extends BaseTestCase { @Override protected void handleCompleted() { final String valueStr = "1"; - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else if (getData().getFormattedValue().equals(valueStr)) { wait.waitFinished(); @@ -2167,7 +2167,7 @@ public class ExpressionServiceTest extends BaseTestCase { @Override protected void handleCompleted() { final String valueStr = "0x1"; - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else if (getData().getFormattedValue().equals(valueStr)) { wait.waitFinished(); @@ -2216,7 +2216,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else if (getData().length != 1) { wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, @@ -2230,7 +2230,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else if (getData().getFormattedValue().equals(valueStr)) { wait.waitFinished(); @@ -2265,7 +2265,7 @@ public class ExpressionServiceTest extends BaseTestCase { @Override protected void handleCompleted() { final String valueStr = "2"; - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else if (getData().getFormattedValue().equals(valueStr)) { wait.waitFinished(); @@ -2292,7 +2292,7 @@ public class ExpressionServiceTest extends BaseTestCase { @Override protected void handleCompleted() { final String valueStr = "{...}"; - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else if (getData().getFormattedValue().equals(valueStr)) { wait.waitFinished(); @@ -2312,7 +2312,7 @@ public class ExpressionServiceTest extends BaseTestCase { @Override protected void handleCompleted() { final String valueStr = "{...}"; - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else if (getData().getFormattedValue().equals(valueStr)) { wait.waitFinished(); @@ -2361,7 +2361,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else if (getData().length != 2) { wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, @@ -2378,7 +2378,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else if (getData().getFormattedValue().equals(firstValue)) { wait.waitFinished(); @@ -2397,7 +2397,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else { wait.setReturnInfo(getData().getFormattedValue()); @@ -2425,7 +2425,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else if (getData().length != 1) { wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, @@ -2438,7 +2438,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else if (getData().getFormattedValue().equals(firstValue)) { wait.waitFinished(); @@ -2473,7 +2473,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else if (getData().length != 2) { wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, @@ -2490,7 +2490,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else if (getData().getFormattedValue().equals(secondValue)) { wait.waitFinished(); @@ -2509,7 +2509,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else if (!getData().getFormattedValue().equals(pointerValue)) { // The value should have changed @@ -2540,7 +2540,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else if (getData().length != 1) { wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, @@ -2553,7 +2553,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else if (getData().getFormattedValue().equals(thirdValue)) { wait.waitFinished(); @@ -2617,7 +2617,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else if (getData() == expectedValues[finalIndex]) { wait.waitFinished(); @@ -2674,7 +2674,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else if (getData() == expectedValues[finalIndex]) { wait.waitFinished(); @@ -2729,7 +2729,7 @@ public class ExpressionServiceTest extends BaseTestCase { fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else { final String[] formatIds = getData(); @@ -2756,7 +2756,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { wait.waitFinished(getStatus()); } else { @@ -2831,7 +2831,7 @@ public class ExpressionServiceTest extends BaseTestCase { .getExecutor(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { wait.setReturnInfo(getData()); } @@ -2923,7 +2923,7 @@ public class ExpressionServiceTest extends BaseTestCase { new DataRequestMonitor(fExpService.getExecutor(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { wait.setReturnInfo(getData()); } wait.waitFinished(getStatus()); diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/GDBProcessesTest.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/GDBProcessesTest.java index 1f8fe3aba88..5f7c84c17f0 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/GDBProcessesTest.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/GDBProcessesTest.java @@ -95,7 +95,7 @@ public class GDBProcessesTest extends BaseTestCase { new DataRequestMonitor(fSession.getExecutor(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { fWait.setReturnInfo(getData()); } fWait.waitFinished(getStatus()); @@ -144,7 +144,7 @@ public class GDBProcessesTest extends BaseTestCase { new DataRequestMonitor(fSession.getExecutor(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { fWait.setReturnInfo(getData()); } fWait.waitFinished(getStatus()); diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIBreakpointsTest.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIBreakpointsTest.java index 86c819b56a4..a3aace6b4f3 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIBreakpointsTest.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIBreakpointsTest.java @@ -346,7 +346,7 @@ public class MIBreakpointsTest extends BaseTestCase { new DataRequestMonitor(fSession.getExecutor(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { fWait.setReturnInfo(getData()); } fWait.waitFinished(getStatus()); diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIDisassemblyTest.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIDisassemblyTest.java index f9ecaccff59..ffd1a3b05f0 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIDisassemblyTest.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIDisassemblyTest.java @@ -145,7 +145,7 @@ public class MIDisassemblyTest extends BaseTestCase { new DataRequestMonitor(fSession.getExecutor(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { fWait.setReturnInfo(getData()); } fWait.waitFinished(getStatus()); @@ -196,7 +196,7 @@ public class MIDisassemblyTest extends BaseTestCase { new DataRequestMonitor(fSession.getExecutor(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { fWait.setReturnInfo(getData()); } fWait.waitFinished(getStatus()); @@ -237,7 +237,7 @@ public class MIDisassemblyTest extends BaseTestCase { new DataRequestMonitor(fSession.getExecutor(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { fWait.setReturnInfo(getData()); } fWait.waitFinished(getStatus()); @@ -277,7 +277,7 @@ public class MIDisassemblyTest extends BaseTestCase { new DataRequestMonitor(fSession.getExecutor(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { fWait.setReturnInfo(getData()); } fWait.waitFinished(getStatus()); @@ -318,7 +318,7 @@ public class MIDisassemblyTest extends BaseTestCase { new DataRequestMonitor(fSession.getExecutor(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { fWait.setReturnInfo(getData()); } fWait.waitFinished(getStatus()); diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIMemoryTest.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIMemoryTest.java index 31632a7e2c2..159abb73c8f 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIMemoryTest.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIMemoryTest.java @@ -213,7 +213,7 @@ public class MIMemoryTest extends BaseTestCase { new DataRequestMonitor(fSession.getExecutor(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { fWait.setReturnInfo(getData()); } fWait.waitFinished(getStatus()); @@ -265,7 +265,7 @@ public class MIMemoryTest extends BaseTestCase { new DataRequestMonitor(fSession.getExecutor(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { fWait.setReturnInfo(getData()); } fWait.waitFinished(getStatus()); @@ -307,7 +307,7 @@ public class MIMemoryTest extends BaseTestCase { new DataRequestMonitor(fSession.getExecutor(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { result[(int) offset] = getData()[0]; } fWait.waitFinished(getStatus()); diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRegistersTest.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRegistersTest.java index d2006049a4a..1c579cecea2 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRegistersTest.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRegistersTest.java @@ -111,7 +111,7 @@ public class MIRegistersTest extends BaseTestCase { new DataRequestMonitor(fRegService.getExecutor(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { fWait.setReturnInfo(getData()); } @@ -148,7 +148,7 @@ public class MIRegistersTest extends BaseTestCase { new DataRequestMonitor(fRegService.getExecutor(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { fWait.setReturnInfo(getData()); } @@ -228,7 +228,7 @@ public class MIRegistersTest extends BaseTestCase { new DataRequestMonitor(fRegService.getExecutor(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { fWait.setReturnInfo(getData()); } diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRunControlTest.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRunControlTest.java index 46405971cd8..92df99a53bd 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRunControlTest.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRunControlTest.java @@ -125,7 +125,7 @@ public class MIRunControlTest extends BaseTestCase { new DataRequestMonitor(fRunCtrl.getExecutor(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { fWait.setReturnInfo(getData()); } fWait.waitFinished(getStatus()); @@ -177,7 +177,7 @@ public class MIRunControlTest extends BaseTestCase { new DataRequestMonitor(fRunCtrl.getExecutor(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { fWait.setReturnInfo(getData()); } fWait.waitFinished(getStatus()); @@ -249,7 +249,7 @@ public class MIRunControlTest extends BaseTestCase { new DataRequestMonitor(fRunCtrl.getExecutor(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { fWait.setReturnInfo(getData()); } fWait.waitFinished(getStatus()); @@ -290,7 +290,7 @@ public class MIRunControlTest extends BaseTestCase { new DataRequestMonitor(fRunCtrl.getExecutor(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { fWait.setReturnInfo(getData()); } fWait.waitFinished(getStatus()); @@ -339,7 +339,7 @@ public class MIRunControlTest extends BaseTestCase { new DataRequestMonitor(fRunCtrl.getExecutor(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { fWait.setReturnInfo(getData()); } fWait.waitFinished(getStatus()); @@ -375,7 +375,7 @@ public class MIRunControlTest extends BaseTestCase { new DataRequestMonitor(fRunCtrl.getExecutor(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { fWait.setReturnInfo(getData()); } fWait.waitFinished(getStatus()); @@ -412,7 +412,7 @@ public class MIRunControlTest extends BaseTestCase { new DataRequestMonitor(fRunCtrl.getExecutor(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { fWait.setReturnInfo(getData()); } fWait.waitFinished(getStatus()); @@ -593,7 +593,7 @@ public class MIRunControlTest extends BaseTestCase { // new DataRequestMonitor(fRunCtrl.getExecutor(), null) { // @Override // protected void handleCompleted() { -// if (getStatus().isOK()) { +// if (isSuccess()) { // assert true; // fWait.setReturnInfo(getData()); // } @@ -618,7 +618,7 @@ public class MIRunControlTest extends BaseTestCase { // new DataRequestMonitor(fRunCtrl.getExecutor(), null) { // @Override // protected void handleCompleted() { -// if (getStatus().isOK()) { +// if (isSuccess()) { // assert true; // fWait.setReturnInfo(getData()); // } diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/SyncUtil.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/SyncUtil.java index 006d6e9df81..147b3983769 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/SyncUtil.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/SyncUtil.java @@ -160,7 +160,7 @@ public class SyncUtil { new DataRequestMonitor(fRunControl.getExecutor(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { wait.setReturnInfo(getData()); } @@ -187,7 +187,7 @@ public class SyncUtil { new DataRequestMonitor(fRunControl.getExecutor(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { wait.setReturnInfo(getData()); } wait.waitFinished(getStatus()); @@ -219,7 +219,7 @@ public class SyncUtil { new DataRequestMonitor(fRunControl.getExecutor(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { wait.setReturnInfo(getData()); } @@ -274,7 +274,7 @@ public class SyncUtil { protected void execute(final DataRequestMonitor rm) { fStack.getFrames(execCtx, new DataRequestMonitor(fSession.getExecutor(), rm) { @Override - protected void handleOK() { + protected void handleSuccess() { if (getData().length > level) { rm.setData(getData()[level]); } else { diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/LaunchSequence.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/LaunchSequence.java index 378d6e913fe..f8e52ac6fc2 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/LaunchSequence.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/LaunchSequence.java @@ -150,14 +150,14 @@ public class LaunchSequence extends Sequence { new MIBreakInsert(fCommandControl.getGDBDMContext(), true, false, null, 0, fStopSymbol, 0), new DataRequestMonitor(getExecutor(), requestMonitor) { @Override - protected void handleOK() { + protected void handleSuccess() { // After the break-insert is done, execute the -exec-run command. fCommandControl.queueCommand( new MIExecRun(fCommandControl.getGDBDMContext(), new String[0]), new DataRequestMonitor(getExecutor(), requestMonitor) { @Override - protected void handleOK() { + protected void handleSuccess() { // Note : Do we not need to do something with the original requestMonitor? // Do nothing. Execution was resumed and the EntryPointHitEventListener // will resume execution @@ -206,7 +206,7 @@ public class LaunchSequence extends Sequence { final MIBreakpoints bpService = new MIBreakpoints(fSession); bpService.initialize(new RequestMonitor(getExecutor(), requestMonitor) { @Override - protected void handleOK() { + protected void handleSuccess() { requestMonitor.done(); } }); @@ -218,7 +218,7 @@ public class LaunchSequence extends Sequence { final MIBreakpointsManager bpmService = new MIBreakpointsManager(fSession, CDebugCorePlugin.PLUGIN_ID); bpmService.initialize(new RequestMonitor(getExecutor(), requestMonitor) { @Override - protected void handleOK() { + protected void handleSuccess() { bpmService.startTrackingBreakpoints(fCommandControl.getGDBDMContext(), requestMonitor); } }); From ad5efaa543f7159b4d7fb7fdf069ae271d4a494c Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 27 Mar 2008 03:09:58 +0000 Subject: [PATCH 329/834] [224279] Fixed handling of request monitor in queries when session is disposed. --- .../register/SyncRegisterDataAccess.java | 355 +++++++----------- .../variable/SyncVariableDataAccess.java | 69 +--- 2 files changed, 143 insertions(+), 281 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java index d044e909ee7..791dc864936 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java @@ -59,16 +59,15 @@ public class SyncRegisterDataAccess { public SyncRegisterDataAccess(DsfSession session) { fSession = session; } - + @ThreadSafe private synchronized IRegisters getService() { - String serviceId = DsfServices.createServiceFilter( IRegisters.class, fSession.getId() ); + String serviceId = DsfServices.createServiceFilter(IRegisters.class, fSession.getId()); if (fServiceTracker == null) { try { - fServiceTracker = new ServiceTracker( - DsfDebugUIPlugin.getBundleContext(), - DsfDebugUIPlugin.getBundleContext().createFilter(serviceId), null); + fServiceTracker = new ServiceTracker(DsfDebugUIPlugin.getBundleContext(), DsfDebugUIPlugin + .getBundleContext().createFilter(serviceId), null); fServiceTracker.open(); } catch (InvalidSyntaxException e) { return null; @@ -76,10 +75,10 @@ public class SyncRegisterDataAccess { } return (IRegisters) fServiceTracker.getService(); } - + @ThreadSafe public synchronized void dispose() { - if ( fServiceTracker != null ) { + if (fServiceTracker != null) { fServiceTracker.close(); } } @@ -104,30 +103,19 @@ public class SyncRegisterDataAccess { final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); if (session == null) { cancel(false); + rm.done(); return; } IRegisters service = getService(); if (service == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Service not available", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, + "Service not available", null)); //$NON-NLS-1$ rm.done(); return; } service.getBitFieldData(fDmc, new DataRequestMonitor(session.getExecutor(), rm) { - @Override - protected void handleCompleted() { - /* - * We're in another dispatch, so we must guard against - * executor shutdown again. - */ - if (!DsfSession.isSessionActive(session.getId())) { - GetBitFieldValueQuery.this.cancel(false); - return; - } - super.handleCompleted(); - } - @Override protected void handleSuccess() { /* @@ -142,7 +130,7 @@ public class SyncRegisterDataAccess { public IBitFieldDMContext getBitFieldDMC(Object element) { if (element instanceof IDMVMContext) { - IDMContext dmc = ((IDMVMContext)element).getDMContext(); + IDMContext dmc = ((IDMVMContext) element).getDMContext(); return DMContexts.getAncestorOfType(dmc, IBitFieldDMContext.class); } return null; @@ -154,9 +142,11 @@ public class SyncRegisterDataAccess { * session is stale, then bail out. */ IBitFieldDMContext dmc = getBitFieldDMC(element); - if (dmc == null) return null; + if (dmc == null) + return null; DsfSession session = DsfSession.getSession(dmc.getSessionId()); - if (session == null) return null; + if (session == null) + return null; /* * Create the query to request the value from service. Note: no need to @@ -184,7 +174,9 @@ public class SyncRegisterDataAccess { public class SetBitFieldValueQuery extends Query { private IBitFieldDMContext fDmc; + private String fValue; + private String fFormatId; public SetBitFieldValueQuery(IBitFieldDMContext dmc, String value, String formatId) { @@ -203,6 +195,7 @@ public class SyncRegisterDataAccess { final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); if (session == null) { cancel(false); + rm.done(); return; } @@ -211,7 +204,8 @@ public class SyncRegisterDataAccess { */ IRegisters service = getService(); if (service == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, + "Service unavailable", null)); //$NON-NLS-1$ rm.done(); return; } @@ -219,34 +213,17 @@ public class SyncRegisterDataAccess { /* * Write the bit field using a string/format style. */ - service.writeBitField( - fDmc, - fValue, - fFormatId, - new DataRequestMonitor(session.getExecutor(), rm) { - @Override - protected void handleCompleted() { - /* - * We're in another dispatch, so we must guard - * against executor shutdown again. - */ - if (!DsfSession.isSessionActive(session.getId())) { - SetBitFieldValueQuery.this.cancel(false); - return; - } - super.handleCompleted(); - } - - @Override - protected void handleSuccess() { - /* - * All good set return value. - */ - rm.setData(new Object()); - rm.done(); - } + service.writeBitField(fDmc, fValue, fFormatId, new DataRequestMonitor(session + .getExecutor(), rm) { + @Override + protected void handleSuccess() { + /* + * All good set return value. + */ + rm.setData(new Object()); + rm.done(); } - ); + }); } } @@ -257,9 +234,11 @@ public class SyncRegisterDataAccess { * session is stale, then bail out. */ IBitFieldDMContext dmc = getBitFieldDMC(element); - if (dmc == null) return; + if (dmc == null) + return; DsfSession session = DsfSession.getSession(dmc.getSessionId()); - if (session == null) return; + if (session == null) + return; /* * Create the query to write the value to the service. Note: no need to @@ -311,6 +290,7 @@ public class SyncRegisterDataAccess { final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); if (session == null) { cancel(false); + rm.done(); return; } @@ -319,7 +299,8 @@ public class SyncRegisterDataAccess { */ IRegisters service = getService(); if (service == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, + "Service unavailable", null)); //$NON-NLS-1$ rm.done(); return; } @@ -327,33 +308,16 @@ public class SyncRegisterDataAccess { /* * Write the bit field using the mnemonic style. */ - service.writeBitField( - fDmc, - fMnemonic, - new DataRequestMonitor(session.getExecutor(), rm) { - @Override - protected void handleCompleted() { - /* - * We're in another dispatch, so we must guard - * against executor shutdown again. - */ - if (!DsfSession.isSessionActive(session.getId())) { - SetBitFieldValueMnemonicQuery.this.cancel(false); - return; - } - super.handleCompleted(); - } - - @Override - protected void handleSuccess() { - /* - * All good set return value. - */ - rm.setData(new Object()); - rm.done(); - } + service.writeBitField(fDmc, fMnemonic, new DataRequestMonitor(session.getExecutor(), rm) { + @Override + protected void handleSuccess() { + /* + * All good set return value. + */ + rm.setData(new Object()); + rm.done(); } - ); + }); } } @@ -364,9 +328,11 @@ public class SyncRegisterDataAccess { * session is stale, then bail out. */ IBitFieldDMContext dmc = getBitFieldDMC(element); - if (dmc == null) return; + if (dmc == null) + return; DsfSession session = DsfSession.getSession(dmc.getSessionId()); - if (session == null) return; + if (session == null) + return; /* * Create the query to write the value to the service. Note: no need to @@ -398,7 +364,7 @@ public class SyncRegisterDataAccess { public IRegisterGroupDMContext getRegisterGroupDMC(Object element) { if (element instanceof IDMVMContext) { - IDMContext dmc = ((IDMVMContext)element).getDMContext(); + IDMContext dmc = ((IDMVMContext) element).getDMContext(); return DMContexts.getAncestorOfType(dmc, IRegisterGroupDMContext.class); } return null; @@ -406,7 +372,7 @@ public class SyncRegisterDataAccess { public IRegisterDMContext getRegisterDMC(Object element) { if (element instanceof IDMVMContext) { - IDMContext dmc = ((IDMVMContext)element).getDMContext(); + IDMContext dmc = ((IDMVMContext) element).getDMContext(); return DMContexts.getAncestorOfType(dmc, IRegisterDMContext.class); } return null; @@ -414,13 +380,13 @@ public class SyncRegisterDataAccess { public IFormattedDataDMContext getFormattedDMC(Object element) { if (element instanceof IDMVMContext) { - IDMContext dmc = ((IDMVMContext)element).getDMContext(); - IRegisterDMContext regdmc = DMContexts.getAncestorOfType(dmc, IRegisterDMContext.class); + IDMContext dmc = ((IDMVMContext) element).getDMContext(); + IRegisterDMContext regdmc = DMContexts.getAncestorOfType(dmc, IRegisterDMContext.class); return DMContexts.getAncestorOfType(regdmc, IFormattedDataDMContext.class); } return null; } - + public class GetRegisterGroupValueQuery extends Query { IRegisterGroupDMContext fDmc; @@ -441,30 +407,19 @@ public class SyncRegisterDataAccess { final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); if (session == null) { cancel(false); + rm.done(); return; } IRegisters service = getService(); if (service == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Service not available", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, + "Service not available", null)); //$NON-NLS-1$ rm.done(); return; } - service.getRegisterGroupData(fDmc, new DataRequestMonitor( session.getExecutor(), rm) { - @Override - protected void handleCompleted() { - /* - * We're in another dispatch, so we must guard against - * executor shutdown again. - */ - if (!DsfSession.isSessionActive(session.getId())) { - GetRegisterGroupValueQuery.this.cancel(false); - return; - } - super.handleCompleted(); - } - + service.getRegisterGroupData(fDmc, new DataRequestMonitor(session.getExecutor(), rm) { @Override protected void handleSuccess() { /* @@ -483,9 +438,11 @@ public class SyncRegisterDataAccess { * session is stale, then bail out. */ IRegisterGroupDMContext dmc = getRegisterGroupDMC(element); - if (dmc == null) return null; + if (dmc == null) + return null; DsfSession session = DsfSession.getSession(dmc.getSessionId()); - if (session == null) return null; + if (session == null) + return null; /* * Create the query to request the value from service. Note: no need to @@ -530,30 +487,19 @@ public class SyncRegisterDataAccess { final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); if (session == null) { cancel(false); + rm.done(); return; } IRegisters service = getService(); if (service == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Service not available", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, + "Service not available", null)); //$NON-NLS-1$ rm.done(); return; } - service.getRegisterData(fDmc, new DataRequestMonitor( session.getExecutor(), rm) { - @Override - protected void handleCompleted() { - /* - * We're in another dispatch, so we must guard against - * executor shutdown again. - */ - if (!DsfSession.isSessionActive(session.getId())) { - GetRegisterValueQuery.this.cancel(false); - return; - } - super.handleCompleted(); - } - + service.getRegisterData(fDmc, new DataRequestMonitor(session.getExecutor(), rm) { @Override protected void handleSuccess() { /* @@ -572,9 +518,11 @@ public class SyncRegisterDataAccess { * session is stale, then bail out. */ IRegisterDMContext dmc = getRegisterDMC(element); - if (dmc == null) return null; + if (dmc == null) + return null; DsfSession session = DsfSession.getSession(dmc.getSessionId()); - if (session == null) return null; + if (session == null) + return null; /* * Create the query to request the value from service. Note: no need to @@ -602,7 +550,9 @@ public class SyncRegisterDataAccess { public class SetRegisterValueQuery extends Query { private IRegisterDMContext fDmc; + private String fValue; + private String fFormatId; public SetRegisterValueQuery(IRegisterDMContext dmc, String value, String formatId) { @@ -621,6 +571,7 @@ public class SyncRegisterDataAccess { final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); if (session == null) { cancel(false); + rm.done(); return; } @@ -629,7 +580,8 @@ public class SyncRegisterDataAccess { */ IRegisters service = getService(); if (service == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, + "Service unavailable", null)); //$NON-NLS-1$ rm.done(); return; } @@ -641,48 +593,32 @@ public class SyncRegisterDataAccess { /* * Write the bit field using a string/format style. */ - service.writeRegister( - fDmc, - fValue, - fFormatId, - new DataRequestMonitor(session.getExecutor(), rm) { - @Override - protected void handleCompleted() { - /* - * We're in another dispatch, so we must guard - * against executor shutdown again. - */ - if (!DsfSession.isSessionActive(session.getId())) { - SetRegisterValueQuery.this.cancel(false); - return; - } - super.handleCompleted(); - } - - @Override - protected void handleSuccess() { - /* - * All good set return value. - */ - rm.setData(new Object()); - rm.done(); - } + service.writeRegister(fDmc, fValue, fFormatId, new DataRequestMonitor(session + .getExecutor(), rm) { + @Override + protected void handleSuccess() { + /* + * All good set return value. + */ + rm.setData(new Object()); + rm.done(); } - ); + }); } } - public void writeRegister(Object element, String value, - String formatId) { + public void writeRegister(Object element, String value, String formatId) { /* * Get the DMC and the session. If element is not an register DMC, or * session is stale, then bail out. */ IRegisterDMContext dmc = getRegisterDMC(element); - if (dmc == null) return; + if (dmc == null) + return; DsfSession session = DsfSession.getSession(dmc.getSessionId()); - if (session == null) return; + if (session == null) + return; /* * Create the query to write the value to the service. Note: no need to @@ -730,6 +666,7 @@ public class SyncRegisterDataAccess { final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); if (session == null) { cancel(false); + rm.done(); return; } @@ -738,7 +675,8 @@ public class SyncRegisterDataAccess { */ IRegisters service = getService(); if (service == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, + "Service unavailable", null)); //$NON-NLS-1$ rm.done(); return; } @@ -746,32 +684,16 @@ public class SyncRegisterDataAccess { /* * Write the bit field using a string/format style. */ - service.getAvailableFormats( - fDmc, - new DataRequestMonitor(session.getExecutor(), rm) { - @Override - protected void handleCompleted() { - /* - * We're in another dispatch, so we must - * guard against executor shutdown again. - */ - if (!DsfSession.isSessionActive(session.getId())) { - GetSupportFormatsValueQuery.this.cancel(false); - return; - } - super.handleCompleted(); - } - - @Override - protected void handleSuccess() { - /* - * All good set return value. - */ - rm.setData(new Object()); - rm.done(); - } + service.getAvailableFormats(fDmc, new DataRequestMonitor(session.getExecutor(), rm) { + @Override + protected void handleSuccess() { + /* + * All good set return value. + */ + rm.setData(new Object()); + rm.done(); } - ); + }); } } @@ -783,15 +705,17 @@ public class SyncRegisterDataAccess { */ IFormattedDataDMContext dmc = null; if (element instanceof IDMVMContext) { - IDMContext vmcdmc = ((IDMVMContext)element).getDMContext(); - IRegisterDMContext regdmc = DMContexts.getAncestorOfType(vmcdmc, IRegisterDMContext.class); + IDMContext vmcdmc = ((IDMVMContext) element).getDMContext(); + IRegisterDMContext regdmc = DMContexts.getAncestorOfType(vmcdmc, IRegisterDMContext.class); dmc = DMContexts.getAncestorOfType(regdmc, IFormattedDataDMContext.class); } - - if (dmc == null) return null; + + if (dmc == null) + return null; DsfSession session = DsfSession.getSession(dmc.getSessionId()); - if (session == null) return null; - + if (session == null) + return null; + /* * Create the query to write the value to the service. Note: no need to * guard agains RejectedExecutionException, because @@ -814,10 +738,11 @@ public class SyncRegisterDataAccess { return null; } } - + public class GetFormattedValueValueQuery extends Query { private IFormattedDataDMContext fDmc; + private String fFormatId; public GetFormattedValueValueQuery(IFormattedDataDMContext dmc, String formatId) { @@ -835,6 +760,7 @@ public class SyncRegisterDataAccess { final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); if (session == null) { cancel(false); + rm.done(); return; } @@ -843,30 +769,21 @@ public class SyncRegisterDataAccess { */ IRegisters service = getService(); if (service == null) { - rm .setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$ + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, + "Service unavailable", null)); //$NON-NLS-1$ rm.done(); return; } /* - * Convert to the proper formatting DMC then go get the formatted value. + * Convert to the proper formatting DMC then go get the formatted + * value. */ - - FormattedValueDMContext formDmc = service.getFormattedValueContext(fDmc, fFormatId); - - service.getFormattedExpressionValue(formDmc, new DataRequestMonitor( session.getExecutor(), rm) { - @Override - protected void handleCompleted() { - /* - * We're in another dispatch, so we must guard against executor shutdown again. - */ - if (!DsfSession.isSessionActive(session.getId())) { - GetFormattedValueValueQuery.this.cancel(false); - return; - } - super.handleCompleted(); - } + FormattedValueDMContext formDmc = service.getFormattedValueContext(fDmc, fFormatId); + + service.getFormattedExpressionValue(formDmc, new DataRequestMonitor(session + .getExecutor(), rm) { @Override protected void handleSuccess() { /* @@ -887,15 +804,17 @@ public class SyncRegisterDataAccess { */ IFormattedDataDMContext dmc = null; if (element instanceof IDMVMContext) { - IDMContext vmcdmc = ((IDMVMContext)element).getDMContext(); - IRegisterDMContext regdmc = DMContexts.getAncestorOfType(vmcdmc, IRegisterDMContext.class); + IDMContext vmcdmc = ((IDMVMContext) element).getDMContext(); + IRegisterDMContext regdmc = DMContexts.getAncestorOfType(vmcdmc, IRegisterDMContext.class); dmc = DMContexts.getAncestorOfType(regdmc, IFormattedDataDMContext.class); } - - if (dmc == null) return null; + + if (dmc == null) + return null; DsfSession session = DsfSession.getSession(dmc.getSessionId()); - if (session == null) return null; - + if (session == null) + return null; + /* * Create the query to write the value to the service. Note: no need to * guard agains RejectedExecutionException, because @@ -918,7 +837,7 @@ public class SyncRegisterDataAccess { return null; } } - + public String getFormattedBitFieldValue(Object element, String formatId) { /* @@ -927,15 +846,17 @@ public class SyncRegisterDataAccess { */ IFormattedDataDMContext dmc = null; if (element instanceof IDMVMContext) { - IDMContext vmcdmc = ((IDMVMContext)element).getDMContext(); - IBitFieldDMContext bitfielddmc = DMContexts.getAncestorOfType(vmcdmc, IBitFieldDMContext.class); + IDMContext vmcdmc = ((IDMVMContext) element).getDMContext(); + IBitFieldDMContext bitfielddmc = DMContexts.getAncestorOfType(vmcdmc, IBitFieldDMContext.class); dmc = DMContexts.getAncestorOfType(bitfielddmc, IFormattedDataDMContext.class); } - - if (dmc == null) return null; + + if (dmc == null) + return null; DsfSession session = DsfSession.getSession(dmc.getSessionId()); - if (session == null) return null; - + if (session == null) + return null; + /* * Create the query to write the value to the service. Note: no need to * guard agains RejectedExecutionException, because diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java index b58d7442220..6a1733aaa10 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java @@ -115,6 +115,7 @@ public class SyncVariableDataAccess { final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); if (session == null) { cancel(false); + rm.done(); return; } @@ -126,20 +127,6 @@ public class SyncVariableDataAccess { } service.getExpressionData(fDmc, new DataRequestMonitor(session.getExecutor(), rm) { - @Override - protected void handleCompleted() { - /* - * We're in another dispatch, so we must guard against - * executor shutdown again. - */ - if (!DsfSession.isSessionActive(session.getId())) { - GetVariableValueQuery.this.cancel(false); - rm.done(); - return; - } - super.handleCompleted(); - } - @Override protected void handleSuccess() { /* @@ -214,6 +201,7 @@ public class SyncVariableDataAccess { final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); if (session == null) { cancel(false); + rm.done(); return; } @@ -235,19 +223,6 @@ public class SyncVariableDataAccess { fValue, fFormatId, new DataRequestMonitor(session.getExecutor(), rm) { - @Override - protected void handleCompleted() { - /* - * We're in another dispatch, so we must guard - * against executor shutdown again. - */ - if (!DsfSession.isSessionActive(session.getId())) { - SetVariableValueQuery.this.cancel(false); - return; - } - super.handleCompleted(); - } - @Override protected void handleSuccess() { /* @@ -325,6 +300,7 @@ public class SyncVariableDataAccess { final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); if (session == null) { cancel(false); + rm.done(); return; } @@ -344,19 +320,6 @@ public class SyncVariableDataAccess { service.getAvailableFormats( fDmc, new DataRequestMonitor(session.getExecutor(), rm) { - @Override - protected void handleCompleted() { - /* - * We're in another dispatch, so we must - * guard against executor shutdown again. - */ - if (!DsfSession.isSessionActive(session.getId())) { - GetSupportFormatsValueQuery.this.cancel(false); - return; - } - super.handleCompleted(); - } - @Override protected void handleSuccess() { /* @@ -424,6 +387,7 @@ public class SyncVariableDataAccess { final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); if (session == null) { cancel(false); + rm.done(); return; } @@ -444,18 +408,6 @@ public class SyncVariableDataAccess { FormattedValueDMContext formDmc = service.getFormattedValueContext(fDmc, fFormatId); service.getFormattedExpressionValue(formDmc, new DataRequestMonitor(session.getExecutor(), rm) { - @Override - protected void handleCompleted() { - /* - * We're in another dispatch, so we must guard against executor shutdown again. - */ - if (!DsfSession.isSessionActive(session.getId())) { - GetFormattedValueValueQuery.this.cancel(false); - return; - } - super.handleCompleted(); - } - @Override protected void handleSuccess() { /* @@ -520,6 +472,7 @@ public class SyncVariableDataAccess { final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); if (session == null) { cancel(false); + rm.done(); return; } @@ -534,18 +487,6 @@ public class SyncVariableDataAccess { } service.canWriteExpression(fDmc, new DataRequestMonitor(session.getExecutor(), rm) { - @Override - protected void handleCompleted() { - /* - * We're in another dispatch, so we must guard against executor shutdown again. - */ - if (!DsfSession.isSessionActive(session.getId())) { - CanWriteExpressionQuery.this.cancel(false); - return; - } - super.handleCompleted(); - } - @Override protected void handleSuccess() { /* From 0ab189a72557f0389a97e4bb5642d77c073aa00f Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Thu, 27 Mar 2008 13:32:56 +0000 Subject: [PATCH 330/834] Compile fix for bug 179293 --- .../src/org/eclipse/dd/examples/dsf/timers/AlarmService.java | 2 +- .../src/org/eclipse/dd/examples/dsf/timers/TimerService.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmService.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmService.java index 1a48ba43113..a87e5df6dcc 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmService.java +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmService.java @@ -131,7 +131,7 @@ public class AlarmService extends AbstractDsfService super.initialize( new RequestMonitor(getExecutor(), requestMonitor) { @Override - protected void handleOK() { + protected void handleSuccess() { // After super-class is finished initializing // perform TimerService initialization. doInitialize(requestMonitor); diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimerService.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimerService.java index ab2ab106d4c..ab4e09a5cf3 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimerService.java +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimerService.java @@ -108,7 +108,7 @@ public class TimerService extends AbstractDsfService super.initialize( new RequestMonitor(getExecutor(), requestMonitor) { @Override - public void handleOK() { + public void handleSuccess() { // After super-class is finished initializing // perform TimerService initialization. doInitialize(requestMonitor); From c60f80ccc0cc1e5e0ae333ea84b7cd458fab988c Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 27 Mar 2008 16:18:04 +0000 Subject: [PATCH 331/834] [179293] Further refactoring of the handle*() methods of the RequestMoniotr. --- .../dd/dsf/concurrent/RequestMonitor.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java index 8219ae9201e..c8d6ce4385d 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/RequestMonitor.java @@ -163,9 +163,12 @@ public class RequestMonitor { public void cancel() { Object[] listeners = null; synchronized (this) { - fCanceled = true; - if (fCancelListeners != null) { - listeners = fCancelListeners.getListeners(); + // Check to make sure the request monitor wasn't previously canceled. + if (!fCanceled) { + fCanceled = true; + if (fCancelListeners != null) { + listeners = fCancelListeners.getListeners(); + } } } @@ -292,7 +295,8 @@ public class RequestMonitor { */ @ConfinedToDsfExecutor("fExecutor") protected void handleFailure() { - assert !getStatus().isOK(); + assert !isSuccess(); + if (isCanceled()) { handleCancel(); } else { @@ -300,9 +304,7 @@ public class RequestMonitor { DsfPlugin.getDefault().getLog().log(new Status( IStatus.ERROR, DsfPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Request monitor: '" + this + "' resulted in a cancel status: " + getStatus() + ", even though the request is not set to cancel.", null)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } - if (getStatus().getSeverity() > IStatus.INFO) { - handleErrorOrWarning(); - } + handleErrorOrWarning(); } } @@ -383,7 +385,6 @@ public class RequestMonitor { * rejects the runnable that is submitted invoke this request monitor. * This usually happens only when the executor is shutting down. */ - @ThreadSafe protected void handleRejectedExecutionException() { MultiStatus logStatus = new MultiStatus(DsfPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Request for monitor: '" + toString() + "' resulted in a rejected execution exception.", null); //$NON-NLS-1$ //$NON-NLS-2$ logStatus.merge(getStatus()); From 0e806a078cb3ed91e4454bcbe5e72916fb2fc503 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 27 Mar 2008 16:29:32 +0000 Subject: [PATCH 332/834] [179293] Coverted remaining RequestMonitor.getStatus().isOK() calls into RequestMonitor.isSuccess(). --- .../viewmodel/numberformat/detail/NumberFormatDetailPane.java | 2 +- .../ui/viewmodel/expression/AbstractExpressionVMNode.java | 2 +- .../dsf/debug/ui/viewmodel/expression/VMExpressionUpdate.java | 2 +- .../dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java | 2 +- .../debug/ui/viewmodel/register/RegisterBitFieldVMNode.java | 2 +- .../dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java | 4 ++-- .../dd/dsf/ui/viewmodel/DefaultVMContentProviderStrategy.java | 4 ++-- .../dd/dsf/ui/viewmodel/DefaultVMModelProxyStrategy.java | 2 +- .../eclipse/dd/dsf/ui/viewmodel/VMChildrenCountUpdate.java | 2 +- .../src/org/eclipse/dd/dsf/ui/viewmodel/VMChildrenUpdate.java | 2 +- .../org/eclipse/dd/dsf/ui/viewmodel/VMHasChildrenUpdate.java | 2 +- .../org/eclipse/dd/gdb/launch/launching/ShutdownSequence.java | 2 +- .../dd/gdb/internal/ui/viewmodel/launch/ThreadVMNode.java | 2 +- .../src/org/eclipse/dd/mi/service/MIVariableManager.java | 2 +- 14 files changed, 16 insertions(+), 16 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/viewmodel/numberformat/detail/NumberFormatDetailPane.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/viewmodel/numberformat/detail/NumberFormatDetailPane.java index 7008f75ebeb..4a7d0f6546b 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/viewmodel/numberformat/detail/NumberFormatDetailPane.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/viewmodel/numberformat/detail/NumberFormatDetailPane.java @@ -404,7 +404,7 @@ public class NumberFormatDetailPane implements IDetailPane, IAdaptable, IPropert new DataRequestMonitor(finalService.getSession().getExecutor(), null) { @Override public void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { /* * Show the information indicating the format. */ diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionVMNode.java index 4e198a6d113..23e382e13fb 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionVMNode.java @@ -61,7 +61,7 @@ public abstract class AbstractExpressionVMNode extends AbstractDMVMNode final MultiRequestMonitor> multiRm = new MultiRequestMonitor>(getExecutor(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + if (isSuccess()) { boolean foundMatchingContext = false; for (int i = 0; i < getRequestMonitors().size(); i++) { if (getRequestMonitors().get(i).getData()) { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/VMExpressionUpdate.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/VMExpressionUpdate.java index 6408819022a..693fd8b152e 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/VMExpressionUpdate.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/VMExpressionUpdate.java @@ -71,7 +71,7 @@ class VMExpressionUpdate extends VMViewerUpdate implements IExpressionUpdate { DataRequestMonitor rm = (DataRequestMonitor)getRequestMonitor(); if (fExpressionElement != null) { rm.setData(fExpressionElement); - } else if (rm.getStatus().isOK()) { + } else if (rm.isSuccess()) { rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, "Incomplete elements of updates", null)); //$NON-NLS-1$ } super.done(); diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java index e057e5aa9df..1ec4d733a52 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java @@ -379,7 +379,7 @@ public class StackFramesVMNode extends AbstractDMVMNode new DataRequestMonitor>(getExecutor(), null) { @Override public void handleCompleted() { - if (getStatus().isOK() && getData().size() != 0) { + if (isSuccess() && getData().size() != 0) { parentDelta.addNode( getData().get(0), 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. diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java index ec598d0d1b7..1911cec30cd 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java @@ -179,7 +179,7 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode new DataRequestMonitor(getSession().getExecutor(), null) { @Override public void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { handleFailedUpdate(update); return; } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java index a336d256762..5b610bffc54 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java @@ -330,7 +330,7 @@ public class VariableVMNode extends AbstractExpressionVMNode new DataRequestMonitor(getSession().getExecutor(), null) { @Override public void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { handleFailedUpdate(update); return; } @@ -606,7 +606,7 @@ public class VariableVMNode extends AbstractExpressionVMNode new DataRequestMonitor(dsfExecutor, null) { @Override public void handleCompleted() { - if (!getStatus().isOK()) { + if (!isSuccess()) { handleFailedUpdate(update); return; } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMContentProviderStrategy.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMContentProviderStrategy.java index 8793d5ddcf5..97e89ef0716 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMContentProviderStrategy.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMContentProviderStrategy.java @@ -321,9 +321,9 @@ public class DefaultVMContentProviderStrategy implements IElementContentProvider protected void handleCompleted() { // Workaround for a bug caused by an optimization in the viewer: // The viewer may request more children then there are at a given level. - // This caues the update to return with an error. + // This causes the update to return with an error. // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=202109 - // Instead of checking getStatus().isOK(), check getData() != null. + // Instead of checking isSuccess(), check getData() != null. if (getData() != null) { for (int i = 0; i < elementsLength && i < getData().size(); i++) { Object child = getData().get(i); diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMModelProxyStrategy.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMModelProxyStrategy.java index 254cb123524..9267f413caa 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMModelProxyStrategy.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMModelProxyStrategy.java @@ -443,7 +443,7 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy { // Check for an empty list of elements. If it's empty then we // don't have to call the children nodes, so return here. // No need to propagate error, there's no means or need to display it. - if (!getStatus().isOK() || getData().size() == 0) { + if (!isSuccess() || getData().size() == 0) { requestMonitor.done(); return; } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMChildrenCountUpdate.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMChildrenCountUpdate.java index 764513deec4..7ead2a93122 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMChildrenCountUpdate.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMChildrenCountUpdate.java @@ -47,7 +47,7 @@ public class VMChildrenCountUpdate extends VMViewerUpdate implements IChildrenCo @Override public void done() { - assert isCanceled() || fCountRequestMonitor.getData() != null || !fCountRequestMonitor.getStatus().isOK(); + assert isCanceled() || fCountRequestMonitor.getData() != null || !fCountRequestMonitor.isSuccess(); super.done(); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMChildrenUpdate.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMChildrenUpdate.java index 93954b441c0..07856b8602a 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMChildrenUpdate.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMChildrenUpdate.java @@ -128,7 +128,7 @@ public class VMChildrenUpdate extends VMViewerUpdate implements IChildrenUpdate * the error status. */ rm.setData(fElements); - if (rm.getStatus().isOK() && fLength != -1 && fElements.size() != fLength) { + if (rm.isSuccess() && fLength != -1 && fElements.size() != fLength) { rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, "Incomplete elements of updates", null)); //$NON-NLS-1$ } super.done(); diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMHasChildrenUpdate.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMHasChildrenUpdate.java index 1ec49ec22df..dabb21bdb69 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMHasChildrenUpdate.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMHasChildrenUpdate.java @@ -48,7 +48,7 @@ public class VMHasChildrenUpdate extends VMViewerUpdate implements IHasChildrenU @Override public void done() { - assert isCanceled() || fHasElemsRequestMonitor.getData() != null || !fHasElemsRequestMonitor.getStatus().isOK(); + assert isCanceled() || fHasElemsRequestMonitor.getData() != null || !fHasElemsRequestMonitor.isSuccess(); super.done(); } } diff --git a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/ShutdownSequence.java b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/ShutdownSequence.java index 53bbc04897c..08177c352c5 100644 --- a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/ShutdownSequence.java +++ b/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/ShutdownSequence.java @@ -92,7 +92,7 @@ public class ShutdownSequence extends Sequence { // @Override // protected void handleCompleted() { // // If un-installing breakpoints fails, log the error but continue shutting down. -// if (!getStatus().isOK()) { +// if (!isSuccess) { // DsfGdbLaunchPlugin.getDefault().getLog().log(getStatus()); // } // requestMonitor.done(); diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ThreadVMNode.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ThreadVMNode.java index 681bf305211..f3e2071b8b3 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ThreadVMNode.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ThreadVMNode.java @@ -214,7 +214,7 @@ public class ThreadVMNode extends AbstractDMVMNode new DataRequestMonitor(getSession().getExecutor(), null) { @Override public void handleCompleted(){ - if (!getStatus().isOK()) { + if (!isSuccess()) { handleFailedUpdate(update); return; } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java index dc3708d93dd..37617969aea 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java @@ -871,7 +871,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon } // If the value has not changed, no need to set it. - // Return a status info so that handleOK is not called and we don't send + // Return a warning status so that handleSuccess is not called and we don't send // an ExpressionChanged event if (value.equals(getValue(formatId))) { rm.setStatus(new Status(IStatus.WARNING, MIPlugin.PLUGIN_ID, IDsfStatusConstants.NOT_SUPPORTED, From d3fddfd2b9edeac7d13e35710304197f32482806 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 27 Mar 2008 16:44:13 +0000 Subject: [PATCH 333/834] [179293] Coverted remaining RequestMonitor.getStatus().isOK() calls into RequestMonitor.isSuccess(). --- .../org/eclipse/dd/dsf/debug/service/command/CommandCache.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java index 2f27c08b22d..27e25cf5fde 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java @@ -253,7 +253,7 @@ public class CommandCache implements ICommandListener */ if(fCachedContexts.get(context) != null && fCachedContexts.get(context).containsKey(cachedCmd)){ CommandResultInfo result = fCachedContexts.get(context).get(cachedCmd); - if (result.getStatus().isOK()) { + if (result.getStatus().getSeverity() <= IStatus.INFO) { @SuppressWarnings("unchecked") V v = (V)result.getData(); rm.setData(v); From 060864a934cd91af73e59d991fd1ff62d2492c6c Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 27 Mar 2008 16:45:03 +0000 Subject: [PATCH 334/834] [179293] Coverted remaining RequestMonitor.getStatus().isOK() calls into RequestMonitor.isSuccess(). --- .../org/eclipse/dd/dsf/debug/service/command/CommandCache.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java index 27e25cf5fde..fb3e2935160 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java @@ -411,7 +411,7 @@ public class CommandCache implements ICommandListener fCachedContexts.put(context, map); } - if (!status.isOK()) { + if (!isSuccess()) { /* * We had some form of error with the original command. So notify the * original requesters of the issues. From 9fd5e0d9ebb69a5ebadf2bef13cfda9dd8ef1f9b Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Thu, 27 Mar 2008 16:57:01 +0000 Subject: [PATCH 335/834] Preliminary solution for Bug 223154. We increase the size of PipedInputBuffer from 1K to 1M but using LargePipedInputBuffer --- .../service/command/AbstractCLIProcess.java | 5 +++-- .../command/LargePipedInputStream.java | 19 +++++++++++++++++++ .../mi/service/command/MIInferiorProcess.java | 6 ++++-- 3 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/LargePipedInputStream.java diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractCLIProcess.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractCLIProcess.java index c4fd26db62c..1fe0c72b4d7 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractCLIProcess.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractCLIProcess.java @@ -101,10 +101,11 @@ public abstract class AbstractCLIProcess extends Process PipedOutputStream miOutLogPipe = null; try { + // Using a LargePipedInputStream see https://bugs.eclipse.org/bugs/show_bug.cgi?id=223154 miOutConsolePipe = new PipedOutputStream(); - miInConsolePipe = new PipedInputStream(miOutConsolePipe); + miInConsolePipe = new LargePipedInputStream(miOutConsolePipe); miOutLogPipe = new PipedOutputStream(); - miInLogPipe = new PipedInputStream(miOutLogPipe); + miInLogPipe = new LargePipedInputStream(miOutLogPipe); } catch (IOException e) { ILog log = MIPlugin.getDefault().getLog(); if (log != null) { diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/LargePipedInputStream.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/LargePipedInputStream.java new file mode 100644 index 00000000000..91b6d4be2f1 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/LargePipedInputStream.java @@ -0,0 +1,19 @@ +package org.eclipse.dd.mi.service.command; + +import java.io.IOException; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; + + +class LargePipedInputStream extends PipedInputStream { + + private final int LARGE_BUF_SIZE = 1024 * 1024; // 1 megs + + public LargePipedInputStream(PipedOutputStream pipedoutputstream) + throws IOException + { + super(pipedoutputstream); + buffer = new byte[LARGE_BUF_SIZE]; + } + +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIInferiorProcess.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIInferiorProcess.java index b8ef43d869c..8455061d919 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIInferiorProcess.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIInferiorProcess.java @@ -138,7 +138,8 @@ public class MIInferiorProcess extends Process fInputStreamPiped = new PipedOutputStream(); PipedInputStream inputStream = null; try { - inputStream = new PipedInputStream(fInputStreamPiped); + // Using a LargePipedInputStream see https://bugs.eclipse.org/bugs/show_bug.cgi?id=223154 + inputStream = new LargePipedInputStream(fInputStreamPiped); } catch (IOException e) { } fInputStream = inputStream; @@ -150,7 +151,8 @@ public class MIInferiorProcess extends Process fErrorStreamPiped = new PipedOutputStream(); PipedInputStream errorStream = null; try { - errorStream = new PipedInputStream(fErrorStreamPiped); + // Using a LargePipedInputStream see https://bugs.eclipse.org/bugs/show_bug.cgi?id=223154 + errorStream = new LargePipedInputStream(fErrorStreamPiped); } catch (IOException e) { } fErrorStream = errorStream; From 89c5e765baadb43963d60bc9e2dc0717b615be80 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Thu, 27 Mar 2008 17:35:50 +0000 Subject: [PATCH 336/834] Bug 221505 The point of having an org.eclipse.dd.gdb.launch plugin was to allow other people to ignore this plugin and not have the standard DSF launches appear. However, the DSF launch classes can still be useful to those people as they can be extended. Therefore, the launch code should not be in org.eclipse.dd.gdb.launch, but put back in org.ecipse.dd.gdb --- .../META-INF/MANIFEST.MF | 11 +--- .../build.properties | 4 +- plugins/org.eclipse.dd.gdb.launch/plugin.xml | 4 +- .../gdb/launch/internal/GdbLaunchPlugin.java | 53 +------------------ .../META-INF/MANIFEST.MF | 3 +- .../org.eclipse.dd.gdb.ui/build.properties | 3 +- plugins/org.eclipse.dd.gdb.ui/plugin.xml | 2 +- .../dd/gdb/internal/ui/GdbAdapterFactory.java | 4 +- .../CBreakpointGdbThreadFilterPage.java | 2 +- .../ui/breakpoints/GdbThreadFilterEditor.java | 2 +- .../org.eclipse.dd.gdb/META-INF/MANIFEST.MF | 5 +- .../eclipse/dd/gdb/internal/GdbPlugin.java | 49 +++++++++++++++++ .../gdb}/launching/FinalLaunchSequence.java | 34 ++++++------ .../eclipse/dd/gdb}/launching/GdbLaunch.java | 14 ++--- .../dd/gdb}/launching/GdbLaunchDelegate.java | 24 ++++----- .../launching/ServicesLaunchSequence.java | 2 +- .../dd/gdb}/launching/ShutdownSequence.java | 16 +++--- .../dd/tests/gdb/framework/BaseTestCase.java | 2 +- .../tests/gdb/launching/LaunchSequence.java | 2 +- .../gdb/launching/TestLaunchDelegate.java | 2 +- 20 files changed, 114 insertions(+), 124 deletions(-) rename plugins/{org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch => org.eclipse.dd.gdb/src/org/eclipse/dd/gdb}/launching/FinalLaunchSequence.java (89%) rename plugins/{org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch => org.eclipse.dd.gdb/src/org/eclipse/dd/gdb}/launching/GdbLaunch.java (89%) rename plugins/{org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch => org.eclipse.dd.gdb/src/org/eclipse/dd/gdb}/launching/GdbLaunchDelegate.java (92%) rename plugins/{org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch => org.eclipse.dd.gdb/src/org/eclipse/dd/gdb}/launching/ServicesLaunchSequence.java (99%) rename plugins/{org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch => org.eclipse.dd.gdb/src/org/eclipse/dd/gdb}/launching/ShutdownSequence.java (92%) diff --git a/plugins/org.eclipse.dd.gdb.launch/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.gdb.launch/META-INF/MANIFEST.MF index d63b2e1a771..6b7f7e3c17f 100644 --- a/plugins/org.eclipse.dd.gdb.launch/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.gdb.launch/META-INF/MANIFEST.MF @@ -6,15 +6,6 @@ Bundle-SymbolicName: org.eclipse.dd.gdb.launch; singleton:=true Bundle-Version: 1.0.0 Bundle-Activator: org.eclipse.dd.gdb.launch.internal.GdbLaunchPlugin Require-Bundle: org.eclipse.core.runtime, - org.eclipse.dd.dsf, - org.eclipse.dd.dsf.debug, - org.eclipse.dd.mi, - org.eclipse.dd.gdb, - org.eclipse.debug.core, - org.eclipse.cdt.core, - org.eclipse.cdt.launch, - org.eclipse.cdt.debug.core, - org.eclipse.cdt.debug.mi.core + org.eclipse.dd.gdb Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: J2SE-1.5 -Export-Package: org.eclipse.dd.gdb.launch.launching diff --git a/plugins/org.eclipse.dd.gdb.launch/build.properties b/plugins/org.eclipse.dd.gdb.launch/build.properties index cf2d90c8779..7651071b534 100644 --- a/plugins/org.eclipse.dd.gdb.launch/build.properties +++ b/plugins/org.eclipse.dd.gdb.launch/build.properties @@ -3,5 +3,5 @@ output.. = bin/ bin.includes = plugin.xml,\ META-INF/,\ .,\ - icons/,\ - about.html + about.html,\ + src/ diff --git a/plugins/org.eclipse.dd.gdb.launch/plugin.xml b/plugins/org.eclipse.dd.gdb.launch/plugin.xml index 0b49da90602..d05db8ece4e 100644 --- a/plugins/org.eclipse.dd.gdb.launch/plugin.xml +++ b/plugins/org.eclipse.dd.gdb.launch/plugin.xml @@ -4,7 +4,7 @@ launchShutdownQuery = new Query() { - @Override - protected void execute(DataRequestMonitor rm) { - gdbLaunch.shutdownSession(rm); - } - }; - - try { - gdbLaunch.getSession().getExecutor().execute(launchShutdownQuery); - } catch (RejectedExecutionException e) { - // We can get this exception if the session is shutdown concurrently - // to this method running. - break; - } - - // The Query.get() method is a synchronous call which blocks until the - // query completes. - try { - launchShutdownQuery.get(); - } catch (InterruptedException e) { - getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, "InterruptedException while shutting down PDA debugger launch " + gdbLaunch, e.getCause())); //$NON-NLS-1$ - } catch (ExecutionException e) { - getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, "Exception while shutting down PDA debugger launch " + gdbLaunch, e.getCause())); //$NON-NLS-1$ - } - } - } - } - + } } diff --git a/plugins/org.eclipse.dd.gdb.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.gdb.ui/META-INF/MANIFEST.MF index 750ac57e684..ab657bc519e 100644 --- a/plugins/org.eclipse.dd.gdb.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.gdb.ui/META-INF/MANIFEST.MF @@ -15,7 +15,6 @@ Require-Bundle: org.eclipse.ui, org.eclipse.dd.mi, org.eclipse.dd.gdb, org.eclipse.dd.dsf.debug, - org.eclipse.cdt.debug.ui, - org.eclipse.dd.gdb.launch + org.eclipse.cdt.debug.ui Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/plugins/org.eclipse.dd.gdb.ui/build.properties b/plugins/org.eclipse.dd.gdb.ui/build.properties index 61543eefe00..91d219bb13a 100644 --- a/plugins/org.eclipse.dd.gdb.ui/build.properties +++ b/plugins/org.eclipse.dd.gdb.ui/build.properties @@ -3,6 +3,5 @@ output.. = bin/ bin.includes = META-INF/,\ .,\ plugin.xml,\ - about.html,\ - icons/ + about.html \ No newline at end of file diff --git a/plugins/org.eclipse.dd.gdb.ui/plugin.xml b/plugins/org.eclipse.dd.gdb.ui/plugin.xml index 7b68df8c943..13ca12a23ec 100644 --- a/plugins/org.eclipse.dd.gdb.ui/plugin.xml +++ b/plugins/org.eclipse.dd.gdb.ui/plugin.xml @@ -7,7 +7,7 @@ + adaptableType="org.eclipse.dd.gdb.launching.GdbLaunch"> diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java index 0a8e25f346b..1b8e185142d 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java @@ -27,8 +27,8 @@ import org.eclipse.dd.dsf.debug.ui.sourcelookup.MISourceDisplayAdapter; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.gdb.internal.ui.actions.DsfTerminateCommand; import org.eclipse.dd.gdb.internal.ui.viewmodel.GdbViewModelAdapter; -import org.eclipse.dd.gdb.launch.launching.GdbLaunch; -import org.eclipse.dd.gdb.launch.launching.GdbLaunchDelegate; +import org.eclipse.dd.gdb.launching.GdbLaunch; +import org.eclipse.dd.gdb.launching.GdbLaunchDelegate; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchesListener2; diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/CBreakpointGdbThreadFilterPage.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/CBreakpointGdbThreadFilterPage.java index 994ba97c6e0..bec7fdadec9 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/CBreakpointGdbThreadFilterPage.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/CBreakpointGdbThreadFilterPage.java @@ -13,7 +13,7 @@ package org.eclipse.dd.gdb.internal.ui.breakpoints; import org.eclipse.cdt.debug.core.model.ICBreakpoint; import org.eclipse.core.runtime.CoreException; import org.eclipse.dd.gdb.breakpoints.CBreakpointGdbThreadsFilterExtension; -import org.eclipse.dd.gdb.launch.launching.GdbLaunchDelegate; +import org.eclipse.dd.gdb.launching.GdbLaunchDelegate; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/GdbThreadFilterEditor.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/GdbThreadFilterEditor.java index 6b963f92b91..957a57bbc08 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/GdbThreadFilterEditor.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/GdbThreadFilterEditor.java @@ -30,7 +30,7 @@ import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.gdb.breakpoints.CBreakpointGdbThreadsFilterExtension; import org.eclipse.dd.gdb.internal.ui.GdbUIPlugin; -import org.eclipse.dd.gdb.launch.launching.GdbLaunch; +import org.eclipse.dd.gdb.launching.GdbLaunch; import org.eclipse.dd.gdb.service.GDBRunControl; import org.eclipse.dd.gdb.service.GDBRunControl.GDBThreadData; import org.eclipse.dd.gdb.service.command.GDBControl; diff --git a/plugins/org.eclipse.dd.gdb/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.gdb/META-INF/MANIFEST.MF index ef35582da38..451260308c2 100644 --- a/plugins/org.eclipse.dd.gdb/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.gdb/META-INF/MANIFEST.MF @@ -11,10 +11,13 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.dd.mi, org.eclipse.debug.core, org.eclipse.cdt.core, - org.eclipse.cdt.debug.core + org.eclipse.cdt.debug.core, + org.eclipse.cdt.debug.mi.core, + org.eclipse.cdt.launch Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: J2SE-1.5 Export-Package: org.eclipse.dd.gdb, org.eclipse.dd.gdb.breakpoints, + org.eclipse.dd.gdb.launching, org.eclipse.dd.gdb.service, org.eclipse.dd.gdb.service.command diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/GdbPlugin.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/GdbPlugin.java index eabdcb2f9ba..f80e2ae24d3 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/GdbPlugin.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/GdbPlugin.java @@ -1,6 +1,16 @@ package org.eclipse.dd.gdb.internal; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Plugin; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.Query; +import org.eclipse.dd.gdb.launching.GdbLaunch; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunch; import org.osgi.framework.BundleContext; /** @@ -39,6 +49,7 @@ public class GdbPlugin extends Plugin { */ @Override public void stop(BundleContext context) throws Exception { + shutdownActiveLaunches(); plugin = null; super.stop(context); fgBundleContext = null; @@ -56,4 +67,42 @@ public class GdbPlugin extends Plugin { public static BundleContext getBundleContext() { return fgBundleContext; } + /** + * Shuts down any active launches. We must shutdown any active sessions + * and services associated with this plugin before this plugin is stopped. + * Any attempts to use the plugins {@link BundleContext} after the plugin + * is shut down will result in exceptions. + */ + private void shutdownActiveLaunches() { + for (ILaunch launch : DebugPlugin.getDefault().getLaunchManager().getLaunches()) { + if (launch instanceof GdbLaunch && ((GdbLaunch)launch).getSession().isActive()) { + final GdbLaunch gdbLaunch = (GdbLaunch)launch; + + Query launchShutdownQuery = new Query() { + @Override + protected void execute(DataRequestMonitor rm) { + gdbLaunch.shutdownSession(rm); + } + }; + + try { + gdbLaunch.getSession().getExecutor().execute(launchShutdownQuery); + } catch (RejectedExecutionException e) { + // We can get this exception if the session is shutdown concurrently + // to this method running. + break; + } + + // The Query.get() method is a synchronous call which blocks until the + // query completes. + try { + launchShutdownQuery.get(); + } catch (InterruptedException e) { + getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, "InterruptedException while shutting down PDA debugger launch " + gdbLaunch, e.getCause())); //$NON-NLS-1$ + } catch (ExecutionException e) { + getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, "Exception while shutting down PDA debugger launch " + gdbLaunch, e.getCause())); //$NON-NLS-1$ + } + } + } + } } diff --git a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/FinalLaunchSequence.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/FinalLaunchSequence.java similarity index 89% rename from plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/FinalLaunchSequence.java rename to plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/FinalLaunchSequence.java index 1533ada87bc..553809daa2a 100644 --- a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/FinalLaunchSequence.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/FinalLaunchSequence.java @@ -8,7 +8,7 @@ * Contributors: * Ericsson - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.gdb.launch.launching; +package org.eclipse.dd.gdb.launching; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector; @@ -23,7 +23,7 @@ import org.eclipse.dd.dsf.concurrent.Sequence; import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; import org.eclipse.dd.dsf.service.DsfServicesTracker; -import org.eclipse.dd.gdb.launch.internal.GdbLaunchPlugin; +import org.eclipse.dd.gdb.internal.GdbPlugin; import org.eclipse.dd.gdb.service.command.GDBControl; import org.eclipse.dd.gdb.service.command.GDBControl.SessionType; import org.eclipse.dd.mi.service.CSourceLookup; @@ -45,7 +45,7 @@ public class FinalLaunchSequence extends Sequence { */ new Step() { @Override public void execute(RequestMonitor requestMonitor) { - DsfServicesTracker tracker = new DsfServicesTracker(GdbLaunchPlugin.getBundleContext(), fLaunch.getSession().getId()); + DsfServicesTracker tracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), fLaunch.getSession().getId()); fCommandControl = tracker.getService(GDBControl.class); tracker.dispose(); @@ -56,7 +56,7 @@ public class FinalLaunchSequence extends Sequence { */ new Step() { @Override public void execute(RequestMonitor requestMonitor) { - DsfServicesTracker tracker = new DsfServicesTracker(GdbLaunchPlugin.getBundleContext(), fLaunch.getSession().getId()); + DsfServicesTracker tracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), fLaunch.getSession().getId()); CSourceLookup sourceLookup = tracker.getService(CSourceLookup.class); tracker.dispose(); @@ -79,7 +79,7 @@ public class FinalLaunchSequence extends Sequence { IGDBServerMILaunchConfigurationConstants.ATTR_REMOTE_TCP, false); } catch (CoreException e) { - requestMonitor.setStatus(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, -1, "Cannot retrieve connection mode", e)); //$NON-NLS-1$ + requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Cannot retrieve connection mode", e)); //$NON-NLS-1$ requestMonitor.done(); return false; } @@ -89,9 +89,9 @@ public class FinalLaunchSequence extends Sequence { private boolean getSerialDevice(RequestMonitor requestMonitor) { try { fSerialDevice = fLaunch.getLaunchConfiguration().getAttribute( - IGDBServerMILaunchConfigurationConstants.ATTR_DEV, "invalid"); + IGDBServerMILaunchConfigurationConstants.ATTR_DEV, "invalid"); //$NON-NLS-1$ } catch (CoreException e) { - requestMonitor.setStatus(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, -1, "Cannot retrieve serial device", e)); //$NON-NLS-1$ + requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Cannot retrieve serial device", e)); //$NON-NLS-1$ requestMonitor.done(); return false; } @@ -101,9 +101,9 @@ public class FinalLaunchSequence extends Sequence { private boolean getTcpHost(RequestMonitor requestMonitor) { try { fRemoteTcpHost = fLaunch.getLaunchConfiguration().getAttribute( - IGDBServerMILaunchConfigurationConstants.ATTR_HOST, "invalid"); + IGDBServerMILaunchConfigurationConstants.ATTR_HOST, "invalid"); //$NON-NLS-1$ } catch (CoreException e) { - requestMonitor.setStatus(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, -1, "Cannot retrieve remote TCP host", e)); //$NON-NLS-1$ + requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Cannot retrieve remote TCP host", e)); //$NON-NLS-1$ requestMonitor.done(); return false; } @@ -113,9 +113,9 @@ public class FinalLaunchSequence extends Sequence { private boolean getTcpPort(RequestMonitor requestMonitor) { try { fRemoteTcpPort = fLaunch.getLaunchConfiguration().getAttribute( - IGDBServerMILaunchConfigurationConstants.ATTR_PORT, "invalid"); + IGDBServerMILaunchConfigurationConstants.ATTR_PORT, "invalid"); //$NON-NLS-1$ } catch (CoreException e) { - requestMonitor.setStatus(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, -1, "Cannot retrieve remote TCP port", e)); //$NON-NLS-1$ + requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Cannot retrieve remote TCP port", e)); //$NON-NLS-1$ requestMonitor.done(); return false; } @@ -132,14 +132,14 @@ public class FinalLaunchSequence extends Sequence { if (!getTcpPort(requestMonitor)) return; fCommandControl.queueCommand( - new MITargetSelect((IContainerDMContext)fCommandControl.getControlDMContext(), - fRemoteTcpHost, fRemoteTcpPort), + new MITargetSelect(fCommandControl.getControlDMContext(), + fRemoteTcpHost, fRemoteTcpPort), new DataRequestMonitor(getExecutor(), requestMonitor)); } else { if (!getSerialDevice(requestMonitor)) return; fCommandControl.queueCommand( - new MITargetSelect((IContainerDMContext)fCommandControl.getControlDMContext(), + new MITargetSelect(fCommandControl.getControlDMContext(), fSerialDevice), new DataRequestMonitor(getExecutor(), requestMonitor)); } @@ -154,7 +154,7 @@ public class FinalLaunchSequence extends Sequence { */ new Step() { @Override public void execute(final RequestMonitor requestMonitor) { - DsfServicesTracker tracker = new DsfServicesTracker(GdbLaunchPlugin.getBundleContext(), fLaunch.getSession().getId()); + DsfServicesTracker tracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), fLaunch.getSession().getId()); MIBreakpointsManager bpmService = tracker.getService(MIBreakpointsManager.class); tracker.dispose(); bpmService.startTrackingBreakpoints(fCommandControl.getGDBDMContext(), requestMonitor); @@ -174,7 +174,7 @@ public class FinalLaunchSequence extends Sequence { try { fStopInMain = fLaunch.getLaunchConfiguration().getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN, false ); } catch (CoreException e) { - requestMonitor.setStatus(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, -1, "Cannot retrieve the entry point symbol", e)); //$NON-NLS-1$ + requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Cannot retrieve the entry point symbol", e)); //$NON-NLS-1$ requestMonitor.done(); return false; } @@ -185,7 +185,7 @@ public class FinalLaunchSequence extends Sequence { try { fStopSymbol = fLaunch.getLaunchConfiguration().getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN_SYMBOL, ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_SYMBOL_DEFAULT ); } catch (CoreException e) { - requestMonitor.setStatus(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, DebugException.CONFIGURATION_INVALID, "Cannot retrieve the entry point symbol", e)); //$NON-NLS-1$ + requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.CONFIGURATION_INVALID, "Cannot retrieve the entry point symbol", e)); //$NON-NLS-1$ requestMonitor.done(); return false; } diff --git a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/GdbLaunch.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunch.java similarity index 89% rename from plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/GdbLaunch.java rename to plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunch.java index f9a6f5f97e7..f723d05eeb1 100644 --- a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/GdbLaunch.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunch.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.gdb.launch.launching; +package org.eclipse.dd.gdb.launching; import java.util.concurrent.ExecutionException; @@ -29,7 +29,7 @@ import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.gdb.launch.internal.GdbLaunchPlugin; +import org.eclipse.dd.gdb.internal.GdbPlugin; import org.eclipse.dd.gdb.service.command.GDBControl; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.ILaunchConfiguration; @@ -71,7 +71,7 @@ public class GdbLaunch extends Launch Runnable initRunnable = new DsfRunnable() { public void run() { - fTracker = new DsfServicesTracker(GdbLaunchPlugin.getBundleContext(), fSession.getId()); + fTracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), fSession.getId()); fSession.addServiceEventListener(GdbLaunch.this, null); fInitialized = true; @@ -83,9 +83,9 @@ public class GdbLaunch extends Launch try { fExecutor.submit(initRunnable).get(); } catch (InterruptedException e) { - new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Error initializing launch", e); //$NON-NLS-1$ + new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Error initializing launch", e); //$NON-NLS-1$ } catch (ExecutionException e) { - new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Error initializing launch", e); //$NON-NLS-1$ + new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Error initializing launch", e); //$NON-NLS-1$ } } @@ -145,8 +145,8 @@ public class GdbLaunch extends Launch public void handleCompleted() { fSession.removeServiceEventListener(GdbLaunch.this); if (!isSuccess()) { - GdbLaunchPlugin.getDefault().getLog().log(new MultiStatus( - GdbLaunchPlugin.PLUGIN_ID, -1, new IStatus[]{getStatus()}, "Session shutdown failed", null)); //$NON-NLS-1$ + GdbPlugin.getDefault().getLog().log(new MultiStatus( + GdbPlugin.PLUGIN_ID, -1, new IStatus[]{getStatus()}, "Session shutdown failed", null)); //$NON-NLS-1$ } // Last order of business, shutdown the dispatch queue. fTracker.dispose(); diff --git a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/GdbLaunchDelegate.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunchDelegate.java similarity index 92% rename from plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/GdbLaunchDelegate.java rename to plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunchDelegate.java index 7dce245a668..8a270f780fd 100644 --- a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/GdbLaunchDelegate.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunchDelegate.java @@ -8,7 +8,7 @@ * Contributors: * QNX Software Systems - Initial API and implementation *******************************************************************************/ -package org.eclipse.dd.gdb.launch.launching; +package org.eclipse.dd.gdb.launching; import java.io.File; import java.io.IOException; @@ -35,7 +35,7 @@ import org.eclipse.dd.dsf.debug.model.DsfMemoryBlockRetrieval; import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryDMContext; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.gdb.IGDBLaunchConfigurationConstants; -import org.eclipse.dd.gdb.launch.internal.GdbLaunchPlugin; +import org.eclipse.dd.gdb.internal.GdbPlugin; import org.eclipse.dd.gdb.service.command.GDBControl; import org.eclipse.dd.gdb.service.command.GDBControl.SessionType; import org.eclipse.dd.mi.service.command.AbstractCLIProcess; @@ -131,9 +131,9 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate try { servicesLaunchSequence.get(); } catch (InterruptedException e1) { - throw new DebugException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, "Interrupted Exception in dispatch thread", e1)); //$NON-NLS-1$ + throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, "Interrupted Exception in dispatch thread", e1)); //$NON-NLS-1$ } catch (ExecutionException e1) { - throw new DebugException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Error in services launch sequence", e1.getCause())); //$NON-NLS-1$ + throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Error in services launch sequence", e1.getCause())); //$NON-NLS-1$ } launch.initializeControl(); @@ -144,7 +144,7 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate try { launch.getDsfExecutor().submit( new Callable() { public Object call() throws CoreException { - DsfServicesTracker tracker = new DsfServicesTracker(GdbLaunchPlugin.getBundleContext(), launch.getSession().getId()); + DsfServicesTracker tracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), launch.getSession().getId()); GDBControl gdb = tracker.getService(GDBControl.class); if (gdb != null) { cliProcessRef.set(gdb.getCLIProcess()); @@ -157,11 +157,11 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate launch.addProcess(DebugPlugin.newProcess(launch, cliProcessRef.get(), "gdb")); //$NON-NLS-1$ launch.addProcess(DebugPlugin.newProcess(launch, inferiorProcessRef.get(), exePath.lastSegment())); } catch (InterruptedException e) { - throw new CoreException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, 0, "Interrupted while waiting for get process callable.", e)); //$NON-NLS-1$ + throw new CoreException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, 0, "Interrupted while waiting for get process callable.", e)); //$NON-NLS-1$ } catch (ExecutionException e) { throw (CoreException)e.getCause(); } catch (RejectedExecutionException e) { - throw new CoreException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, 0, "Debugger shut down before launch was completed.", e)); //$NON-NLS-1$ + throw new CoreException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, 0, "Debugger shut down before launch was completed.", e)); //$NON-NLS-1$ } // Create and invoke the final launch sequence to setup GDB @@ -171,15 +171,15 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate try { finalLaunchSequence.get(); } catch (InterruptedException e1) { - throw new DebugException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, "Interrupted Exception in dispatch thread", e1)); //$NON-NLS-1$ + throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, "Interrupted Exception in dispatch thread", e1)); //$NON-NLS-1$ } catch (ExecutionException e1) { - throw new DebugException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Error in final launch sequence", e1.getCause())); //$NON-NLS-1$ + throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Error in final launch sequence", e1.getCause())); //$NON-NLS-1$ } // Create a memory retrieval and register it with session try { launch.getDsfExecutor().submit( new Callable() { public Object call() throws CoreException { - DsfServicesTracker tracker = new DsfServicesTracker(GdbLaunchPlugin.getBundleContext(), launch.getSession().getId()); + DsfServicesTracker tracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), launch.getSession().getId()); GDBControl gdbControl = tracker.getService(GDBControl.class); if (gdbControl != null) { IMemoryBlockRetrieval memRetrieval = new DsfMemoryBlockRetrieval( @@ -192,11 +192,11 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate } }).get(); } catch (InterruptedException e) { - throw new CoreException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, 0, "Interrupted while waiting for get process callable.", e)); //$NON-NLS-1$ + throw new CoreException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, 0, "Interrupted while waiting for get process callable.", e)); //$NON-NLS-1$ } catch (ExecutionException e) { throw (CoreException)e.getCause(); } catch (RejectedExecutionException e) { - throw new CoreException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, 0, "Debugger shut down before launch was completed.", e)); //$NON-NLS-1$ + throw new CoreException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, 0, "Debugger shut down before launch was completed.", e)); //$NON-NLS-1$ } } diff --git a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/ServicesLaunchSequence.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/ServicesLaunchSequence.java similarity index 99% rename from plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/ServicesLaunchSequence.java rename to plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/ServicesLaunchSequence.java index 62ef5d4c0d7..4b87b6b8400 100644 --- a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/ServicesLaunchSequence.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/ServicesLaunchSequence.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.gdb.launch.launching; +package org.eclipse.dd.gdb.launching; import org.eclipse.cdt.debug.core.CDebugCorePlugin; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; diff --git a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/ShutdownSequence.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/ShutdownSequence.java similarity index 92% rename from plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/ShutdownSequence.java rename to plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/ShutdownSequence.java index 08177c352c5..3afdd49c864 100644 --- a/plugins/org.eclipse.dd.gdb.launch/src/org/eclipse/dd/gdb/launch/launching/ShutdownSequence.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/ShutdownSequence.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.gdb.launch.launching; +package org.eclipse.dd.gdb.launching; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; @@ -18,7 +18,7 @@ import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.concurrent.Sequence; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.IDsfService; -import org.eclipse.dd.gdb.launch.internal.GdbLaunchPlugin; +import org.eclipse.dd.gdb.internal.GdbPlugin; import org.eclipse.dd.gdb.service.GDBRunControl; import org.eclipse.dd.gdb.service.command.GDBControl; import org.eclipse.dd.mi.service.CSourceLookup; @@ -54,8 +54,8 @@ public class ShutdownSequence extends Sequence { private final Step[] fSteps = new Step[] { new Step() { @Override public void execute(RequestMonitor requestMonitor) { - assert GdbLaunchPlugin.getBundleContext() != null; - fTracker = new DsfServicesTracker(GdbLaunchPlugin.getBundleContext(), fSessionId); + assert GdbPlugin.getBundleContext() != null; + fTracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), fSessionId); requestMonitor.done(); } @@ -93,13 +93,13 @@ public class ShutdownSequence extends Sequence { // protected void handleCompleted() { // // If un-installing breakpoints fails, log the error but continue shutting down. // if (!isSuccess) { -// DsfGdbLaunchPlugin.getDefault().getLog().log(getStatus()); +// DsfGdbPlugin.getDefault().getLog().log(getStatus()); // } // requestMonitor.done(); // } // }); // } else { -// requestMonitor.setStatus(new Status(IStatus.ERROR, DsfGdbLaunchPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, +// requestMonitor.setStatus(new Status(IStatus.ERROR, DsfGdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, // "Needed services not found.", null)); //$NON-NLS-1$ // requestMonitor.done(); // } @@ -166,13 +166,13 @@ public class ShutdownSequence extends Sequence { @Override protected void handleCompleted() { if (!isSuccess()) { - GdbLaunchPlugin.getDefault().getLog().log(getStatus()); + GdbPlugin.getDefault().getLog().log(getStatus()); } requestMonitor.done(); } }); } else { - requestMonitor.setStatus(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, + requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Service '" + clazz.getName() + "' not found.", null)); //$NON-NLS-1$//$NON-NLS-2$ requestMonitor.done(); } diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java index 15b239a6185..7e86c586dec 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java @@ -15,7 +15,7 @@ import java.util.Map; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.dd.gdb.launch.launching.GdbLaunch; +import org.eclipse.dd.gdb.launching.GdbLaunch; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationType; diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/LaunchSequence.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/LaunchSequence.java index f8e52ac6fc2..ba0357795b6 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/LaunchSequence.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/LaunchSequence.java @@ -27,7 +27,7 @@ import org.eclipse.dd.dsf.concurrent.Sequence; import org.eclipse.dd.dsf.debug.service.StepQueueManager; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.gdb.launch.launching.GdbLaunch; +import org.eclipse.dd.gdb.launching.GdbLaunch; import org.eclipse.dd.gdb.service.GDBRunControl; import org.eclipse.dd.gdb.service.command.GDBControl; import org.eclipse.dd.mi.service.CSourceLookup; diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java index eb011ac3cf2..114ee8324c7 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java @@ -35,7 +35,7 @@ import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.debug.model.DsfMemoryBlockRetrieval; import org.eclipse.dd.dsf.service.DsfServicesTracker; -import org.eclipse.dd.gdb.launch.launching.GdbLaunch; +import org.eclipse.dd.gdb.launching.GdbLaunch; import org.eclipse.dd.gdb.service.command.GDBControl; import org.eclipse.dd.mi.service.command.AbstractCLIProcess; import org.eclipse.dd.mi.service.command.MIInferiorProcess; From 8c8a9fddffd3d8da730cdcb7c84c9ec819965c5f Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Thu, 27 Mar 2008 18:13:55 +0000 Subject: [PATCH 337/834] Bug 221505 Moves the code out of org.eclipse.dd.gdb.launch.ui into org.eclipse.dd.gdb.ui to allow people to extend the classes without taking in the extensions defined by org.eclipse.dd.gdb.launch.ui --- .../META-INF/MANIFEST.MF | 5 +- .../internal/ui/launching/CDebuggerTab.java | 556 ++++++++++++++++++ ...dbLocalRunLaunchConfigurationTabGroup.java | 35 ++ ...bRemoteRunLaunchConfigurationTabGroup.java | 36 ++ .../META-INF/MANIFEST.MF | 4 +- 5 files changed, 632 insertions(+), 4 deletions(-) create mode 100644 plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/CDebuggerTab.java create mode 100644 plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbLocalRunLaunchConfigurationTabGroup.java create mode 100644 plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbRemoteRunLaunchConfigurationTabGroup.java diff --git a/plugins/org.eclipse.dd.gdb.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.gdb.ui/META-INF/MANIFEST.MF index ab657bc519e..0837f2bbc7c 100644 --- a/plugins/org.eclipse.dd.gdb.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.gdb.ui/META-INF/MANIFEST.MF @@ -15,6 +15,9 @@ Require-Bundle: org.eclipse.ui, org.eclipse.dd.mi, org.eclipse.dd.gdb, org.eclipse.dd.dsf.debug, - org.eclipse.cdt.debug.ui + org.eclipse.cdt.debug.ui, + org.eclipse.cdt.core, + org.eclipse.cdt.launch Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Export-Package: org.eclipse.dd.gdb.internal.ui.launching diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/CDebuggerTab.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/CDebuggerTab.java new file mode 100644 index 00000000000..b8d5f6e46d1 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/CDebuggerTab.java @@ -0,0 +1,556 @@ +/******************************************************************************* + * Copyright (c) 2005, 2007, 2008 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Ken Ryall (Nokia) - https://bugs.eclipse.org/bugs/show_bug.cgi?id=118894 + * IBM Corporation + * Ericsson + *******************************************************************************/ +package org.eclipse.dd.gdb.internal.ui.launching; + +import java.io.IOException; +import java.text.Collator; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.IBinaryParser; +import org.eclipse.cdt.core.ICExtensionReference; +import org.eclipse.cdt.core.IBinaryParser.IBinaryObject; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; +import org.eclipse.cdt.core.settings.model.ICProjectDescription; +import org.eclipse.cdt.debug.core.CDebugCorePlugin; +import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; +import org.eclipse.cdt.debug.core.ICDebugConfiguration; +import org.eclipse.cdt.debug.core.ICDebugConstants; +import org.eclipse.cdt.debug.ui.ICDebuggerPage; +import org.eclipse.cdt.launch.internal.ui.AbstractCDebuggerTab; +import org.eclipse.cdt.launch.internal.ui.LaunchMessages; +import org.eclipse.cdt.launch.ui.ICDTLaunchHelpContextIds; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.dd.gdb.IGDBLaunchConfigurationConstants; +import org.eclipse.dd.gdb.service.command.GDBControl.SessionType; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.accessibility.AccessibleAdapter; +import org.eclipse.swt.accessibility.AccessibleEvent; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.PlatformUI; + +public class CDebuggerTab extends AbstractCDebuggerTab { + + public class AdvancedDebuggerOptionsDialog extends Dialog { + + private Button fVarBookKeeping; + + private Button fRegBookKeeping; + + /** + * Constructor for AdvancedDebuggerOptionsDialog. + */ + protected AdvancedDebuggerOptionsDialog(Shell parentShell) { + super(parentShell); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite) + */ + protected Control createDialogArea(Composite parent) { + Composite composite = (Composite)super.createDialogArea(parent); + Group group = new Group(composite, SWT.NONE); + group.setText(LaunchMessages.getString("CDebuggerTab.Automatically_track_values_of")); //$NON-NLS-1$ + GridLayout layout = new GridLayout(); + group.setLayout(layout); + group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + fVarBookKeeping = new Button(group, SWT.CHECK); + fVarBookKeeping.setText(LaunchMessages.getString("CDebuggerTab.Variables")); //$NON-NLS-1$ + fRegBookKeeping = new Button(group, SWT.CHECK); + fRegBookKeeping.setText(LaunchMessages.getString("CDebuggerTab.Registers")); //$NON-NLS-1$ + initialize(); + return composite; + } + + protected void okPressed() { + saveValues(); + super.okPressed(); + } + + private void initialize() { + Map attr = getAdvancedAttributes(); + Object varBookkeeping = attr.get(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_ENABLE_VARIABLE_BOOKKEEPING); + fVarBookKeeping.setSelection( (varBookkeeping instanceof Boolean) ? !((Boolean)varBookkeeping).booleanValue() : true); + Object regBookkeeping = attr.get(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_ENABLE_REGISTER_BOOKKEEPING); + fRegBookKeeping.setSelection( (regBookkeeping instanceof Boolean) ? !((Boolean)regBookkeeping).booleanValue() : true); + } + + private void saveValues() { + Map attr = getAdvancedAttributes(); + Boolean varBookkeeping = Boolean.valueOf( !fVarBookKeeping.getSelection() ); + attr.put(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_ENABLE_VARIABLE_BOOKKEEPING, varBookkeeping); + Boolean regBookkeeping = Boolean.valueOf( !fRegBookKeeping.getSelection() ); + attr.put(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_ENABLE_REGISTER_BOOKKEEPING, regBookkeeping); + update(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell) + */ + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + newShell.setText(LaunchMessages.getString("CDebuggerTab.Advanced_Options_Dialog_Title")); //$NON-NLS-1$ + } + } + + final protected SessionType fSessionType; + + protected Button fAdvancedButton; + protected Button fStopInMain; + protected Text fStopInMainSymbol; + protected Button fAttachButton; + + private Map fAdvancedAttributes = new HashMap(5); + + private ScrolledComposite fContainer; + + private Composite fContents; + + public CDebuggerTab(SessionType type) { + fSessionType = type; + + // If the default debugger has not been set, use the MI debugger. + // The MI plug-in also does this, but it may not have been loaded yet. Bug 158391. + ICDebugConfiguration dc = CDebugCorePlugin.getDefault().getDefaultDefaultDebugConfiguration(); + if (dc == null) { + CDebugCorePlugin.getDefault().getPluginPreferences().setDefault(ICDebugConstants.PREF_DEFAULT_DEBUGGER_TYPE, "org.eclipse.cdt.debug.mi.core.CDebuggerNew"); //$NON-NLS-1$ + } + } + + public void createControl(Composite parent) { + fContainer = new ScrolledComposite( parent, SWT.V_SCROLL | SWT.H_SCROLL ); + fContainer.setLayoutData(new GridData(GridData.FILL_BOTH)); + fContainer.setLayout( new FillLayout() ); + fContainer.setExpandHorizontal(true); + fContainer.setExpandVertical(true); + + fContents = new Composite( fContainer, SWT.NONE ); + setControl(fContainer); + /*GdbUILaunchPlugin.getDefault()*/PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), + ICDTLaunchHelpContextIds.LAUNCH_CONFIGURATION_DIALOG_DEBBUGER_TAB); + int numberOfColumns = (fSessionType == SessionType.ATTACH) ? 2 : 1; + GridLayout layout = new GridLayout(numberOfColumns, false); + fContents.setLayout(layout); + GridData gd = new GridData( GridData.BEGINNING, GridData.CENTER, true, false ); + fContents.setLayoutData(gd); + + createDebuggerCombo(fContents, (fSessionType == SessionType.ATTACH) ? 1 : 2 ); + createOptionsComposite(fContents); + createDebuggerGroup(fContents, 2); + + fContainer.setContent( fContents ); + } + + protected void loadDebuggerComboBox(ILaunchConfiguration config, String selection) { + ICDebugConfiguration[] debugConfigs; + String configPlatform = getPlatform(config); + debugConfigs = CDebugCorePlugin.getDefault().getActiveDebugConfigurations(); + Arrays.sort(debugConfigs, new Comparator() { + public int compare(ICDebugConfiguration c1, ICDebugConfiguration c2) { + return Collator.getInstance().compare(c1.getName(), c2.getName()); + } + }); + List list = new ArrayList(); + String mode; + if (fSessionType == SessionType.ATTACH) { + mode = ICDTLaunchConfigurationConstants.DEBUGGER_MODE_ATTACH; + } else if (fSessionType == SessionType.REMOTE) { + mode = IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE; + } else { + mode = ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN; + } + if (selection.equals("")) { //$NON-NLS-1$ + ICDebugConfiguration dc = CDebugCorePlugin.getDefault().getDefaultDebugConfiguration(); + if (dc == null) { + CDebugCorePlugin.getDefault().saveDefaultDebugConfiguration("org.eclipse.cdt.debug.mi.core.CDebuggerNew"); + dc = CDebugCorePlugin.getDefault().getDefaultDebugConfiguration(); + } + if (dc != null) + selection = dc.getID(); + } + String defaultSelection = selection; + for (int i = 0; i < debugConfigs.length; i++) { + if (mode.equals(IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE) || debugConfigs[i].supportsMode(mode)) { + String debuggerPlatform = debugConfigs[i].getPlatform(); + if (validatePlatform(config, debugConfigs[i])) { + list.add(debugConfigs[i]); + // select first exact matching debugger for platform or + // requested selection + if ( (defaultSelection.equals("") && debuggerPlatform.equalsIgnoreCase(configPlatform))) { //$NON-NLS-1$ + defaultSelection = debugConfigs[i].getID(); + } + } + } + } + // if no selection meaning nothing in config the force initdefault on + // tab + setInitializeDefault(selection.equals("") ? true : false); //$NON-NLS-1$ + loadDebuggerCombo((ICDebugConfiguration[])list.toArray(new ICDebugConfiguration[list.size()]), defaultSelection); + } + + protected void updateComboFromSelection() { + super.updateComboFromSelection(); + initializeCommonControls(getLaunchConfiguration()); + } + + public void setDefaults(ILaunchConfigurationWorkingCopy config) { + super.setDefaults(config); + if (fSessionType == SessionType.ATTACH) { + config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, + ICDTLaunchConfigurationConstants.DEBUGGER_MODE_ATTACH); + } else if (fSessionType == SessionType.REMOTE) { + config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, + IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE); + config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN, + ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_DEFAULT); + } else { + config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, + ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN); + config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN, + ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_DEFAULT); + } + config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_ENABLE_VARIABLE_BOOKKEEPING, false); + config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_ENABLE_REGISTER_BOOKKEEPING, false); + + // Set the default debugger based on the active toolchain on the project (if possible) + String defaultDebugger = null; + try { + String projectName = config.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME, ""); + if (projectName.length() > 0) { + IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); + ICProjectDescription projDesc = CoreModel.getDefault().getProjectDescription(project); + ICConfigurationDescription configDesc = projDesc.getActiveConfiguration(); + String configId = configDesc.getId(); + ICDebugConfiguration[] debugConfigs = CDebugCorePlugin.getDefault().getActiveDebugConfigurations(); + outer: for (int i = 0; i < debugConfigs.length; ++i) { + ICDebugConfiguration debugConfig = debugConfigs[i]; + String[] patterns = debugConfig.getSupportedBuildConfigPatterns(); + if (patterns != null) { + for (int j = 0; j < patterns.length; ++j) { + if (configId.matches(patterns[j])) { + defaultDebugger = debugConfig.getID(); + break outer; + } + } + } + } + } + } catch (CoreException e) { + } + + if (defaultDebugger == null) { + ICDebugConfiguration dc = CDebugCorePlugin.getDefault().getDefaultDebugConfiguration(); + if (dc != null) { + defaultDebugger = dc.getID(); + } + } + + config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_ID, defaultDebugger); + } + + public void initializeFrom(ILaunchConfiguration config) { + setInitializing(true); + super.initializeFrom(config); + try { + String id = config.getAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_ID, ""); //$NON-NLS-1$ + loadDebuggerComboBox(config, id); + initializeCommonControls(config); + } catch (CoreException e) { + } + setInitializing(false); + } + + public void performApply(ILaunchConfigurationWorkingCopy config) { + super.performApply(config); + if (fSessionType == SessionType.ATTACH) { + config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, + ICDTLaunchConfigurationConstants.DEBUGGER_MODE_ATTACH); + } else { + config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN, fStopInMain.getSelection()); + config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN_SYMBOL, fStopInMainSymbol.getText()); + if (fSessionType == SessionType.REMOTE) { + config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, + IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE); + } else { + config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, + ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN); + } + } + applyAdvancedAttributes(config); + } + + public boolean isValid(ILaunchConfiguration config) { + if (!validateDebuggerConfig(config)) { + return false; + } + ICDebugConfiguration debugConfig = getDebugConfig(); + String mode = ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN; + if (fSessionType == SessionType.ATTACH) mode = ICDTLaunchConfigurationConstants.DEBUGGER_MODE_ATTACH; + else if (fSessionType == SessionType.REMOTE) mode = IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE; + + if (!mode.equals(IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE) && !debugConfig.supportsMode(mode)) { + setErrorMessage(MessageFormat.format(LaunchMessages.getString("CDebuggerTab.Mode_not_supported"), new String[]{mode})); //$NON-NLS-1$ + return false; + } + if ( fStopInMain != null && fStopInMainSymbol != null ) { + // The "Stop on startup at" field must not be empty + String mainSymbol = fStopInMainSymbol.getText().trim(); + if (fStopInMain.getSelection() && mainSymbol.length() == 0) { + setErrorMessage( LaunchMessages.getString("CDebuggerTab.Stop_on_startup_at_can_not_be_empty")); //$NON-NLS-1$ + return false; + } + } + if (super.isValid(config) == false) { + return false; + } + return true; + } + + protected boolean validatePlatform(ILaunchConfiguration config, ICDebugConfiguration debugConfig) { + String configPlatform = getPlatform(config); + String debuggerPlatform = debugConfig.getPlatform(); + return (debuggerPlatform.equals("*") || debuggerPlatform.equalsIgnoreCase(configPlatform)); //$NON-NLS-1$ + } + + protected boolean validateCPU(ILaunchConfiguration config, ICDebugConfiguration debugConfig) { + IBinaryObject binaryFile = null; + try { + binaryFile = getBinary(config); + } catch (CoreException e) { + setErrorMessage(e.getLocalizedMessage()); + } + String projectCPU = ICDebugConfiguration.CPU_NATIVE; + if (binaryFile != null) { + projectCPU = binaryFile.getCPU(); + } + return debugConfig.supportsCPU(projectCPU); + } + + protected IBinaryObject getBinary(ILaunchConfiguration config) throws CoreException { + String programName = null; + String projectName = null; + try { + projectName = config.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME, (String)null); + programName = config.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, (String)null); + } catch (CoreException e) { + } + if (programName != null ) { + IPath exePath = new Path(programName); + if (projectName != null && !projectName.equals("")) { //$NON-NLS-1$ + IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); + if (!project.isAccessible()) { + return null; + } + if (!exePath.isAbsolute()) { + exePath = project.getLocation().append(exePath); + } + ICExtensionReference[] parserRef = CCorePlugin.getDefault().getBinaryParserExtensions(project); + for (int i = 0; i < parserRef.length; i++) { + try { + IBinaryParser parser = (IBinaryParser)parserRef[i].createExtension(); + IBinaryObject exe = (IBinaryObject)parser.getBinary(exePath); + if (exe != null) { + return exe; + } + } catch (ClassCastException e) { + } catch (IOException e) { + } + } + } + IBinaryParser parser = CCorePlugin.getDefault().getDefaultBinaryParser(); + try { + IBinaryObject exe = (IBinaryObject)parser.getBinary(exePath); + return exe; + } catch (ClassCastException e) { + } catch (IOException e) { + } + } + return null; + } + + protected boolean validateDebuggerConfig(ILaunchConfiguration config) { + ICDebugConfiguration debugConfig = getDebugConfig(); + if (debugConfig == null) { + setErrorMessage(LaunchMessages.getString("CDebuggerTab.No_debugger_available")); //$NON-NLS-1$ + return false; + } + // We do not validate platform and CPU compatibility to avoid accidentally disabling + // a valid configuration. It's much better to let an incompatible configuration through + // than to disable a valid one. + return true; + } + + /** + * @see org.eclipse.debug.ui.AbstractLaunchConfigurationTab#updateLaunchConfigurationDialog() + */ + protected void update() { + if (!isInitializing()) { + super.updateLaunchConfigurationDialog(); + } + } + + protected void createOptionsComposite(Composite parent) { + Composite optionsComp = new Composite(parent, SWT.NONE); + int numberOfColumns = (fSessionType == SessionType.ATTACH) ? 1 : 3; + GridLayout layout = new GridLayout( numberOfColumns, false ); + optionsComp.setLayout( layout ); + optionsComp.setLayoutData( new GridData( GridData.BEGINNING, GridData.CENTER, true, false, 1, 1 ) ); + if (fSessionType != SessionType.ATTACH) { + fStopInMain = createCheckButton( optionsComp, LaunchMessages.getString( "CDebuggerTab.Stop_at_main_on_startup" ) ); //$NON-NLS-1$ + fStopInMain.addSelectionListener(new SelectionAdapter() { + + public void widgetSelected(SelectionEvent e) { + fStopInMainSymbol.setEnabled(fStopInMain.getSelection()); + update(); + } + }); + fStopInMainSymbol = new Text(optionsComp, SWT.SINGLE | SWT.BORDER); + final GridData gridData = new GridData(GridData.FILL, GridData.CENTER, false, false); + gridData.widthHint = 100; + fStopInMainSymbol.setLayoutData(gridData); + fStopInMainSymbol.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent evt) { + update(); + } + }); + fStopInMainSymbol.getAccessible().addAccessibleListener( + new AccessibleAdapter() { + public void getName(AccessibleEvent e) { + e.result = LaunchMessages.getString( "CDebuggerTab.Stop_at_main_on_startup"); //$NON-NLS-1$ + } + } + ); + } + fAdvancedButton = createPushButton(optionsComp, LaunchMessages.getString("CDebuggerTab.Advanced"), null); //$NON-NLS-1$ + ((GridData)fAdvancedButton.getLayoutData()).horizontalAlignment = GridData.END; + fAdvancedButton.addSelectionListener(new SelectionAdapter() { + + public void widgetSelected(SelectionEvent e) { + Dialog dialog = new AdvancedDebuggerOptionsDialog(getShell()); + dialog.open(); + } + }); + } + + protected Map getAdvancedAttributes() { + return fAdvancedAttributes; + } + + private void initializeAdvancedAttributes(ILaunchConfiguration config) { + Map attr = getAdvancedAttributes(); + try { + Boolean varBookkeeping = (config.getAttribute( + ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_ENABLE_VARIABLE_BOOKKEEPING, false)) + ? Boolean.TRUE + : Boolean.FALSE; + attr.put(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_ENABLE_VARIABLE_BOOKKEEPING, varBookkeeping); + } catch (CoreException e) { + } + try { + Boolean regBookkeeping = (config.getAttribute( + ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_ENABLE_REGISTER_BOOKKEEPING, false)) + ? Boolean.TRUE + : Boolean.FALSE; + attr.put(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_ENABLE_REGISTER_BOOKKEEPING, regBookkeeping); + } catch (CoreException e) { + } + } + + private void applyAdvancedAttributes(ILaunchConfigurationWorkingCopy config) { + Map attr = getAdvancedAttributes(); + Object varBookkeeping = attr.get(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_ENABLE_VARIABLE_BOOKKEEPING); + if (varBookkeeping instanceof Boolean) + config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_ENABLE_VARIABLE_BOOKKEEPING, + ((Boolean)varBookkeeping).booleanValue()); + Object regBookkeeping = attr.get(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_ENABLE_REGISTER_BOOKKEEPING); + if (regBookkeeping instanceof Boolean) + config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_ENABLE_REGISTER_BOOKKEEPING, + ((Boolean)regBookkeeping).booleanValue()); + } + + protected Shell getShell() { + return super.getShell(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.debug.ui.ILaunchConfigurationTab#dispose() + */ + public void dispose() { + getAdvancedAttributes().clear(); + ICDebuggerPage debuggerPage = getDynamicTab(); + if ( debuggerPage != null ) + debuggerPage.dispose(); + super.dispose(); + } + + protected void initializeCommonControls(ILaunchConfiguration config) { + try { + if (fSessionType != SessionType.ATTACH) { + fStopInMain.setSelection(config.getAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN, + ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_DEFAULT)); + fStopInMainSymbol.setText(config.getAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN_SYMBOL, + ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_SYMBOL_DEFAULT)); + fStopInMainSymbol.setEnabled(fStopInMain.getSelection()); + } + initializeAdvancedAttributes(config); + } catch (CoreException e) { + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.launch.internal.ui.AbstractCDebuggerTab#setInitializeDefault(boolean) + */ + protected void setInitializeDefault(boolean init) { + super.setInitializeDefault(init); + } + + protected void contentsChanged() { + fContainer.setMinSize(fContents.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + } +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbLocalRunLaunchConfigurationTabGroup.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbLocalRunLaunchConfigurationTabGroup.java new file mode 100644 index 00000000000..c95d5c61733 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbLocalRunLaunchConfigurationTabGroup.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2005 QNX Software 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: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.gdb.internal.ui.launching; + +import org.eclipse.cdt.launch.ui.CMainTab; +import org.eclipse.dd.gdb.service.command.GDBControl.SessionType; +import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup; +import org.eclipse.debug.ui.CommonTab; +import org.eclipse.debug.ui.ILaunchConfigurationDialog; +import org.eclipse.debug.ui.ILaunchConfigurationTab; +import org.eclipse.debug.ui.sourcelookup.SourceLookupTab; + +public class GdbLocalRunLaunchConfigurationTabGroup extends AbstractLaunchConfigurationTabGroup { + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.ILaunchConfigurationTabGroup#createTabs(org.eclipse.debug.ui.ILaunchConfigurationDialog, java.lang.String) + */ + public void createTabs(ILaunchConfigurationDialog dialog, String mode) { + ILaunchConfigurationTab[] tabs = new ILaunchConfigurationTab[] { + new CMainTab(true), + new CDebuggerTab(SessionType.RUN), + new SourceLookupTab(), + new CommonTab() + }; + setTabs(tabs); + } +} diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbRemoteRunLaunchConfigurationTabGroup.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbRemoteRunLaunchConfigurationTabGroup.java new file mode 100644 index 00000000000..9b00424d1ae --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbRemoteRunLaunchConfigurationTabGroup.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2008 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.gdb.internal.ui.launching; + +import org.eclipse.cdt.launch.ui.CMainTab; +import org.eclipse.dd.gdb.service.command.GDBControl.SessionType; +import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup; +import org.eclipse.debug.ui.CommonTab; +import org.eclipse.debug.ui.ILaunchConfigurationDialog; +import org.eclipse.debug.ui.ILaunchConfigurationTab; +import org.eclipse.debug.ui.sourcelookup.SourceLookupTab; + +public class GdbRemoteRunLaunchConfigurationTabGroup extends AbstractLaunchConfigurationTabGroup { + + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.ILaunchConfigurationTabGroup#createTabs(org.eclipse.debug.ui.ILaunchConfigurationDialog, java.lang.String) + */ + public void createTabs(ILaunchConfigurationDialog dialog, String mode) { + ILaunchConfigurationTab[] tabs = new ILaunchConfigurationTab[] { + new CMainTab(true), + new CDebuggerTab(SessionType.REMOTE), + new SourceLookupTab(), + new CommonTab() + }; + setTabs(tabs); + } +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.tests.gdb/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.tests.gdb/META-INF/MANIFEST.MF index f244648c223..ab27099db8c 100644 --- a/plugins/org.eclipse.dd.tests.gdb/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.tests.gdb/META-INF/MANIFEST.MF @@ -5,7 +5,6 @@ Bundle-SymbolicName: org.eclipse.dd.tests.gdb;singleton:=true Bundle-Version: 1.0.0 Bundle-Activator: org.eclipse.dd.tests.gdb.launching.TestsPlugin Bundle-Vendor: Ericsson -Bundle-Localization: plugin Require-Bundle: org.eclipse.core.runtime, org.eclipse.dd.dsf, org.eclipse.dd.dsf.debug, @@ -17,8 +16,7 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.debug.core, org.eclipse.cdt.debug.mi.core, org.eclipse.swt, - org.eclipse.dd.gdb, - org.eclipse.dd.gdb.launch + org.eclipse.dd.gdb Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: J2SE-1.5 Bundle-ClassPath: . From 5ac30e181b3bc5ad7fa5faf6be7aee40bbc81491 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 27 Mar 2008 19:07:07 +0000 Subject: [PATCH 338/834] [223969] Extended CommanCache to track multiple contexts as "available". --- .../debug/service/command/CommandCache.java | 52 ++++++++++--------- .../examples/pda/service/PDAExpressions.java | 4 +- .../dd/examples/pda/service/PDAStack.java | 4 +- .../dd/mi/service/ExpressionService.java | 4 +- .../org/eclipse/dd/mi/service/MIMemory.java | 12 ++--- .../eclipse/dd/mi/service/MIRegisters.java | 4 +- .../eclipse/dd/mi/service/MIRunControl.java | 12 ++--- 7 files changed, 48 insertions(+), 44 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java index fb3e2935160..7b7f91ddbf5 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java @@ -14,10 +14,12 @@ package org.eclipse.dd.dsf.debug.service.command; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Set; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; @@ -63,17 +65,12 @@ public class CommandCache implements ICommandListener /** Command being processed for this command */ CommandInfo fCoalescedCmd; - /** No longer really used and needs to be deleted */ - int fResetCounterStatus; - public CommandInfo( CommandStyle cmdstyle, ICommand cmd, DataRequestMonitor rm ) { - fCmdStyle = cmdstyle; fCommand = cmd; fCurrentRequestMonitors = new LinkedList>(); fCurrentRequestMonitors.add(rm); fCoalescedCmd = null; - fResetCounterStatus = fResetCounter; } public CommandStyle getCommandstyle() { return fCmdStyle; } @@ -92,7 +89,7 @@ public class CommandCache implements ICommandListener @Override public int hashCode() { - return (fCommand.hashCode()+ (fResetCounterStatus + 1)); + return fCommand.hashCode(); } } @@ -143,8 +140,7 @@ public class CommandCache implements ICommandListener * when back into individual results from this command. */ - private boolean fIsTargetAvailable = true; - private int fResetCounter = 0; + private Set fAvailableContexts = new HashSet(); private ICommandControl fCommandControl; @@ -267,7 +263,7 @@ public class CommandCache implements ICommandListener /* * Return an error if the target is available anymore. */ - if (!fIsTargetAvailable) { + if (!isTargetAvailable(command.getContext())) { rm.setStatus(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Target not available.", null)); //$NON-NLS-1$ rm.done(); return; @@ -440,33 +436,41 @@ public class CommandCache implements ICommandListener } /** - * Sets the cache to a state in which target access is not allowed. - * When target is not available, commands to the target will either - * return data that is found in the cache already, or will return an - * error. This is useful in avoiding sending commands to target when - * they are known to fail or return unreliable results, while still - * providing access to the cached data. - * - * @param isAvailable Flag indicating whether target can be accessed. + * TODO */ - public void setTargetAvailable(boolean isAvailable) { - fIsTargetAvailable = isAvailable; + public void setContextAvailable(IDMContext context, boolean isAvailable) { + if (isAvailable) { + fAvailableContexts.add(context); + } else { + fAvailableContexts.remove(context); + for (Iterator itr = fAvailableContexts.iterator(); itr.hasNext();) { + if (DMContexts.isAncestorOf(itr.next(), context)) { + itr.remove(); + } + } + } } /** - * Retrieves current flag indicating target availability. - * @see #setTargetAvailable(boolean) + * TODO + * @see #setContextAvailable(IDMContext, boolean) */ - public boolean isTargetAvailable() { - return fIsTargetAvailable; + public boolean isTargetAvailable(IDMContext context) { + for (IDMContext availableContext : fAvailableContexts) { + if (context.equals(availableContext) || DMContexts.isAncestorOf(context, availableContext)) { + return true; + } + } + return false; } + + /** * Clears the cache data. */ public void reset() { fCachedContexts.clear(); - fResetCounter++; } public void commandRemoved(ICommand command) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAExpressions.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAExpressions.java index 7e0e4236b32..3ebafb920b8 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAExpressions.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAExpressions.java @@ -357,7 +357,7 @@ public class PDAExpressions extends AbstractDsfService implements IExpressions { public void eventDispatched(IResumedDMEvent e) { // Mark the cache as not available, so that data retrieval commands // will fail. Also reset the cache unless it was a step command. - fCommandCache.setTargetAvailable(false); + fCommandCache.setContextAvailable(e.getDMContext(), false); if (!e.getReason().equals(StateChangeReason.STEP)) { fCommandCache.reset(); } @@ -367,7 +367,7 @@ public class PDAExpressions extends AbstractDsfService implements IExpressions { @DsfServiceEventHandler public void eventDispatched(ISuspendedDMEvent e) { // Enable sending commands to target and clear the cache. - fCommandCache.setTargetAvailable(true); + fCommandCache.setContextAvailable(e.getDMContext(), true); fCommandCache.reset(); } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java index 5f4648414dc..6fe86364277 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java @@ -364,7 +364,7 @@ public class PDAStack extends AbstractDsfService implements IStack { public void eventDispatched(IResumedDMEvent e) { // Mark the cache as not available, so that stack commands will // fail. Also reset the cache unless it was a step command. - fCommandCache.setTargetAvailable(false); + fCommandCache.setContextAvailable(e.getDMContext(), false); if (!e.getReason().equals(StateChangeReason.STEP)) { fCommandCache.reset(); } @@ -374,7 +374,7 @@ public class PDAStack extends AbstractDsfService implements IStack { @DsfServiceEventHandler public void eventDispatched(ISuspendedDMEvent e) { // Enable sending commands to target and clear the cache. - fCommandCache.setTargetAvailable(true); + fCommandCache.setContextAvailable(e.getDMContext(), true); fCommandCache.reset(); } } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/ExpressionService.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/ExpressionService.java index 5a085191629..2db9093e88a 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/ExpressionService.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/ExpressionService.java @@ -884,7 +884,7 @@ public class ExpressionService extends AbstractDsfService implements IExpression @DsfServiceEventHandler public void eventDispatched(IRunControl.IResumedDMEvent e) { - fExpressionCache.setTargetAvailable(false); + fExpressionCache.setContextAvailable(e.getDMContext(), false); if (e.getReason() != StateChangeReason.STEP) { fExpressionCache.reset(); } @@ -892,7 +892,7 @@ public class ExpressionService extends AbstractDsfService implements IExpression @DsfServiceEventHandler public void eventDispatched(IRunControl.ISuspendedDMEvent e) { - fExpressionCache.setTargetAvailable(true); + fExpressionCache.setContextAvailable(e.getDMContext(), true); fExpressionCache.reset(); } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIMemory.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIMemory.java index 0870b86f01a..1296edaf1a5 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIMemory.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIMemory.java @@ -280,7 +280,7 @@ public class MIMemory extends AbstractDsfService implements IMemory { @DsfServiceEventHandler public void eventDispatched(IRunControl.IResumedDMEvent e) { - fMemoryCache.setTargetAvailable(false); + fMemoryCache.setTargetAvailable(e.getDMContext(), false); if (e.getReason() != StateChangeReason.STEP) { fMemoryCache.reset(); } @@ -288,7 +288,7 @@ public class MIMemory extends AbstractDsfService implements IMemory { @DsfServiceEventHandler public void eventDispatched(IRunControl.ISuspendedDMEvent e) { - fMemoryCache.setTargetAvailable(true); + fMemoryCache.setTargetAvailable(e.getDMContext(), true); fMemoryCache.reset(); } @@ -450,12 +450,12 @@ public class MIMemory extends AbstractDsfService implements IMemory { fMemoryBlockList.clear(); } - public void setTargetAvailable(boolean isAvailable) { - fCommandCache.setTargetAvailable(isAvailable); + public void setTargetAvailable(IDMContext dmc, boolean isAvailable) { + fCommandCache.setContextAvailable(dmc, isAvailable); } - public boolean isTargetAvailable() { - return fCommandCache.isTargetAvailable(); + public boolean isTargetAvailable(IDMContext dmc) { + return fCommandCache.isTargetAvailable(dmc); } /** diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRegisters.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRegisters.java index a7c658569ad..222464175d2 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRegisters.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRegisters.java @@ -397,7 +397,7 @@ public class MIRegisters extends AbstractDsfService implements IRegisters { */ @DsfServiceEventHandler public void eventDispatched(IRunControl.IResumedDMEvent e) { - fRegisterValueCache.setTargetAvailable(false); + fRegisterValueCache.setContextAvailable(e.getDMContext(), false); if (e.getReason() != StateChangeReason.STEP) { fRegisterValueCache.reset(); } @@ -405,7 +405,7 @@ public class MIRegisters extends AbstractDsfService implements IRegisters { @DsfServiceEventHandler public void eventDispatched( IRunControl.ISuspendedDMEvent e) { - fRegisterValueCache.setTargetAvailable(true); + fRegisterValueCache.setContextAvailable(e.getDMContext(), true); fRegisterValueCache.reset(); } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java index a70af84f3be..31481a48b4c 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java @@ -394,7 +394,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl fSuspended = false; fResumePending = false; fStateChangeReason = e.getReason(); - fMICommandCache.setTargetAvailable(false); + fMICommandCache.setContextAvailable(e.getDMContext(), false); //fStateChangeTriggeringContext = e.getTriggeringContext(); if (e.getReason().equals(StateChangeReason.STEP)) { fStepping = true; @@ -406,8 +406,8 @@ public class MIRunControl extends AbstractDsfService implements IRunControl @DsfServiceEventHandler public void eventDispatched(ContainerSuspendedEvent e) { - fMICommandCache.setTargetAvailable(true); - fMICommandCache.reset(); + fMICommandCache.setContextAvailable(e.getDMContext(), true); + fMICommandCache.reset(e.getDMContext()); fStateChangeReason = e.getReason(); fStateChangeTriggeringContext = e.getTriggeringContext(); fSuspended = true; @@ -467,7 +467,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl // Cygwin GDB will accept commands and execute them after the step // which is not what we want, so mark the target as unavailable // as soon as we send a resume command. - fMICommandCache.setTargetAvailable(false); + fMICommandCache.setContextAvailable(context, false); MIExecContinue cmd = null; if(context instanceof IContainerDMContext) cmd = new MIExecContinue(context); @@ -549,7 +549,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl fResumePending = true; fStepping = true; - fMICommandCache.setTargetAvailable(false); + fMICommandCache.setContextAvailable(context, false); switch(stepType) { case STEP_INTO: fConnection.queueCommand( @@ -649,7 +649,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl if (canResume(context)) { fResumePending = true; - fMICommandCache.setTargetAvailable(false); + fMICommandCache.setContextAvailable(context, false); fConnection.queueCommand(new MIExecUntil(dmc, fileName + ":" + lineNo), //$NON-NLS-1$ new DataRequestMonitor( getExecutor(), rm) { From 23cf575f17e94c9b4e9ce240e72b0a224fcaf86b Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 27 Mar 2008 20:53:39 +0000 Subject: [PATCH 339/834] [219031] Added the StepType parameter to IRunControl.canStep(). --- .../debug/ui/actions/DsfStepIntoCommand.java | 2 +- .../debug/ui/actions/DsfStepOverCommand.java | 2 +- .../ui/actions/DsfStepReturnCommand.java | 2 +- .../dd/dsf/debug/service/IRunControl.java | 4 ++-- .../dsf/debug/service/StepQueueManager.java | 20 +++++++++---------- .../examples/pda/service/PDARunControl.java | 4 ++-- .../eclipse/dd/mi/service/MIRunControl.java | 4 ++-- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepIntoCommand.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepIntoCommand.java index 31a184e29b0..52ce0cefcb6 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepIntoCommand.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepIntoCommand.java @@ -44,7 +44,7 @@ public class DsfStepIntoCommand implements IStepIntoHandler { fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) { @Override public void doExecute() { - request.setEnabled(getStepQueueMgr().canEnqueueStep(getContext())); + request.setEnabled(getStepQueueMgr().canEnqueueStep(getContext(), StepType.STEP_INTO)); } }); } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepOverCommand.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepOverCommand.java index 6967dedd3be..f4c2a28afa7 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepOverCommand.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepOverCommand.java @@ -44,7 +44,7 @@ public class DsfStepOverCommand implements IStepOverHandler { fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) { @Override public void doExecute() { - request.setEnabled(getStepQueueMgr().canEnqueueStep(getContext())); + request.setEnabled(getStepQueueMgr().canEnqueueStep(getContext(), StepType.STEP_OVER)); } }); } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepReturnCommand.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepReturnCommand.java index 295919ac191..d3d9dc2d16b 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepReturnCommand.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepReturnCommand.java @@ -44,7 +44,7 @@ public class DsfStepReturnCommand implements IStepReturnHandler { fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) { @Override public void doExecute() { - request.setEnabled(getStepQueueMgr().canEnqueueStep(getContext())); + request.setEnabled(getStepQueueMgr().canEnqueueStep(getContext(), StepType.STEP_RETURN)); } }); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java index a7f5b14bab8..b5b0d4a3421 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java @@ -128,8 +128,8 @@ public interface IRunControl extends IDMService void suspend(IExecutionDMContext context, RequestMonitor requestMonitor); public enum StepType { STEP_OVER, STEP_INTO, STEP_RETURN }; boolean isStepping(IExecutionDMContext context); - boolean canStep(IExecutionDMContext context); + boolean canStep(IExecutionDMContext context, StepType stepType); void step(IExecutionDMContext context, StepType stepType, RequestMonitor requestMonitor); - boolean canInstructionStep(IExecutionDMContext context); + boolean canInstructionStep(IExecutionDMContext context, StepType stepType); void instructionStep(IExecutionDMContext context, StepType stepType, RequestMonitor requestMonitor); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/StepQueueManager.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/StepQueueManager.java index e15bbcb5040..2fea35e74bd 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/StepQueueManager.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/StepQueueManager.java @@ -116,16 +116,16 @@ public class StepQueueManager extends AbstractDsfService /** * Checks whether a step command can be queued up for given context. */ - public boolean canEnqueueStep(IExecutionDMContext execCtx) { - return (fRunControl.isSuspended(execCtx) && fRunControl.canStep(execCtx)) || + public boolean canEnqueueStep(IExecutionDMContext execCtx, StepType stepType) { + return (fRunControl.isSuspended(execCtx) && fRunControl.canStep(execCtx, stepType)) || (fRunControl.isStepping(execCtx) && !isSteppingTimedOut(execCtx)); } /** * Checks whether an instruction step command can be queued up for given context. */ - public boolean canEnqueueInstructionStep(IExecutionDMContext execCtx) { - return (fRunControl.isSuspended(execCtx) && fRunControl.canInstructionStep(execCtx)) || + public boolean canEnqueueInstructionStep(IExecutionDMContext execCtx, StepType stepType) { + return (fRunControl.isSuspended(execCtx) && fRunControl.canInstructionStep(execCtx, stepType)) || (fRunControl.isStepping(execCtx) && !isSteppingTimedOut(execCtx)); } @@ -145,9 +145,9 @@ public class StepQueueManager extends AbstractDsfService * @param stepType Type of step to execute. */ public void enqueueStep(IExecutionDMContext execCtx, StepType stepType) { - if (fRunControl.canStep(execCtx)) { + if (fRunControl.canStep(execCtx, stepType)) { fRunControl.step(execCtx, stepType, new RequestMonitor(getExecutor(), null)); - } else if (canEnqueueStep(execCtx)) { + } else if (canEnqueueStep(execCtx, stepType)) { List stepQueue = fStepQueues.get(execCtx); if (stepQueue == null) { stepQueue = new LinkedList(); @@ -166,9 +166,9 @@ public class StepQueueManager extends AbstractDsfService * @param stepType Type of step to execute. */ public void enqueueInstructionStep(IExecutionDMContext execCtx, StepType stepType) { - if (fRunControl.canInstructionStep(execCtx)) { + if (fRunControl.canInstructionStep(execCtx, stepType)) { fRunControl.instructionStep(execCtx, stepType, new RequestMonitor(getExecutor(), null)); - } else if (canEnqueueInstructionStep(execCtx)) { + } else if (canEnqueueInstructionStep(execCtx, stepType)) { List stepQueue = fStepQueues.get(execCtx); if (stepQueue == null) { stepQueue = new LinkedList(); @@ -203,7 +203,7 @@ public class StepQueueManager extends AbstractDsfService StepRequest request = queue.remove(queue.size() - 1); if (queue.isEmpty()) fStepQueues.remove(e.getDMContext()); if (request.fIsInstructionStep) { - if (fRunControl.canInstructionStep(e.getDMContext())) { + if (fRunControl.canInstructionStep(e.getDMContext(), request.fStepType)) { fRunControl.instructionStep( e.getDMContext(), request.fStepType, new RequestMonitor(getExecutor(), null)); } else { @@ -212,7 +212,7 @@ public class StepQueueManager extends AbstractDsfService fStepQueues.remove(e.getDMContext()); } } else { - if (fRunControl.canStep(e.getDMContext())) { + if (fRunControl.canStep(e.getDMContext(), request.fStepType)) { fRunControl.step(e.getDMContext(), request.fStepType,new RequestMonitor(getExecutor(), null)); } else { // For whatever reason we can't step anymore, so clear out diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java index 6a0c0c59ed9..a9e70efc4d7 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java @@ -270,7 +270,7 @@ public class PDARunControl extends AbstractDsfService } } - public boolean canStep(IExecutionDMContext context) { + public boolean canStep(IExecutionDMContext context, StepType stepType) { return canResume(context); } @@ -299,7 +299,7 @@ public class PDARunControl extends AbstractDsfService } } - public boolean canInstructionStep(IExecutionDMContext context) { + public boolean canInstructionStep(IExecutionDMContext context, StepType stepType) { return false; } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java index 31481a48b4c..0294e4035cc 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java @@ -527,7 +527,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl } } - public boolean canStep(IExecutionDMContext context) { + public boolean canStep(IExecutionDMContext context, StepType stepType) { return canResume(context); } @@ -583,7 +583,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl } } - public boolean canInstructionStep(IExecutionDMContext context) { + public boolean canInstructionStep(IExecutionDMContext context, StepType stepType) { return false; } From 7018e1238bf0d134bc5800252f5ea099f2f793f1 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 27 Mar 2008 20:57:56 +0000 Subject: [PATCH 340/834] [224466] Renamed MISourceDisplayAdapter to SourceDisplayAdapter. --- ...ISourceDisplayAdapter.java => SourceDisplayAdapter.java} | 4 ++-- .../org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java | 6 +++--- .../org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/{MISourceDisplayAdapter.java => SourceDisplayAdapter.java} (99%) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/SourceDisplayAdapter.java similarity index 99% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/SourceDisplayAdapter.java index 1f0ce0e2762..6deabb6d97d 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/SourceDisplayAdapter.java @@ -81,7 +81,7 @@ import org.eclipse.ui.texteditor.ITextEditor; * dispatch thread to synchronize access to the state data of the running jobs. */ @ThreadSafe -public class MISourceDisplayAdapter implements ISourceDisplay +public class SourceDisplayAdapter implements ISourceDisplay { /** * A job to perform source lookup on the given DMC. @@ -398,7 +398,7 @@ public class MISourceDisplayAdapter implements ISourceDisplay private ClearingJob fRunningClearingJob; private List fPendingExecDmcsToClear = new LinkedList(); - public MISourceDisplayAdapter(DsfSession session, ISourceLookupDirector sourceLocator) { + public SourceDisplayAdapter(DsfSession session, ISourceLookupDirector sourceLocator) { fSession = session; fExecutor = session.getExecutor(); fServicesTracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), session.getId()); diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java index 5fba35f857a..b19ebafa7d2 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java @@ -22,7 +22,7 @@ import org.eclipse.dd.dsf.debug.ui.actions.DsfStepIntoCommand; import org.eclipse.dd.dsf.debug.ui.actions.DsfStepOverCommand; import org.eclipse.dd.dsf.debug.ui.actions.DsfStepReturnCommand; import org.eclipse.dd.dsf.debug.ui.actions.DsfSuspendCommand; -import org.eclipse.dd.dsf.debug.ui.sourcelookup.MISourceDisplayAdapter; +import org.eclipse.dd.dsf.debug.ui.sourcelookup.SourceDisplayAdapter; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.examples.pda.PDAPlugin; import org.eclipse.dd.examples.pda.launch.PDALaunch; @@ -68,7 +68,7 @@ public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2 final PDAVMAdapter fViewModelAdapter; // Source lookup and positioning adapter - final MISourceDisplayAdapter fSourceDisplayAdapter; + final SourceDisplayAdapter fSourceDisplayAdapter; // Command adapters final DsfStepIntoCommand fStepIntoCommand; @@ -91,7 +91,7 @@ public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2 fViewModelAdapter = new PDAVMAdapter(session); // Initialize source lookup - fSourceDisplayAdapter = new MISourceDisplayAdapter(session, (ISourceLookupDirector)launch.getSourceLocator()); + fSourceDisplayAdapter = new SourceDisplayAdapter(session, (ISourceLookupDirector)launch.getSourceLocator()); session.registerModelAdapter(ISourceDisplay.class, fSourceDisplayAdapter); // Initialize retargetable command handler. diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java index 1b8e185142d..a156c8d7fdd 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java @@ -23,7 +23,7 @@ import org.eclipse.dd.dsf.debug.ui.actions.DsfStepOverCommand; import org.eclipse.dd.dsf.debug.ui.actions.DsfStepReturnCommand; import org.eclipse.dd.dsf.debug.ui.actions.DsfSuspendCommand; import org.eclipse.dd.dsf.debug.ui.contexts.DsfSuspendTrigger; -import org.eclipse.dd.dsf.debug.ui.sourcelookup.MISourceDisplayAdapter; +import org.eclipse.dd.dsf.debug.ui.sourcelookup.SourceDisplayAdapter; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.gdb.internal.ui.actions.DsfTerminateCommand; import org.eclipse.dd.gdb.internal.ui.viewmodel.GdbViewModelAdapter; @@ -61,7 +61,7 @@ public class GdbAdapterFactory class SessionAdapterSet { final GdbLaunch fLaunch; final GdbViewModelAdapter fViewModelAdapter; - final MISourceDisplayAdapter fSourceDisplayAdapter; + final SourceDisplayAdapter fSourceDisplayAdapter; final DsfStepIntoCommand fStepIntoCommand; final DsfStepOverCommand fStepOverCommand; final DsfStepReturnCommand fStepReturnCommand; @@ -78,7 +78,7 @@ public class GdbAdapterFactory fViewModelAdapter = new GdbViewModelAdapter(session); if (launch.getSourceLocator() instanceof ISourceLookupDirector) { - fSourceDisplayAdapter = new MISourceDisplayAdapter(session, (ISourceLookupDirector)launch.getSourceLocator()); + fSourceDisplayAdapter = new SourceDisplayAdapter(session, (ISourceLookupDirector)launch.getSourceLocator()); } else { fSourceDisplayAdapter = null; } From 549cdbd6fd7ad0ddf8619cff4ee7c2fe868947a0 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 27 Mar 2008 21:06:06 +0000 Subject: [PATCH 341/834] [224466] Renamed SourceDisplayAdapter to DsfSourceDisplayAdapter, and DsfMISourceLookupParticipant to DsfSourceLookupParticipant. --- ...isplayAdapter.java => DsfSourceDisplayAdapter.java} | 10 +++++----- ...articipant.java => DsfSourceLookupParticipant.java} | 5 +++-- .../eclipse/dd/examples/pda/ui/PDAAdapterFactory.java | 6 +++--- .../eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java | 6 +++--- 4 files changed, 14 insertions(+), 13 deletions(-) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/{SourceDisplayAdapter.java => DsfSourceDisplayAdapter.java} (98%) rename plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/{DsfMISourceLookupParticipant.java => DsfSourceLookupParticipant.java} (97%) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/SourceDisplayAdapter.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/DsfSourceDisplayAdapter.java similarity index 98% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/SourceDisplayAdapter.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/DsfSourceDisplayAdapter.java index 6deabb6d97d..7e3e9e63e68 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/SourceDisplayAdapter.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/DsfSourceDisplayAdapter.java @@ -36,7 +36,7 @@ import org.eclipse.dd.dsf.debug.service.StepQueueManager; 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.sourcelookup.DsfMISourceLookupParticipant; +import org.eclipse.dd.dsf.debug.sourcelookup.DsfSourceLookupParticipant; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; @@ -81,7 +81,7 @@ import org.eclipse.ui.texteditor.ITextEditor; * dispatch thread to synchronize access to the state data of the running jobs. */ @ThreadSafe -public class SourceDisplayAdapter implements ISourceDisplay +public class DsfSourceDisplayAdapter implements ISourceDisplay { /** * A job to perform source lookup on the given DMC. @@ -389,7 +389,7 @@ public class SourceDisplayAdapter implements ISourceDisplay private IDMContext fPrevModelContext; private SourceLookupResult fPrevResult; private ISourceLookupDirector fSourceLookup; - private DsfMISourceLookupParticipant fSourceLookupParticipant; + private DsfSourceLookupParticipant fSourceLookupParticipant; private InstructionPointerManager fIPManager; private LookupJob fRunningLookupJob; @@ -398,12 +398,12 @@ public class SourceDisplayAdapter implements ISourceDisplay private ClearingJob fRunningClearingJob; private List fPendingExecDmcsToClear = new LinkedList(); - public SourceDisplayAdapter(DsfSession session, ISourceLookupDirector sourceLocator) { + public DsfSourceDisplayAdapter(DsfSession session, ISourceLookupDirector sourceLocator) { fSession = session; fExecutor = session.getExecutor(); fServicesTracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), session.getId()); fSourceLookup = sourceLocator; - fSourceLookupParticipant = new DsfMISourceLookupParticipant(session); + fSourceLookupParticipant = new DsfSourceLookupParticipant(session); fSourceLookup.addParticipants(new ISourceLookupParticipant[] {fSourceLookupParticipant} ); fIPManager = new InstructionPointerManager(); diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfSourceLookupParticipant.java similarity index 97% rename from plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java rename to plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfSourceLookupParticipant.java index 565ddfa6de3..9457beb423e 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfSourceLookupParticipant.java @@ -41,9 +41,10 @@ import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector; import org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant; /** + * Source lookup participant that should be used with DSF-based debuggers. */ @ThreadSafe -public class DsfMISourceLookupParticipant implements ISourceLookupParticipant { +public class DsfSourceLookupParticipant implements ISourceLookupParticipant { protected static final Object[] EMPTY = new Object[0]; private DsfExecutor fExecutor; @@ -52,7 +53,7 @@ public class DsfMISourceLookupParticipant implements ISourceLookupParticipant { private ISourceLookupDirector fDirector; private Map> fLookupCache = Collections.synchronizedMap(new HashMap>()); - public DsfMISourceLookupParticipant(DsfSession session) { + public DsfSourceLookupParticipant(DsfSession session) { fSessionId = session.getId(); fExecutor = session.getExecutor(); fServicesTracker = new DsfServicesTracker(DsfDebugPlugin.getBundleContext(), fSessionId); diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java index b19ebafa7d2..adfc577442e 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java @@ -22,7 +22,7 @@ import org.eclipse.dd.dsf.debug.ui.actions.DsfStepIntoCommand; import org.eclipse.dd.dsf.debug.ui.actions.DsfStepOverCommand; import org.eclipse.dd.dsf.debug.ui.actions.DsfStepReturnCommand; import org.eclipse.dd.dsf.debug.ui.actions.DsfSuspendCommand; -import org.eclipse.dd.dsf.debug.ui.sourcelookup.SourceDisplayAdapter; +import org.eclipse.dd.dsf.debug.ui.sourcelookup.DsfSourceDisplayAdapter; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.examples.pda.PDAPlugin; import org.eclipse.dd.examples.pda.launch.PDALaunch; @@ -68,7 +68,7 @@ public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2 final PDAVMAdapter fViewModelAdapter; // Source lookup and positioning adapter - final SourceDisplayAdapter fSourceDisplayAdapter; + final DsfSourceDisplayAdapter fSourceDisplayAdapter; // Command adapters final DsfStepIntoCommand fStepIntoCommand; @@ -91,7 +91,7 @@ public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2 fViewModelAdapter = new PDAVMAdapter(session); // Initialize source lookup - fSourceDisplayAdapter = new SourceDisplayAdapter(session, (ISourceLookupDirector)launch.getSourceLocator()); + fSourceDisplayAdapter = new DsfSourceDisplayAdapter(session, (ISourceLookupDirector)launch.getSourceLocator()); session.registerModelAdapter(ISourceDisplay.class, fSourceDisplayAdapter); // Initialize retargetable command handler. diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java index a156c8d7fdd..5bc506c8f50 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java @@ -23,7 +23,7 @@ import org.eclipse.dd.dsf.debug.ui.actions.DsfStepOverCommand; import org.eclipse.dd.dsf.debug.ui.actions.DsfStepReturnCommand; import org.eclipse.dd.dsf.debug.ui.actions.DsfSuspendCommand; import org.eclipse.dd.dsf.debug.ui.contexts.DsfSuspendTrigger; -import org.eclipse.dd.dsf.debug.ui.sourcelookup.SourceDisplayAdapter; +import org.eclipse.dd.dsf.debug.ui.sourcelookup.DsfSourceDisplayAdapter; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.gdb.internal.ui.actions.DsfTerminateCommand; import org.eclipse.dd.gdb.internal.ui.viewmodel.GdbViewModelAdapter; @@ -61,7 +61,7 @@ public class GdbAdapterFactory class SessionAdapterSet { final GdbLaunch fLaunch; final GdbViewModelAdapter fViewModelAdapter; - final SourceDisplayAdapter fSourceDisplayAdapter; + final DsfSourceDisplayAdapter fSourceDisplayAdapter; final DsfStepIntoCommand fStepIntoCommand; final DsfStepOverCommand fStepOverCommand; final DsfStepReturnCommand fStepReturnCommand; @@ -78,7 +78,7 @@ public class GdbAdapterFactory fViewModelAdapter = new GdbViewModelAdapter(session); if (launch.getSourceLocator() instanceof ISourceLookupDirector) { - fSourceDisplayAdapter = new SourceDisplayAdapter(session, (ISourceLookupDirector)launch.getSourceLocator()); + fSourceDisplayAdapter = new DsfSourceDisplayAdapter(session, (ISourceLookupDirector)launch.getSourceLocator()); } else { fSourceDisplayAdapter = null; } From 4f71f37d159d3b29c54ecccdcff4022cfbc1ca9e Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 27 Mar 2008 21:20:10 +0000 Subject: [PATCH 342/834] [159046] Got rid of IStack.isStackAvailable(). --- .../debug/ui/viewmodel/launch/StackFramesVMNode.java | 11 +++++------ .../src/org/eclipse/dd/dsf/debug/service/IStack.java | 5 ----- .../src/org/eclipse/dd/mi/service/MIStack.java | 6 ------ 3 files changed, 5 insertions(+), 17 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java index 1ec4d733a52..6ed33d7797a 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java @@ -58,15 +58,14 @@ public class StackFramesVMNode extends AbstractDMVMNode @Override protected void updateHasElementsInSessionThread(IHasChildrenUpdate update) { - if (!checkService(IStack.class, null, update)) return; - - IExecutionDMContext execDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IExecutionDMContext.class); - if (execDmc == null) { + IRunControl runControl = getServicesTracker().getService(IRunControl.class); + IExecutionDMContext execCtx = findDmcInPath(update.getViewerInput(), update.getElementPath(), IExecutionDMContext.class); + if (runControl == null || execCtx == null) { handleFailedUpdate(update); return; - } + } - update.setHasChilren(getServicesTracker().getService(IStack.class).isStackAvailable(execDmc)); + update.setHasChilren(runControl.isSuspended(execCtx) || runControl.isStepping(execCtx)); update.done(); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java index 24a8e5c39ee..710a3d132b5 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStack.java @@ -71,11 +71,6 @@ public interface IStack extends IDMService { */ public void getVariableData(IVariableDMContext variableDmc, DataRequestMonitor rm); - /** - * Returns whether the stack frames can be retrieved for given thread. - */ - boolean isStackAvailable(IDMContext execContext); - /** * Retrieves list of stack frames for the given execution context. Request * will fail if the stack frame data is not available. diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIStack.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIStack.java index c268e272d8d..42c796cf41d 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIStack.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIStack.java @@ -185,12 +185,6 @@ public class MIStack extends AbstractDsfService return new MIFrameDMC(getSession().getId(), execDmc, level); } - - public boolean isStackAvailable(IDMContext context) { - IExecutionDMContext execCtx = DMContexts.getAncestorOfType(context, IExecutionDMContext.class); - return execCtx != null && (fRunControl.isSuspended(execCtx) || (fRunControl.isStepping(execCtx))); - } - public void getFrames(final IDMContext ctx, final DataRequestMonitor rm) { final IMIExecutionDMContext execDmc = DMContexts.getAncestorOfType(ctx, IMIExecutionDMContext.class); From 506cc50df7c25aaddf2ccc4ae53404f80e4ac3e9 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 27 Mar 2008 21:33:59 +0000 Subject: [PATCH 343/834] [223969] Fixed a thread-handling problem introduced by fix. --- .../src/org/eclipse/dd/mi/service/MIRunControl.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java index 0294e4035cc..5316ebcc231 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java @@ -407,7 +407,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl @DsfServiceEventHandler public void eventDispatched(ContainerSuspendedEvent e) { fMICommandCache.setContextAvailable(e.getDMContext(), true); - fMICommandCache.reset(e.getDMContext()); + fMICommandCache.reset(); fStateChangeReason = e.getReason(); fStateChangeTriggeringContext = e.getTriggeringContext(); fSuspended = true; @@ -431,7 +431,6 @@ public class MIRunControl extends AbstractDsfService implements IRunControl @DsfServiceEventHandler public void eventDispatched(ExitedDMEvent e) { fMICommandCache.reset(e.getExecutionContext()); - } /////////////////////////////////////////////////////////////////////////// From c50257d07df16e3c4ff0f97e969775a6c6a97fb9 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 27 Mar 2008 22:09:11 +0000 Subject: [PATCH 344/834] [224434] Changed the context used in IRunControl.IStartedDMEvent and IRunControl.IExitedDMEvent events. --- .../sourcelookup/DsfSourceDisplayAdapter.java | 10 ++--- .../dd/dsf/debug/service/IRunControl.java | 14 ++----- .../ui/viewmodel/launch/ContainerVMNode.java | 9 +++- .../eclipse/dd/mi/service/MIRunControl.java | 41 ++++++------------- .../dd/tests/gdb/MIRunControlTest.java | 2 +- 5 files changed, 30 insertions(+), 46 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/DsfSourceDisplayAdapter.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/DsfSourceDisplayAdapter.java index 7e3e9e63e68..d8e66e186ad 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/DsfSourceDisplayAdapter.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/DsfSourceDisplayAdapter.java @@ -502,10 +502,10 @@ public class DsfSourceDisplayAdapter implements ISourceDisplay } private void startAnnotationClearingJob(IRunControl.IExecutionDMContext execDmc) { - // Make sure to add the dmc to the list. + // Make sure to add the context to the list. fPendingExecDmcsToClear.add(execDmc); - // If lookup job is running, check it agains the exec context, + // If lookup job is running, check it against the execution context, // and cancel it if matches. if (fRunningLookupJob != null) { if (DMContexts.isAncestorOf(fRunningLookupJob.getDmc(), execDmc)) { @@ -513,8 +513,8 @@ public class DsfSourceDisplayAdapter implements ISourceDisplay fRunningLookupJob = null; } } - // If there is a pending displahy job, make sure it doesn't get - // pre-empted by this event. If so, just cancel the pending + // If there is a pending display job, make sure it doesn't get + // preempted by this event. If so, just cancel the pending // display job. if (fPendingDisplayJob != null) { if (DMContexts.isAncestorOf(fPendingDisplayJob.getDmc(), execDmc)) { @@ -539,7 +539,7 @@ public class DsfSourceDisplayAdapter implements ISourceDisplay @DsfServiceEventHandler public void eventDispatched(IRunControl.IExitedDMEvent e) { - startAnnotationClearingJob(e.getExecutionContext()); + startAnnotationClearingJob(e.getDMContext()); } @DsfServiceEventHandler diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java index b5b0d4a3421..3bbc4242275 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java @@ -83,20 +83,14 @@ public interface IRunControl extends IDMService } /** - * Indicates that a new execution context (thread) was started. The DMC - * for the event is the container of the new exec context. + * Indicates that a new execution context (thread) was started. */ - public interface IStartedDMEvent extends IDMEvent { - IExecutionDMContext getExecutionContext(); - } + public interface IStartedDMEvent extends IDMEvent {} /** - * Indicates that an execution context has exited. As in the started event, - * the DMC for the event is the container of the exec context. + * Indicates that an execution context has exited. */ - public interface IExitedDMEvent extends IDMEvent { - IExecutionDMContext getExecutionContext(); - } + public interface IExitedDMEvent extends IDMEvent {} /** * Display information for an execution context. diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ContainerVMNode.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ContainerVMNode.java index f0f3542e170..7e970636371 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ContainerVMNode.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ContainerVMNode.java @@ -17,8 +17,10 @@ import java.util.concurrent.RejectedExecutionException; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMEvent; import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; import org.eclipse.dd.dsf.debug.service.IRunControl.IExitedDMEvent; import org.eclipse.dd.dsf.debug.service.IRunControl.IStartedDMEvent; import org.eclipse.dd.dsf.service.DsfSession; @@ -124,13 +126,16 @@ public class ContainerVMNode extends AbstractDMVMNode } public void buildDelta(Object e, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) { - if(e instanceof IRunControl.IContainerResumedDMEvent || e instanceof IRunControl.IContainerSuspendedDMEvent) { parentDelta.addNode(createVMContext(((IDMEvent)e).getDMContext()), IModelDelta.CONTENT); } else if (e instanceof IStartedDMEvent || e instanceof IExitedDMEvent) { - parentDelta.addNode(createVMContext(((IDMEvent)e).getDMContext()), IModelDelta.CONTENT); + IContainerDMContext containerCtx = DMContexts.getAncestorOfType( + ((IDMEvent)e).getDMContext(), IContainerDMContext.class); + if (containerCtx != null) { + parentDelta.addNode(createVMContext(containerCtx), IModelDelta.CONTENT); + } } else if (e instanceof GDBControl.ExitedEvent || e instanceof MIInferiorExitEvent || e instanceof MIInferiorSignalExitEvent) diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java index 5316ebcc231..c0879ffed74 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java @@ -236,35 +236,20 @@ public class MIRunControl extends AbstractDsfService implements IRunControl } @Immutable - protected static class StartedDMEvent extends RunControlEvent - implements IStartedDMEvent{ - - private final IMIExecutionDMContext fExecutionDmc; - - StartedDMEvent(IContainerDMContext containerDmc, IMIExecutionDMContext executionDmc, MIThreadCreatedEvent miInfo) { - super(containerDmc, miInfo); - fExecutionDmc = executionDmc; + protected static class StartedDMEvent extends RunControlEvent + implements IStartedDMEvent + { + StartedDMEvent(IMIExecutionDMContext executionDmc, MIThreadCreatedEvent miInfo) { + super(executionDmc, miInfo); } - - public IExecutionDMContext getExecutionContext(){ - return fExecutionDmc; - } - } @Immutable - protected static class ExitedDMEvent extends RunControlEvent - implements IExitedDMEvent{ - - private final IMIExecutionDMContext fExecutionDmc; - - ExitedDMEvent(IContainerDMContext containerDmc, IMIExecutionDMContext executionDmc, MIThreadExitEvent miInfo) { - super(containerDmc, miInfo); - fExecutionDmc = executionDmc; - } - - public IExecutionDMContext getExecutionContext(){ - return fExecutionDmc; + protected static class ExitedDMEvent extends RunControlEvent + implements IExitedDMEvent + { + ExitedDMEvent(IMIExecutionDMContext executionDmc, MIThreadExitEvent miInfo) { + super(executionDmc, miInfo); } } @@ -375,7 +360,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl public void eventDispatched(final MIThreadCreatedEvent e) { IContainerDMContext containerDmc = e.getDMContext(); IMIExecutionDMContext executionCtx = e.getId() != -1 ? new MIExecutionDMC(getSession().getId(), containerDmc, e.getId()) : null; - getSession().dispatchEvent(new StartedDMEvent(containerDmc, executionCtx, e), getProperties()); + getSession().dispatchEvent(new StartedDMEvent(executionCtx, e), getProperties()); } // @@ -386,7 +371,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl public void eventDispatched(final MIThreadExitEvent e) { IContainerDMContext containerDmc = e.getDMContext(); IMIExecutionDMContext executionCtx = e.getId() != -1 ? new MIExecutionDMC(getSession().getId(), containerDmc, e.getId()) : null; - getSession().dispatchEvent(new ExitedDMEvent(containerDmc, executionCtx, e), getProperties()); + getSession().dispatchEvent(new ExitedDMEvent(executionCtx, e), getProperties()); } @DsfServiceEventHandler @@ -430,7 +415,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl // Event handler when a thread is destroyed @DsfServiceEventHandler public void eventDispatched(ExitedDMEvent e) { - fMICommandCache.reset(e.getExecutionContext()); + fMICommandCache.reset(e.getDMContext()); } /////////////////////////////////////////////////////////////////////////// diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRunControlTest.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRunControlTest.java index 92df99a53bd..e42ae5da1f9 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRunControlTest.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRunControlTest.java @@ -438,7 +438,7 @@ public class MIRunControlTest extends BaseTestCase { @DsfServiceEventHandler public void eventDispatched(IStartedDMEvent e) { if(fIsTestingThreadCreateEvent){ - if(((IMIExecutionDMContext)e.getExecutionContext()).getThreadId() != 2) + if(((IMIExecutionDMContext)e.getDMContext()).getThreadId() != 2) /* * Set variable if thread create event is unsuccesful */ From d571b6e48a360fc3110e0acd55a3072419272f02 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Fri, 28 Mar 2008 15:18:45 +0000 Subject: [PATCH 345/834] Fix for the JUnit test due to Bug 223969. The JUnit launch now re-uses (without any changes) the standard DSF launch sequence. The problem then became that the tests would start too fast, before the suspend event was received. To address this, I added a wait for the Suspend event in the BaseTestCase.baseBeforeMethod() which runs before every test. --- .../dd/tests/gdb/framework/BaseTestCase.java | 11 + .../tests/gdb/launching/LaunchSequence.java | 267 ------------------ .../tests/gdb/launching/ShutdownSequence.java | 108 ------- .../gdb/launching/TestLaunchDelegate.java | 28 +- 4 files changed, 33 insertions(+), 381 deletions(-) delete mode 100644 plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/LaunchSequence.java delete mode 100644 plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/ShutdownSequence.java diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java index 7e86c586dec..9bb59f00fbb 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java @@ -16,6 +16,7 @@ import java.util.Map; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.dd.gdb.launching.GdbLaunch; +import org.eclipse.dd.mi.service.command.events.MIStoppedEvent; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationType; @@ -81,6 +82,16 @@ public class BaseTestCase { // Now initialize our SyncUtility, since we have the launcher SyncUtil.initialize(fLaunch.getSession()); + + try { + // Also wait for the program to stop before allowing tests to start + final ServiceEventWaitor eventWaitor = + new ServiceEventWaitor( + fLaunch.getSession(), + MIStoppedEvent.class); + eventWaitor.waitForEvent(10000); + } catch (Exception e) {} + } @After diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/LaunchSequence.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/LaunchSequence.java deleted file mode 100644 index ba0357795b6..00000000000 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/LaunchSequence.java +++ /dev/null @@ -1,267 +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.tests.gdb.launching; - -import java.util.concurrent.TimeUnit; - -import org.eclipse.cdt.debug.core.CDebugCorePlugin; -import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; -import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector; -import org.eclipse.cdt.debug.mi.core.IMILaunchConfigurationConstants; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.concurrent.Sequence; -import org.eclipse.dd.dsf.debug.service.StepQueueManager; -import org.eclipse.dd.dsf.service.DsfServiceEventHandler; -import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.gdb.launching.GdbLaunch; -import org.eclipse.dd.gdb.service.GDBRunControl; -import org.eclipse.dd.gdb.service.command.GDBControl; -import org.eclipse.dd.mi.service.CSourceLookup; -import org.eclipse.dd.mi.service.ExpressionService; -import org.eclipse.dd.mi.service.MIBreakpoints; -import org.eclipse.dd.mi.service.MIBreakpointsManager; -import org.eclipse.dd.mi.service.MIDisassembly; -import org.eclipse.dd.mi.service.MIMemory; -import org.eclipse.dd.mi.service.MIRegisters; -import org.eclipse.dd.mi.service.MIStack; -import org.eclipse.dd.mi.service.command.commands.MIBreakInsert; -import org.eclipse.dd.mi.service.command.commands.MIExecRun; -import org.eclipse.dd.mi.service.command.events.MIStoppedEvent; -import org.eclipse.dd.mi.service.command.output.MIBreakInsertInfo; -import org.eclipse.dd.mi.service.command.output.MIInfo; -import org.eclipse.debug.core.DebugException; - -public class LaunchSequence extends Sequence { - - public class EntryPointHitEventListener { - boolean fAborted = false; - boolean fFinished = false; - final RequestMonitor fRequestMonitor; - - EntryPointHitEventListener(RequestMonitor requestMonitor) { - fRequestMonitor = requestMonitor; - } - - @DsfServiceEventHandler - public void eventDispatched(@SuppressWarnings("unused") - MIStoppedEvent e) { - fFinished = true; - if (!fAborted) { - fSession.removeServiceEventListener(this); - fRequestMonitor.done(); - } - } - } - - - Step[] fSteps = new Step[] { - // Create and initialize the Connection service. - new Step() { - @Override - public void execute(RequestMonitor requestMonitor) { - // - // Create the connection. - // - fCommandControl = new GDBControl( - fSession, getGDBPath(), fExecPath, GDBControl.SessionType.RUN, 30); - fCommandControl.initialize(requestMonitor); - } - }, - /* - * If needed, insert breakpoint at main and run to it. - */ - new Step() { - private boolean fStopInMain = false; - private String fStopSymbol = null; - - /** - * @return The return value actually indicates whether the get operation succeeded, - * not whether to stop. - */ - private boolean readStopAtMain(RequestMonitor requestMonitor) { - try { - fStopInMain = fLaunch.getLaunchConfiguration().getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN, false ); - } catch (CoreException e) { - requestMonitor.setStatus(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, -1, "Cannot retrieve the entry point symbol", e)); //$NON-NLS-1$ - requestMonitor.done(); - return false; - } - return true; - } - - private boolean readStopSymbol(RequestMonitor requestMonitor) { - try { - fStopSymbol = fLaunch.getLaunchConfiguration().getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN_SYMBOL, ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_SYMBOL_DEFAULT ); - } catch (CoreException e) { - requestMonitor.setStatus(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, DebugException.CONFIGURATION_INVALID, "Cannot retrieve the entry point symbol", e)); //$NON-NLS-1$ - requestMonitor.done(); - return false; - } - return true; - } - - @Override - public void execute(final RequestMonitor requestMonitor) { - if (!readStopAtMain(requestMonitor)) return; - if (!fStopInMain) { - requestMonitor.done(); - return; - } - - if (!readStopSymbol(requestMonitor)) return; - - // Create a listener to wait for the stopped event, and register as even handler. - // This handler will execute the requestMonitor. - final EntryPointHitEventListener entryPointHitListener = new EntryPointHitEventListener(requestMonitor); - fSession.addServiceEventListener(entryPointHitListener, null); - - // Create a time-out, to abort if breakpoint not hit. - fSession.getExecutor().schedule( - new Runnable() { public void run() { - // Only process the event if we have not finished yet (hit the breakpoint). - if (!entryPointHitListener.fFinished) { - // Mark the listener as aborted, and unregister it as event listener. - entryPointHitListener.fAborted = true; - fSession.removeServiceEventListener(entryPointHitListener); - - // Submit the error result for the step. - requestMonitor.setStatus(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, DebugException.TARGET_REQUEST_FAILED, "Timed out running to entry point.", null)); //$NON-NLS-1$ - requestMonitor.done(); - } - }}, - 60, TimeUnit.SECONDS); - - // Insert a breakpoint at the requested stop symbol. - fCommandControl.queueCommand( - new MIBreakInsert(fCommandControl.getGDBDMContext(), true, false, null, 0, fStopSymbol, 0), - new DataRequestMonitor(getExecutor(), requestMonitor) { - @Override - protected void handleSuccess() { - - // After the break-insert is done, execute the -exec-run command. - fCommandControl.queueCommand( - new MIExecRun(fCommandControl.getGDBDMContext(), new String[0]), - new DataRequestMonitor(getExecutor(), requestMonitor) { - @Override - protected void handleSuccess() { - // Note : Do we not need to do something with the original requestMonitor? - // Do nothing. Execution was resumed and the EntryPointHitEventListener - // will resume execution - } - } - ); - } - }); - } - }, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - new GDBRunControl(fSession).initialize(requestMonitor); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - new StepQueueManager(fSession).initialize(requestMonitor); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - new MIMemory(fSession).initialize(requestMonitor); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - new MIStack(fSession).initialize(requestMonitor); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - new ExpressionService(fSession).initialize(requestMonitor); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - fSourceLookup = new CSourceLookup(fSession); - fSourceLookup.initialize(requestMonitor); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - fSourceLookup.setSourceLookupDirector( - fCommandControl.getGDBDMContext(), - ((CSourceLookupDirector)fLaunch.getSourceLocator())); - requestMonitor.done(); - }}, - new Step() { @Override - public void execute(final RequestMonitor requestMonitor) { - // Create the low-level breakpoint service - final MIBreakpoints bpService = new MIBreakpoints(fSession); - bpService.initialize(new RequestMonitor(getExecutor(), requestMonitor) { - @Override - protected void handleSuccess() { - requestMonitor.done(); - } - }); - }}, - new Step() { @Override - public void execute(final RequestMonitor requestMonitor) { - // Create high-level breakpoint service and install breakpoints - // for the GDB debug context. - final MIBreakpointsManager bpmService = new MIBreakpointsManager(fSession, CDebugCorePlugin.PLUGIN_ID); - bpmService.initialize(new RequestMonitor(getExecutor(), requestMonitor) { - @Override - protected void handleSuccess() { - bpmService.startTrackingBreakpoints(fCommandControl.getGDBDMContext(), requestMonitor); - } - }); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - new MIRegisters(fSession).initialize(requestMonitor); - }}, - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - new MIDisassembly(fSession).initialize(requestMonitor); - }}, - /*new Step() { public void execute(RequestMonitor requestMonitor) { - new GDBVariables(fSession).initialize(requestMonitor); - }},*/ - }; - - final DsfSession fSession; - final GdbLaunch fLaunch; - final IPath fExecPath; - - GDBControl fCommandControl; - CSourceLookup fSourceLookup; - - public LaunchSequence(DsfSession session, GdbLaunch launch, IPath execPath) { - super(session.getExecutor()); - fSession = session; - fLaunch = launch; - fExecPath = execPath; - } - - @Override - public Step[] getSteps() { - return fSteps; - } - - private IPath getGDBPath() { - IPath retVal = new Path("gdb.exe"); //$NON-NLS-1$ - try { - retVal = new Path( fLaunch.getLaunchConfiguration().getAttribute( IMILaunchConfigurationConstants.ATTR_DEBUG_NAME, IMILaunchConfigurationConstants.DEBUGGER_DEBUG_NAME_DEFAULT ) ); - } catch (CoreException e) { - } - return retVal; - } - -} diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/ShutdownSequence.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/ShutdownSequence.java deleted file mode 100644 index 14357c73502..00000000000 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/ShutdownSequence.java +++ /dev/null @@ -1,108 +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.tests.gdb.launching; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.concurrent.DsfExecutor; -import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.concurrent.Sequence; -import org.eclipse.dd.dsf.service.DsfServicesTracker; -import org.eclipse.dd.dsf.service.IDsfService; -import org.eclipse.dd.gdb.service.GDBRunControl; -import org.eclipse.dd.gdb.service.command.GDBControl; -import org.eclipse.dd.mi.service.CSourceLookup; -import org.eclipse.dd.mi.service.ExpressionService; -import org.eclipse.dd.mi.service.MIBreakpoints; -import org.eclipse.dd.mi.service.MIBreakpointsManager; -import org.eclipse.dd.mi.service.MIDisassembly; -import org.eclipse.dd.mi.service.MIMemory; -import org.eclipse.dd.mi.service.MIRegisters; -import org.eclipse.dd.mi.service.MIStack; - - -public class ShutdownSequence extends Sequence { - - String fSessionId; - String fApplicationName; - String fDebugModelId; - DsfServicesTracker fTracker; - - - public ShutdownSequence(DsfExecutor executor, String sessionId, RequestMonitor requestMonitor) { - super(executor, requestMonitor); - fSessionId = sessionId; - } - - @Override - public Step[] getSteps() { return fSteps; } - - private final Step[] fSteps = new Step[] { - new Step() { - @Override - public void execute(RequestMonitor requestMonitor) { - fTracker = new DsfServicesTracker(TestsPlugin.getBundleContext(), fSessionId); - requestMonitor.done(); - } - - @Override - public void rollBack(RequestMonitor requestMonitor) { - fTracker.dispose(); - fTracker = null; - requestMonitor.done(); - } - }, - new Step() { @Override public void execute(RequestMonitor requestMonitor) { shutdownService(MIDisassembly.class, requestMonitor); }}, - new Step() { @Override public void execute(RequestMonitor requestMonitor) { shutdownService(MIRegisters.class, requestMonitor); }}, - new Step() { - // Uninstall the breakpoints before the service is shut down. - @Override - public void execute(RequestMonitor requestMonitor) { - MIBreakpointsManager bpm = fTracker.getService(MIBreakpointsManager.class); - GDBControl commandControl = fTracker.getService(GDBControl.class); - if (bpm != null && commandControl != null) { - bpm.stopTrackingBreakpoints(commandControl.getGDBDMContext(), requestMonitor); - } else { - requestMonitor.setStatus(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, - "Needed services not found.", null)); //$NON-NLS-1$ - requestMonitor.done(); - } - } - }, - new Step() { @Override public void execute(RequestMonitor requestMonitor) { shutdownService(MIBreakpointsManager.class, requestMonitor); }}, - new Step() { @Override public void execute(RequestMonitor requestMonitor) { shutdownService(MIBreakpoints.class, requestMonitor); }}, - new Step() { @Override public void execute(RequestMonitor requestMonitor) { shutdownService(CSourceLookup.class, requestMonitor); }}, - new Step() { @Override public void execute(RequestMonitor requestMonitor) { shutdownService(ExpressionService.class, requestMonitor); }}, - new Step() { @Override public void execute(RequestMonitor requestMonitor) { shutdownService(MIStack.class, requestMonitor); }}, - new Step() { @Override public void execute(RequestMonitor requestMonitor) { shutdownService(MIMemory.class, requestMonitor); }}, - new Step() { @Override public void execute(RequestMonitor requestMonitor) { shutdownService(GDBRunControl.class, requestMonitor); }}, - new Step() { @Override public void execute(RequestMonitor requestMonitor) { shutdownService(GDBControl.class, requestMonitor); }}, - new Step() { @Override public void execute(RequestMonitor requestMonitor) { - fTracker.dispose(); - fTracker = null; - requestMonitor.done(); - }} - }; - - @SuppressWarnings("unchecked") - private void shutdownService(Class clazz, RequestMonitor requestMonitor) { - IDsfService service = fTracker.getService(clazz); - if (service != null) { - service.shutdown(requestMonitor); - } - else { - requestMonitor.setStatus(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, - "Service '" + clazz.getName() + "' not found.", null)); //$NON-NLS-1$//$NON-NLS-2$ - requestMonitor.done(); - } - } -} diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java index 114ee8324c7..aca586a6e29 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java @@ -34,9 +34,13 @@ import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.debug.model.DsfMemoryBlockRetrieval; +import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryDMContext; import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.gdb.launching.FinalLaunchSequence; import org.eclipse.dd.gdb.launching.GdbLaunch; +import org.eclipse.dd.gdb.launching.ServicesLaunchSequence; import org.eclipse.dd.gdb.service.command.GDBControl; +import org.eclipse.dd.gdb.service.command.GDBControl.SessionType; import org.eclipse.dd.mi.service.command.AbstractCLIProcess; import org.eclipse.dd.mi.service.command.MIInferiorProcess; import org.eclipse.debug.core.DebugException; @@ -104,15 +108,16 @@ public class TestLaunchDelegate extends AbstractCLaunchDelegate monitor.worked( 1 ); // Create and invoke the launch sequence to create the debug control and services - final LaunchSequence launchSequence = - new LaunchSequence(launch.getSession(), launch, exePath); - launch.getSession().getExecutor().execute(launchSequence); + // Create and invoke the launch sequence to create the debug control and services + final ServicesLaunchSequence servicesLaunchSequence = + new ServicesLaunchSequence(launch.getSession(), launch, exePath); + launch.getSession().getExecutor().execute(servicesLaunchSequence); try { - launchSequence.get(); + servicesLaunchSequence.get(); } catch (InterruptedException e1) { throw new DebugException(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, "Interrupted Exception in dispatch thread", e1)); //$NON-NLS-1$ } catch (ExecutionException e1) { - throw new DebugException(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Error in launch sequence", e1.getCause())); //$NON-NLS-1$ + throw new DebugException(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Error in services launch sequence", e1.getCause())); //$NON-NLS-1$ } launch.initializeControl(); @@ -143,6 +148,17 @@ public class TestLaunchDelegate extends AbstractCLaunchDelegate throw new CoreException(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, 0, "Debugger shut down before launch was completed.", e)); //$NON-NLS-1$ } + // Create and invoke the final launch sequence to setup GDB + final FinalLaunchSequence finalLaunchSequence = + new FinalLaunchSequence(launch.getSession().getExecutor(), launch, SessionType.RUN); + launch.getSession().getExecutor().execute(finalLaunchSequence); + try { + finalLaunchSequence.get(); + } catch (InterruptedException e1) { + throw new DebugException(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, "Interrupted Exception in dispatch thread", e1)); //$NON-NLS-1$ + } catch (ExecutionException e1) { + throw new DebugException(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Error in final launch sequence", e1.getCause())); //$NON-NLS-1$ + } // Create a memory retrieval and register it with session try { launch.getDsfExecutor().submit( new Callable() { @@ -151,7 +167,7 @@ public class TestLaunchDelegate extends AbstractCLaunchDelegate GDBControl gdbControl = tracker.getService(GDBControl.class); if (gdbControl != null) { IMemoryBlockRetrieval memRetrieval = new DsfMemoryBlockRetrieval( - GDB_DEBUG_MODEL_ID, config, gdbControl.getGDBDMContext()); + GDB_DEBUG_MODEL_ID, config, (IMemoryDMContext)gdbControl.getControlDMContext()); launch.getSession().registerModelAdapter(IMemoryBlockRetrieval.class, memRetrieval); ((DsfMemoryBlockRetrieval) memRetrieval).initialize(); } From 7b062fd9571446f61b5d77b2f3bb8444dc428df1 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Fri, 28 Mar 2008 15:42:24 +0000 Subject: [PATCH 346/834] Bug 224485 Moved the packages org.eclipse.dd.gdb.* to org.eclipse.dd.gdb.internal.provisional.* since it's expected that these classes are likely to need substantial changes in not too distant future. --- plugins/org.eclipse.dd.gdb.launch/plugin.xml | 4 ++-- plugins/org.eclipse.dd.gdb.ui/plugin.xml | 2 +- .../eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java | 4 ++-- .../gdb/internal/ui/actions/DsfTerminateCommand.java | 2 +- .../ui/breakpoints/CBreakpointGdbThreadFilterPage.java | 4 ++-- .../internal/ui/breakpoints/GdbThreadFilterEditor.java | 10 +++++----- .../dd/gdb/internal/ui/launching/CDebuggerTab.java | 4 ++-- .../GdbLocalRunLaunchConfigurationTabGroup.java | 2 +- .../GdbRemoteRunLaunchConfigurationTabGroup.java | 2 +- .../internal/ui/viewmodel/launch/ContainerVMNode.java | 10 +++++----- .../gdb/internal/ui/viewmodel/launch/ThreadVMNode.java | 4 ++-- plugins/org.eclipse.dd.gdb/META-INF/MANIFEST.MF | 10 +++++----- plugins/org.eclipse.dd.gdb/plugin.xml | 2 +- .../src/org/eclipse/dd/gdb/internal/GdbPlugin.java | 2 +- .../provisional}/IGDBLaunchConfigurationConstants.java | 2 +- .../CBreakpointGdbThreadsFilterExtension.java | 2 +- .../provisional}/launching/FinalLaunchSequence.java | 6 +++--- .../provisional}/launching/GdbLaunch.java | 4 ++-- .../provisional}/launching/GdbLaunchDelegate.java | 8 ++++---- .../provisional}/launching/ServicesLaunchSequence.java | 10 +++++----- .../provisional}/launching/ShutdownSequence.java | 6 +++--- .../provisional}/service/GDBRunControl.java | 6 +++--- .../provisional}/service/command/GDBCLIProcess.java | 2 +- .../provisional}/service/command/GDBControl.java | 2 +- .../service/command/GDBControlDMContext.java | 2 +- .../service/command/GDBInferiorProcess.java | 4 ++-- .../eclipse/dd/tests/gdb/ExpressionServiceTest.java | 2 +- .../src/org/eclipse/dd/tests/gdb/GDBProcessesTest.java | 8 ++++---- .../org/eclipse/dd/tests/gdb/MIBreakpointsTest.java | 4 ++-- .../org/eclipse/dd/tests/gdb/MIDisassemblyTest.java | 4 ++-- .../src/org/eclipse/dd/tests/gdb/MIMemoryTest.java | 4 ++-- .../src/org/eclipse/dd/tests/gdb/MIRegistersTest.java | 4 ++-- .../src/org/eclipse/dd/tests/gdb/MIRunControlTest.java | 4 ++-- .../eclipse/dd/tests/gdb/framework/BaseTestCase.java | 2 +- .../org/eclipse/dd/tests/gdb/framework/SyncUtil.java | 2 +- .../dd/tests/gdb/launching/TestLaunchDelegate.java | 10 +++++----- 36 files changed, 80 insertions(+), 80 deletions(-) rename plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/{ => internal/provisional}/IGDBLaunchConfigurationConstants.java (93%) rename plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/{ => internal/provisional}/breakpoints/CBreakpointGdbThreadsFilterExtension.java (98%) rename plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/{ => internal/provisional}/launching/FinalLaunchSequence.java (98%) rename plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/{ => internal/provisional}/launching/GdbLaunch.java (98%) rename plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/{ => internal/provisional}/launching/GdbLaunchDelegate.java (98%) rename plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/{ => internal/provisional}/launching/ServicesLaunchSequence.java (94%) rename plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/{ => internal/provisional}/launching/ShutdownSequence.java (97%) rename plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/{ => internal/provisional}/service/GDBRunControl.java (97%) rename plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/{ => internal/provisional}/service/command/GDBCLIProcess.java (98%) rename plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/{ => internal/provisional}/service/command/GDBControl.java (99%) rename plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/{ => internal/provisional}/service/command/GDBControlDMContext.java (95%) rename plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/{ => internal/provisional}/service/command/GDBInferiorProcess.java (94%) diff --git a/plugins/org.eclipse.dd.gdb.launch/plugin.xml b/plugins/org.eclipse.dd.gdb.launch/plugin.xml index d05db8ece4e..21c922f7c63 100644 --- a/plugins/org.eclipse.dd.gdb.launch/plugin.xml +++ b/plugins/org.eclipse.dd.gdb.launch/plugin.xml @@ -4,7 +4,7 @@ + adaptableType="org.eclipse.dd.gdb.internal.provisional.launching.GdbLaunch"> diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java index 5bc506c8f50..0936f428377 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java @@ -25,10 +25,10 @@ import org.eclipse.dd.dsf.debug.ui.actions.DsfSuspendCommand; import org.eclipse.dd.dsf.debug.ui.contexts.DsfSuspendTrigger; import org.eclipse.dd.dsf.debug.ui.sourcelookup.DsfSourceDisplayAdapter; import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.gdb.internal.provisional.launching.GdbLaunch; +import org.eclipse.dd.gdb.internal.provisional.launching.GdbLaunchDelegate; import org.eclipse.dd.gdb.internal.ui.actions.DsfTerminateCommand; import org.eclipse.dd.gdb.internal.ui.viewmodel.GdbViewModelAdapter; -import org.eclipse.dd.gdb.launching.GdbLaunch; -import org.eclipse.dd.gdb.launching.GdbLaunchDelegate; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchesListener2; diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/actions/DsfTerminateCommand.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/actions/DsfTerminateCommand.java index 2a9a1f99c0d..1f7cbe2f15c 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/actions/DsfTerminateCommand.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/actions/DsfTerminateCommand.java @@ -19,8 +19,8 @@ import org.eclipse.dd.dsf.debug.ui.actions.DsfCommandRunnable; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl; import org.eclipse.dd.gdb.internal.ui.GdbUIPlugin; -import org.eclipse.dd.gdb.service.command.GDBControl; import org.eclipse.debug.core.commands.IDebugCommandRequest; import org.eclipse.debug.core.commands.IEnabledStateRequest; import org.eclipse.debug.core.commands.ITerminateHandler; diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/CBreakpointGdbThreadFilterPage.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/CBreakpointGdbThreadFilterPage.java index bec7fdadec9..ac4359c8710 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/CBreakpointGdbThreadFilterPage.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/CBreakpointGdbThreadFilterPage.java @@ -12,8 +12,8 @@ package org.eclipse.dd.gdb.internal.ui.breakpoints; import org.eclipse.cdt.debug.core.model.ICBreakpoint; import org.eclipse.core.runtime.CoreException; -import org.eclipse.dd.gdb.breakpoints.CBreakpointGdbThreadsFilterExtension; -import org.eclipse.dd.gdb.launching.GdbLaunchDelegate; +import org.eclipse.dd.gdb.internal.provisional.breakpoints.CBreakpointGdbThreadsFilterExtension; +import org.eclipse.dd.gdb.internal.provisional.launching.GdbLaunchDelegate; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/GdbThreadFilterEditor.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/GdbThreadFilterEditor.java index 957a57bbc08..3e525b8f3f2 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/GdbThreadFilterEditor.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/GdbThreadFilterEditor.java @@ -28,12 +28,12 @@ import org.eclipse.dd.dsf.debug.service.IRunControl; import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.gdb.breakpoints.CBreakpointGdbThreadsFilterExtension; +import org.eclipse.dd.gdb.internal.provisional.breakpoints.CBreakpointGdbThreadsFilterExtension; +import org.eclipse.dd.gdb.internal.provisional.launching.GdbLaunch; +import org.eclipse.dd.gdb.internal.provisional.service.GDBRunControl; +import org.eclipse.dd.gdb.internal.provisional.service.GDBRunControl.GDBThreadData; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl; import org.eclipse.dd.gdb.internal.ui.GdbUIPlugin; -import org.eclipse.dd.gdb.launching.GdbLaunch; -import org.eclipse.dd.gdb.service.GDBRunControl; -import org.eclipse.dd.gdb.service.GDBRunControl.GDBThreadData; -import org.eclipse.dd.gdb.service.command.GDBControl; import org.eclipse.dd.mi.service.IMIExecutionDMContext; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/CDebuggerTab.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/CDebuggerTab.java index b8d5f6e46d1..17c0df7afe2 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/CDebuggerTab.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/CDebuggerTab.java @@ -43,8 +43,8 @@ import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; -import org.eclipse.dd.gdb.IGDBLaunchConfigurationConstants; -import org.eclipse.dd.gdb.service.command.GDBControl.SessionType; +import org.eclipse.dd.gdb.internal.provisional.IGDBLaunchConfigurationConstants; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl.SessionType; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.jface.dialogs.Dialog; diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbLocalRunLaunchConfigurationTabGroup.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbLocalRunLaunchConfigurationTabGroup.java index c95d5c61733..0b02972e1c3 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbLocalRunLaunchConfigurationTabGroup.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbLocalRunLaunchConfigurationTabGroup.java @@ -11,7 +11,7 @@ package org.eclipse.dd.gdb.internal.ui.launching; import org.eclipse.cdt.launch.ui.CMainTab; -import org.eclipse.dd.gdb.service.command.GDBControl.SessionType; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl.SessionType; import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup; import org.eclipse.debug.ui.CommonTab; import org.eclipse.debug.ui.ILaunchConfigurationDialog; diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbRemoteRunLaunchConfigurationTabGroup.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbRemoteRunLaunchConfigurationTabGroup.java index 9b00424d1ae..fb5689b894f 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbRemoteRunLaunchConfigurationTabGroup.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbRemoteRunLaunchConfigurationTabGroup.java @@ -11,7 +11,7 @@ package org.eclipse.dd.gdb.internal.ui.launching; import org.eclipse.cdt.launch.ui.CMainTab; -import org.eclipse.dd.gdb.service.command.GDBControl.SessionType; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl.SessionType; import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup; import org.eclipse.debug.ui.CommonTab; import org.eclipse.debug.ui.ILaunchConfigurationDialog; diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ContainerVMNode.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ContainerVMNode.java index 7e970636371..ac0ee1e86b1 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ContainerVMNode.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ContainerVMNode.java @@ -27,11 +27,11 @@ import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMNode; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; -import org.eclipse.dd.gdb.service.GDBRunControl; -import org.eclipse.dd.gdb.service.GDBRunControl.GDBProcessData; -import org.eclipse.dd.gdb.service.command.GDBControl; -import org.eclipse.dd.gdb.service.command.GDBControlDMContext; -import org.eclipse.dd.gdb.service.command.GDBControl.StartedEvent; +import org.eclipse.dd.gdb.internal.provisional.service.GDBRunControl; +import org.eclipse.dd.gdb.internal.provisional.service.GDBRunControl.GDBProcessData; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControlDMContext; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl.StartedEvent; import org.eclipse.dd.mi.service.command.AbstractMIControl; import org.eclipse.dd.mi.service.command.MIControlDMContext; import org.eclipse.dd.mi.service.command.events.MIInferiorExitEvent; diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ThreadVMNode.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ThreadVMNode.java index f3e2071b8b3..deb7ab3364d 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ThreadVMNode.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ThreadVMNode.java @@ -41,8 +41,8 @@ import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMNode; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext; -import org.eclipse.dd.gdb.service.GDBRunControl; -import org.eclipse.dd.gdb.service.GDBRunControl.GDBThreadData; +import org.eclipse.dd.gdb.internal.provisional.service.GDBRunControl; +import org.eclipse.dd.gdb.internal.provisional.service.GDBRunControl.GDBThreadData; import org.eclipse.dd.mi.service.IMIExecutionDMContext; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; diff --git a/plugins/org.eclipse.dd.gdb/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.gdb/META-INF/MANIFEST.MF index 451260308c2..a1b50984b49 100644 --- a/plugins/org.eclipse.dd.gdb/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.gdb/META-INF/MANIFEST.MF @@ -16,8 +16,8 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.cdt.launch Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: J2SE-1.5 -Export-Package: org.eclipse.dd.gdb, - org.eclipse.dd.gdb.breakpoints, - org.eclipse.dd.gdb.launching, - org.eclipse.dd.gdb.service, - org.eclipse.dd.gdb.service.command +Export-Package: org.eclipse.dd.gdb.internal.provisional, + org.eclipse.dd.gdb.internal.provisional.breakpoints, + org.eclipse.dd.gdb.internal.provisional.launching, + org.eclipse.dd.gdb.internal.provisional.service, + org.eclipse.dd.gdb.internal.provisional.service.command diff --git a/plugins/org.eclipse.dd.gdb/plugin.xml b/plugins/org.eclipse.dd.gdb/plugin.xml index cc5d8ab3398..bee9b15fe6e 100644 --- a/plugins/org.eclipse.dd.gdb/plugin.xml +++ b/plugins/org.eclipse.dd.gdb/plugin.xml @@ -4,7 +4,7 @@ diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/GdbPlugin.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/GdbPlugin.java index f80e2ae24d3..98679f425b2 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/GdbPlugin.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/GdbPlugin.java @@ -8,7 +8,7 @@ import org.eclipse.core.runtime.Plugin; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.Query; -import org.eclipse.dd.gdb.launching.GdbLaunch; +import org.eclipse.dd.gdb.internal.provisional.launching.GdbLaunch; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; import org.osgi.framework.BundleContext; diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/IGDBLaunchConfigurationConstants.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/IGDBLaunchConfigurationConstants.java similarity index 93% rename from plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/IGDBLaunchConfigurationConstants.java rename to plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/IGDBLaunchConfigurationConstants.java index 73f3801c151..b2d3f81384c 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/IGDBLaunchConfigurationConstants.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/IGDBLaunchConfigurationConstants.java @@ -8,7 +8,7 @@ * Contributors: * Ericsson - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.gdb; +package org.eclipse.dd.gdb.internal.provisional; public class IGDBLaunchConfigurationConstants { diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/breakpoints/CBreakpointGdbThreadsFilterExtension.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/breakpoints/CBreakpointGdbThreadsFilterExtension.java similarity index 98% rename from plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/breakpoints/CBreakpointGdbThreadsFilterExtension.java rename to plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/breakpoints/CBreakpointGdbThreadsFilterExtension.java index 1a81d3f5fc3..dd9a908d74c 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/breakpoints/CBreakpointGdbThreadsFilterExtension.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/breakpoints/CBreakpointGdbThreadsFilterExtension.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.gdb.breakpoints; +package org.eclipse.dd.gdb.internal.provisional.breakpoints; import java.util.Arrays; import java.util.HashMap; diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/FinalLaunchSequence.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java similarity index 98% rename from plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/FinalLaunchSequence.java rename to plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java index 553809daa2a..aed438f0031 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/FinalLaunchSequence.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java @@ -8,7 +8,7 @@ * Contributors: * Ericsson - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.gdb.launching; +package org.eclipse.dd.gdb.internal.provisional.launching; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector; @@ -24,8 +24,8 @@ import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.gdb.internal.GdbPlugin; -import org.eclipse.dd.gdb.service.command.GDBControl; -import org.eclipse.dd.gdb.service.command.GDBControl.SessionType; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl.SessionType; import org.eclipse.dd.mi.service.CSourceLookup; import org.eclipse.dd.mi.service.MIBreakpointsManager; import org.eclipse.dd.mi.service.command.commands.MIBreakInsert; diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunch.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunch.java similarity index 98% rename from plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunch.java rename to plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunch.java index f723d05eeb1..da3885bea29 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunch.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunch.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.gdb.launching; +package org.eclipse.dd.gdb.internal.provisional.launching; import java.util.concurrent.ExecutionException; @@ -30,7 +30,7 @@ import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.gdb.internal.GdbPlugin; -import org.eclipse.dd.gdb.service.command.GDBControl; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.Launch; diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunchDelegate.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java similarity index 98% rename from plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunchDelegate.java rename to plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java index 8a270f780fd..8fbe2468cbc 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/GdbLaunchDelegate.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java @@ -8,7 +8,7 @@ * Contributors: * QNX Software Systems - Initial API and implementation *******************************************************************************/ -package org.eclipse.dd.gdb.launching; +package org.eclipse.dd.gdb.internal.provisional.launching; import java.io.File; import java.io.IOException; @@ -34,10 +34,10 @@ import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.debug.model.DsfMemoryBlockRetrieval; import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryDMContext; import org.eclipse.dd.dsf.service.DsfServicesTracker; -import org.eclipse.dd.gdb.IGDBLaunchConfigurationConstants; import org.eclipse.dd.gdb.internal.GdbPlugin; -import org.eclipse.dd.gdb.service.command.GDBControl; -import org.eclipse.dd.gdb.service.command.GDBControl.SessionType; +import org.eclipse.dd.gdb.internal.provisional.IGDBLaunchConfigurationConstants; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl.SessionType; import org.eclipse.dd.mi.service.command.AbstractCLIProcess; import org.eclipse.dd.mi.service.command.MIInferiorProcess; import org.eclipse.debug.core.DebugException; diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/ServicesLaunchSequence.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/ServicesLaunchSequence.java similarity index 94% rename from plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/ServicesLaunchSequence.java rename to plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/ServicesLaunchSequence.java index 4b87b6b8400..f5003ef691c 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/ServicesLaunchSequence.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/ServicesLaunchSequence.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.gdb.launching; +package org.eclipse.dd.gdb.internal.provisional.launching; import org.eclipse.cdt.debug.core.CDebugCorePlugin; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; @@ -21,10 +21,10 @@ import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.concurrent.Sequence; import org.eclipse.dd.dsf.debug.service.StepQueueManager; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.gdb.IGDBLaunchConfigurationConstants; -import org.eclipse.dd.gdb.service.GDBRunControl; -import org.eclipse.dd.gdb.service.command.GDBControl; -import org.eclipse.dd.gdb.service.command.GDBControl.SessionType; +import org.eclipse.dd.gdb.internal.provisional.IGDBLaunchConfigurationConstants; +import org.eclipse.dd.gdb.internal.provisional.service.GDBRunControl; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl.SessionType; import org.eclipse.dd.mi.service.CSourceLookup; import org.eclipse.dd.mi.service.ExpressionService; import org.eclipse.dd.mi.service.MIBreakpoints; diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/ShutdownSequence.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/ShutdownSequence.java similarity index 97% rename from plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/ShutdownSequence.java rename to plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/ShutdownSequence.java index 3afdd49c864..08cdbf531fa 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/launching/ShutdownSequence.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/ShutdownSequence.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.gdb.launching; +package org.eclipse.dd.gdb.internal.provisional.launching; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; @@ -19,8 +19,8 @@ import org.eclipse.dd.dsf.concurrent.Sequence; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.gdb.internal.GdbPlugin; -import org.eclipse.dd.gdb.service.GDBRunControl; -import org.eclipse.dd.gdb.service.command.GDBControl; +import org.eclipse.dd.gdb.internal.provisional.service.GDBRunControl; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl; import org.eclipse.dd.mi.service.CSourceLookup; import org.eclipse.dd.mi.service.ExpressionService; import org.eclipse.dd.mi.service.MIBreakpoints; diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/GDBRunControl.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/GDBRunControl.java similarity index 97% rename from plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/GDBRunControl.java rename to plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/GDBRunControl.java index 36ad19ce117..2ff88c4205a 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/GDBRunControl.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/GDBRunControl.java @@ -10,7 +10,7 @@ * Ericsson AB - Modified for additional functionality *******************************************************************************/ -package org.eclipse.dd.gdb.service; +package org.eclipse.dd.gdb.internal.provisional.service; import java.util.Arrays; @@ -26,8 +26,8 @@ import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.debug.service.IRunControl; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.gdb.internal.GdbPlugin; -import org.eclipse.dd.gdb.service.command.GDBControl; -import org.eclipse.dd.gdb.service.command.GDBControlDMContext; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControlDMContext; import org.eclipse.dd.mi.service.IMIExecutionDMContext; import org.eclipse.dd.mi.service.MIRunControl; import org.eclipse.dd.mi.service.command.commands.CLIInfoThreads; diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBCLIProcess.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBCLIProcess.java similarity index 98% rename from plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBCLIProcess.java rename to plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBCLIProcess.java index 6c6c80c251b..10b95f8bb27 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBCLIProcess.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBCLIProcess.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.gdb.service.command; +package org.eclipse.dd.gdb.internal.provisional.service.command; import java.io.IOException; import java.util.concurrent.Callable; diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControl.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java similarity index 99% rename from plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControl.java rename to plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java index c9656dfdd63..ff2fd1e067e 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControl.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java @@ -9,7 +9,7 @@ * Wind River Systems - initial API and implementation * Ericsson - Modified for additional features in DSF Reference implementation *******************************************************************************/ -package org.eclipse.dd.gdb.service.command; +package org.eclipse.dd.gdb.internal.provisional.service.command; import java.io.BufferedReader; import java.io.IOException; diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControlDMContext.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControlDMContext.java similarity index 95% rename from plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControlDMContext.java rename to plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControlDMContext.java index ea3741e6e81..c744996add4 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBControlDMContext.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControlDMContext.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.gdb.service.command; +package org.eclipse.dd.gdb.internal.provisional.service.command; import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; import org.eclipse.dd.dsf.debug.service.IDisassembly.IDisassemblyDMContext; diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBInferiorProcess.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBInferiorProcess.java similarity index 94% rename from plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBInferiorProcess.java rename to plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBInferiorProcess.java index d4c16ab68c7..c556a1dafee 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/service/command/GDBInferiorProcess.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBInferiorProcess.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.gdb.service.command; +package org.eclipse.dd.gdb.internal.provisional.service.command; import java.io.OutputStream; import java.util.concurrent.ExecutionException; @@ -17,7 +17,7 @@ import java.util.concurrent.RejectedExecutionException; import org.eclipse.cdt.utils.pty.PTY; import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.ThreadSafeAndProhibitedFromDsfExecutor; -import org.eclipse.dd.gdb.service.command.GDBControl.SessionType; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl.SessionType; import org.eclipse.dd.mi.service.command.MIInferiorProcess; /** diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/ExpressionServiceTest.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/ExpressionServiceTest.java index 7ea0742a50a..df5f8a509fb 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/ExpressionServiceTest.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/ExpressionServiceTest.java @@ -38,7 +38,7 @@ import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.gdb.service.command.GDBControl; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl; import org.eclipse.dd.mi.service.ClassAccessor.MIExpressionDMCAccessor; import org.eclipse.dd.mi.service.command.events.MIStoppedEvent; import org.eclipse.dd.tests.gdb.framework.AsyncCompletionWaitor; diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/GDBProcessesTest.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/GDBProcessesTest.java index 5f7c84c17f0..893a20a328d 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/GDBProcessesTest.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/GDBProcessesTest.java @@ -23,10 +23,10 @@ import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.gdb.service.GDBRunControl; -import org.eclipse.dd.gdb.service.GDBRunControl.GDBProcessData; -import org.eclipse.dd.gdb.service.GDBRunControl.GDBThreadData; -import org.eclipse.dd.gdb.service.command.GDBControl; +import org.eclipse.dd.gdb.internal.provisional.service.GDBRunControl; +import org.eclipse.dd.gdb.internal.provisional.service.GDBRunControl.GDBProcessData; +import org.eclipse.dd.gdb.internal.provisional.service.GDBRunControl.GDBThreadData; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl; import org.eclipse.dd.mi.service.IMIExecutionDMContext; import org.eclipse.dd.tests.gdb.framework.AsyncCompletionWaitor; import org.eclipse.dd.tests.gdb.framework.BaseTestCase; diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIBreakpointsTest.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIBreakpointsTest.java index a3aace6b4f3..549b11ce315 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIBreakpointsTest.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIBreakpointsTest.java @@ -36,8 +36,8 @@ import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.gdb.service.command.GDBControl; -import org.eclipse.dd.gdb.service.command.GDBControlDMContext; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControlDMContext; import org.eclipse.dd.mi.service.MIBreakpointDMData; import org.eclipse.dd.mi.service.MIBreakpoints; import org.eclipse.dd.mi.service.MIRunControl; diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIDisassemblyTest.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIDisassemblyTest.java index ffd1a3b05f0..4bc12239b2f 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIDisassemblyTest.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIDisassemblyTest.java @@ -30,8 +30,8 @@ import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.gdb.service.command.GDBControl; -import org.eclipse.dd.gdb.service.command.GDBControlDMContext; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControlDMContext; import org.eclipse.dd.mi.service.MIDisassembly; import org.eclipse.dd.tests.gdb.framework.AsyncCompletionWaitor; import org.eclipse.dd.tests.gdb.framework.BackgroundRunner; diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIMemoryTest.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIMemoryTest.java index 159abb73c8f..efc42ec3cbe 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIMemoryTest.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIMemoryTest.java @@ -30,8 +30,8 @@ import org.eclipse.dd.dsf.debug.service.IRunControl.StepType; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.gdb.service.command.GDBControl; -import org.eclipse.dd.gdb.service.command.GDBControlDMContext; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControlDMContext; import org.eclipse.dd.mi.service.MIRunControl; import org.eclipse.dd.tests.gdb.framework.AsyncCompletionWaitor; import org.eclipse.dd.tests.gdb.framework.BackgroundRunner; diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRegistersTest.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRegistersTest.java index 1c579cecea2..4dc7c5c6e6a 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRegistersTest.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRegistersTest.java @@ -20,8 +20,8 @@ import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext; import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.gdb.service.command.GDBControl; -import org.eclipse.dd.gdb.service.command.GDBControlDMContext; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControlDMContext; import org.eclipse.dd.mi.service.IMIExecutionDMContext; import org.eclipse.dd.mi.service.MIRunControl; import org.eclipse.dd.mi.service.MIStack; diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRunControlTest.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRunControlTest.java index e42ae5da1f9..309d2827bda 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRunControlTest.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRunControlTest.java @@ -24,8 +24,8 @@ import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason; import org.eclipse.dd.dsf.debug.service.IRunControl.StepType; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfServicesTracker; -import org.eclipse.dd.gdb.service.command.GDBControl; -import org.eclipse.dd.gdb.service.command.GDBControlDMContext; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControlDMContext; import org.eclipse.dd.mi.service.IMIExecutionDMContext; import org.eclipse.dd.mi.service.MIRunControl; import org.eclipse.dd.mi.service.MIStack; diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java index 9bb59f00fbb..d1fa4bb92b1 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java @@ -15,7 +15,7 @@ import java.util.Map; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.dd.gdb.launching.GdbLaunch; +import org.eclipse.dd.gdb.internal.provisional.launching.GdbLaunch; import org.eclipse.dd.mi.service.command.events.MIStoppedEvent; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunchConfiguration; diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/SyncUtil.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/SyncUtil.java index 147b3983769..39af5993f76 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/SyncUtil.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/SyncUtil.java @@ -31,7 +31,7 @@ import org.eclipse.dd.dsf.debug.service.IRunControl.StepType; import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.gdb.service.command.GDBControl; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl; import org.eclipse.dd.mi.service.MIRunControl; import org.eclipse.dd.mi.service.MIStack; import org.eclipse.dd.mi.service.command.commands.MIBreakDelete; diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java index aca586a6e29..cc80277ca4f 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java @@ -36,11 +36,11 @@ import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.debug.model.DsfMemoryBlockRetrieval; import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryDMContext; import org.eclipse.dd.dsf.service.DsfServicesTracker; -import org.eclipse.dd.gdb.launching.FinalLaunchSequence; -import org.eclipse.dd.gdb.launching.GdbLaunch; -import org.eclipse.dd.gdb.launching.ServicesLaunchSequence; -import org.eclipse.dd.gdb.service.command.GDBControl; -import org.eclipse.dd.gdb.service.command.GDBControl.SessionType; +import org.eclipse.dd.gdb.internal.provisional.launching.FinalLaunchSequence; +import org.eclipse.dd.gdb.internal.provisional.launching.GdbLaunch; +import org.eclipse.dd.gdb.internal.provisional.launching.ServicesLaunchSequence; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl.SessionType; import org.eclipse.dd.mi.service.command.AbstractCLIProcess; import org.eclipse.dd.mi.service.command.MIInferiorProcess; import org.eclipse.debug.core.DebugException; From f740036430ba16b08f691860fe8e81092186ee5c Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 28 Mar 2008 16:58:47 +0000 Subject: [PATCH 347/834] [224677] Adjusted tests to account for new launch sequence. --- .../src/org/eclipse/dd/tests/gdb/MIRunControlTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRunControlTest.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRunControlTest.java index 309d2827bda..6841238a1be 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRunControlTest.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRunControlTest.java @@ -274,7 +274,7 @@ public class MIRunControlTest extends BaseTestCase { * getModelData should return StateChangeReason. */ Assert.assertTrue(" State change reason for a normal execution should be CONTAINER." , - StateChangeReason.CONTAINER == data.getStateChangeReason()); + StateChangeReason.USER_REQUEST == data.getStateChangeReason()); } } @@ -397,7 +397,8 @@ public class MIRunControlTest extends BaseTestCase { /* * StateChangeReason in getModelData for Container DMC is null. */ - Assert.assertNull(data.getStateChangeReason()); + Assert.assertTrue(" State change reason for a normal execution should be CONTAINER." , + StateChangeReason.USER_REQUEST == data.getStateChangeReason()); } } From e42dcea7a8573ded4c08a972eeaf3edbdb76cbbf Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 28 Mar 2008 17:42:49 +0000 Subject: [PATCH 348/834] [158610] Converted the IRunControl.can*() methods to be asynchronous. --- .../debug/ui/actions/DsfResumeCommand.java | 12 +- .../debug/ui/actions/DsfStepIntoCommand.java | 12 +- .../debug/ui/actions/DsfStepOverCommand.java | 12 +- .../ui/actions/DsfStepReturnCommand.java | 12 +- .../debug/ui/actions/DsfSuspendCommand.java | 12 +- .../dd/dsf/debug/service/IRunControl.java | 10 +- .../dsf/debug/service/StepQueueManager.java | 113 ++++++++---------- .../examples/pda/service/PDARunControl.java | 36 +++--- .../provisional/service/GDBRunControl.java | 21 ++-- 9 files changed, 139 insertions(+), 101 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfResumeCommand.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfResumeCommand.java index 8f30f31bc0a..5784b917323 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfResumeCommand.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfResumeCommand.java @@ -10,7 +10,9 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.actions; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; @@ -44,7 +46,15 @@ public class DsfResumeCommand implements IResumeHandler { fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) { @Override public void doExecute() { - request.setEnabled(getRunControl().canResume(getContext())); + getRunControl().canResume( + getContext(), + new DataRequestMonitor(ImmediateExecutor.getInstance(), null) { + @Override + protected void handleCompleted() { + request.setEnabled(isSuccess() && getData()); + request.done(); + } + }); } }); } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepIntoCommand.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepIntoCommand.java index 52ce0cefcb6..d3c9e2a8aa5 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepIntoCommand.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepIntoCommand.java @@ -10,7 +10,9 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.actions; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.service.IRunControl.StepType; @@ -44,7 +46,15 @@ public class DsfStepIntoCommand implements IStepIntoHandler { fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) { @Override public void doExecute() { - request.setEnabled(getStepQueueMgr().canEnqueueStep(getContext(), StepType.STEP_INTO)); + getStepQueueMgr().canEnqueueStep( + getContext(), StepType.STEP_INTO, + new DataRequestMonitor(ImmediateExecutor.getInstance(), null) { + @Override + protected void handleCompleted() { + request.setEnabled(isSuccess() && getData()); + request.done(); + } + }); } }); } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepOverCommand.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepOverCommand.java index f4c2a28afa7..10ee48c77b5 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepOverCommand.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepOverCommand.java @@ -10,7 +10,9 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.actions; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.service.IRunControl.StepType; @@ -44,7 +46,15 @@ public class DsfStepOverCommand implements IStepOverHandler { fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) { @Override public void doExecute() { - request.setEnabled(getStepQueueMgr().canEnqueueStep(getContext(), StepType.STEP_OVER)); + getStepQueueMgr().canEnqueueStep( + getContext(), StepType.STEP_OVER, + new DataRequestMonitor(ImmediateExecutor.getInstance(), null) { + @Override + protected void handleCompleted() { + request.setEnabled(isSuccess() && getData()); + request.done(); + } + }); } }); } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepReturnCommand.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepReturnCommand.java index d3d9dc2d16b..91b0363bdd4 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepReturnCommand.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepReturnCommand.java @@ -10,7 +10,9 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.actions; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.service.IRunControl.StepType; @@ -44,7 +46,15 @@ public class DsfStepReturnCommand implements IStepReturnHandler { fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) { @Override public void doExecute() { - request.setEnabled(getStepQueueMgr().canEnqueueStep(getContext(), StepType.STEP_RETURN)); + getStepQueueMgr().canEnqueueStep( + getContext(), StepType.STEP_RETURN, + new DataRequestMonitor(ImmediateExecutor.getInstance(), null) { + @Override + protected void handleCompleted() { + request.setEnabled(isSuccess() && getData()); + request.done(); + } + }); } }); } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfSuspendCommand.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfSuspendCommand.java index 6f1a3e963ce..def744406e0 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfSuspendCommand.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfSuspendCommand.java @@ -10,7 +10,9 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.actions; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; @@ -43,7 +45,15 @@ public class DsfSuspendCommand implements ISuspendHandler { fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) { @Override public void doExecute() { - request.setEnabled(getRunControl().canSuspend(getContext())); + getRunControl().canSuspend( + getContext(), + new DataRequestMonitor(ImmediateExecutor.getInstance(), null) { + @Override + protected void handleCompleted() { + request.setEnabled(isSuccess() && getData()); + request.done(); + } + }); } }); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java index 3bbc4242275..82e36257fd6 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java @@ -115,15 +115,13 @@ public interface IRunControl extends IDMService * Run control commands. They all require the IExecutionContext object on * which they perform the operations. */ - boolean canResume(IExecutionDMContext context); - boolean canSuspend(IExecutionDMContext context); + void canResume(IExecutionDMContext context, DataRequestMonitor rm); + void canSuspend(IExecutionDMContext context, DataRequestMonitor rm); boolean isSuspended(IExecutionDMContext context); void resume(IExecutionDMContext context, RequestMonitor requestMonitor); void suspend(IExecutionDMContext context, RequestMonitor requestMonitor); - public enum StepType { STEP_OVER, STEP_INTO, STEP_RETURN }; + public enum StepType { STEP_OVER, STEP_INTO, STEP_RETURN, INSTRUCTION_STEP_OVER, INSTRUCTION_STEP_INTO, INSTRUCTION_STEP_RETUTRN }; boolean isStepping(IExecutionDMContext context); - boolean canStep(IExecutionDMContext context, StepType stepType); + void canStep(IExecutionDMContext context, StepType stepType, DataRequestMonitor rm); void step(IExecutionDMContext context, StepType stepType, RequestMonitor requestMonitor); - boolean canInstructionStep(IExecutionDMContext context, StepType stepType); - void instructionStep(IExecutionDMContext context, StepType stepType, RequestMonitor requestMonitor); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/StepQueueManager.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/StepQueueManager.java index 2fea35e74bd..47d91c5fc19 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/StepQueueManager.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/StepQueueManager.java @@ -18,6 +18,7 @@ import java.util.Map; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMEvent; @@ -64,10 +65,8 @@ public class StepQueueManager extends AbstractDsfService private static class StepRequest { StepType fStepType; - boolean fIsInstructionStep; - StepRequest(StepType type, boolean instruction) { + StepRequest(StepType type) { fStepType = type; - fIsInstructionStep = instruction; } } @@ -116,17 +115,17 @@ public class StepQueueManager extends AbstractDsfService /** * Checks whether a step command can be queued up for given context. */ - public boolean canEnqueueStep(IExecutionDMContext execCtx, StepType stepType) { - return (fRunControl.isSuspended(execCtx) && fRunControl.canStep(execCtx, stepType)) || - (fRunControl.isStepping(execCtx) && !isSteppingTimedOut(execCtx)); + public void canEnqueueStep(IExecutionDMContext execCtx, StepType stepType, DataRequestMonitor rm) { + if (doCanEnqueueStep(execCtx, stepType)) { + rm.setData(true); + rm.done(); + } else { + fRunControl.canStep(execCtx, stepType, rm); + } } - /** - * Checks whether an instruction step command can be queued up for given context. - */ - public boolean canEnqueueInstructionStep(IExecutionDMContext execCtx, StepType stepType) { - return (fRunControl.isSuspended(execCtx) && fRunControl.canInstructionStep(execCtx, stepType)) || - (fRunControl.isStepping(execCtx) && !isSteppingTimedOut(execCtx)); + private boolean doCanEnqueueStep(IExecutionDMContext execCtx, StepType stepType) { + return fRunControl.isStepping(execCtx) && !isSteppingTimedOut(execCtx); } /** @@ -144,40 +143,25 @@ public class StepQueueManager extends AbstractDsfService * @param execCtx Execution context that should perform the step. * @param stepType Type of step to execute. */ - public void enqueueStep(IExecutionDMContext execCtx, StepType stepType) { - if (fRunControl.canStep(execCtx, stepType)) { - fRunControl.step(execCtx, stepType, new RequestMonitor(getExecutor(), null)); - } else if (canEnqueueStep(execCtx, stepType)) { - List stepQueue = fStepQueues.get(execCtx); - if (stepQueue == null) { - stepQueue = new LinkedList(); - fStepQueues.put(execCtx, stepQueue); - } - if (stepQueue.size() < fQueueDepth) { - stepQueue.add(new StepRequest(stepType, false)); - } - } - } - - /** - * Adds an instruction 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. - */ - public void enqueueInstructionStep(IExecutionDMContext execCtx, StepType stepType) { - if (fRunControl.canInstructionStep(execCtx, stepType)) { - fRunControl.instructionStep(execCtx, stepType, new RequestMonitor(getExecutor(), null)); - } else if (canEnqueueInstructionStep(execCtx, stepType)) { - List stepQueue = fStepQueues.get(execCtx); - if (stepQueue == null) { - stepQueue = new LinkedList(); - fStepQueues.put(execCtx, stepQueue); - } - if (stepQueue.size() < fQueueDepth) { - stepQueue.add(new StepRequest(stepType, true)); - } - } + public void enqueueStep(final IExecutionDMContext execCtx, final StepType stepType) { + fRunControl.canStep( + execCtx, stepType, new DataRequestMonitor(getExecutor(), null) { + @Override + protected void handleCompleted() { + if (isSuccess() && getData()) { + fRunControl.step(execCtx, stepType, new RequestMonitor(getExecutor(), null)); + } else if (doCanEnqueueStep(execCtx, stepType)) { + List stepQueue = fStepQueues.get(execCtx); + if (stepQueue == null) { + stepQueue = new LinkedList(); + fStepQueues.put(execCtx, stepQueue); + } + if (stepQueue.size() < fQueueDepth) { + stepQueue.add(new StepRequest(stepType)); + } + } + } + }); } /** @@ -191,7 +175,7 @@ public class StepQueueManager extends AbstractDsfService /////////////////////////////////////////////////////////////////////////// @DsfServiceEventHandler - public void eventDispatched(ISuspendedDMEvent e) { + public void eventDispatched(final ISuspendedDMEvent e) { // Take care of the stepping time out fTimedOutFlags.remove(e.getDMContext()); ScheduledFuture future = fTimedOutFutures.remove(e.getDMContext()); @@ -200,26 +184,23 @@ public class StepQueueManager extends AbstractDsfService // Check if there's a step pending, if so execute it if (fStepQueues.containsKey(e.getDMContext())) { List queue = fStepQueues.get(e.getDMContext()); - StepRequest request = queue.remove(queue.size() - 1); + final StepRequest request = queue.remove(queue.size() - 1); if (queue.isEmpty()) fStepQueues.remove(e.getDMContext()); - if (request.fIsInstructionStep) { - if (fRunControl.canInstructionStep(e.getDMContext(), request.fStepType)) { - fRunControl.instructionStep( - e.getDMContext(), request.fStepType, new RequestMonitor(getExecutor(), null)); - } else { - // For whatever reason we can't step anymore, so clear out - // the step queue. - fStepQueues.remove(e.getDMContext()); - } - } else { - if (fRunControl.canStep(e.getDMContext(), request.fStepType)) { - fRunControl.step(e.getDMContext(), request.fStepType,new RequestMonitor(getExecutor(), null)); - } else { - // For whatever reason we can't step anymore, so clear out - // the step queue. - fStepQueues.remove(e.getDMContext()); - } - } + fRunControl.canStep( + e.getDMContext(), request.fStepType, + new DataRequestMonitor(getExecutor(), null) { + @Override + protected void handleCompleted() { + if (isSuccess() && getData()) { + fRunControl.step( + e.getDMContext(), request.fStepType, new RequestMonitor(getExecutor(), null)); + } else { + // For whatever reason we can't step anymore, so clear out + // the step queue. + fStepQueues.remove(e.getDMContext()); + } + } + }); } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java index a9e70efc4d7..7d6fc93aff6 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java @@ -219,13 +219,23 @@ public class PDARunControl extends AbstractDsfService } - public boolean canResume(IExecutionDMContext context) { + public void canResume(IExecutionDMContext context, DataRequestMonitor rm) { + rm.setData(doCanResume(context)); + rm.done(); + } + + private boolean doCanResume(IExecutionDMContext context) { return isSuspended(context) && !fResumePending; - } + } - public boolean canSuspend(IExecutionDMContext context) { + public void canSuspend(IExecutionDMContext context, DataRequestMonitor rm) { + rm.setData(doCanSuspend(context)); + rm.done(); + } + + private boolean doCanSuspend(IExecutionDMContext context) { return !isSuspended(context); - } + } public boolean isSuspended(IExecutionDMContext context) { return fSuspended; @@ -238,7 +248,7 @@ public class PDARunControl extends AbstractDsfService public void resume(IExecutionDMContext context, final RequestMonitor rm) { assert context != null; - if (canResume(context)) { + if (doCanResume(context)) { fResumePending = true; fCommandControl.queueCommand( new PDAResumeCommand(fCommandControl.getProgramDMContext()), @@ -260,7 +270,7 @@ public class PDARunControl extends AbstractDsfService public void suspend(IExecutionDMContext context, final RequestMonitor rm){ assert context != null; - if (canSuspend(context)) { + if (doCanSuspend(context)) { fCommandControl.queueCommand( new PDASuspendCommand(fCommandControl.getProgramDMContext()), new DataRequestMonitor(getExecutor(), rm)); @@ -270,14 +280,14 @@ public class PDARunControl extends AbstractDsfService } } - public boolean canStep(IExecutionDMContext context, StepType stepType) { - return canResume(context); + public void canStep(IExecutionDMContext context, StepType stepType, DataRequestMonitor rm) { + canResume(context, rm); } public void step(IExecutionDMContext context, StepType stepType, final RequestMonitor rm) { assert context != null; - if (canResume(context)) { + if (doCanResume(context)) { fResumePending = true; fStepping = true; @@ -299,14 +309,6 @@ public class PDARunControl extends AbstractDsfService } } - public boolean canInstructionStep(IExecutionDMContext context, StepType stepType) { - return false; - } - - public void instructionStep(IExecutionDMContext context, StepType stepType, RequestMonitor rm) { - PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Operation not implemented"); - } - public void getExecutionContexts(final IContainerDMContext containerDmc, final DataRequestMonitor rm) { PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Operation not implemented"); } diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/GDBRunControl.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/GDBRunControl.java index 2ff88c4205a..b658d8774c1 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/GDBRunControl.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/GDBRunControl.java @@ -110,13 +110,20 @@ public class GDBRunControl extends MIRunControl { } @Override - public void suspend(IExecutionDMContext context, RequestMonitor requestMonitor){ - if (canSuspend(context)) { - fGdb.interrupt(); - } else { - requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, "Context cannot be suspended.", null)); //$NON-NLS-1$ - } - requestMonitor.done(); + public void suspend(IExecutionDMContext context, final RequestMonitor rm){ + canSuspend( + context, + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleSuccess() { + if (getData()) { + fGdb.interrupt(); + } else { + rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, "Context cannot be suspended.", null)); //$NON-NLS-1$ + } + rm.done(); + } + }); } From d5f39af5a8cbd15b301d457fcf5e97fad9c09c74 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 28 Mar 2008 18:05:54 +0000 Subject: [PATCH 349/834] [224435] Changed the IContainerSuspendedDMEvent/IContainerResumedEvent.getTriggeringContext() to return an array instead of a single context. --- .../viewmodel/launch/StackFramesVMNode.java | 13 +++- .../dd/dsf/debug/service/IRunControl.java | 12 ++-- .../ui/viewmodel/launch/ThreadVMNode.java | 25 ++++---- .../eclipse/dd/mi/service/MIRunControl.java | 60 ++++++++++--------- 4 files changed, 60 insertions(+), 50 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java index 6ed33d7797a..89023c461e3 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java @@ -330,11 +330,18 @@ public class StackFramesVMNode extends AbstractDMVMNode public void buildDelta(final Object e, final VMDelta parent, final int nodeOffset, final RequestMonitor rm) { if (e instanceof IContainerSuspendedDMEvent) { - IExecutionDMContext threadDmc = null; + IContainerSuspendedDMEvent csEvent = (IContainerSuspendedDMEvent)e; + + IExecutionDMContext triggeringCtx = csEvent.getTriggeringContexts().length != 0 + ? csEvent.getTriggeringContexts()[0] : null; + if (parent.getElement() instanceof IDMVMContext) { + IExecutionDMContext threadDmc = null; threadDmc = DMContexts.getAncestorOfType( ((IDMVMContext)parent.getElement()).getDMContext(), IExecutionDMContext.class); + buildDeltaForSuspendedEvent((ISuspendedDMEvent)e, threadDmc, triggeringCtx, parent, nodeOffset, rm); + } else { + rm.done(); } - buildDeltaForSuspendedEvent((ISuspendedDMEvent)e, threadDmc, ((IContainerSuspendedDMEvent)e).getTriggeringContext(), parent, nodeOffset, rm); } else if (e instanceof ISuspendedDMEvent) { IExecutionDMContext execDmc = ((ISuspendedDMEvent)e).getDMContext(); buildDeltaForSuspendedEvent((ISuspendedDMEvent)e, execDmc, execDmc, parent, nodeOffset, rm); @@ -361,7 +368,7 @@ public class StackFramesVMNode extends AbstractDMVMNode // 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 (!runControlService.isStepping(triggeringCtx)) { + if (triggeringCtx == null || !runControlService.isStepping(triggeringCtx)) { parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java index 82e36257fd6..7d5342dc272 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java @@ -65,10 +65,10 @@ public interface IRunControl extends IDMService */ public interface IContainerSuspendedDMEvent extends ISuspendedDMEvent { /** - * Returns the context which triggered the resume, which could be - * null if not known. + * Returns the contexts which triggered the resume, which could be + * an empty array if not known. */ - IExecutionDMContext getTriggeringContext(); + IExecutionDMContext[] getTriggeringContexts(); } /** @@ -76,10 +76,10 @@ public interface IRunControl extends IDMService */ public interface IContainerResumedDMEvent extends IResumedDMEvent { /** - * Returns the context which triggered the resume, which could be - * null if not known. + * Returns the contexts which triggered the resume, which could be an + * empty array if not known. */ - IExecutionDMContext getTriggeringContext(); + IExecutionDMContext[] getTriggeringContexts(); } /** diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ThreadVMNode.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ThreadVMNode.java index deb7ab3364d..1ab9ccd43be 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ThreadVMNode.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ThreadVMNode.java @@ -21,7 +21,6 @@ import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.DMContexts; -import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMEvent; import org.eclipse.dd.dsf.debug.service.IRunControl; import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; @@ -101,16 +100,16 @@ public class ThreadVMNode extends AbstractDMVMNode @Override public void getContextsForEvent(VMDelta parentDelta, Object e, final DataRequestMonitor rm) { if(e instanceof IContainerResumedDMEvent) { - IDMContext triggerContext = ((IContainerResumedDMEvent)e).getTriggeringContext(); - if (triggerContext != null) { - rm.setData(new IVMContext[] { createVMContext(triggerContext) }); + IExecutionDMContext[] triggerContexts = ((IContainerResumedDMEvent)e).getTriggeringContexts(); + if (triggerContexts.length != 0) { + rm.setData(new IVMContext[] { createVMContext(triggerContexts[0]) }); rm.done(); return; } } else if(e instanceof IContainerSuspendedDMEvent) { - IDMContext triggerContext = ((IContainerSuspendedDMEvent)e).getTriggeringContext(); - if (triggerContext != null) { - rm.setData(new IVMContext[] { createVMContext(triggerContext) }); + IExecutionDMContext[] triggerContexts = ((IContainerSuspendedDMEvent)e).getTriggeringContexts(); + if (triggerContexts.length != 0) { + rm.setData(new IVMContext[] { createVMContext(triggerContexts[0]) }); rm.done(); return; } @@ -274,15 +273,15 @@ public class ThreadVMNode extends AbstractDMVMNode public void buildDelta(Object e, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor rm) { if(e instanceof IContainerResumedDMEvent) { - IDMContext triggeringContext = ((IContainerResumedDMEvent)e).getTriggeringContext(); - if (triggeringContext != null) { - parentDelta.addNode(createVMContext(triggeringContext), IModelDelta.CONTENT); + IExecutionDMContext[] triggeringContexts = ((IContainerResumedDMEvent)e).getTriggeringContexts(); + if (triggeringContexts.length != 0) { + parentDelta.addNode(createVMContext(triggeringContexts[0]), IModelDelta.CONTENT); } rm.done(); } else if (e instanceof IContainerSuspendedDMEvent) { - IDMContext triggeringContext = ((IContainerSuspendedDMEvent)e).getTriggeringContext(); - if (triggeringContext != null) { - parentDelta.addNode(createVMContext(triggeringContext), IModelDelta.CONTENT); + IExecutionDMContext[] triggeringContexts = ((IContainerSuspendedDMEvent)e).getTriggeringContexts(); + if (triggeringContexts.length != 0) { + parentDelta.addNode(createVMContext(triggeringContexts[0]), IModelDelta.CONTENT); } rm.done(); } else if(e instanceof IResumedDMEvent || e instanceof ISuspendedDMEvent) { diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java index c0879ffed74..b87010fdc49 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java @@ -180,14 +180,15 @@ public class MIRunControl extends AbstractDsfService implements IRunControl protected static class ContainerSuspendedEvent extends SuspendedEvent implements IContainerSuspendedDMEvent { - final IExecutionDMContext triggeringDmc; + final IExecutionDMContext[] triggeringDmcs; ContainerSuspendedEvent(IContainerDMContext containerDmc, MIStoppedEvent miInfo, IExecutionDMContext triggeringDmc) { super(containerDmc, miInfo); - this.triggeringDmc = triggeringDmc; + this.triggeringDmcs = triggeringDmc != null + ? new IExecutionDMContext[] { triggeringDmc } : new IExecutionDMContext[0]; } - public IExecutionDMContext getTriggeringContext() { - return triggeringDmc; + public IExecutionDMContext[] getTriggeringContexts() { + return triggeringDmcs; } } @@ -223,15 +224,16 @@ public class MIRunControl extends AbstractDsfService implements IRunControl protected static class ContainerResumedEvent extends ResumedEvent implements IContainerResumedDMEvent { - final IExecutionDMContext triggeringDmc; + final IExecutionDMContext[] triggeringDmcs; ContainerResumedEvent(IContainerDMContext containerDmc, MIRunningEvent miInfo, IExecutionDMContext triggeringDmc) { super(containerDmc, miInfo); - this.triggeringDmc = triggeringDmc; + this.triggeringDmcs = triggeringDmc != null + ? new IExecutionDMContext[] { triggeringDmc } : new IExecutionDMContext[0]; } - public IExecutionDMContext getTriggeringContext() { - return triggeringDmc; + public IExecutionDMContext[] getTriggeringContexts() { + return triggeringDmcs; } } @@ -394,7 +396,8 @@ public class MIRunControl extends AbstractDsfService implements IRunControl fMICommandCache.setContextAvailable(e.getDMContext(), true); fMICommandCache.reset(); fStateChangeReason = e.getReason(); - fStateChangeTriggeringContext = e.getTriggeringContext(); + fStateChangeTriggeringContext = e.getTriggeringContexts().length != 0 + ? e.getTriggeringContexts()[0] : null; fSuspended = true; fStepping = false; } @@ -427,13 +430,23 @@ public class MIRunControl extends AbstractDsfService implements IRunControl /////////////////////////////////////////////////////////////////////////// // IRunControl - public boolean canResume(IExecutionDMContext context) { - return !fTerminated && isSuspended(context) && !fResumePending; + public void canResume(IExecutionDMContext context, DataRequestMonitor rm) { + rm.setData(doCanResume(context)); + rm.done(); + } + + private boolean doCanResume(IExecutionDMContext context) { + return !fTerminated && isSuspended(context) && !fResumePending; } - public boolean canSuspend(IExecutionDMContext context) { - return !fTerminated && !isSuspended(context); + public void canSuspend(IExecutionDMContext context, DataRequestMonitor rm) { + rm.setData(doCanSuspend(context)); + rm.done(); } + + private boolean doCanSuspend(IExecutionDMContext context) { + return !fTerminated && !isSuspended(context); + } public boolean isSuspended(IExecutionDMContext context) { return !fTerminated && fSuspended; @@ -446,7 +459,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl public void resume(IExecutionDMContext context, final RequestMonitor rm) { assert context != null; - if (canResume(context)) { + if (doCanResume(context)) { fResumePending = true; // Cygwin GDB will accept commands and execute them after the step // which is not what we want, so mark the target as unavailable @@ -482,7 +495,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl public void suspend(IExecutionDMContext context, final RequestMonitor rm){ assert context != null; - if (canSuspend(context)) { + if (doCanSuspend(context)) { MIExecInterrupt cmd = null; if(context instanceof IContainerDMContext){ cmd = new MIExecInterrupt(context); @@ -511,8 +524,8 @@ public class MIRunControl extends AbstractDsfService implements IRunControl } } - public boolean canStep(IExecutionDMContext context, StepType stepType) { - return canResume(context); + public void canStep(IExecutionDMContext context, StepType stepType, DataRequestMonitor rm) { + canResume(context, rm); } public void step(IExecutionDMContext context, StepType stepType, final RequestMonitor rm) { @@ -525,7 +538,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl return; } - if (!canResume(context)) { + if (!doCanResume(context)) { rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_STATE, "Cannot resume context", null)); //$NON-NLS-1$ rm.done(); return; @@ -567,15 +580,6 @@ public class MIRunControl extends AbstractDsfService implements IRunControl } } - public boolean canInstructionStep(IExecutionDMContext context, StepType stepType) { - return false; - } - - public void instructionStep(IExecutionDMContext context, StepType stepType, RequestMonitor rm) { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, "Operation not implemented", null)); //$NON-NLS-1$ - rm.done(); - } - public void getExecutionContexts(final IContainerDMContext containerDmc, final DataRequestMonitor rm) { fMICommandCache.execute( new MIThreadListIds(containerDmc), @@ -631,7 +635,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl return; } - if (canResume(context)) { + if (doCanResume(context)) { fResumePending = true; fMICommandCache.setContextAvailable(context, false); fConnection.queueCommand(new MIExecUntil(dmc, fileName + ":" + lineNo), //$NON-NLS-1$ From af4f8c99e1c134f7dbad28f94ffcd92c22d0834f Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 28 Mar 2008 18:21:36 +0000 Subject: [PATCH 350/834] [202510] Changed the IRegisters.getBitFields() method to take a generic IDMContext argument. --- .../src/org/eclipse/dd/dsf/debug/service/IRegisters.java | 2 +- .../src/org/eclipse/dd/mi/service/MIRegisters.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java index 2de1e39d168..afd2193a50f 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java @@ -152,7 +152,7 @@ public interface IRegisters extends IFormattedValues { * @param ctx Context for the returned data. * @param rm Request completion monitor. */ - void getBitFields(IRegisterDMContext ctx, DataRequestMonitor rm); + void getBitFields(IDMContext ctx, DataRequestMonitor rm); /** * Writes a register value for a given register to the target diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRegisters.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRegisters.java index 222464175d2..e4aaca93a0a 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRegisters.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRegisters.java @@ -490,7 +490,7 @@ public class MIRegisters extends AbstractDsfService implements IRegisters { * (non-Javadoc) * @see org.eclipse.dd.dsf.debug.service.IRegisters#getBitFields(org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) */ - public void getBitFields( IRegisterDMContext regDmc , DataRequestMonitor rm ) { + public void getBitFields( IDMContext regDmc , DataRequestMonitor rm ) { rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, "BitField not supported", null)); //$NON-NLS-1$ rm.done(); } From 72792685eec8abf27d37b44de19dbec0e4f319a2 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Fri, 28 Mar 2008 18:39:04 +0000 Subject: [PATCH 351/834] Fixing typo in Assert --- .../src/org/eclipse/dd/tests/gdb/MIRunControlTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRunControlTest.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRunControlTest.java index 6841238a1be..7f65a32a858 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRunControlTest.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRunControlTest.java @@ -273,7 +273,7 @@ public class MIRunControlTest extends BaseTestCase { /* * getModelData should return StateChangeReason. */ - Assert.assertTrue(" State change reason for a normal execution should be CONTAINER." , + Assert.assertTrue(" State change reason for a normal execution should be USER_REQUEST." , StateChangeReason.USER_REQUEST == data.getStateChangeReason()); } } @@ -397,7 +397,7 @@ public class MIRunControlTest extends BaseTestCase { /* * StateChangeReason in getModelData for Container DMC is null. */ - Assert.assertTrue(" State change reason for a normal execution should be CONTAINER." , + Assert.assertTrue(" State change reason for a normal execution should be USER_REQUEST." , StateChangeReason.USER_REQUEST == data.getStateChangeReason()); } } From e8207901088ab95896cdd0d57e3452eb5b773afc Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Fri, 28 Mar 2008 19:11:02 +0000 Subject: [PATCH 352/834] Bug 221505 Moves all extensions of org.eclipse.dd.gdb.launch.ui into org.eclipse.dd.gdb.launch. org.eclipse.dd.gdb.launch.ui will be removed --- .../META-INF/MANIFEST.MF | 3 +- .../icons/full/obj16/c_app.gif | Bin 0 -> 1042 bytes plugins/org.eclipse.dd.gdb.launch/plugin.xml | 26 ++++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 plugins/org.eclipse.dd.gdb.launch/icons/full/obj16/c_app.gif diff --git a/plugins/org.eclipse.dd.gdb.launch/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.gdb.launch/META-INF/MANIFEST.MF index 6b7f7e3c17f..b3c5d0dcbf3 100644 --- a/plugins/org.eclipse.dd.gdb.launch/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.gdb.launch/META-INF/MANIFEST.MF @@ -6,6 +6,7 @@ Bundle-SymbolicName: org.eclipse.dd.gdb.launch; singleton:=true Bundle-Version: 1.0.0 Bundle-Activator: org.eclipse.dd.gdb.launch.internal.GdbLaunchPlugin Require-Bundle: org.eclipse.core.runtime, - org.eclipse.dd.gdb + org.eclipse.dd.gdb, + org.eclipse.dd.gdb.ui Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/plugins/org.eclipse.dd.gdb.launch/icons/full/obj16/c_app.gif b/plugins/org.eclipse.dd.gdb.launch/icons/full/obj16/c_app.gif new file mode 100644 index 0000000000000000000000000000000000000000..805a1d0ab8b0dc4b86212fc35178db4d5af5a274 GIT binary patch literal 1042 zcmZ?wbhEHb6krfwcs_+eBWape%5?qo83ySyUCLIum9KWISnXN4#}3>Djrk z%_5_3Pe%WqWu4|Z6Zd6L+Pk{jtZ>Tu{K@kH=C2`df zhPA8MHmzk?v(zSI^TVy1g>$z)%HQ^A&koKl8@zU}EZMzN``}*oid|2(ZLB(anBmAl zsg?uJ_U&joa>Vw~{=~DVWF{PYari*P*)t}W&dHoVt9S04&atCqmoJK4zNmEZjQ{!b zLG#YM+Ij5w?&Bvmo_=xXmhS3HZ|~f;xOv<8&TZ?fSIQpVm%Vs9|IuUdhmU2p-+2Gv zLGtap8(zOPIDGHp<0n;b-Wt7mYxDGJ)zcS6Z$6m6eiQNWv;LV!pI^SIy#DaztJj_H zKZU*fnEdMX#LG{=eEq5a=408bSIb|&?|t*3_1Vj#@4uA3{ZjYsm+!a##;@LO`1RNB z(Yw!&KRmno`Tz3|pI(0W{Qm2SS0BE-{P_9Nmp_lb{(bS~`=f9F9)J7y|K1sz?nT;i3$qHU+=kB0C!VlFaEfHjx zXCWxS!QXGyAM)q-19l;mHO(xHmy+9Er`wzTEBtWzgy1!8*QS)h$4Wjj`kqEVJg0E1 zo~h*%Rj^R$xL1#q*dG}umeeCGI+@1~oGgBFY*M|@9|fu24gq;1ivt-8i_?$pXJ6zg v{^~RH$vLua-+ug + + + + + + + + + + + + From a74f59c186600ce183656f681585a1e35551e431 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Mon, 31 Mar 2008 01:32:37 +0000 Subject: [PATCH 353/834] Bug 202339 For a local launch, only gdb/mi debugger will be available, while for a remote launch, only gdbserver debugger will be available. This is a temporary solution. --- .../gdb/internal/ui/launching/CDebuggerTab.java | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/CDebuggerTab.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/CDebuggerTab.java index 17c0df7afe2..c9bbe45ce37 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/CDebuggerTab.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/CDebuggerTab.java @@ -212,15 +212,20 @@ public class CDebuggerTab extends AbstractCDebuggerTab { } String defaultSelection = selection; for (int i = 0; i < debugConfigs.length; i++) { - if (mode.equals(IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE) || debugConfigs[i].supportsMode(mode)) { + if ((mode.equals(IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE) + && debugConfigs[i].getName().equals("gdbserver Debugger")) || //$NON-NLS-1$ + (mode.equals(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN) + && debugConfigs[i].getName().equals("gdb/mi") && debugConfigs[i].supportsMode(mode)) || //$NON-NLS-1$ + (mode.equals(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_ATTACH) + && debugConfigs[i].getName().equals("gdb Debugger") && debugConfigs[i].supportsMode(mode))) { //$NON-NLS-1$ String debuggerPlatform = debugConfigs[i].getPlatform(); if (validatePlatform(config, debugConfigs[i])) { list.add(debugConfigs[i]); - // select first exact matching debugger for platform or - // requested selection - if ( (defaultSelection.equals("") && debuggerPlatform.equalsIgnoreCase(configPlatform))) { //$NON-NLS-1$ - defaultSelection = debugConfigs[i].getID(); - } +// // select first exact matching debugger for platform or +// // requested selection +// if ( (defaultSelection.equals("") && debuggerPlatform.equalsIgnoreCase(configPlatform))) { //$NON-NLS-1$ +// defaultSelection = debugConfigs[i].getID(); +// } } } } From bb57cba31b3560de5bdb434625d0617434e528d2 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Mon, 31 Mar 2008 14:33:32 +0000 Subject: [PATCH 354/834] Bug 202339 comment #3 Currently, DSF launches gdb with a argument, which tells gdb where the executable file and the symbols are. This is potentially restrictive to someone wanting to extend gdb. This change removes the argument to gdb and uses -file-exec-file and -file-symbol-file commands to set this parameter in the FinalLaunchSequence. This has the exact same effect, but allows to easily override these commands by using a tailored FinalLaunchSequence. --- .../launching/FinalLaunchSequence.java | 22 ++++++++++++ .../launching/ServicesLaunchSequence.java | 5 +-- .../service/command/GDBControl.java | 7 ++-- .../command/commands/MIFileExecFile.java | 36 +++++++++++++++++++ .../command/commands/MIFileSymbolFile.java | 35 ++++++++++++++++++ 5 files changed, 98 insertions(+), 7 deletions(-) create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIFileExecFile.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIFileSymbolFile.java diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java index aed438f0031..609311e9e34 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java @@ -32,6 +32,8 @@ import org.eclipse.dd.mi.service.command.commands.MIBreakInsert; import org.eclipse.dd.mi.service.command.commands.MICommand; import org.eclipse.dd.mi.service.command.commands.MIExecContinue; import org.eclipse.dd.mi.service.command.commands.MIExecRun; +import org.eclipse.dd.mi.service.command.commands.MIFileExecFile; +import org.eclipse.dd.mi.service.command.commands.MIFileSymbolFile; import org.eclipse.dd.mi.service.command.commands.MITargetSelect; import org.eclipse.dd.mi.service.command.output.MIBreakInsertInfo; import org.eclipse.dd.mi.service.command.output.MIInfo; @@ -51,6 +53,26 @@ public class FinalLaunchSequence extends Sequence { requestMonitor.done(); }}, + /* + * Specify the executable file to be debugged. + */ + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + fCommandControl.queueCommand( + new MIFileExecFile(fCommandControl.getControlDMContext(), + fCommandControl.getExecutablePath().toOSString()), + new DataRequestMonitor(getExecutor(), requestMonitor)); + }}, + /* + * Read symbol table. + */ + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + fCommandControl.queueCommand( + new MIFileSymbolFile(fCommandControl.getControlDMContext(), + fCommandControl.getExecutablePath().toOSString()), + new DataRequestMonitor(getExecutor(), requestMonitor)); + }}, /* * Setup the source paths */ diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/ServicesLaunchSequence.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/ServicesLaunchSequence.java index f5003ef691c..8dc218b1a26 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/ServicesLaunchSequence.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/ServicesLaunchSequence.java @@ -147,9 +147,10 @@ public class ServicesLaunchSequence extends Sequence { } private IPath getGDBPath() { - IPath retVal = new Path("gdb.exe"); //$NON-NLS-1$ + IPath retVal = new Path(IMILaunchConfigurationConstants.DEBUGGER_DEBUG_NAME_DEFAULT); try { - retVal = new Path( fLaunch.getLaunchConfiguration().getAttribute( IMILaunchConfigurationConstants.ATTR_DEBUG_NAME, IMILaunchConfigurationConstants.DEBUGGER_DEBUG_NAME_DEFAULT ) ); + retVal = new Path(fLaunch.getLaunchConfiguration().getAttribute(IMILaunchConfigurationConstants.ATTR_DEBUG_NAME, + IMILaunchConfigurationConstants.DEBUGGER_DEBUG_NAME_DEFAULT)); } catch (CoreException e) { } return retVal; diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java index ff2fd1e067e..09eee80da61 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java @@ -375,11 +375,8 @@ public class GDBControl extends AbstractMIControl { List commandList = new ArrayList(); commandList.add(fGdbPath.toOSString()); - if (fExecPath != null) { - commandList.add("--interpreter"); //$NON-NLS-1$ - commandList.add("mi"); //$NON-NLS-1$ - commandList.add(fExecPath.toOSString()); - } + commandList.add("--interpreter"); //$NON-NLS-1$ + commandList.add("mi"); //$NON-NLS-1$ String[] commandLine = commandList.toArray(new String[commandList.size()]); diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIFileExecFile.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIFileExecFile.java new file mode 100644 index 00000000000..97728cb4b6d --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIFileExecFile.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Ericsson - Modified for handling of contexts + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.mi.service.command.MIControlDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; + + +/** + * -file-exec-file [FILE] + * + * Specify the executable file to be debugged. Unlike `-file-exec-and-symbols', + * the symbol table is not read from this file. If used without argument, GDB + * clears the information about the executable file. No output is produced, + * except a completion notification. + */ +public class MIFileExecFile extends MICommand +{ + public MIFileExecFile(MIControlDMContext dmc, String file) { + super(dmc, "-file-exec-file", new String[] {file}); //$NON-NLS-1$ + } + + public MIFileExecFile(MIControlDMContext dmc) { + super(dmc, "-file-exec-file"); //$NON-NLS-1$ + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIFileSymbolFile.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIFileSymbolFile.java new file mode 100644 index 00000000000..83ab8883f70 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIFileSymbolFile.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * Ericsson - Modified for handling of contexts + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.mi.service.command.MIControlDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; + + +/** + * -file-symbol-file [FILE] + * + * Read symbol table info from the specified file argument. When used without + * arguments, clears GDB's symbol table info. No output is produced, except + * for a completion notification. + */ +public class MIFileSymbolFile extends MICommand +{ + public MIFileSymbolFile(MIControlDMContext dmc, String file) { + super(dmc, "-file-symbol-file", new String[] {file}); //$NON-NLS-1$ + } + + public MIFileSymbolFile(MIControlDMContext dmc) { + super(dmc, "-file-symbol-file"); //$NON-NLS-1$ + } +} From 76a46593678690fa76abadc7a7ee997ed0838622 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Mon, 31 Mar 2008 14:36:20 +0000 Subject: [PATCH 355/834] Give a way for the JUnit tests to specify which GDB to use. --- .../src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java index d1fa4bb92b1..a6202a0fce5 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java @@ -14,6 +14,7 @@ import java.util.HashMap; import java.util.Map; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; +import org.eclipse.cdt.debug.mi.core.IMILaunchConfigurationConstants; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.dd.gdb.internal.provisional.launching.GdbLaunch; import org.eclipse.dd.mi.service.command.events.MIStoppedEvent; @@ -56,6 +57,7 @@ public class BaseTestCase { attrs.put(ICDTLaunchConfigurationConstants.ATTR_USE_TERMINAL, true); attrs.put(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN, true); attrs.put(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN_SYMBOL, ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_SYMBOL_DEFAULT); + attrs.put(IMILaunchConfigurationConstants.ATTR_DEBUG_NAME, "gdb"); } @Before From 5542247e158a5480723722501b30c91e775f6448 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Mon, 31 Mar 2008 16:49:48 +0000 Subject: [PATCH 356/834] [223969] Make the CommandCache.setContextAvailable() optional. --- .../dsf/debug/service/command/CommandCache.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java index 7b7f91ddbf5..6982a8346c9 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java @@ -140,7 +140,7 @@ public class CommandCache implements ICommandListener * when back into individual results from this command. */ - private Set fAvailableContexts = new HashSet(); + private Set fUnavailableContexts = new HashSet(); private ICommandControl fCommandControl; @@ -439,11 +439,11 @@ public class CommandCache implements ICommandListener * TODO */ public void setContextAvailable(IDMContext context, boolean isAvailable) { - if (isAvailable) { - fAvailableContexts.add(context); + if (!isAvailable) { + fUnavailableContexts.add(context); } else { - fAvailableContexts.remove(context); - for (Iterator itr = fAvailableContexts.iterator(); itr.hasNext();) { + fUnavailableContexts.remove(context); + for (Iterator itr = fUnavailableContexts.iterator(); itr.hasNext();) { if (DMContexts.isAncestorOf(itr.next(), context)) { itr.remove(); } @@ -456,12 +456,12 @@ public class CommandCache implements ICommandListener * @see #setContextAvailable(IDMContext, boolean) */ public boolean isTargetAvailable(IDMContext context) { - for (IDMContext availableContext : fAvailableContexts) { + for (IDMContext availableContext : fUnavailableContexts) { if (context.equals(availableContext) || DMContexts.isAncestorOf(context, availableContext)) { - return true; + return false; } } - return false; + return true; } From deabab9f21be768d1a03187f6c40ecc90e5431c6 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Mon, 31 Mar 2008 17:00:28 +0000 Subject: [PATCH 357/834] [216803] Removed the getName() methos from Data Model contexts declared in IRegisters service interface. --- .../register/RegisterBitFieldVMNode.java | 66 +- .../register/RegisterGroupVMNode.java | 43 +- .../ui/viewmodel/register/RegisterVMNode.java | 54 +- .../register/SyncRegisterDataAccess.java | 581 ++++++++---------- .../dd/dsf/debug/service/IRegisters.java | 3 - .../eclipse/dd/tests/gdb/MIRegistersTest.java | 51 +- 6 files changed, 404 insertions(+), 394 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java index 1911cec30cd..90a40f5cc44 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java @@ -18,6 +18,7 @@ import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; +import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; @@ -32,7 +33,8 @@ import org.eclipse.dd.dsf.debug.service.IRegisters.IBitFieldDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IBitFieldDMData; import org.eclipse.dd.dsf.debug.service.IRegisters.IMnemonic; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext; -import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext; +import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMData; +import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMData; import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.AbstractExpressionVMNode; @@ -116,32 +118,22 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode } public String createWatchExpression(Object element) throws CoreException { - BitFieldVMC bitFieldVmc = ((BitFieldVMC)element); + IRegisterGroupDMData groupData = fDataAccess.getRegisterGroupDMData(element); + IRegisterDMData registerData = fDataAccess.getRegisterDMData(element); + IBitFieldDMData bitFieldData = fDataAccess.getBitFieldDMData(element); - StringBuffer exprBuf = new StringBuffer(); - IRegisterGroupDMContext groupDmc = - DMContexts.getAncestorOfType(bitFieldVmc.getDMContext(), IRegisterGroupDMContext.class); - if (groupDmc != null) { + if (groupData != null && registerData != null && bitFieldData != null) { + StringBuffer exprBuf = new StringBuffer(); exprBuf.append("$$\""); //$NON-NLS-1$ - exprBuf.append(groupDmc.getName()); + exprBuf.append(groupData.getName()); exprBuf.append('"'); - } - - IRegisterDMContext registerDmc = - DMContexts.getAncestorOfType(bitFieldVmc.getDMContext(), IRegisterDMContext.class); - if (registerDmc != null) { exprBuf.append('$'); - exprBuf.append(registerDmc.getName()); - } - - IBitFieldDMContext bitFieldDmc = - DMContexts.getAncestorOfType(bitFieldVmc.getDMContext(), IBitFieldDMContext.class); - if (bitFieldDmc != null) { + exprBuf.append(registerData.getName()); exprBuf.append('.'); - exprBuf.append(bitFieldDmc.getName()); + exprBuf.append(bitFieldData.getName()); + return exprBuf.toString(); } - - return exprBuf.toString(); + return null; } } @@ -512,7 +504,7 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode } @Override - protected void testElementForExpression(Object element, IExpression expression, DataRequestMonitor rm) { + protected void testElementForExpression(Object element, IExpression expression, final DataRequestMonitor rm) { if (!(element instanceof IDMVMContext)) { rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ rm.done(); @@ -526,13 +518,31 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode return; } - String bitFieldName = parseExpressionForBitFieldName(expression.getExpressionText()); - if (dmc.getName().equals(bitFieldName)) { - rm.setData(Boolean.TRUE); - } else { - rm.setData(Boolean.FALSE); + final String bitFieldName = parseExpressionForBitFieldName(expression.getExpressionText()); + try { + getSession().getExecutor().execute(new DsfRunnable() { + public void run() { + IRegisters registersService = getServicesTracker().getService(IRegisters.class); + if (registersService != null) { + registersService.getBitFieldData( + dmc, + new DataRequestMonitor(ImmediateExecutor.getInstance(), rm) { + @Override + protected void handleSuccess() { + rm.setData( getData().getName().equals(bitFieldName) ); + rm.done(); + } + }); + } else { + rm.setStatus(new Status(IStatus.WARNING, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Register service not available", null)); //$NON-NLS-1$ + rm.done(); + } + } + }); + } catch (RejectedExecutionException e) { + rm.setStatus(new Status(IStatus.WARNING, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "DSF session shut down", null)); //$NON-NLS-1$ + rm.done(); } - rm.done(); } public boolean canParseExpression(IExpression expression) { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java index afed1987537..0e98c9951c7 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java @@ -18,6 +18,7 @@ import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; +import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; @@ -102,13 +103,11 @@ public class RegisterGroupVMNode extends AbstractExpressionVMNode } public String createWatchExpression(Object element) throws CoreException { - RegisterGroupVMC registerVmc = ((RegisterGroupVMC)element); - - StringBuffer exprBuf = new StringBuffer(); - IRegisterGroupDMContext groupDmc = DMContexts.getAncestorOfType(registerVmc.getDMContext(), IRegisterGroupDMContext.class); - if (groupDmc != null) { + IRegisterGroupDMData groupData = fSyncRegisterDataAccess.getRegisterGroupDMData(element); + if (groupData != null) { + StringBuffer exprBuf = new StringBuffer(); exprBuf.append("$$\""); //$NON-NLS-1$ - exprBuf.append(groupDmc.getName()); + exprBuf.append(groupData.getName()); exprBuf.append('"'); return exprBuf.toString(); } @@ -328,7 +327,7 @@ public class RegisterGroupVMNode extends AbstractExpressionVMNode } @Override - protected void testElementForExpression(Object element, IExpression expression, DataRequestMonitor rm) { + protected void testElementForExpression(Object element, IExpression expression, final DataRequestMonitor rm) { if (!(element instanceof IDMVMContext)) { rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ rm.done(); @@ -341,13 +340,31 @@ public class RegisterGroupVMNode extends AbstractExpressionVMNode return; } - String groupName = parseExpressionForGroupName(expression.getExpressionText()); - if (dmc.getName().equals(groupName)) { - rm.setData(Boolean.TRUE); - } else { - rm.setData(Boolean.FALSE); + final String groupName = parseExpressionForGroupName(expression.getExpressionText()); + try { + getSession().getExecutor().execute(new DsfRunnable() { + public void run() { + IRegisters registersService = getServicesTracker().getService(IRegisters.class); + if (registersService != null) { + registersService.getRegisterGroupData( + dmc, + new DataRequestMonitor(ImmediateExecutor.getInstance(), rm) { + @Override + protected void handleSuccess() { + rm.setData( getData().getName().equals(groupName) ); + rm.done(); + } + }); + } else { + rm.setStatus(new Status(IStatus.WARNING, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Register service not available", null)); //$NON-NLS-1$ + rm.done(); + } + } + }); + } catch (RejectedExecutionException e) { + rm.setStatus(new Status(IStatus.WARNING, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "DSF session shut down", null)); //$NON-NLS-1$ + rm.done(); } - rm.done(); } @Override diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java index bdabd600730..3c4f6d587ce 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java @@ -18,6 +18,7 @@ import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; +import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; @@ -30,7 +31,7 @@ import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterChangedDMEvent; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMData; -import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext; +import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMData; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.AbstractExpressionVMNode; import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValuePreferenceStore; @@ -114,22 +115,15 @@ public class RegisterVMNode extends AbstractExpressionVMNode } public String createWatchExpression(Object element) throws CoreException { - RegisterVMC registerVmc = ((RegisterVMC)element); - - StringBuffer exprBuf = new StringBuffer(); - IRegisterGroupDMContext groupDmc = - DMContexts.getAncestorOfType(registerVmc.getDMContext(), IRegisterGroupDMContext.class); - if (groupDmc != null) { + IRegisterGroupDMData groupData = fSyncRegisterDataAccess.getRegisterGroupDMData(element); + IRegisterDMData registerData = fSyncRegisterDataAccess.getRegisterDMData(element); + if (groupData != null && registerData != null) { + StringBuffer exprBuf = new StringBuffer(); exprBuf.append("$$\""); //$NON-NLS-1$ - exprBuf.append(groupDmc.getName()); + exprBuf.append(groupData.getName()); exprBuf.append('"'); - } - - IRegisterDMContext registerDmc = - DMContexts.getAncestorOfType(registerVmc.getDMContext(), IRegisterDMContext.class); - if (registerDmc != null) { exprBuf.append('$'); - exprBuf.append(registerDmc.getName()); + exprBuf.append(registerData.getName()); return exprBuf.toString(); } @@ -485,7 +479,7 @@ public class RegisterVMNode extends AbstractExpressionVMNode } @Override - protected void testElementForExpression(Object element, IExpression expression, DataRequestMonitor rm) { + protected void testElementForExpression(Object element, IExpression expression, final DataRequestMonitor rm) { if (!(element instanceof IDMVMContext)) { rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ rm.done(); @@ -498,13 +492,31 @@ public class RegisterVMNode extends AbstractExpressionVMNode return; } - String regName = parseExpressionForRegisterName(expression.getExpressionText()); - if (dmc.getName().equals(regName)) { - rm.setData(Boolean.TRUE); - } else { - rm.setData(Boolean.FALSE); + final String regName = parseExpressionForRegisterName(expression.getExpressionText()); + try { + getSession().getExecutor().execute(new DsfRunnable() { + public void run() { + IRegisters registersService = getServicesTracker().getService(IRegisters.class); + if (registersService != null) { + registersService.getRegisterData( + dmc, + new DataRequestMonitor(ImmediateExecutor.getInstance(), rm) { + @Override + protected void handleSuccess() { + rm.setData( getData().getName().equals(regName) ); + rm.done(); + } + }); + } else { + rm.setStatus(new Status(IStatus.WARNING, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Register service not available", null)); //$NON-NLS-1$ + rm.done(); + } + } + }); + } catch (RejectedExecutionException e) { + rm.setStatus(new Status(IStatus.WARNING, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "DSF session shut down", null)); //$NON-NLS-1$ + rm.done(); } - rm.done(); } @Override diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java index 791dc864936..d9d4f883fb4 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java @@ -17,6 +17,7 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; +import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; import org.eclipse.dd.dsf.concurrent.Query; import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.concurrent.ThreadSafeAndProhibitedFromDsfExecutor; @@ -43,6 +44,45 @@ import org.osgi.util.tracker.ServiceTracker; @ThreadSafeAndProhibitedFromDsfExecutor("fSession#getExecutor") public class SyncRegisterDataAccess { + abstract public class RegistersServiceQuery extends Query { + + final protected K fDmc; + + public RegistersServiceQuery(K dmc) { + fDmc = dmc; + } + + @Override + protected void execute(final DataRequestMonitor rm) { + /* + * We're in another dispatch, so we must guard against executor + * shutdown again. + */ + final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); + if (session == null) { + cancel(false); + rm.done(); + return; + } + + /* + * Guard against a disposed service + */ + IRegisters service = getService(); + if (service == null) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, + "Service unavailable", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + doExecute(service, rm); + } + + abstract protected void doExecute(IRegisters registersService, DataRequestMonitor rm); + } + + /** * The session that this data access operates in. */ @@ -83,48 +123,26 @@ public class SyncRegisterDataAccess { } } - public class GetBitFieldValueQuery extends Query { - - private IBitFieldDMContext fDmc; + public class GetBitFieldValueQuery extends RegistersServiceQuery { public GetBitFieldValueQuery(IBitFieldDMContext dmc) { - super(); - fDmc = dmc; + super(dmc); } @Override - protected void execute(final DataRequestMonitor rm) { - /* - * Guard agains the session being disposed. If session is disposed - * it could mean that the executor is shut-down, which in turn could - * mean that we can't complete the RequestMonitor argument. in that - * case, cancel to notify waiting thread. - */ - final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); - if (session == null) { - cancel(false); - rm.done(); - return; - } - - IRegisters service = getService(); - if (service == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, - "Service not available", null)); //$NON-NLS-1$ - rm.done(); - return; - } - - service.getBitFieldData(fDmc, new DataRequestMonitor(session.getExecutor(), rm) { - @Override - protected void handleSuccess() { - /* - * All good set return value. - */ - rm.setData(getData()); - rm.done(); - } - }); + protected void doExecute(IRegisters service, final DataRequestMonitor rm) { + service.getBitFieldData( + fDmc, + new DataRequestMonitor(ImmediateExecutor.getInstance(), rm) { + @Override + protected void handleSuccess() { + /* + * All good set return value. + */ + rm.setData(getData()); + rm.done(); + } + }); } } @@ -171,59 +189,32 @@ public class SyncRegisterDataAccess { } } - public class SetBitFieldValueQuery extends Query { - - private IBitFieldDMContext fDmc; + public class SetBitFieldValueQuery extends RegistersServiceQuery { private String fValue; - private String fFormatId; public SetBitFieldValueQuery(IBitFieldDMContext dmc, String value, String formatId) { - super(); - fDmc = dmc; + super(dmc); fValue = value; fFormatId = formatId; } @Override - protected void execute(final DataRequestMonitor rm) { - /* - * We're in another dispatch, so we must guard against executor - * shutdown again. - */ - final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); - if (session == null) { - cancel(false); - rm.done(); - return; - } - - /* - * Guard against a disposed service - */ - IRegisters service = getService(); - if (service == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, - "Service unavailable", null)); //$NON-NLS-1$ - rm.done(); - return; - } - - /* - * Write the bit field using a string/format style. - */ - service.writeBitField(fDmc, fValue, fFormatId, new DataRequestMonitor(session - .getExecutor(), rm) { - @Override - protected void handleSuccess() { - /* - * All good set return value. - */ - rm.setData(new Object()); - rm.done(); - } - }); + protected void doExecute(IRegisters service, final DataRequestMonitor rm) { + // Write the bit field using a string/format style. + service.writeBitField( + fDmc, fValue, fFormatId, + new DataRequestMonitor(ImmediateExecutor.getInstance(), rm) { + @Override + protected void handleSuccess() { + /* + * All good set return value. + */ + rm.setData(new Object()); + rm.done(); + } + }); } } @@ -269,55 +260,29 @@ public class SyncRegisterDataAccess { } } - public class SetBitFieldValueMnemonicQuery extends Query { - - IBitFieldDMContext fDmc; - + public class SetBitFieldValueMnemonicQuery extends RegistersServiceQuery { IMnemonic fMnemonic; public SetBitFieldValueMnemonicQuery(IBitFieldDMContext dmc, IMnemonic mnemonic) { - super(); - fDmc = dmc; + super(dmc); fMnemonic = mnemonic; } @Override - protected void execute(final DataRequestMonitor rm) { - /* - * We're in another dispatch, so we must guard against executor - * shutdown again. - */ - final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); - if (session == null) { - cancel(false); - rm.done(); - return; - } - - /* - * Guard against a disposed service - */ - IRegisters service = getService(); - if (service == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, - "Service unavailable", null)); //$NON-NLS-1$ - rm.done(); - return; - } - - /* - * Write the bit field using the mnemonic style. - */ - service.writeBitField(fDmc, fMnemonic, new DataRequestMonitor(session.getExecutor(), rm) { - @Override - protected void handleSuccess() { - /* - * All good set return value. - */ - rm.setData(new Object()); - rm.done(); - } - }); + protected void doExecute(IRegisters service, final DataRequestMonitor rm) { + // Write the bit field using the mnemonic style. + service.writeBitField( + fDmc, fMnemonic, + new DataRequestMonitor(ImmediateExecutor.getInstance(), rm) { + @Override + protected void handleSuccess() { + /* + * All good set return value. + */ + rm.setData(new Object()); + rm.done(); + } + }); } } @@ -387,48 +352,25 @@ public class SyncRegisterDataAccess { return null; } - public class GetRegisterGroupValueQuery extends Query { - - IRegisterGroupDMContext fDmc; - + public class GetRegisterGroupValueQuery extends RegistersServiceQuery { public GetRegisterGroupValueQuery(IRegisterGroupDMContext dmc) { - super(); - fDmc = dmc; + super(dmc); } @Override - protected void execute(final DataRequestMonitor rm) { - /* - * Guard agains the session being disposed. If session is disposed - * it could mean that the executor is shut-down, which in turn could - * mean that we can't complete the RequestMonitor argument. in that - * case, cancel to notify waiting thread. - */ - final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); - if (session == null) { - cancel(false); - rm.done(); - return; - } - - IRegisters service = getService(); - if (service == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, - "Service not available", null)); //$NON-NLS-1$ - rm.done(); - return; - } - - service.getRegisterGroupData(fDmc, new DataRequestMonitor(session.getExecutor(), rm) { - @Override - protected void handleSuccess() { - /* - * All good set return value. - */ - rm.setData(getData()); - rm.done(); - } - }); + protected void doExecute(IRegisters service, final DataRequestMonitor rm) { + service.getRegisterGroupData( + fDmc, + new DataRequestMonitor(ImmediateExecutor.getInstance(), rm) { + @Override + protected void handleSuccess() { + /* + * All good set return value. + */ + rm.setData(getData()); + rm.done(); + } + }); } } @@ -467,48 +409,25 @@ public class SyncRegisterDataAccess { } } - public class GetRegisterValueQuery extends Query { - - IRegisterDMContext fDmc; - + public class GetRegisterValueQuery extends RegistersServiceQuery { public GetRegisterValueQuery(IRegisterDMContext dmc) { - super(); - fDmc = dmc; + super(dmc); } @Override - protected void execute(final DataRequestMonitor rm) { - /* - * Guard agains the session being disposed. If session is disposed - * it could mean that the executor is shut-down, which in turn could - * mean that we can't complete the RequestMonitor argument. in that - * case, cancel to notify waiting thread. - */ - final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); - if (session == null) { - cancel(false); - rm.done(); - return; - } - - IRegisters service = getService(); - if (service == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, - "Service not available", null)); //$NON-NLS-1$ - rm.done(); - return; - } - - service.getRegisterData(fDmc, new DataRequestMonitor(session.getExecutor(), rm) { - @Override - protected void handleSuccess() { - /* - * All good set return value. - */ - rm.setData(getData()); - rm.done(); - } - }); + protected void doExecute(IRegisters service, final DataRequestMonitor rm) { + service.getRegisterData( + fDmc, + new DataRequestMonitor(ImmediateExecutor.getInstance(), rm) { + @Override + protected void handleSuccess() { + /* + * All good set return value. + */ + rm.setData(getData()); + rm.done(); + } + }); } } @@ -547,63 +466,34 @@ public class SyncRegisterDataAccess { } } - public class SetRegisterValueQuery extends Query { - - private IRegisterDMContext fDmc; - + public class SetRegisterValueQuery extends RegistersServiceQuery { private String fValue; private String fFormatId; public SetRegisterValueQuery(IRegisterDMContext dmc, String value, String formatId) { - super(); - fDmc = dmc; + super(dmc); fValue = value; fFormatId = formatId; } @Override - protected void execute(final DataRequestMonitor rm) { - /* - * We're in another dispatch, so we must guard against executor - * shutdown again. - */ - final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); - if (session == null) { - cancel(false); - rm.done(); - return; - } - - /* - * Guard against a disposed service - */ - IRegisters service = getService(); - if (service == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, - "Service unavailable", null)); //$NON-NLS-1$ - rm.done(); - return; - } - - /* - * The interface does not currently have a write function. It needs - * to and now would seem to be the time to add it. - */ + protected void doExecute(IRegisters service, final DataRequestMonitor rm) { /* * Write the bit field using a string/format style. */ - service.writeRegister(fDmc, fValue, fFormatId, new DataRequestMonitor(session - .getExecutor(), rm) { - @Override - protected void handleSuccess() { - /* - * All good set return value. - */ - rm.setData(new Object()); - rm.done(); - } - }); + service.writeRegister( + fDmc, fValue, fFormatId, + new DataRequestMonitor(ImmediateExecutor.getInstance(), rm) { + @Override + protected void handleSuccess() { + /* + * All good set return value. + */ + rm.setData(new Object()); + rm.done(); + } + }); } } @@ -648,52 +538,15 @@ public class SyncRegisterDataAccess { } } - public class GetSupportFormatsValueQuery extends Query { - - IFormattedDataDMContext fDmc; + public class GetSupportFormatsValueQuery extends RegistersServiceQuery { public GetSupportFormatsValueQuery(IFormattedDataDMContext dmc) { - super(); - fDmc = dmc; + super(dmc); } @Override - protected void execute(final DataRequestMonitor rm) { - /* - * We're in another dispatch, so we must guard against executor - * shutdown again. - */ - final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); - if (session == null) { - cancel(false); - rm.done(); - return; - } - - /* - * Guard against a disposed service - */ - IRegisters service = getService(); - if (service == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, - "Service unavailable", null)); //$NON-NLS-1$ - rm.done(); - return; - } - - /* - * Write the bit field using a string/format style. - */ - service.getAvailableFormats(fDmc, new DataRequestMonitor(session.getExecutor(), rm) { - @Override - protected void handleSuccess() { - /* - * All good set return value. - */ - rm.setData(new Object()); - rm.done(); - } - }); + protected void doExecute(IRegisters service, final DataRequestMonitor rm) { + service.getAvailableFormats(fDmc, rm); } } @@ -730,7 +583,7 @@ public class SyncRegisterDataAccess { * data. */ try { - return (String[]) query.get(); + return query.get(); } catch (InterruptedException e) { assert false; return null; @@ -739,42 +592,17 @@ public class SyncRegisterDataAccess { } } - public class GetFormattedValueValueQuery extends Query { - - private IFormattedDataDMContext fDmc; + public class GetFormattedValueValueQuery extends RegistersServiceQuery { private String fFormatId; public GetFormattedValueValueQuery(IFormattedDataDMContext dmc, String formatId) { - super(); - fDmc = dmc; + super(dmc); fFormatId = formatId; } @Override - protected void execute(final DataRequestMonitor rm) { - /* - * We're in another dispatch, so we must guard against executor - * shutdown again. - */ - final DsfSession session = DsfSession.getSession(fDmc.getSessionId()); - if (session == null) { - cancel(false); - rm.done(); - return; - } - - /* - * Guard against a disposed service - */ - IRegisters service = getService(); - if (service == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, - "Service unavailable", null)); //$NON-NLS-1$ - rm.done(); - return; - } - + protected void doExecute(IRegisters service, final DataRequestMonitor rm) { /* * Convert to the proper formatting DMC then go get the formatted * value. @@ -782,17 +610,18 @@ public class SyncRegisterDataAccess { FormattedValueDMContext formDmc = service.getFormattedValueContext(fDmc, fFormatId); - service.getFormattedExpressionValue(formDmc, new DataRequestMonitor(session - .getExecutor(), rm) { - @Override - protected void handleSuccess() { - /* - * All good set return value. - */ - rm.setData(getData().getFormattedValue()); - rm.done(); - } - }); + service.getFormattedExpressionValue( + formDmc, + new DataRequestMonitor(ImmediateExecutor.getInstance(), rm) { + @Override + protected void handleSuccess() { + /* + * All good set return value. + */ + rm.setData(getData().getFormattedValue()); + rm.done(); + } + }); } } @@ -829,7 +658,7 @@ public class SyncRegisterDataAccess { * data. */ try { - return (String) query.get(); + return query.get(); } catch (InterruptedException e) { assert false; return null; @@ -871,7 +700,7 @@ public class SyncRegisterDataAccess { * data. */ try { - return (String) query.get(); + return query.get(); } catch (InterruptedException e) { assert false; return null; @@ -879,4 +708,106 @@ public class SyncRegisterDataAccess { return null; } } + + public class GetRegisterGroupDataQuery extends RegistersServiceQuery { + + public GetRegisterGroupDataQuery(IRegisterGroupDMContext dmc) { + super(dmc); + } + + @Override + protected void doExecute(IRegisters service, final DataRequestMonitor rm) { + service.getRegisterGroupData(fDmc, rm); + } + } + + public IRegisterGroupDMData getRegisterGroupDMData(Object element) { + IRegisterGroupDMContext dmc = null; + if (element instanceof IDMVMContext) { + dmc = DMContexts.getAncestorOfType( + ((IDMVMContext) element).getDMContext(), + IRegisterGroupDMContext.class); + } + + DsfSession session = DsfSession.getSession(dmc.getSessionId()); + + if (dmc != null && session != null) { + GetRegisterGroupDataQuery query = new GetRegisterGroupDataQuery(dmc); + session.getExecutor().execute(query); + + try { + return query.get(); + } catch (InterruptedException e) { + } catch (ExecutionException e) { + } + } + return null; + } + + + public class GetRegisterDataQuery extends RegistersServiceQuery { + + public GetRegisterDataQuery(IRegisterDMContext dmc) { + super(dmc); + } + + @Override + protected void doExecute(IRegisters service, final DataRequestMonitor rm) { + service.getRegisterData(fDmc, rm); + } + } + + public IRegisterDMData getRegisterDMData(Object element) { + IRegisterDMContext dmc = null; + if (element instanceof IDMVMContext) { + dmc = DMContexts.getAncestorOfType( ((IDMVMContext) element).getDMContext(), IRegisterDMContext.class ); + } + DsfSession session = DsfSession.getSession(dmc.getSessionId()); + + if (dmc != null && session != null) { + GetRegisterDataQuery query = new GetRegisterDataQuery(dmc); + session.getExecutor().execute(query); + + try { + return query.get(); + } catch (InterruptedException e) { + } catch (ExecutionException e) { + } + } + return null; + } + + public class GetBitFieldQuery extends RegistersServiceQuery { + + public GetBitFieldQuery(IBitFieldDMContext dmc) { + super(dmc); + } + + @Override + protected void doExecute(IRegisters service, final DataRequestMonitor rm) { + service.getBitFieldData(fDmc, rm); + } + } + + public IBitFieldDMData getBitFieldDMData(Object element) { + IBitFieldDMContext dmc = null; + if (element instanceof IDMVMContext) { + dmc = DMContexts.getAncestorOfType( ((IDMVMContext) element).getDMContext(), IBitFieldDMContext.class ); + } + DsfSession session = DsfSession.getSession(dmc.getSessionId()); + + if (dmc != null && session != null) { + GetBitFieldQuery query = new GetBitFieldQuery(dmc); + session.getExecutor().execute(query); + + try { + return query.get(); + } catch (InterruptedException e) { + } catch (ExecutionException e) { + } + } + return null; + } + + } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java index afd2193a50f..f96f134c295 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java @@ -32,7 +32,6 @@ public interface IRegisters extends IFormattedValues { /** Register group context */ public interface IRegisterGroupDMContext extends IFormattedDataDMContext { - public String getName(); } /** Event indicating values for the group have changed. */ @@ -52,7 +51,6 @@ public interface IRegisters extends IFormattedValues { /** Register context */ public interface IRegisterDMContext extends IFormattedDataDMContext { - public String getName(); } /** Event indicating register value changed. */ @@ -73,7 +71,6 @@ public interface IRegisters extends IFormattedValues { /** Bit field context */ public interface IBitFieldDMContext extends IFormattedDataDMContext { - public String getName(); } /** Event indicating register value changed. */ diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRegistersTest.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRegistersTest.java index 4dc7c5c6e6a..c3c109ccfec 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRegistersTest.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRegistersTest.java @@ -9,14 +9,19 @@ import java.util.List; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; +import org.eclipse.dd.dsf.concurrent.Query; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.dd.dsf.debug.service.IRegisters; import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext; import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext; +import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMData; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext; +import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMData; import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; @@ -189,9 +194,19 @@ public class MIRegistersTest extends BaseTestCase { public void getRegisterGroups() throws Throwable { final IRegisterGroupDMContext regGroupsDMC = getRegisterGroup(); + Query query = new Query() { + @Override + protected void execute(DataRequestMonitor rm) { + fRegService.getRegisterGroupData(regGroupsDMC, rm); + } + }; + fSession.getExecutor().execute(query); + + IRegisterGroupDMData data = query.get(); + assertTrue("The name of the main group should be: General Registers instead of: " + - regGroupsDMC.getName(), - regGroupsDMC.getName().equals("General Registers")); + data.getName(), + data.getName().equals("General Registers")); } @Test @@ -211,8 +226,36 @@ public class MIRegistersTest extends BaseTestCase { IFrameDMContext frameDmc = SyncUtil.SyncGetStackFrame(execDmc, 0); final IRegisterDMContext[] regDMCs = getRegisters(frameDmc); List regNames = Arrays.asList("eax","ecx","edx","ebx","esp","ebp","esi","edi","eip","eflags","cs","ss","ds","es","fs","gs","st0","st1","st2","st3","st4","st5","st6","st7","fctrl","fstat","ftag","fiseg","fioff","foseg","fooff","fop","xmm0","xmm1","xmm2","xmm3","xmm4","xmm5","xmm6","xmm7","mxcsr","orig_eax","mm0","mm1","mm2","mm3","mm4","mm5","mm6","mm7"); - for(IRegisterDMContext reg: regDMCs){ - String regName = reg.getName(); + + Query query = new Query() { + @Override + protected void execute(DataRequestMonitor rm) { + final IRegisterDMData[] datas = new IRegisterDMData[regDMCs.length]; + rm.setData(datas); + final CountingRequestMonitor countingRm = new CountingRequestMonitor(ImmediateExecutor.getInstance(), rm); + countingRm.setDoneCount(regDMCs.length); + for (int i = 0; i < regDMCs.length; i++) { + final int index = i; + fRegService.getRegisterData( + regDMCs[index], + new DataRequestMonitor(ImmediateExecutor.getInstance(), countingRm) { + @Override + protected void handleSuccess() { + datas[index] = getData(); + countingRm.done(); + } + }); + } + + } + }; + + fSession.getExecutor().execute(query); + + IRegisterDMData[] datas = query.get(); + + for(IRegisterDMData data: datas){ + String regName = data.getName(); Assert.assertFalse("GDB does not support register name: " + regName, !regNames.contains(regName)); } } From 1420d16bdd046b662a1da6a313b2a7c6ebec783a Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Mon, 31 Mar 2008 18:08:03 +0000 Subject: [PATCH 358/834] [224438] Renamed view model packages in org.eclipse.dd.dsf.debub.ui as a provisional API. --- .../META-INF/MANIFEST.MF | 20 +++++++++---------- .../org.eclipse.dd.dsf.debug.ui/plugin.xml | 16 +++++++-------- .../ui/viewmodel/IDebugVMConstants.java | 2 +- .../AbstractVMProviderActionDelegate.java | 2 +- .../expression/AbstractExpressionVMNode.java | 2 +- .../ExpressionColumnPresentation.java | 4 ++-- .../expression/ExpressionManagerVMNode.java | 6 +++--- .../expression/ExpressionVMProvider.java | 16 +++++++-------- .../ExpressionVMProviderContentStragegy.java | 2 +- ...xpressionVMProviderModelProxyStrategy.java | 2 +- .../expression/IExpressionUpdate.java | 2 +- .../expression/IExpressionVMNode.java | 2 +- .../expression/MessagesForExpressionVM.java | 4 ++-- .../expression/VMExpressionUpdate.java | 2 +- .../WatchExpressionCellModifier.java | 6 +++--- .../expression/WatchExpressionDelegate.java | 2 +- .../viewmodel/expression/messages.properties | 0 .../ui/viewmodel/launch/LaunchRootVMNode.java | 2 +- .../viewmodel/launch/StackFramesVMNode.java | 2 +- .../launch/StandardProcessVMNode.java | 2 +- .../viewmodel/modules/ModuleDetailPane.java | 2 +- .../modules/ModuleDetailPaneFactory.java | 2 +- .../ui/viewmodel/modules/ModulesVMNode.java | 2 +- .../viewmodel/modules/ModulesVMProvider.java | 2 +- .../numberformat/AbstractSetFormatStyle.java | 4 ++-- .../FormattedValuePreferenceStore.java | 4 ++-- .../IFormattedValuePreferenceStore.java | 2 +- .../IFormattedValueVMContext.java | 2 +- .../actions/SetDefaultFormatBinary.java | 4 ++-- .../actions/SetDefaultFormatDecimal.java | 4 ++-- .../actions/SetDefaultFormatHex.java | 4 ++-- .../actions/SetDefaultFormatNatural.java | 4 ++-- .../actions/SetDefaultFormatOctal.java | 4 ++-- .../register/MessagesForRegisterVM.java | 4 ++-- .../RegisterBitFieldCellModifier.java | 8 ++++---- .../register/RegisterBitFieldVMNode.java | 12 +++++------ .../register/RegisterCellModifier.java | 8 ++++---- .../register/RegisterColumnPresentation.java | 4 ++-- .../register/RegisterGroupVMNode.java | 8 ++++---- .../ui/viewmodel/register/RegisterVMNode.java | 10 +++++----- .../register/RegisterVMProvider.java | 6 +++--- .../register/SyncRegisterDataAccess.java | 2 +- .../ui/viewmodel/register/messages.properties | 0 .../update/BreakpointHitUpdatePolicy.java | 4 ++-- .../update/actions/RefreshActionDelegate.java | 4 ++-- .../actions/SelectUpdatePolicyAction.java | 4 ++-- .../variable/MessagesForVariablesVM.java | 4 ++-- .../variable/SyncVariableDataAccess.java | 2 +- .../variable/VariableCellModifier.java | 8 ++++---- .../variable/VariableColumnPresentation.java | 4 ++-- .../ui/viewmodel/variable/VariableVMNode.java | 12 +++++------ .../variable/VariableVMProvider.java | 6 +++--- .../ui/viewmodel/variable/messages.properties | 0 .../detail/MessagesForNumberFormatDetail.java | 2 +- .../pda/ui/viewmodel/PDAVMAdapter.java | 4 ++-- .../viewmodel/launch/PDALaunchVMProvider.java | 8 ++++---- .../ui/viewmodel/GdbViewModelAdapter.java | 8 ++++---- .../ui/viewmodel/launch/LaunchVMProvider.java | 8 ++++---- 58 files changed, 138 insertions(+), 138 deletions(-) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/IDebugVMConstants.java (93%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/actions/AbstractVMProviderActionDelegate.java (98%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/expression/AbstractExpressionVMNode.java (98%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/expression/ExpressionColumnPresentation.java (95%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/expression/ExpressionManagerVMNode.java (98%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/expression/ExpressionVMProvider.java (94%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/expression/ExpressionVMProviderContentStragegy.java (98%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/expression/ExpressionVMProviderModelProxyStrategy.java (98%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/expression/IExpressionUpdate.java (94%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/expression/IExpressionVMNode.java (96%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/expression/MessagesForExpressionVM.java (85%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/expression/VMExpressionUpdate.java (97%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/expression/WatchExpressionCellModifier.java (90%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/expression/WatchExpressionDelegate.java (94%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/expression/messages.properties (100%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/launch/LaunchRootVMNode.java (98%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/launch/StackFramesVMNode.java (99%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/launch/StandardProcessVMNode.java (99%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/modules/ModuleDetailPane.java (99%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/modules/ModuleDetailPaneFactory.java (95%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/modules/ModulesVMNode.java (98%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/modules/ModulesVMProvider.java (96%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/numberformat/AbstractSetFormatStyle.java (97%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/numberformat/FormattedValuePreferenceStore.java (90%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/numberformat/IFormattedValuePreferenceStore.java (92%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/numberformat/IFormattedValueVMContext.java (90%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/numberformat/actions/SetDefaultFormatBinary.java (80%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/numberformat/actions/SetDefaultFormatDecimal.java (80%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/numberformat/actions/SetDefaultFormatHex.java (80%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/numberformat/actions/SetDefaultFormatNatural.java (80%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/numberformat/actions/SetDefaultFormatOctal.java (80%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/register/MessagesForRegisterVM.java (76%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/register/RegisterBitFieldCellModifier.java (95%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/register/RegisterBitFieldVMNode.java (97%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/register/RegisterCellModifier.java (94%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/register/RegisterColumnPresentation.java (94%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/register/RegisterGroupVMNode.java (97%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/register/RegisterVMNode.java (98%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/register/RegisterVMProvider.java (93%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/register/SyncRegisterDataAccess.java (99%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/register/messages.properties (100%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/update/BreakpointHitUpdatePolicy.java (89%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/update/actions/RefreshActionDelegate.java (90%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/update/actions/SelectUpdatePolicyAction.java (95%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/variable/MessagesForVariablesVM.java (76%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/variable/SyncVariableDataAccess.java (99%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/variable/VariableCellModifier.java (92%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/variable/VariableColumnPresentation.java (95%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/variable/VariableVMNode.java (98%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/variable/VariableVMProvider.java (92%) rename plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/{ => internal/provisional}/ui/viewmodel/variable/messages.properties (100%) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF index fd7fe663941..4ede97ef39d 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF @@ -21,17 +21,17 @@ Require-Bundle: org.eclipse.ui, org.eclipse.cdt.debug.ui Bundle-ActivationPolicy: lazy Export-Package: + org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel, + org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression, + org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch, + org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.modules, + org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat, + org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.register, + org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.update, + org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.update.actions, + org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.variable, org.eclipse.dd.dsf.debug.ui, org.eclipse.dd.dsf.debug.ui.actions, org.eclipse.dd.dsf.debug.ui.contexts, - org.eclipse.dd.dsf.debug.ui.sourcelookup, - org.eclipse.dd.dsf.debug.ui.viewmodel, - org.eclipse.dd.dsf.debug.ui.viewmodel.expression, - org.eclipse.dd.dsf.debug.ui.viewmodel.launch, - org.eclipse.dd.dsf.debug.ui.viewmodel.modules, - org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat, - org.eclipse.dd.dsf.debug.ui.viewmodel.register, - org.eclipse.dd.dsf.debug.ui.viewmodel.update, - org.eclipse.dd.dsf.debug.ui.viewmodel.update.actions, - org.eclipse.dd.dsf.debug.ui.viewmodel.variable + org.eclipse.dd.dsf.debug.ui.sourcelookup Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml index 1c4c74cc81f..7bee3bc9d1c 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml +++ b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml @@ -4,7 +4,7 @@ + delegateClass="org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression.WatchExpressionDelegate"/> @@ -56,7 +56,7 @@ id="org.eclipse.dd.dsf.debug.ui.viewmodel.update.Refresh" targetID="org.eclipse.debug.ui.RegisterView"> @@ -99,7 +99,7 @@ id="org.eclipse.dd.dsf.debug.ui.update.register.updatePolicies" targetID="org.eclipse.debug.ui.RegisterView"> @@ -115,13 +115,13 @@ - + diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/IDebugVMConstants.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/IDebugVMConstants.java similarity index 93% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/IDebugVMConstants.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/IDebugVMConstants.java index 213728fcc94..6c29058deee 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/IDebugVMConstants.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/IDebugVMConstants.java @@ -1,4 +1,4 @@ -package org.eclipse.dd.dsf.debug.ui.viewmodel; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel; import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/actions/AbstractVMProviderActionDelegate.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/actions/AbstractVMProviderActionDelegate.java similarity index 98% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/actions/AbstractVMProviderActionDelegate.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/actions/AbstractVMProviderActionDelegate.java index 5e262b409f4..47d20109b8c 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/actions/AbstractVMProviderActionDelegate.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/actions/AbstractVMProviderActionDelegate.java @@ -9,7 +9,7 @@ * Ted R Williams (Wind River Systems, Inc.) - initial implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.actions; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.actions; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.dd.dsf.ui.viewmodel.IVMAdapter; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/AbstractExpressionVMNode.java similarity index 98% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionVMNode.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/AbstractExpressionVMNode.java index 23e382e13fb..f9ae608f3e3 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/AbstractExpressionVMNode.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression; import java.util.List; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionColumnPresentation.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/ExpressionColumnPresentation.java similarity index 95% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionColumnPresentation.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/ExpressionColumnPresentation.java index 01d249ccea8..311b8f36301 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionColumnPresentation.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/ExpressionColumnPresentation.java @@ -8,10 +8,10 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.IDebugVMConstants; import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; -import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.jface.resource.ImageDescriptor; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/ExpressionManagerVMNode.java similarity index 98% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerVMNode.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/ExpressionManagerVMNode.java index f9e67bd53f9..46db0162f08 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/ExpressionManagerVMNode.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression; import java.util.LinkedList; import java.util.List; @@ -16,8 +16,8 @@ import java.util.List; import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; -import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.ExpressionVMProvider.ExpressionsChangedEvent; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.IDebugVMConstants; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression.ExpressionVMProvider.ExpressionsChangedEvent; import org.eclipse.dd.dsf.ui.concurrent.ViewerCountingRequestMonitor; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMContext; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMNode; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/ExpressionVMProvider.java similarity index 94% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/ExpressionVMProvider.java index b9613fe4980..536b1aeab30 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/ExpressionVMProvider.java @@ -8,20 +8,20 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.FormattedValuePreferenceStore; -import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterGroupVMNode; -import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterVMNode; -import org.eclipse.dd.dsf.debug.ui.viewmodel.register.SyncRegisterDataAccess; -import org.eclipse.dd.dsf.debug.ui.viewmodel.update.BreakpointHitUpdatePolicy; -import org.eclipse.dd.dsf.debug.ui.viewmodel.variable.SyncVariableDataAccess; -import org.eclipse.dd.dsf.debug.ui.viewmodel.variable.VariableVMNode; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat.FormattedValuePreferenceStore; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.register.RegisterGroupVMNode; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.register.RegisterVMNode; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.register.SyncRegisterDataAccess; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.update.BreakpointHitUpdatePolicy; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.variable.SyncVariableDataAccess; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.variable.VariableVMNode; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; import org.eclipse.dd.dsf.ui.viewmodel.DefaultVMContentProviderStrategy; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderContentStragegy.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/ExpressionVMProviderContentStragegy.java similarity index 98% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderContentStragegy.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/ExpressionVMProviderContentStragegy.java index 9b3eb6e0623..e9db8566eac 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderContentStragegy.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/ExpressionVMProviderContentStragegy.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderModelProxyStrategy.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/ExpressionVMProviderModelProxyStrategy.java similarity index 98% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderModelProxyStrategy.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/ExpressionVMProviderModelProxyStrategy.java index 187cec3fa88..4ae4e1271d4 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProviderModelProxyStrategy.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/ExpressionVMProviderModelProxyStrategy.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression; import java.util.Map; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionUpdate.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/IExpressionUpdate.java similarity index 94% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionUpdate.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/IExpressionUpdate.java index 822a4ec0cc2..f44df01ab56 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionUpdate.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/IExpressionUpdate.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression; import org.eclipse.debug.core.model.IExpression; import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/IExpressionVMNode.java similarity index 96% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionVMNode.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/IExpressionVMNode.java index ffe51869417..aa00c6472ab 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/IExpressionVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/IExpressionVMNode.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.ui.viewmodel.IVMNode; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/MessagesForExpressionVM.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/MessagesForExpressionVM.java similarity index 85% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/MessagesForExpressionVM.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/MessagesForExpressionVM.java index acc8b005c96..c0d8db72b58 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/MessagesForExpressionVM.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/MessagesForExpressionVM.java @@ -1,9 +1,9 @@ -package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression; import org.eclipse.osgi.util.NLS; public class MessagesForExpressionVM extends NLS { - private static final String BUNDLE_NAME = "org.eclipse.dd.dsf.debug.ui.viewmodel.expression.messages"; //$NON-NLS-1$ + private static final String BUNDLE_NAME = "org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression.messages"; //$NON-NLS-1$ public static String ExpressionColumnPresentation_expression; public static String ExpressionColumnPresentation_name; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/VMExpressionUpdate.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/VMExpressionUpdate.java similarity index 97% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/VMExpressionUpdate.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/VMExpressionUpdate.java index 693fd8b152e..4ddac33d19b 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/VMExpressionUpdate.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/VMExpressionUpdate.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/WatchExpressionCellModifier.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/WatchExpressionCellModifier.java similarity index 90% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/WatchExpressionCellModifier.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/WatchExpressionCellModifier.java index c1fde17b8af..e1b486c7cba 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/WatchExpressionCellModifier.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/WatchExpressionCellModifier.java @@ -8,12 +8,12 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.dd.dsf.concurrent.ThreadSafeAndProhibitedFromDsfExecutor; -import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; -import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.ExpressionManagerVMNode.NewExpressionVMC; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.IDebugVMConstants; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression.ExpressionManagerVMNode.NewExpressionVMC; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.IExpressionManager; import org.eclipse.debug.core.model.IWatchExpression; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/WatchExpressionDelegate.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/WatchExpressionDelegate.java similarity index 94% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/WatchExpressionDelegate.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/WatchExpressionDelegate.java index 0d0bd695dc7..38fd09cb3c4 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/WatchExpressionDelegate.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/WatchExpressionDelegate.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.model.IDebugElement; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/messages.properties b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/messages.properties similarity index 100% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/messages.properties rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/messages.properties diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/LaunchRootVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/LaunchRootVMNode.java similarity index 98% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/LaunchRootVMNode.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/LaunchRootVMNode.java index bd39dd7271f..a34b1715449 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/LaunchRootVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/LaunchRootVMNode.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.launch; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch; import java.util.Arrays; import java.util.List; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/StackFramesVMNode.java similarity index 99% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/StackFramesVMNode.java index 89023c461e3..aa89b9e9cbd 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/StackFramesVMNode.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.launch; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch; import java.util.List; import java.util.concurrent.RejectedExecutionException; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/StandardProcessVMNode.java similarity index 99% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessVMNode.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/StandardProcessVMNode.java index 9a0a4cb0e20..318b12601a7 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/launch/StandardProcessVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/StandardProcessVMNode.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.launch; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMContext; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPane.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/modules/ModuleDetailPane.java similarity index 99% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPane.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/modules/ModuleDetailPane.java index 3eeb02d9716..da36a7a58f9 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPane.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/modules/ModuleDetailPane.java @@ -11,7 +11,7 @@ * Wind River Systems - adopted to use with Modules view * Ericsson AB - Modules view for DSF implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.modules; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.modules; import java.util.concurrent.ExecutionException; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPaneFactory.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/modules/ModuleDetailPaneFactory.java similarity index 95% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPaneFactory.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/modules/ModuleDetailPaneFactory.java index 745cf413e35..480561c9f6a 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModuleDetailPaneFactory.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/modules/ModuleDetailPaneFactory.java @@ -8,7 +8,7 @@ * Contributors: * Ericsson AB - Modules view for DSF implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.modules; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.modules; import java.util.HashSet; import java.util.Set; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/modules/ModulesVMNode.java similarity index 98% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMNode.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/modules/ModulesVMNode.java index cbad5058e92..2714b2d606b 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/modules/ModulesVMNode.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.modules; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.modules; import java.util.concurrent.RejectedExecutionException; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/modules/ModulesVMProvider.java similarity index 96% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMProvider.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/modules/ModulesVMProvider.java index 231bb84d748..30ec06400ea 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/modules/ModulesVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/modules/ModulesVMProvider.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.modules; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.modules; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/AbstractSetFormatStyle.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/numberformat/AbstractSetFormatStyle.java similarity index 97% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/AbstractSetFormatStyle.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/numberformat/AbstractSetFormatStyle.java index 39bf8fda798..a804c176099 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/AbstractSetFormatStyle.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/numberformat/AbstractSetFormatStyle.java @@ -8,10 +8,10 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.IDebugVMConstants; import org.eclipse.dd.dsf.debug.service.IFormattedValues; -import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext; import org.eclipse.debug.core.model.IDebugElement; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/FormattedValuePreferenceStore.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/numberformat/FormattedValuePreferenceStore.java similarity index 90% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/FormattedValuePreferenceStore.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/numberformat/FormattedValuePreferenceStore.java index b2e5659a6df..5cddbb80660 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/FormattedValuePreferenceStore.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/numberformat/FormattedValuePreferenceStore.java @@ -8,10 +8,10 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.IDebugVMConstants; import org.eclipse.dd.dsf.debug.service.IFormattedValues; -import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; /** diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/IFormattedValuePreferenceStore.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/numberformat/IFormattedValuePreferenceStore.java similarity index 92% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/IFormattedValuePreferenceStore.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/numberformat/IFormattedValuePreferenceStore.java index bb334ed9e56..0b052b60006 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/IFormattedValuePreferenceStore.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/numberformat/IFormattedValuePreferenceStore.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/IFormattedValueVMContext.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/numberformat/IFormattedValueVMContext.java similarity index 90% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/IFormattedValueVMContext.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/numberformat/IFormattedValueVMContext.java index 6993af6f0fb..1d81f558b89 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/IFormattedValueVMContext.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/numberformat/IFormattedValueVMContext.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/actions/SetDefaultFormatBinary.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/numberformat/actions/SetDefaultFormatBinary.java similarity index 80% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/actions/SetDefaultFormatBinary.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/numberformat/actions/SetDefaultFormatBinary.java index a1c24053d7c..5e5c2e31c80 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/actions/SetDefaultFormatBinary.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/numberformat/actions/SetDefaultFormatBinary.java @@ -8,10 +8,10 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.actions; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat.actions; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat.AbstractSetFormatStyle; import org.eclipse.dd.dsf.debug.service.IFormattedValues; -import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.AbstractSetFormatStyle; @SuppressWarnings("restriction") public class SetDefaultFormatBinary extends AbstractSetFormatStyle { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/actions/SetDefaultFormatDecimal.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/numberformat/actions/SetDefaultFormatDecimal.java similarity index 80% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/actions/SetDefaultFormatDecimal.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/numberformat/actions/SetDefaultFormatDecimal.java index ce2aa237b31..a7b7bba785b 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/actions/SetDefaultFormatDecimal.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/numberformat/actions/SetDefaultFormatDecimal.java @@ -8,10 +8,10 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.actions; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat.actions; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat.AbstractSetFormatStyle; import org.eclipse.dd.dsf.debug.service.IFormattedValues; -import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.AbstractSetFormatStyle; @SuppressWarnings("restriction") public class SetDefaultFormatDecimal extends AbstractSetFormatStyle { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/actions/SetDefaultFormatHex.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/numberformat/actions/SetDefaultFormatHex.java similarity index 80% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/actions/SetDefaultFormatHex.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/numberformat/actions/SetDefaultFormatHex.java index e193c685959..919b7938e89 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/actions/SetDefaultFormatHex.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/numberformat/actions/SetDefaultFormatHex.java @@ -8,10 +8,10 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.actions; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat.actions; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat.AbstractSetFormatStyle; import org.eclipse.dd.dsf.debug.service.IFormattedValues; -import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.AbstractSetFormatStyle; @SuppressWarnings("restriction") public class SetDefaultFormatHex extends AbstractSetFormatStyle { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/actions/SetDefaultFormatNatural.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/numberformat/actions/SetDefaultFormatNatural.java similarity index 80% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/actions/SetDefaultFormatNatural.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/numberformat/actions/SetDefaultFormatNatural.java index 60e83c20362..a03f03793e3 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/actions/SetDefaultFormatNatural.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/numberformat/actions/SetDefaultFormatNatural.java @@ -8,10 +8,10 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.actions; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat.actions; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat.AbstractSetFormatStyle; import org.eclipse.dd.dsf.debug.service.IFormattedValues; -import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.AbstractSetFormatStyle; @SuppressWarnings("restriction") public class SetDefaultFormatNatural extends AbstractSetFormatStyle { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/actions/SetDefaultFormatOctal.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/numberformat/actions/SetDefaultFormatOctal.java similarity index 80% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/actions/SetDefaultFormatOctal.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/numberformat/actions/SetDefaultFormatOctal.java index edf05b5fb49..cf257035286 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/numberformat/actions/SetDefaultFormatOctal.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/numberformat/actions/SetDefaultFormatOctal.java @@ -8,10 +8,10 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.actions; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat.actions; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat.AbstractSetFormatStyle; import org.eclipse.dd.dsf.debug.service.IFormattedValues; -import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.AbstractSetFormatStyle; @SuppressWarnings("restriction") public class SetDefaultFormatOctal extends AbstractSetFormatStyle { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/MessagesForRegisterVM.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/MessagesForRegisterVM.java similarity index 76% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/MessagesForRegisterVM.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/MessagesForRegisterVM.java index c0ef4c28346..d71f175acd1 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/MessagesForRegisterVM.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/MessagesForRegisterVM.java @@ -1,9 +1,9 @@ -package org.eclipse.dd.dsf.debug.ui.viewmodel.register; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.register; import org.eclipse.osgi.util.NLS; public class MessagesForRegisterVM extends NLS { - private static final String BUNDLE_NAME = "org.eclipse.dd.dsf.debug.ui.viewmodel.register.messages"; //$NON-NLS-1$ + private static final String BUNDLE_NAME = "org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.register.messages"; //$NON-NLS-1$ public static String RegisterColumnPresentation_description; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldCellModifier.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterBitFieldCellModifier.java similarity index 95% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldCellModifier.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterBitFieldCellModifier.java index 67bc504f975..249cc66f1a1 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldCellModifier.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterBitFieldCellModifier.java @@ -4,17 +4,17 @@ * * Copyright 2007 Wind River Systems Inc. All rights reserved. */ -package org.eclipse.dd.dsf.debug.ui.viewmodel.register; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.register; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.IDebugVMConstants; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression.WatchExpressionCellModifier; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat.IFormattedValuePreferenceStore; import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.dd.dsf.debug.service.IRegisters.IBitFieldDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IBitFieldDMData; import org.eclipse.dd.dsf.debug.service.IRegisters.IMnemonic; -import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; -import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionCellModifier; -import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValuePreferenceStore; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext; import org.eclipse.dd.dsf.ui.viewmodel.update.AbstractCachingVMProvider; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterBitFieldVMNode.java similarity index 97% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterBitFieldVMNode.java index 90a40f5cc44..9abb624b0a6 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterBitFieldVMNode.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.register; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.register; import java.util.concurrent.RejectedExecutionException; @@ -22,6 +22,11 @@ import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.IDebugVMConstants; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression.AbstractExpressionVMNode; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat.IFormattedValuePreferenceStore; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat.IFormattedValueVMContext; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.register.RegisterBitFieldCellModifier.BitFieldEditorStyle; import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.dd.dsf.debug.service.IRegisters; @@ -36,11 +41,6 @@ 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.IRegisterGroupDMData; import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent; -import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; -import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.AbstractExpressionVMNode; -import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValuePreferenceStore; -import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValueVMContext; -import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterBitFieldCellModifier.BitFieldEditorStyle; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterCellModifier.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterCellModifier.java similarity index 94% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterCellModifier.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterCellModifier.java index 0b28160e064..11497a9d7de 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterCellModifier.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterCellModifier.java @@ -8,16 +8,16 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.register; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.register; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.IDebugVMConstants; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression.WatchExpressionCellModifier; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat.IFormattedValuePreferenceStore; import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMData; -import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; -import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionCellModifier; -import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValuePreferenceStore; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext; import org.eclipse.dd.dsf.ui.viewmodel.update.AbstractCachingVMProvider; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterColumnPresentation.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterColumnPresentation.java similarity index 94% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterColumnPresentation.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterColumnPresentation.java index 360a29a1de8..8daddc7b060 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterColumnPresentation.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterColumnPresentation.java @@ -8,10 +8,10 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.register; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.register; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.IDebugVMConstants; import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; -import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.jface.resource.ImageDescriptor; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterGroupVMNode.java similarity index 97% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterGroupVMNode.java index 0e98c9951c7..6c93c0ad4cd 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterGroupVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterGroupVMNode.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.register; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.register; import java.util.concurrent.RejectedExecutionException; @@ -22,15 +22,15 @@ import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.IDebugVMConstants; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression.AbstractExpressionVMNode; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression.WatchExpressionCellModifier; import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.service.IRegisters; import org.eclipse.dd.dsf.debug.service.IRunControl; import org.eclipse.dd.dsf.debug.service.IRegisters.IGroupChangedDMEvent; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMData; -import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; -import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.AbstractExpressionVMNode; -import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionCellModifier; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterVMNode.java similarity index 98% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterVMNode.java index 3c4f6d587ce..22d0980ac67 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterVMNode.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.register; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.register; import java.util.concurrent.RejectedExecutionException; @@ -22,6 +22,10 @@ import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.IDebugVMConstants; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression.AbstractExpressionVMNode; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat.IFormattedValuePreferenceStore; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat.IFormattedValueVMContext; import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.dd.dsf.debug.service.IRegisters; @@ -32,10 +36,6 @@ import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterChangedDMEvent; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMData; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMData; -import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; -import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.AbstractExpressionVMNode; -import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValuePreferenceStore; -import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValueVMContext; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterVMProvider.java similarity index 93% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterVMProvider.java index e1ec8cefae0..06f08e1ed0e 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterVMProvider.java @@ -8,10 +8,10 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.register; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.register; -import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.FormattedValuePreferenceStore; -import org.eclipse.dd.dsf.debug.ui.viewmodel.update.BreakpointHitUpdatePolicy; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat.FormattedValuePreferenceStore; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.update.BreakpointHitUpdatePolicy; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; import org.eclipse.dd.dsf.ui.viewmodel.IRootVMNode; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/SyncRegisterDataAccess.java similarity index 99% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/SyncRegisterDataAccess.java index d9d4f883fb4..c39d2e5fb45 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/SyncRegisterDataAccess.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/SyncRegisterDataAccess.java @@ -9,7 +9,7 @@ * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.register; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.register; import java.util.concurrent.ExecutionException; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/messages.properties b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/messages.properties similarity index 100% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/messages.properties rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/messages.properties diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/BreakpointHitUpdatePolicy.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/update/BreakpointHitUpdatePolicy.java similarity index 89% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/BreakpointHitUpdatePolicy.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/update/BreakpointHitUpdatePolicy.java index fc25fcd0cbc..c8b9591c80c 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/BreakpointHitUpdatePolicy.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/update/BreakpointHitUpdatePolicy.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.update; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.update; import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent; import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason; @@ -20,7 +20,7 @@ import org.eclipse.dd.dsf.ui.viewmodel.update.ManualUpdatePolicy; */ public class BreakpointHitUpdatePolicy extends ManualUpdatePolicy { - public static String BREAKPOINT_HIT_UPDATE_POLICY_ID = "org.eclipse.dd.dsf.debug.ui.viewmodel.update.breakpointHitUpdatePolicy"; //$NON-NLS-1$ + public static String BREAKPOINT_HIT_UPDATE_POLICY_ID = "org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.update.breakpointHitUpdatePolicy"; //$NON-NLS-1$ @Override public String getID() { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshActionDelegate.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/update/actions/RefreshActionDelegate.java similarity index 90% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshActionDelegate.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/update/actions/RefreshActionDelegate.java index d4aace40560..95f6033ad0c 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/RefreshActionDelegate.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/update/actions/RefreshActionDelegate.java @@ -8,9 +8,9 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.update.actions; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.update.actions; -import org.eclipse.dd.dsf.debug.ui.viewmodel.actions.AbstractVMProviderActionDelegate; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.actions.AbstractVMProviderActionDelegate; import org.eclipse.dd.dsf.ui.viewmodel.IVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.update.ICachingVMProvider; import org.eclipse.debug.ui.contexts.DebugContextEvent; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/SelectUpdatePolicyAction.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/update/actions/SelectUpdatePolicyAction.java similarity index 95% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/SelectUpdatePolicyAction.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/update/actions/SelectUpdatePolicyAction.java index 76e64c2fa43..3ad5a1936d4 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/update/actions/SelectUpdatePolicyAction.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/update/actions/SelectUpdatePolicyAction.java @@ -8,9 +8,9 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.update.actions; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.update.actions; -import org.eclipse.dd.dsf.debug.ui.viewmodel.actions.AbstractVMProviderActionDelegate; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.actions.AbstractVMProviderActionDelegate; import org.eclipse.dd.dsf.ui.viewmodel.IVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.update.ICachingVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.update.IVMUpdatePolicy; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/MessagesForVariablesVM.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/MessagesForVariablesVM.java similarity index 76% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/MessagesForVariablesVM.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/MessagesForVariablesVM.java index 9f2f0febf91..4261cf0131b 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/MessagesForVariablesVM.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/MessagesForVariablesVM.java @@ -1,9 +1,9 @@ -package org.eclipse.dd.dsf.debug.ui.viewmodel.variable; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.variable; import org.eclipse.osgi.util.NLS; public class MessagesForVariablesVM extends NLS { - private static final String BUNDLE_NAME = "org.eclipse.dd.dsf.debug.ui.viewmodel.variable.messages"; //$NON-NLS-1$ + private static final String BUNDLE_NAME = "org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.variable.messages"; //$NON-NLS-1$ public static String VariableColumnPresentation_name; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/SyncVariableDataAccess.java similarity index 99% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/SyncVariableDataAccess.java index 6a1733aaa10..9b98dab1584 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/SyncVariableDataAccess.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/SyncVariableDataAccess.java @@ -4,7 +4,7 @@ * * Copyright 2007 Wind River Systems Inc. All rights reserved. */ -package org.eclipse.dd.dsf.debug.ui.viewmodel.variable; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.variable; import java.util.concurrent.ExecutionException; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableCellModifier.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/VariableCellModifier.java similarity index 92% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableCellModifier.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/VariableCellModifier.java index 222b01c536c..4559c04dc93 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableCellModifier.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/VariableCellModifier.java @@ -4,14 +4,14 @@ * * Copyright 2007 Wind River Systems Inc. All rights reserved. */ -package org.eclipse.dd.dsf.debug.ui.viewmodel.variable; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.variable; import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.IDebugVMConstants; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression.WatchExpressionCellModifier; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat.IFormattedValuePreferenceStore; import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; -import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; -import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionCellModifier; -import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValuePreferenceStore; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.update.AbstractCachingVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.update.UserEditEvent; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableColumnPresentation.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/VariableColumnPresentation.java similarity index 95% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableColumnPresentation.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/VariableColumnPresentation.java index 2a35acd6f2f..9123170adcc 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableColumnPresentation.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/VariableColumnPresentation.java @@ -8,10 +8,10 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel.variable; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.variable; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.IDebugVMConstants; import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; -import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.jface.resource.ImageDescriptor; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/VariableVMNode.java similarity index 98% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/VariableVMNode.java index 5b610bffc54..b07ff746078 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/VariableVMNode.java @@ -7,7 +7,7 @@ * Contributors: Wind River Systems - initial API and implementation */ -package org.eclipse.dd.dsf.debug.ui.viewmodel.variable; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.variable; import java.util.ArrayList; import java.util.List; @@ -24,6 +24,11 @@ import org.eclipse.dd.dsf.concurrent.MultiRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.IDebugVMConstants; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression.AbstractExpressionVMNode; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression.IExpressionUpdate; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat.IFormattedValuePreferenceStore; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat.IFormattedValueVMContext; import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.service.IExpressions; import org.eclipse.dd.dsf.debug.service.IFormattedValues; @@ -37,11 +42,6 @@ import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData; import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; import org.eclipse.dd.dsf.debug.service.IStack.IVariableDMContext; import org.eclipse.dd.dsf.debug.service.IStack.IVariableDMData; -import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; -import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.AbstractExpressionVMNode; -import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.IExpressionUpdate; -import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValuePreferenceStore; -import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.IFormattedValueVMContext; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/VariableVMProvider.java similarity index 92% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/VariableVMProvider.java index 1e27d8921f0..226d543c45a 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/VariableVMProvider.java @@ -6,10 +6,10 @@ * * Contributors: Wind River Systems - initial API and implementation */ -package org.eclipse.dd.dsf.debug.ui.viewmodel.variable; +package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.variable; -import org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.FormattedValuePreferenceStore; -import org.eclipse.dd.dsf.debug.ui.viewmodel.update.BreakpointHitUpdatePolicy; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat.FormattedValuePreferenceStore; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.update.BreakpointHitUpdatePolicy; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; import org.eclipse.dd.dsf.ui.viewmodel.IRootVMNode; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/messages.properties b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/messages.properties similarity index 100% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/messages.properties rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/messages.properties diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/viewmodel/numberformat/detail/MessagesForNumberFormatDetail.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/viewmodel/numberformat/detail/MessagesForNumberFormatDetail.java index 17b12ebcd28..db569450015 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/viewmodel/numberformat/detail/MessagesForNumberFormatDetail.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/viewmodel/numberformat/detail/MessagesForNumberFormatDetail.java @@ -3,7 +3,7 @@ package org.eclipse.dd.dsf.debug.internal.ui.viewmodel.numberformat.detail; import org.eclipse.osgi.util.NLS; class MessagesForNumberFormatDetail extends NLS { - private static final String BUNDLE_NAME = "org.eclipse.dd.dsf.debug.ui.viewmodel.numberformat.detail.messages"; //$NON-NLS-1$ + private static final String BUNDLE_NAME = "org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat.detail.messages"; //$NON-NLS-1$ public static String NumberFormatDetailPane_name; public static String NumberFormatDetailPane_description; diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java index b8b2f9866d0..0059b7dbd8e 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java @@ -11,8 +11,8 @@ package org.eclipse.dd.examples.pda.ui.viewmodel; import org.eclipse.dd.dsf.concurrent.ThreadSafe; -import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.ExpressionVMProvider; -import org.eclipse.dd.dsf.debug.ui.viewmodel.variable.VariableVMProvider; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression.ExpressionVMProvider; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.variable.VariableVMProvider; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMAdapter; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDALaunchVMProvider.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDALaunchVMProvider.java index 44ff9952a85..ddc77db8815 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDALaunchVMProvider.java +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDALaunchVMProvider.java @@ -14,10 +14,10 @@ package org.eclipse.dd.examples.pda.ui.viewmodel.launch; import java.util.concurrent.RejectedExecutionException; import org.eclipse.dd.dsf.concurrent.ThreadSafe; -import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.LaunchRootVMNode; -import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.StackFramesVMNode; -import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.StandardProcessVMNode; -import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.LaunchRootVMNode.LaunchesEvent; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch.LaunchRootVMNode; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch.StackFramesVMNode; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch.StandardProcessVMNode; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch.LaunchRootVMNode.LaunchesEvent; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; import org.eclipse.dd.dsf.ui.viewmodel.IRootVMNode; diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java index a8f003eddf0..91eb685c3e7 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java @@ -12,10 +12,10 @@ package org.eclipse.dd.gdb.internal.ui.viewmodel; import org.eclipse.cdt.debug.ui.ICDebugUIConstants; import org.eclipse.dd.dsf.concurrent.ThreadSafe; -import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.ExpressionVMProvider; -import org.eclipse.dd.dsf.debug.ui.viewmodel.modules.ModulesVMProvider; -import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterVMProvider; -import org.eclipse.dd.dsf.debug.ui.viewmodel.variable.VariableVMProvider; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression.ExpressionVMProvider; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.modules.ModulesVMProvider; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.register.RegisterVMProvider; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.variable.VariableVMProvider; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMAdapter; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/LaunchVMProvider.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/LaunchVMProvider.java index 87675c2b6f9..48f526cd4d0 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/LaunchVMProvider.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/LaunchVMProvider.java @@ -14,10 +14,10 @@ package org.eclipse.dd.gdb.internal.ui.viewmodel.launch; import java.util.concurrent.RejectedExecutionException; import org.eclipse.dd.dsf.concurrent.ThreadSafe; -import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.LaunchRootVMNode; -import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.StackFramesVMNode; -import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.StandardProcessVMNode; -import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.LaunchRootVMNode.LaunchesEvent; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch.LaunchRootVMNode; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch.StackFramesVMNode; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch.StandardProcessVMNode; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch.LaunchRootVMNode.LaunchesEvent; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; import org.eclipse.dd.dsf.ui.viewmodel.IRootVMNode; From 5f378a17517fdc8ba572771ff0426378a9f5fda6 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 1 Apr 2008 03:39:29 +0000 Subject: [PATCH 359/834] [223969] Extended DsfMemoryBlockRetrieval to support multiple contexts. --- .../dd/dsf/debug/model/DsfMemoryBlock.java | 12 ++-- .../debug/model/DsfMemoryBlockRetrieval.java | 58 +++++++++---------- .../launching/GdbLaunchDelegate.java | 4 +- 3 files changed, 36 insertions(+), 38 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java index 3f6d22d3829..c5d800122f7 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlock.java @@ -31,6 +31,7 @@ import org.eclipse.dd.dsf.debug.internal.DsfDebugPlugin; import org.eclipse.dd.dsf.debug.service.IMemory; import org.eclipse.dd.dsf.debug.service.IRunControl; import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryChangedEvent; +import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryDMContext; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.DebugException; @@ -49,6 +50,7 @@ import org.eclipse.debug.core.model.MemoryByte; */ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtension { + private final IMemoryDMContext fContext; private final ILaunch fLaunch; private final IDebugTarget fDebugTarget; private final DsfMemoryBlockRetrieval fRetrieval; @@ -76,11 +78,11 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens * @param word_size - the number of bytes per address * @param length - the requested block length (could be 0) */ - DsfMemoryBlock(DsfMemoryBlockRetrieval retrieval, String modelId, String expression, BigInteger address, int word_size, long length) { - + DsfMemoryBlock(DsfMemoryBlockRetrieval retrieval, IMemoryDMContext context, String modelId, String expression, BigInteger address, int word_size, long length) { fLaunch = retrieval.getLaunch(); fDebugTarget = retrieval.getDebugTarget(); fRetrieval = retrieval; + fContext = context; fModelId = modelId; fExpression = expression; fBaseAddress = address; @@ -425,7 +427,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens if (memoryService != null) { // Go for it memoryService.getMemory( - fRetrieval.getContext(), address, 0, fWordSize, (int) length, + fContext, address, 0, fWordSize, (int) length, new DataRequestMonitor(fRetrieval.getExecutor(), drm) { @Override protected void handleSuccess() { @@ -471,7 +473,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens if (memoryService != null) { // Go for it memoryService.setMemory( - fRetrieval.getContext(), address, offset, fWordSize, bytes.length, bytes, + fContext, address, offset, fWordSize, bytes.length, bytes, new RequestMonitor(fRetrieval.getExecutor(), null)); } @@ -511,7 +513,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens public void eventDispatched(IMemoryChangedEvent e) { // Check if we are in the same address space - if (e.getDMContext().equals(fRetrieval.getContext())) { + if (e.getDMContext().equals(fContext)) { IAddress[] addresses = e.getAddresses(); for (int i = 0; i < addresses.length; i++) handleMemoryChange(addresses[i].getValue()); diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java index 6ec2b2b5938..bc5bad8d61a 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java @@ -27,6 +27,7 @@ import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfExecutor; import org.eclipse.dd.dsf.concurrent.Query; +import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.debug.internal.DsfDebugPlugin; import org.eclipse.dd.dsf.debug.service.IExpressions; @@ -78,7 +79,6 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl private final String fModelId; private final DsfSession fSession; private final DsfExecutor fExecutor; - private final IMemoryDMContext fContext; private final String fContextString; private final ServiceTracker fMemoryServiceTracker; private final ServiceTracker fExpressionServiceTracker; @@ -98,11 +98,10 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl * @param dmc * @throws DebugException */ - public DsfMemoryBlockRetrieval(String modelId, ILaunchConfiguration config, IMemoryDMContext dmc) throws DebugException { + public DsfMemoryBlockRetrieval(String modelId, ILaunchConfiguration config, DsfSession session) throws DebugException { // DSF stuff fModelId = modelId; - fContext = dmc; // FIXME: Currently memory contexts are differentiated by sessionID // so there is no way to guarantee the memory blocks will be reinstated @@ -114,10 +113,10 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl // fContextString = fContext.toString(); fContextString = "Context string"; //$NON-NLS-1$ - fSession = DsfSession.getSession(fContext.getSessionId()); + fSession = session; if (fSession == null) { throw new IllegalArgumentException( - "Session for context " + fContext + " is not active"); //$NON-NLS-1$ //$NON-NLS-2$ + "Session " + session + " is not active"); //$NON-NLS-1$ //$NON-NLS-2$ } fExecutor = fSession.getExecutor(); BundleContext bundle = DsfDebugPlugin.getBundleContext(); @@ -126,7 +125,7 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl // amalgamated one because it is less error prone (and we are lazy). // Create a tracker for the MemoryService - String memoryServiceFilter = DsfServices.createServiceFilter(IMemory.class, dmc.getSessionId()); + String memoryServiceFilter = DsfServices.createServiceFilter(IMemory.class, session.getId()); try { fMemoryServiceTracker = new ServiceTracker( @@ -144,7 +143,7 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl + IExpressions.class.getName() + ")" + //$NON-NLS-1$ "(" + IDsfService.PROP_SESSION_ID //$NON-NLS-1$ - + "=" + dmc.getSessionId() + ")" + //$NON-NLS-1$//$NON-NLS-2$ + + "=" + session.getId() + ")" + //$NON-NLS-1$//$NON-NLS-2$ ")"; //$NON-NLS-1$ try { @@ -214,7 +213,7 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl /** * Restore the memory monitors from the memento in the launch configuration */ - public void initialize() { + public void initialize(final IMemoryDMContext memoryCtx) { try { final String memento = fLaunchConfig.getAttribute(ATTR_DEBUGGER_MEMORY_BLOCKS, ""); //$NON-NLS-1$ if (memento != null && memento.trim().length() != 0) { @@ -222,7 +221,7 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl getExecutor().submit(new Runnable() { public void run() { try { - createBlocksFromConfiguration(memento); + createBlocksFromConfiguration(memoryCtx, memento); } catch (CoreException e) { DsfDebugPlugin.getDefault().getLog().log(e.getStatus()); } @@ -234,7 +233,7 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl } } - private void createBlocksFromConfiguration(String memento) throws CoreException { + private void createBlocksFromConfiguration(IMemoryDMContext memoryCtx, String memento) throws CoreException { // Parse the memento and validate its type Element root = DebugPlugin.parseDocument(memento); @@ -258,7 +257,7 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl String label = entry.getAttribute(ATTR_MEMORY_BLOCK_EXPR_LABEL); String address = entry.getAttribute(ATTR_MEMORY_BLOCK_EXPR_ADDRESS); BigInteger blockAddress = new BigInteger(address); - DsfMemoryBlock block = new DsfMemoryBlock(this, fModelId, label, blockAddress, fWordSize, 0); + DsfMemoryBlock block = new DsfMemoryBlock(this, memoryCtx, fModelId, label, blockAddress, fWordSize, 0); blocks.add(block); } } @@ -319,10 +318,6 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl return fExecutor; } - public IMemoryDMContext getContext() { - return fContext; - } - public ServiceTracker getServiceTracker() { return fMemoryServiceTracker; } @@ -375,10 +370,9 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl * long) */ public IMemoryBlock getMemoryBlock(final long startAddress, final long length) throws DebugException { - // The expression to display in the rendering tab (in hex by convention) - // Put here for the sake of completeness (not used with IMemoryBlockExtension) - String expression = "0x" + Long.toHexString(startAddress); //$NON-NLS-1$ - return new DsfMemoryBlock(this, fModelId, expression, BigInteger.valueOf(startAddress), fWordSize, length); + throw new DebugException(new Status( + IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, DebugException.NOT_SUPPORTED, + "getMemoryBlock() not supported, use getExtendedMemoryBlock()", null)); //$NON-NLS-1$ } /////////////////////////////////////////////////////////////////////////// @@ -392,7 +386,19 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl * java.lang.Object) */ public IMemoryBlockExtension getExtendedMemoryBlock(String expression, Object context) throws DebugException { + // Drill for the actual DMC + IMemoryDMContext memoryDmc = null; + if (context instanceof IAdaptable) { + IDMContext dmc = (IDMContext)((IAdaptable)context).getAdapter(IDMContext.class); + if (dmc != null) { + memoryDmc = DMContexts.getAncestorOfType(dmc, IMemoryDMContext.class); + } + } + if (memoryDmc == null) { + return null; + } + // The block start address (supports 64-bit processors) BigInteger blockAddress; @@ -427,18 +433,8 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl // try to resolve as an expression. // In case of failure, simply return 'null' - // Drill for the actual DMC - IDMContext dmc = null; - if (context instanceof IAdaptable) { - dmc = (IDMContext)((IAdaptable)context).getAdapter(IDMContext.class); - } - - if (dmc == null) { - return null; - } - // Resolve the expression - blockAddress = resolveMemoryAddress(dmc, expression); + blockAddress = resolveMemoryAddress(memoryDmc, expression); if (blockAddress == null) { return null; } @@ -457,7 +453,7 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl * the memory request cache should save the day. */ - return new DsfMemoryBlock(this, fModelId, expression, blockAddress, fWordSize, 0); + return new DsfMemoryBlock(this, memoryDmc, fModelId, expression, blockAddress, fWordSize, 0); } /////////////////////////////////////////////////////////////////////////// diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java index 8fbe2468cbc..20671367bfe 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java @@ -183,9 +183,9 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate GDBControl gdbControl = tracker.getService(GDBControl.class); if (gdbControl != null) { IMemoryBlockRetrieval memRetrieval = new DsfMemoryBlockRetrieval( - GDB_DEBUG_MODEL_ID, config, (IMemoryDMContext)gdbControl.getControlDMContext()); + GDB_DEBUG_MODEL_ID, config, launch.getSession()); launch.getSession().registerModelAdapter(IMemoryBlockRetrieval.class, memRetrieval); - ((DsfMemoryBlockRetrieval) memRetrieval).initialize(); + ((DsfMemoryBlockRetrieval) memRetrieval).initialize((IMemoryDMContext)gdbControl.getControlDMContext()); } tracker.dispose(); return null; From 624f00aa981bc32dada226b58ca09b47b07207be Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Tue, 1 Apr 2008 15:43:38 +0000 Subject: [PATCH 360/834] Compilation fix after changes to DsfMemoryBlockRetrieval. --- .../eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java index cc80277ca4f..19b72fb7cd6 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java @@ -167,9 +167,9 @@ public class TestLaunchDelegate extends AbstractCLaunchDelegate GDBControl gdbControl = tracker.getService(GDBControl.class); if (gdbControl != null) { IMemoryBlockRetrieval memRetrieval = new DsfMemoryBlockRetrieval( - GDB_DEBUG_MODEL_ID, config, (IMemoryDMContext)gdbControl.getControlDMContext()); + GDB_DEBUG_MODEL_ID, config, launch.getSession()); launch.getSession().registerModelAdapter(IMemoryBlockRetrieval.class, memRetrieval); - ((DsfMemoryBlockRetrieval) memRetrieval).initialize(); + ((DsfMemoryBlockRetrieval) memRetrieval).initialize((IMemoryDMContext)gdbControl.getControlDMContext()); } tracker.dispose(); return null; From 4fe057895384a0d66f949ee50f0a6f2ac5e6c86e Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Tue, 1 Apr 2008 18:23:01 +0000 Subject: [PATCH 361/834] Bug 222766 Adds the use of solib-search-path as done in the CDT (by filling the Shared Library subtab in the debugger tab of the launch). Also adds the use of auto-solib-add as in the CDT. --- .../launching/FinalLaunchSequence.java | 46 ++++++++++++++++++- .../command/commands/MIFileExecFile.java | 2 +- .../command/commands/MIFileSymbolFile.java | 2 +- .../mi/service/command/commands/MIGDBSet.java | 26 +++++++++++ .../command/commands/MIGDBSetAutoSolib.java | 25 ++++++++++ .../commands/MIGDBSetSolibSearchPath.java | 37 +++++++++++++++ 6 files changed, 135 insertions(+), 3 deletions(-) create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIGDBSet.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIGDBSetAutoSolib.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIGDBSetSolibSearchPath.java diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java index 609311e9e34..cd770d3c529 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java @@ -10,9 +10,13 @@ *******************************************************************************/ package org.eclipse.dd.gdb.internal.provisional.launching; +import java.util.ArrayList; +import java.util.List; + import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector; import org.eclipse.cdt.debug.mi.core.IGDBServerMILaunchConfigurationConstants; +import org.eclipse.cdt.debug.mi.core.IMILaunchConfigurationConstants; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; @@ -34,6 +38,8 @@ import org.eclipse.dd.mi.service.command.commands.MIExecContinue; import org.eclipse.dd.mi.service.command.commands.MIExecRun; import org.eclipse.dd.mi.service.command.commands.MIFileExecFile; import org.eclipse.dd.mi.service.command.commands.MIFileSymbolFile; +import org.eclipse.dd.mi.service.command.commands.MIGDBSetAutoSolib; +import org.eclipse.dd.mi.service.command.commands.MIGDBSetSolibSearchPath; import org.eclipse.dd.mi.service.command.commands.MITargetSelect; import org.eclipse.dd.mi.service.command.output.MIBreakInsertInfo; import org.eclipse.dd.mi.service.command.output.MIInfo; @@ -71,8 +77,46 @@ public class FinalLaunchSequence extends Sequence { fCommandControl.queueCommand( new MIFileSymbolFile(fCommandControl.getControlDMContext(), fCommandControl.getExecutablePath().toOSString()), - new DataRequestMonitor(getExecutor(), requestMonitor)); + new DataRequestMonitor(getExecutor(), requestMonitor)); }}, + /* + * Tell GDB to automatically load or not the shared library symbols + */ + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + try { + boolean autolib = fLaunch.getLaunchConfiguration().getAttribute(IMILaunchConfigurationConstants.ATTR_DEBUGGER_AUTO_SOLIB, + IMILaunchConfigurationConstants.DEBUGGER_AUTO_SOLIB_DEFAULT); + fCommandControl.queueCommand( + new MIGDBSetAutoSolib(fCommandControl.getControlDMContext(), autolib), + new DataRequestMonitor(getExecutor(), requestMonitor)); + } catch (CoreException e) { + requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Cannot set shared library option", e)); //$NON-NLS-1$ + requestMonitor.done(); + } + }}, + /* + * Set the shared library paths + */ + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + try { + @SuppressWarnings("unchecked") + List p = fLaunch.getLaunchConfiguration().getAttribute(IMILaunchConfigurationConstants.ATTR_DEBUGGER_SOLIB_PATH, + new ArrayList(1)); + if (p.size() > 0) { + String[] paths = p.toArray(new String[p.size()]); + fCommandControl.queueCommand( + new MIGDBSetSolibSearchPath(fCommandControl.getControlDMContext(), paths), + new DataRequestMonitor(getExecutor(), requestMonitor)); + } else { + requestMonitor.done(); + } + } catch (CoreException e) { + requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Cannot set share library paths", e)); //$NON-NLS-1$ + requestMonitor.done(); + } + }}, /* * Setup the source paths */ diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIFileExecFile.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIFileExecFile.java index 97728cb4b6d..29accf6a176 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIFileExecFile.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIFileExecFile.java @@ -27,7 +27,7 @@ import org.eclipse.dd.mi.service.command.output.MIInfo; public class MIFileExecFile extends MICommand { public MIFileExecFile(MIControlDMContext dmc, String file) { - super(dmc, "-file-exec-file", new String[] {file}); //$NON-NLS-1$ + super(dmc, "-file-exec-file", null, new String[] {file}); //$NON-NLS-1$ } public MIFileExecFile(MIControlDMContext dmc) { diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIFileSymbolFile.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIFileSymbolFile.java index 83ab8883f70..418082b6b89 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIFileSymbolFile.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIFileSymbolFile.java @@ -26,7 +26,7 @@ import org.eclipse.dd.mi.service.command.output.MIInfo; public class MIFileSymbolFile extends MICommand { public MIFileSymbolFile(MIControlDMContext dmc, String file) { - super(dmc, "-file-symbol-file", new String[] {file}); //$NON-NLS-1$ + super(dmc, "-file-symbol-file", null, new String[] {file}); //$NON-NLS-1$ } public MIFileSymbolFile(MIControlDMContext dmc) { diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIGDBSet.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIGDBSet.java new file mode 100644 index 00000000000..d142e8d8119 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIGDBSet.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2008 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; + +/** + * + * -gdb-set + * + */ +public class MIGDBSet extends MICommand +{ + public MIGDBSet(IDMContext ctx, String[] params) { + super(ctx, "-gdb-set", null, params); //$NON-NLS-1$ + } +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIGDBSetAutoSolib.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIGDBSetAutoSolib.java new file mode 100644 index 00000000000..4c6e19bda93 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIGDBSetAutoSolib.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2008 QNX Software 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.mi.service.command.MIControlDMContext; + +/** + * + * -gdb-set + * + */ +public class MIGDBSetAutoSolib extends MIGDBSet +{ + public MIGDBSetAutoSolib(MIControlDMContext ctx, boolean isSet) { + super(ctx, new String[] {"auto-solib-add", isSet ? "on" : "off"});//$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ + } +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIGDBSetSolibSearchPath.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIGDBSetSolibSearchPath.java new file mode 100644 index 00000000000..cc27b724634 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIGDBSetSolibSearchPath.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2008 QNX Software 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.mi.service.command.MIControlDMContext; + +/** + * + * -gdb-set + * + */ +public class MIGDBSetSolibSearchPath extends MIGDBSet +{ + public MIGDBSetSolibSearchPath(MIControlDMContext ctx, String[] paths) { + super(ctx, paths); + // Overload the parameter + String sep = System.getProperty("path.separator", ":"); //$NON-NLS-1$ //$NON-NLS-2$ + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < paths.length; i++) { + if (buffer.length() == 0) { + buffer.append(paths[i]); + } else { + buffer.append(sep).append(paths[i]); + } + } + String[] p = new String [] {"solib-search-path", buffer.toString()}; //$NON-NLS-1$ + setParameters(p); + } +} \ No newline at end of file From 7fe354ae79f7fba5b2399025d2ddcf287f33ee95 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 1 Apr 2008 20:04:30 +0000 Subject: [PATCH 362/834] [225193] Simplified AbstractVMContext constructor. --- .../expression/ExpressionManagerVMNode.java | 4 +- .../launch/StandardProcessVMNode.java | 2 +- .../dsf/ui/viewmodel/AbstractVMContext.java | 55 ++++++++++--------- .../viewmodel/datamodel/AbstractDMVMNode.java | 11 ++-- .../dsf/filebrowser/FileVMContext.java | 5 +- .../examples/dsf/filebrowser/FileVMNode.java | 4 +- .../filebrowser/FilesystemRootsVMNode.java | 4 +- 7 files changed, 44 insertions(+), 41 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/ExpressionManagerVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/ExpressionManagerVMNode.java index 46db0162f08..fb9acb9c39c 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/ExpressionManagerVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/ExpressionManagerVMNode.java @@ -73,7 +73,7 @@ public class ExpressionManagerVMNode extends AbstractVMNode final private IExpression fExpression; public InvalidExpressionVMContext(ExpressionManagerVMNode node, IExpression expression) { - super(node.getVMProvider().getVMAdapter(), node); + super(node); fExpression = expression; } @@ -108,7 +108,7 @@ public class ExpressionManagerVMNode extends AbstractVMNode */ class NewExpressionVMC extends AbstractVMContext { public NewExpressionVMC() { - super(getVMProvider().getVMAdapter(), ExpressionManagerVMNode.this); + super(ExpressionManagerVMNode.this); } @Override diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/StandardProcessVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/StandardProcessVMNode.java index 318b12601a7..86591b2eec5 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/StandardProcessVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/StandardProcessVMNode.java @@ -49,7 +49,7 @@ public class StandardProcessVMNode extends AbstractVMNode { private final IProcess fProcess; VMC(IProcess process) { - super(getVMProvider().getVMAdapter(), StandardProcessVMNode.this); + super(StandardProcessVMNode.this); fProcess = process; } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMContext.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMContext.java index 5fab2eb44d7..60a5810c604 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMContext.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMContext.java @@ -1,50 +1,51 @@ package org.eclipse.dd.dsf.ui.viewmodel; -import org.eclipse.dd.dsf.ui.viewmodel.properties.IElementPropertiesProvider; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory; +import org.eclipse.core.runtime.Platform; /** - * Implementation of basic view model context interface. The main - * purpose of the VMC wrapper is to re-direct adapter queries to the IVMAdapter - * and the layout node that the given context was created by. - *

              + * Implementation of basic view model context interface. + *

              The main purpose of the VMC wrapper is to re-direct adapter + * queries. The redirecting of adapter queries follows this order: + *

                + *
              1. If context implements the adapter itself, it is returned.
              2. + *
              3. If the VM Adapter implements the adapter, the VM Adapter is returned.
              4. + *
              5. If the VM Provider implements the adapter, the VM Provider is returned.
              6. + *
              7. If the VM Node implements the adapter, the VM Node is returned.
              8. + *
              + *

              + *

              * Note: Deriving classes must override the Object.equals/hashCode methods. * This is because the view model context objects are just wrappers that are * created by the view model on demand, so the equals methods must use the * object being wrapped to perform a meaningful comparison. */ -@SuppressWarnings("restriction") abstract public class AbstractVMContext implements IVMContext { - protected final IVMAdapter fVMAdapter; protected final IVMNode fNode; - public AbstractVMContext(IVMAdapter adapter, IVMNode node) { - fVMAdapter = adapter; + public AbstractVMContext(IVMNode node) { fNode = node; } public IVMNode getVMNode() { return fNode; } - /** - * IAdapter implementation returns the {@link IVMAdapter} instance for - * the interfaces that are actually implemented by the VM Adapter. - * These should at least include {@link IElementContentProvider}, - * {@link IModelProxyFactory}, and {@link IColumnPresentationFactory}. - * It also returns the {@link IVMNode} instance for adapters implemented - * by the context's node. The interfaces typically implemented by the - * node include {@link IElementLabelProvider} and {@link IElementPropertiesProvider}. - */ @SuppressWarnings("unchecked") public Object getAdapter(Class adapter) { - if (adapter.isInstance(fVMAdapter)) { - return fVMAdapter; - } else if (adapter.isInstance(fNode)) { - return fNode; + // If the context implements the given adapter directly, it always takes + // precedence. + if (adapter.isInstance(this)) { + return this; } - return null; + + IVMProvider vmProvider = getVMNode().getVMProvider(); + IVMAdapter vmAdapter = vmProvider.getVMAdapter(); + if (adapter.isInstance(vmAdapter)) { + return vmAdapter; + } else if (adapter.isInstance(vmProvider)) { + return vmProvider; + } else if (adapter.isInstance(getVMNode())) { + return getVMNode(); + } + return Platform.getAdapterManager().getAdapter(this, adapter); } /** Deriving classes must override. */ diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/datamodel/AbstractDMVMNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/datamodel/AbstractDMVMNode.java index 21ff0b60ac8..9b2c040bfb4 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/datamodel/AbstractDMVMNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/datamodel/AbstractDMVMNode.java @@ -57,7 +57,7 @@ abstract public class AbstractDMVMNode extends AbstractVMNode implements IVMNode private final IDMContext fDmc; public DMVMContext(IDMContext dmc) { - super(getVMProvider().getVMAdapter(), AbstractDMVMNode.this); + super(AbstractDMVMNode.this); fDmc = dmc; } @@ -73,10 +73,13 @@ abstract public class AbstractDMVMNode extends AbstractVMNode implements IVMNode Object superAdapter = super.getAdapter(adapter); if (superAdapter != null) { return superAdapter; - } else if (adapter.isInstance(fDmc)) { - return fDmc; } else { - return fDmc.getAdapter(adapter); + // Delegate to the Data Model to find the context. + if (adapter.isInstance(fDmc)) { + return fDmc; + } else { + return fDmc.getAdapter(adapter); + } } } diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileVMContext.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileVMContext.java index 989038cdfeb..ab342c2253b 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileVMContext.java +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileVMContext.java @@ -13,13 +13,12 @@ package org.eclipse.dd.examples.dsf.filebrowser; import java.io.File; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMContext; -import org.eclipse.dd.dsf.ui.viewmodel.IVMAdapter; import org.eclipse.dd.dsf.ui.viewmodel.IVMNode; class FileVMContext extends AbstractVMContext { private File fFile; - FileVMContext(IVMAdapter adapter, IVMNode layoutNode, File file) { - super(adapter, layoutNode); + FileVMContext(IVMNode layoutNode, File file) { + super(layoutNode); fFile = file; } diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileVMNode.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileVMNode.java index 1d40f990503..6e2c903327d 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileVMNode.java +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FileVMNode.java @@ -135,7 +135,7 @@ class FileVMNode int offset = update.getOffset() != -1 ? update.getOffset() : 0; int length = update.getLength() != -1 ? update.getLength() : files.length; for (int i = offset; (i < files.length) && (i < (offset + length)); i++) { - update.setChild(new FileVMContext(fProvider.getVMAdapter(), FileVMNode.this, files[i]), i); + update.setChild(new FileVMContext(FileVMNode.this, files[i]), i); } update.done(); } @@ -260,7 +260,7 @@ class FileVMNode File[] pathSegmentDirectoryFiles = pathSegment.listFiles(); delta = delta.addNode( - new FileVMContext(fProvider.getVMAdapter(), FileVMNode.this, pathSegment), + new FileVMContext(FileVMNode.this, pathSegment), nodeOffset + Arrays.asList(allFilesInDirectory).indexOf(pathSegment), IModelDelta.NO_CHANGE, pathSegmentDirectoryFiles != null ? pathSegmentDirectoryFiles.length : 0); diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FilesystemRootsVMNode.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FilesystemRootsVMNode.java index 3e64684267f..9d0445b952d 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FilesystemRootsVMNode.java +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/filebrowser/FilesystemRootsVMNode.java @@ -56,7 +56,7 @@ class FilesystemRootsVMNode extends AbstractVMNode int offset = update.getOffset() != -1 ? update.getOffset() : 0; int length = update.getLength() != -1 ? update.getLength() : files.length; for (int i = offset; (i < files.length) && (i < (offset + length)); i++) { - update.setChild(new FileVMContext(getVMProvider().getVMAdapter(), FilesystemRootsVMNode.this, files[i]), i); + update.setChild(new FileVMContext(FilesystemRootsVMNode.this, files[i]), i); } update.done(); } @@ -168,7 +168,7 @@ class FilesystemRootsVMNode extends AbstractVMNode // Check if the specified file is not one of the roots. if (index < roots.length) { ModelDelta delta = parentDelta.addNode( - new FileVMContext(getVMProvider().getVMAdapter(), FilesystemRootsVMNode.this, eventRoot), + new FileVMContext(FilesystemRootsVMNode.this, eventRoot), index, IModelDelta.NO_CHANGE); if (eventFile.equals(eventRoot)) { From cb02c10c78e518b977e67110b3dfe3f109eccd7a Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 1 Apr 2008 20:09:43 +0000 Subject: [PATCH 363/834] [225193] Simplified AbstractVMContext constructor. --- .../examples/pda/ui/viewmodel/launch/PDAProgramVMNode.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDAProgramVMNode.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDAProgramVMNode.java index 33fc71780bd..452cd0869b2 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDAProgramVMNode.java +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDAProgramVMNode.java @@ -67,8 +67,8 @@ public class PDAProgramVMNode extends AbstractDMVMNode // VM node object, such that two terminated program contexts // from the same instance of VM node will be equal. private static class TerminatedProgramVMContext extends AbstractVMContext { - TerminatedProgramVMContext(IVMAdapter adapter, IVMNode node) { - super(adapter, node); + TerminatedProgramVMContext(IVMNode node) { + super(node); } @Override @@ -123,7 +123,7 @@ public class PDAProgramVMNode extends AbstractDMVMNode if (launch != null && launch.isInitialized() && launch.isShutDown()) { // If the debug session has been shut down, add a dummy // VM context representing the PDA thread. - update.setChild(new TerminatedProgramVMContext(getVMProvider().getVMAdapter(), this), 0); + update.setChild(new TerminatedProgramVMContext(this), 0); update.done(); } else { super.update(new IChildrenUpdate[] { update }); From 19e920c43345dfc0073d831bc0e69dc8fa9bfaa0 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 1 Apr 2008 20:18:09 +0000 Subject: [PATCH 364/834] [225197] Got rid of IElementPropertiesProvider.getPropertyName/Description methods. --- .../properties/IElementPropertiesProvider.java | 10 ---------- .../eclipse/dd/examples/dsf/timers/TimersVMNode.java | 10 ---------- .../eclipse/dd/examples/dsf/timers/TriggersVMNode.java | 8 -------- 3 files changed, 28 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/IElementPropertiesProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/IElementPropertiesProvider.java index 139bd3408cd..2776beca3fd 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/IElementPropertiesProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/IElementPropertiesProvider.java @@ -14,14 +14,4 @@ public interface IElementPropertiesProvider { * a set of properties is requested and stores them */ public void update(IPropertiesUpdate[] updates); - - /** - * Returns a user-presentable name for the given property. - */ - public String getPropertyName(String property); - - /** - * Returns a description for the given property. - */ - public String getPropertyDescription(String property); } diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersVMNode.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersVMNode.java index 64c0186a12f..d4e6f456893 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersVMNode.java +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersVMNode.java @@ -161,14 +161,4 @@ class TimersVMNode extends AbstractDMVMNode } requestMonitor.done(); } - - - public String getPropertyDescription(String property) { - return null; - } - - public String getPropertyName(String property) { - return null; - } - } diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TriggersVMNode.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TriggersVMNode.java index 9934e2e8d6e..952b1778aed 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TriggersVMNode.java +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TriggersVMNode.java @@ -192,12 +192,4 @@ class TriggersVMNode extends AbstractDMVMNode } super.dispose(); } - - public String getPropertyDescription(String property) { - return null; - } - - public String getPropertyName(String property) { - return null; - } } From 706d77cc0ca5f0e355d6f710e65fad857fdc42da Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 1 Apr 2008 20:46:11 +0000 Subject: [PATCH 365/834] [206932] Made ICommandControl independent from the IDsfService class. --- .../debug/service/command/CommandCache.java | 15 ++-- .../service/command/ICommandControl.java | 3 +- .../dd/dsf/service/DsfServicesTracker.java | 6 +- .../launch/PDAServicesShutdownSequence.java | 2 +- .../examples/pda/service/PDAExpressions.java | 2 +- .../dd/examples/pda/service/PDAStack.java | 2 +- .../launching/ShutdownSequence.java | 2 +- .../dd/mi/service/ExpressionService.java | 4 +- .../org/eclipse/dd/mi/service/MIMemory.java | 2 +- .../org/eclipse/dd/mi/service/MIModules.java | 2 +- .../eclipse/dd/mi/service/MIRegisters.java | 4 +- .../eclipse/dd/mi/service/MIRunControl.java | 2 +- .../dd/mi/service/MIVariableManager.java | 83 +++++++++---------- 13 files changed, 63 insertions(+), 66 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java index 6982a8346c9..881493eb269 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java @@ -28,6 +28,7 @@ import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.debug.internal.DsfDebugPlugin; +import org.eclipse.dd.dsf.service.DsfSession; /** * This is a utility class for caching results of MI Commands. Return MIInfo @@ -105,6 +106,10 @@ public class CommandCache implements ICommandListener public ICommandResult getData() { return fData; } public IStatus getStatus() { return fStatus; } } + + private DsfSession fSession; + + private ICommandControl fCommandControl; /* * This class contains 5 significant lists. @@ -139,11 +144,8 @@ public class CommandCache implements ICommandListener * created. When the coalesced commands completes the results will be decomposed * when back into individual results from this command. */ - private Set fUnavailableContexts = new HashSet(); - private ICommandControl fCommandControl; - private Map> fCachedContexts = new HashMap>(); private ArrayList fPendingQCommandsSent = new ArrayList(); @@ -152,7 +154,8 @@ public class CommandCache implements ICommandListener private ArrayList fPendingQWaitingForCoalescedCompletion = new ArrayList(); - public CommandCache(ICommandControl control) { + public CommandCache(DsfSession session, ICommandControl control) { + fSession = session; fCommandControl = control; /* @@ -232,7 +235,7 @@ public class CommandCache implements ICommandListener * well as its cache status. */ public void execute(ICommand command, DataRequestMonitor rm) { - assert fCommandControl.getExecutor().isInExecutorThread(); + assert fSession.getExecutor().isInExecutorThread(); // Cast the generic ?'s to concrete types in the cache implementation. @SuppressWarnings("unchecked") @@ -315,7 +318,7 @@ public class CommandCache implements ICommandListener fCommandControl.queueCommand( finalCachedCmd.getCommand(), - new DataRequestMonitor(fCommandControl.getExecutor(), null) { + new DataRequestMonitor(fSession.getExecutor(), null) { @Override public void handleCompleted() { diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandControl.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandControl.java index bf4effb9962..3d6620338af 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandControl.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandControl.java @@ -11,13 +11,12 @@ package org.eclipse.dd.dsf.debug.service.command; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.service.IDsfService; /** * API for sending commands to the debugger and for receiving command results * and asynchronous events. */ -public interface ICommandControl extends IDsfService{ +public interface ICommandControl { /** * Adds the specified command to the queue of commands to be processed. diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServicesTracker.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServicesTracker.java index ab794d24d5f..4ab4c6dc55d 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServicesTracker.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/service/DsfServicesTracker.java @@ -73,7 +73,7 @@ public class DsfServicesTracker { private BundleContext fBundleContext; private Map fServiceReferences = new HashMap(); - private Map fServices = new HashMap(); + private Map fServices = new HashMap(); private String fServiceFilter; /** @@ -125,7 +125,7 @@ public class DsfServicesTracker { * @param serviceClass class of the desired service * @return instance of the desired service, null if not found */ - public V getService(Class serviceClass) { + public V getService(Class serviceClass) { return getService(serviceClass, null); } @@ -140,7 +140,7 @@ public class DsfServicesTracker { * @return instance of the desired service, null if not found */ @SuppressWarnings("unchecked") - public V getService(Class serviceClass, String filter) { + public V getService(Class serviceClass, String filter) { ServiceReference serviceRef = getServiceReference(serviceClass, filter); if (serviceRef == null) { return null; diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java index 4ca6df9cfe9..f73fe7108d4 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java @@ -122,7 +122,7 @@ public class PDAServicesShutdownSequence extends Sequence { @SuppressWarnings("unchecked") private void shutdownService(Class clazz, final RequestMonitor requestMonitor) { - IDsfService service = fTracker.getService(clazz); + IDsfService service = (IDsfService)fTracker.getService(clazz); if (service != null) { service.shutdown(new RequestMonitor(getExecutor(), requestMonitor) { @Override diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAExpressions.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAExpressions.java index 3ebafb920b8..29fbfa38061 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAExpressions.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAExpressions.java @@ -189,7 +189,7 @@ public class PDAExpressions extends AbstractDsfService implements IExpressions { private void doInitialize(final RequestMonitor rm) { fCommandControl = getServicesTracker().getService(PDACommandControl.class); fStack = getServicesTracker().getService(IStack.class); - fCommandCache = new CommandCache(fCommandControl); + fCommandCache = new CommandCache(getSession(), fCommandControl); getSession().addServiceEventListener(this, null); diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java index 6fe86364277..90abe899d44 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java @@ -195,7 +195,7 @@ public class PDAStack extends AbstractDsfService implements IStack { fRunControl = getServicesTracker().getService(IRunControl.class); // Create the commands cache - fCommandCache = new CommandCache(fCommandControl); + fCommandCache = new CommandCache(getSession(), fCommandControl); // Register to listen for run control events, to clear cache accordingly. getSession().addServiceEventListener(this, null); diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/ShutdownSequence.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/ShutdownSequence.java index 08cdbf531fa..8a59da52f77 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/ShutdownSequence.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/ShutdownSequence.java @@ -160,7 +160,7 @@ public class ShutdownSequence extends Sequence { @SuppressWarnings("unchecked") private void shutdownService(Class clazz, final RequestMonitor requestMonitor) { - IDsfService service = fTracker.getService(clazz); + IDsfService service = (IDsfService)fTracker.getService(clazz); if (service != null) { service.shutdown(new RequestMonitor(getExecutor(), requestMonitor) { @Override diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/ExpressionService.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/ExpressionService.java index 2db9093e88a..62380ce4674 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/ExpressionService.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/ExpressionService.java @@ -452,7 +452,7 @@ public class ExpressionService extends AbstractDsfService implements IExpression // Create the meta command cache which will use the variable manager // to actually send MI commands to the back-end - fExpressionCache = new CommandCache(varManager); + fExpressionCache = new CommandCache(getSession(), varManager); requestMonitor.done(); } @@ -467,7 +467,7 @@ public class ExpressionService extends AbstractDsfService implements IExpression @Override public void shutdown(RequestMonitor requestMonitor) { unregister(); - varManager.shutdown(); + varManager.dispose(); getSession().removeServiceEventListener(this); super.shutdown(requestMonitor); } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIMemory.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIMemory.java index 1296edaf1a5..c47752e903e 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIMemory.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIMemory.java @@ -438,7 +438,7 @@ public class MIMemory extends AbstractDsfService implements IMemory { public MIMemoryCache() { // Create the command cache - fCommandCache = new CommandCache(getServicesTracker().getService(ICommandControl.class)); + fCommandCache = new CommandCache(getSession(), getServicesTracker().getService(ICommandControl.class)); // Create the memory block cache fMemoryBlockList = new SortedMemoryBlockList(); } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIModules.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIModules.java index d013393fceb..af155a16abc 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIModules.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIModules.java @@ -60,7 +60,7 @@ public class MIModules extends AbstractDsfService implements IModules { private void doInitialize(RequestMonitor requestMonitor) { // Cache for holding Modules data - fModulesCache = new CommandCache(getServicesTracker().getService(ICommandControl.class)); + fModulesCache = new CommandCache(getSession(), getServicesTracker().getService(ICommandControl.class)); /* * Make ourselves known so clients can use us. */ diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRegisters.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRegisters.java index e4aaca93a0a..568a477a0d6 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRegisters.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRegisters.java @@ -171,8 +171,8 @@ public class MIRegisters extends AbstractDsfService implements IRegisters { /* * Create the lower level register cache. */ - fRegisterValueCache = new CommandCache(getServicesTracker().getService(ICommandControl.class)); - fRegisterNameCache = new CommandCache(getServicesTracker().getService(ICommandControl.class)); + fRegisterValueCache = new CommandCache(getSession(), getServicesTracker().getService(ICommandControl.class)); + fRegisterNameCache = new CommandCache(getSession(), getServicesTracker().getService(ICommandControl.class)); /* * Signup so we see events. We use these events to decide how to manage diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java index b87010fdc49..0542e1d7429 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java @@ -285,7 +285,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl private void doInitialize(final RequestMonitor rm) { fConnection = getServicesTracker().getService(ICommandControl.class); - fMICommandCache = new CommandCache(fConnection); + fMICommandCache = new CommandCache(getSession(), fConnection); getSession().addServiceEventListener(this, null); //register(new String[]{IRunControl.class.getName(), MIRunControl.class.getName()}, new Hashtable()); diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java index 37617969aea..7e860d9c7c7 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java @@ -41,7 +41,6 @@ import org.eclipse.dd.dsf.debug.service.command.ICommandControl; import org.eclipse.dd.dsf.debug.service.command.ICommandListener; import org.eclipse.dd.dsf.debug.service.command.ICommandResult; import org.eclipse.dd.dsf.debug.service.command.IEventListener; -import org.eclipse.dd.dsf.service.AbstractDsfService; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; @@ -81,7 +80,6 @@ import org.eclipse.dd.mi.service.command.output.MIVarListChildrenInfo; import org.eclipse.dd.mi.service.command.output.MIVarSetFormatInfo; import org.eclipse.dd.mi.service.command.output.MIVarShowAttributesInfo; import org.eclipse.dd.mi.service.command.output.MIVarUpdateInfo; -import org.osgi.framework.BundleContext; /** * Manages a list of variable objects as created through GDB/MI commands. @@ -195,7 +193,7 @@ import org.osgi.framework.BundleContext; * with a specified format, therefore allowing us to never use -var-set-format, and * consequently, to easily keep the display format of all variable objects to natural. */ -public class MIVariableManager extends AbstractDsfService implements ICommandControl { +public class MIVariableManager implements ICommandControl { /** @@ -353,7 +351,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon updatesPending.add(rm); } else { currentState = STATE_UPDATING; - getRootToUpdate().update(new DataRequestMonitor(getExecutor(), rm) { + getRootToUpdate().update(new DataRequestMonitor(fSession.getExecutor(), rm) { @Override protected void handleCompleted() { currentState = STATE_READY; @@ -412,7 +410,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon } else { fCommandControl.queueCommand( new MIVarShowAttributes(fControlDmc, getGdbName()), - new DataRequestMonitor(getExecutor(), rm) { + new DataRequestMonitor(fSession.getExecutor(), rm) { @Override protected void handleSuccess() { editable = getData().isEditable(); @@ -457,14 +455,14 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon IExpressionDMContext addrCxt = fExpressionService.createExpression(exprCxt, "&(" + exprCxt.getExpression() + ")"); //$NON-NLS-1$//$NON-NLS-2$ final FormattedValueDMContext formatCxt = new FormattedValueDMContext( - fExpressionService.getSession().getId(), + fSession.getId(), addrCxt, dmc.getFormatID() ); getVariable( addrCxt, - new DataRequestMonitor(getExecutor(), rm) { + new DataRequestMonitor(fSession.getExecutor(), rm) { @Override protected void handleSuccess() { getData().getValue(formatCxt, rm); @@ -483,7 +481,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon } if (locked) { - operationsPending.add(new RequestMonitor(getExecutor(), rm) { + operationsPending.add(new RequestMonitor(fSession.getExecutor(), rm) { @Override protected void handleSuccess() { getValue(dmc, rm); @@ -500,7 +498,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon // We must first set the new format and then evaluate the variable fCommandControl.queueCommand( new MIVarSetFormat(fControlDmc, getGdbName(), dmc.getFormatID()), - new DataRequestMonitor(getExecutor(), rm) { + new DataRequestMonitor(fSession.getExecutor(), rm) { @Override protected void handleCompleted() { if (isSuccess()) { @@ -536,7 +534,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon private void evaluate(final DataRequestMonitor rm) { fCommandControl.queueCommand( new MIVarEvaluateExpression(fControlDmc, getGdbName()), - new DataRequestMonitor(getExecutor(), rm) { + new DataRequestMonitor(fSession.getExecutor(), rm) { @Override protected void handleCompleted() { if (isSuccess()) { @@ -573,7 +571,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon if (!getCurrentFormat().equals(IFormattedValues.NATURAL_FORMAT)) { fCommandControl.queueCommand( new MIVarSetFormat(fControlDmc, getGdbName(), IFormattedValues.NATURAL_FORMAT), - new DataRequestMonitor(getExecutor(), null) { + new DataRequestMonitor(fSession.getExecutor(), null) { @Override protected void handleCompleted() { if (isSuccess()) { @@ -639,13 +637,13 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon // Also no need to lock the object, since getting the children won't affect other operations fCommandControl.queueCommand( new MIVarListChildren(fControlDmc, getGdbName()), - new DataRequestMonitor(getExecutor(), rm) { + new DataRequestMonitor(fSession.getExecutor(), rm) { @Override protected void handleSuccess() { MIVar[] children = getData().getMIVars(); final List realChildren = new ArrayList(); - final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm) { + final CountingRequestMonitor countingRm = new CountingRequestMonitor(fSession.getExecutor(), rm) { @Override protected void handleSuccess() { // Store the children in our variable object cache @@ -676,7 +674,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon numSubRequests++; final DataRequestMonitor childPathRm = - new DataRequestMonitor(getExecutor(), countingRm) { + new DataRequestMonitor(fSession.getExecutor(), countingRm) { @Override protected void handleSuccess() { String childFullExpression = getData(); @@ -727,7 +725,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon // get the children of this child to get the real children childVar.getChildren( exprDmc, - new DataRequestMonitor(getExecutor(), countingRm) { + new DataRequestMonitor(fSession.getExecutor(), countingRm) { @Override protected void handleSuccess() { ExpressionInfo[] vars = getData(); @@ -756,7 +754,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon // can get from -var-info-path-expression starting from GDB 6.7 fCommandControl.queueCommand( new MIVarInfoPathExpression(fControlDmc, child.getVarName()), - new DataRequestMonitor(getExecutor(), childPathRm) { + new DataRequestMonitor(fSession.getExecutor(), childPathRm) { @Override protected void handleCompleted() { if (isSuccess()) { @@ -883,7 +881,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon // No need to be in ready state or to lock the object fCommandControl.queueCommand( new MIVarAssign(fControlDmc, getGdbName(), value), - new DataRequestMonitor(getExecutor(), rm) { + new DataRequestMonitor(fSession.getExecutor(), rm) { @Override protected void handleSuccess() { // We must also mark all variable objects @@ -960,7 +958,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon fCommandControl.queueCommand( new MIVarCreate(exprCtx, exprCtx.getExpression()), - new DataRequestMonitor(getExecutor(), rm) { + new DataRequestMonitor(fSession.getExecutor(), rm) { @Override protected void handleCompleted() { if (isSuccess()) { @@ -1016,7 +1014,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon // Creation failed, inform anyone waiting. while (updatesPending.size() > 0) { RequestMonitor rm = updatesPending.poll(); - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_HANDLE, "Unable to create variable object", null)); //$NON-NLS-1$ rm.done(); } @@ -1057,7 +1055,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon // var-set-format command. This is done in the getValue() method fCommandControl.queueCommand( new MIVarUpdate(fControlDmc, getGdbName()), - new DataRequestMonitor(getExecutor(), rm) { + new DataRequestMonitor(fSession.getExecutor(), rm) { @Override protected void handleCompleted() { currentState = STATE_READY; @@ -1127,7 +1125,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon if (getGdbName() != null) { fCommandControl.queueCommand( new MIVarDelete(fControlDmc, getGdbName()), - new DataRequestMonitor(getExecutor(), null)); + new DataRequestMonitor(fSession.getExecutor(), null)); // Nothing to do in the requestMonitor, since the object was already // removed from our list before calling this method. @@ -1199,7 +1197,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon // from the StackService command cache after the first time. fStackService.getStackDepth( execCtx, 0, - new DataRequestMonitor(getExecutor(), rm) { + new DataRequestMonitor(fSession.getExecutor(), rm) { @Override protected void handleSuccess() { fFrameId = new Integer(getData() - frameCtx.getLevel()); @@ -1294,6 +1292,8 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon } } + private final DsfSession fSession; + /** Provides access to the GDB/MI back-end */ private final ICommandControl fCommandControl; // The stack service needs to be used to get information such @@ -1326,7 +1326,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon * The service tracker that can be used to find other services */ public MIVariableManager(DsfSession session, DsfServicesTracker tracker) { - super(session); + fSession = session; lruVariableList = new LRUVariableCache(); fCommandControl = tracker.getService(ICommandControl.class); fStackService = tracker.getService(IStack.class); @@ -1334,11 +1334,11 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon fControlDmc = ((AbstractMIControl)fCommandControl).getControlDMContext(); // Register to receive service events for this session. - getSession().addServiceEventListener(this, null); + fSession.addServiceEventListener(this, null); } - public void shutdown() { - getSession().removeServiceEventListener(this); + public void dispose() { + fSession.removeServiceEventListener(this); } /** @@ -1360,7 +1360,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon final VariableObjectId id = new VariableObjectId(); id.generateId( exprCtx, - new RequestMonitor(getExecutor(), rm) { + new RequestMonitor(fSession.getExecutor(), rm) { @Override protected void handleSuccess() { getVariable(id, exprCtx, rm); @@ -1381,7 +1381,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon // We have found a varObject, but it may not be updated yet. // Updating the object will also tell us if it is out-of-scope // and if we should re-create it. - varObj.update(new DataRequestMonitor(getExecutor(), rm) { + varObj.update(new DataRequestMonitor(fSession.getExecutor(), rm) { @Override protected void handleSuccess() { @@ -1441,7 +1441,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon // Note that this will replace any old entry with the same id. lruVariableList.put(id, newVarObj); - newVarObj.create(exprCtx, new RequestMonitor(getExecutor(), rm) { + newVarObj.create(exprCtx, new RequestMonitor(fSession.getExecutor(), rm) { @Override protected void handleCompleted() { if (isSuccess()) { @@ -1479,7 +1479,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon getVariable( ctx, - new DataRequestMonitor(getExecutor(), rm) { + new DataRequestMonitor(fSession.getExecutor(), rm) { @Override protected void handleSuccess() { getData().writeValue(expressionValue, formatId, rm); @@ -1502,7 +1502,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon getVariable( exprCtx, - new DataRequestMonitor(getExecutor(), drm) { + new DataRequestMonitor(fSession.getExecutor(), drm) { @Override protected void handleSuccess() { drm.setData( @@ -1521,11 +1521,11 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon getVariable( exprCtx, - new DataRequestMonitor(getExecutor(), drm) { + new DataRequestMonitor(fSession.getExecutor(), drm) { @Override protected void handleSuccess() { getData().getAttributes( - new DataRequestMonitor(getExecutor(), drm) { + new DataRequestMonitor(fSession.getExecutor(), drm) { @Override protected void handleSuccess() { drm.setData(new ExprMetaGetAttributesInfo(getData())); @@ -1544,12 +1544,12 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon getVariable( exprCtx, - new DataRequestMonitor(getExecutor(), drm) { + new DataRequestMonitor(fSession.getExecutor(), drm) { @Override protected void handleSuccess() { getData().getValue( valueCtx, - new DataRequestMonitor(getExecutor(), drm) { + new DataRequestMonitor(fSession.getExecutor(), drm) { @Override protected void handleSuccess() { drm.setData( @@ -1567,12 +1567,12 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon getVariable( exprCtx, - new DataRequestMonitor(getExecutor(), drm) { + new DataRequestMonitor(fSession.getExecutor(), drm) { @Override protected void handleSuccess() { getData().getChildren( exprCtx, - new DataRequestMonitor(getExecutor(), drm) { + new DataRequestMonitor(fSession.getExecutor(), drm) { @Override protected void handleSuccess() { drm.setData(new ExprMetaGetChildrenInfo(getData())); @@ -1589,11 +1589,11 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon getVariable( exprCtx, - new DataRequestMonitor(getExecutor(), drm) { + new DataRequestMonitor(fSession.getExecutor(), drm) { @Override protected void handleSuccess() { getData().getChildrenCount( - new DataRequestMonitor(getExecutor(), drm) { + new DataRequestMonitor(fSession.getExecutor(), drm) { @Override protected void handleSuccess() { drm.setData(new ExprMetaGetChildCountInfo(getData())); @@ -1650,11 +1650,6 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon } } - @Override - protected BundleContext getBundleContext() { - return MIPlugin.getBundleContext(); - } - private void markAllOutOfDate() { MIRootVariableObject root; while ((root = updatedRootList.poll()) != null) { From b76951e59e2488eb5a96f03f9cd8dadb815325b2 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 2 Apr 2008 04:09:35 +0000 Subject: [PATCH 366/834] [217020] Refactored ICommandControl interface to use a token to identify queued commands. --- .../debug/service/command/CommandCache.java | 26 +++---- .../service/command/ICommandControl.java | 16 +---- .../service/command/ICommandListener.java | 8 +-- .../debug/service/command/ICommandToken.java | 23 ++++++ .../pda/service/PDACommandControl.java | 36 +++++----- .../tests/pda/service/command/BasicTests.java | 21 +++--- .../dd/mi/service/MIVariableManager.java | 33 ++++++--- .../service/command/AbstractCLIProcess.java | 13 ++-- .../mi/service/command/AbstractMIControl.java | 71 ++++++++----------- .../mi/service/command/CLIEventProcessor.java | 26 +++---- .../mi/service/command/MIInferiorProcess.java | 14 ++-- .../command/MIRunControlEventProcessor.java | 10 +-- 12 files changed, 163 insertions(+), 134 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandToken.java diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java index 881493eb269..f1842403f97 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java @@ -55,18 +55,20 @@ public class CommandCache implements ICommandListener */ /** List of the request monitors associated with this command */ - List> fCurrentRequestMonitors ; + private final List> fCurrentRequestMonitors ; /** Original command. Need for reference from Queue completion notification */ - ICommand fCommand; + private final ICommand fCommand; /** Style of this command ( internal coalesced or not) */ - CommandStyle fCmdStyle; + private final CommandStyle fCmdStyle; /** Command being processed for this command */ - CommandInfo fCoalescedCmd; + private CommandInfo fCoalescedCmd; + + private ICommandToken fToken; - public CommandInfo( CommandStyle cmdstyle, ICommand cmd, DataRequestMonitor rm ) { + public CommandInfo(CommandStyle cmdstyle, ICommand cmd, DataRequestMonitor rm ) { fCmdStyle = cmdstyle; fCommand = cmd; fCurrentRequestMonitors = new LinkedList>(); @@ -219,7 +221,7 @@ public class CommandCache implements ICommandListener * does not continue to process it. */ fPendingQCommandsNotYetSent.remove(currentUnsentEntry); - fCommandControl.removeCommand(unsentCommand); + fCommandControl.removeCommand(currentUnsentEntry.fToken); return( coalescedCmdInfo ); } @@ -316,7 +318,7 @@ public class CommandCache implements ICommandListener final CommandInfo finalCachedCmd = cachedCmd; fPendingQCommandsNotYetSent.add(finalCachedCmd); - fCommandControl.queueCommand( + finalCachedCmd.fToken = fCommandControl.queueCommand( finalCachedCmd.getCommand(), new DataRequestMonitor(fSession.getExecutor(), null) { @Override @@ -476,7 +478,7 @@ public class CommandCache implements ICommandListener fCachedContexts.clear(); } - public void commandRemoved(ICommand command) { + public void commandRemoved(ICommandToken token) { /* * Do nothing. */ @@ -486,7 +488,7 @@ public class CommandCache implements ICommandListener * (non-Javadoc) * @see org.eclipse.dd.dsf.mi.service.control.IDebuggerControl.ICommandListener#commandQueued(org.eclipse.dd.dsf.mi.core.command.ICommand) */ - public void commandQueued(ICommand command) { + public void commandQueued(ICommandToken token) { /* * Do nothing. */ @@ -496,7 +498,7 @@ public class CommandCache implements ICommandListener * (non-Javadoc) * @see org.eclipse.dd.dsf.mi.service.control.IDebuggerControl.ICommandListener#commandDone(org.eclipse.dd.dsf.mi.core.command.ICommand, org.eclipse.dd.dsf.mi.core.command.ICommandResult) */ - public void commandDone(ICommand command, ICommandResult result) { + public void commandDone(ICommandToken token, ICommandResult result) { /* * We handle the done with a runnable where we initiated the command * so there is nothing to do here. @@ -511,11 +513,11 @@ public class CommandCache implements ICommandListener * (non-Javadoc) * @see org.eclipse.dd.dsf.mi.service.control.IDebuggerControl.ICommandListener#commandSent(org.eclipse.dd.dsf.mi.core.command.ICommand) */ - public void commandSent(ICommand command) { + public void commandSent(ICommandToken token) { // Cast the generic ?'s to concrete types in the cache implementation. @SuppressWarnings("unchecked") - ICommand genericCommand = (ICommand)command; + ICommand genericCommand = (ICommand)token.getCommand(); CommandInfo cachedCmd = new CommandInfo( CommandStyle.NONCOALESCED, genericCommand, null) ; diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandControl.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandControl.java index 3d6620338af..6edd9d3f3ce 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandControl.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandControl.java @@ -17,7 +17,7 @@ import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; * and asynchronous events. */ public interface ICommandControl { - + /** * Adds the specified command to the queue of commands to be processed. * @@ -25,7 +25,7 @@ public interface ICommandControl { * @param rm Request completion monitor * @return None */ - void queueCommand(ICommand command, DataRequestMonitor rm); + ICommandToken queueCommand(ICommand command, DataRequestMonitor rm); /** * Removes the specified command from the processor queue. @@ -33,17 +33,7 @@ public interface ICommandControl { * @param command Specific command to be removed * @return None */ - void removeCommand(ICommand command); - - /** - * Attempts to cancel and already sent command. Some versions - * of GDB/MI implement control commands which allow this. The - * GDB/MI standard does not currently allow for this. - * - * @param command Specific command to be removed - * @return None - */ - void cancelCommand(ICommand command); + void removeCommand(ICommandToken token); /** * Adds a notification handler for the Command processor. diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandListener.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandListener.java index 5a2f8e813a6..b4388ae31a1 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandListener.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandListener.java @@ -18,7 +18,7 @@ public interface ICommandListener { * @return None * @param command Command which has been added to the Queue */ - public void commandQueued(ICommand command); + public void commandQueued(ICommandToken token); /** * Notification that the given command was sent to the debugger. At this @@ -29,7 +29,7 @@ public interface ICommandListener { * @return None * @param command */ - public void commandSent(ICommand command); + public void commandSent(ICommandToken token); /** * Notifies that the specified command has been removed from the @@ -42,7 +42,7 @@ public interface ICommandListener { * @return None * @param Command which has been sent to the backend */ - public void commandRemoved(ICommand command); + public void commandRemoved(ICommandToken token); /** * Notifies that the specified command has been completed. @@ -50,5 +50,5 @@ public interface ICommandListener { * @return None * @param Command which has been sent to the backend */ - public void commandDone(ICommand command, ICommandResult result); + public void commandDone(ICommandToken token, ICommandResult result); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandToken.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandToken.java new file mode 100644 index 00000000000..9149af2be42 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandToken.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.service.command; + +/** + * Token returned by ICommandControl.queueCommand(). This token can be used + * to uniquely identify a command when calling ICommandControl.removeCommand() + * or when implementing the ICommandListener listener methods. + */ +public interface ICommandToken { + /** + * Returns the command that this was created for. + */ + public ICommand getCommand(); +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java index 8530ca85543..23dfe15593d 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java @@ -27,6 +27,7 @@ import org.eclipse.dd.dsf.debug.service.command.ICommand; import org.eclipse.dd.dsf.debug.service.command.ICommandControl; import org.eclipse.dd.dsf.debug.service.command.ICommandListener; import org.eclipse.dd.dsf.debug.service.command.ICommandResult; +import org.eclipse.dd.dsf.debug.service.command.ICommandToken; import org.eclipse.dd.dsf.debug.service.command.IEventListener; import org.eclipse.dd.dsf.service.AbstractDsfService; import org.eclipse.dd.dsf.service.DsfSession; @@ -44,10 +45,12 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon // Structure used to store command information in services internal queues. private static class CommandHandle { + final private ICommandToken fToken; final private AbstractPDACommand fCommand; final private DataRequestMonitor fRequestMonitor; - CommandHandle(AbstractPDACommand c, DataRequestMonitor rm) { + CommandHandle(ICommandToken token, AbstractPDACommand c, DataRequestMonitor rm) { + fToken = token; fCommand = c; fRequestMonitor = rm; } @@ -334,7 +337,13 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon } - public void queueCommand(ICommand command, DataRequestMonitor rm) { + public ICommandToken queueCommand(final ICommand command, DataRequestMonitor rm) { + ICommandToken token = new ICommandToken() { + public ICommand getCommand() { + return command; + } + }; + if (command instanceof AbstractPDACommand) { // Cast from command with "" to a more concrete // type to use internally in the command control. @@ -346,9 +355,9 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon DataRequestMonitor pdaRM = (DataRequestMonitor)rm; // Add the command to the queue and notify command listeners. - fCommandQueue.add( new CommandHandle(pdaCommand, pdaRM) ); + fCommandQueue.add( new CommandHandle(token, pdaCommand, pdaRM) ); for (ICommandListener listener : fCommandListeners) { - listener.commandQueued(command); + listener.commandQueued(token); } // In a separate dispatch cycle. This allows command listeners to respond to the @@ -358,25 +367,20 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon processQueues(); } }); - } else { PDAPlugin.failRequest(rm, INTERNAL_ERROR, "Unrecognized command: " + command); } + return token; } - public void cancelCommand(ICommand command) { - // This debugger is unable of canceling commands once they have - // been sent. - } - - public void removeCommand(ICommand command) { + public void removeCommand(ICommandToken token) { // Removes given command from the queue and notify the listeners for (Iterator itr = fCommandQueue.iterator(); itr.hasNext();) { CommandHandle handle = itr.next(); - if (command.equals(handle.fCommand)) { + if (token.equals(handle.fToken)) { itr.remove(); for (ICommandListener listener : fCommandListeners) { - listener.commandRemoved(command); + listener.commandRemoved(token); } } } @@ -414,7 +418,7 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon // Notify listeners of the response for (ICommandListener listener : fCommandListeners) { - listener.commandDone(handle.fCommand, result); + listener.commandDone(handle.fToken, result); } // Process next command in queue. @@ -431,7 +435,7 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon // Notify listeners also. for (ICommandListener listener : fCommandListeners) { - listener.commandDone(handle.fCommand, null); + listener.commandDone(handle.fToken, null); } } @@ -462,7 +466,7 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon fTxCommands.add(handle); PDAPlugin.debug("C: " + handle.fCommand.getRequest()); for (ICommandListener listener : fCommandListeners) { - listener.commandSent(handle.fCommand); + listener.commandSent(handle.fToken); } } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/BasicTests.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/BasicTests.java index f8124f277e8..5d1f330f0d1 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/BasicTests.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/BasicTests.java @@ -23,6 +23,7 @@ import org.eclipse.dd.dsf.concurrent.Query; import org.eclipse.dd.dsf.debug.service.command.ICommand; import org.eclipse.dd.dsf.debug.service.command.ICommandListener; import org.eclipse.dd.dsf.debug.service.command.ICommandResult; +import org.eclipse.dd.dsf.debug.service.command.ICommandToken; import org.eclipse.dd.examples.pda.service.commands.PDACommandResult; import org.junit.BeforeClass; import org.junit.Test; @@ -53,17 +54,17 @@ public class BasicTests extends CommandControlTestsBase { List fRemovedCommands = new LinkedList(); List fSentCommands = new LinkedList(); - public void commandDone(ICommand command, ICommandResult result) { - fDoneCommands.add(new CommandInfo(command, result)); + public void commandDone(ICommandToken token, ICommandResult result) { + fDoneCommands.add(new CommandInfo(token.getCommand(), result)); } - public void commandQueued(ICommand command) { - fQueuedCommands.add(new CommandInfo(command, null)); + public void commandQueued(ICommandToken token) { + fQueuedCommands.add(new CommandInfo(token.getCommand(), null)); } - public void commandRemoved(ICommand command) { - fRemovedCommands.add(new CommandInfo(command, null)); + public void commandRemoved(ICommandToken token) { + fRemovedCommands.add(new CommandInfo(token.getCommand(), null)); } - public void commandSent(ICommand command) { - fSentCommands.add(new CommandInfo(command, null)); + public void commandSent(ICommandToken token) { + fSentCommands.add(new CommandInfo(token.getCommand(), null)); } void reset() { @@ -106,7 +107,7 @@ public class BasicTests extends CommandControlTestsBase { Query queueRemoveCommandQuery = new Query() { @Override protected void execute(DataRequestMonitor rm) { - fCommandControl.queueCommand( + ICommandToken token = fCommandControl.queueCommand( testCommand, new DataRequestMonitor(fExecutor, null) { @Override @@ -114,7 +115,7 @@ public class BasicTests extends CommandControlTestsBase { Assert.fail("This command should never have been executed."); } }); - fCommandControl.removeCommand(testCommand); + fCommandControl.removeCommand(token); rm.setData(new Object()); rm.done(); diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java index 7e860d9c7c7..5419f125828 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java @@ -40,6 +40,7 @@ import org.eclipse.dd.dsf.debug.service.command.ICommand; import org.eclipse.dd.dsf.debug.service.command.ICommandControl; import org.eclipse.dd.dsf.debug.service.command.ICommandListener; import org.eclipse.dd.dsf.debug.service.command.ICommandResult; +import org.eclipse.dd.dsf.debug.service.command.ICommandToken; import org.eclipse.dd.dsf.debug.service.command.IEventListener; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfServicesTracker; @@ -1487,13 +1488,19 @@ public class MIVariableManager implements ICommandControl { }); } - public void queueCommand(final ICommand command, DataRequestMonitor rm) { + public ICommandToken queueCommand(final ICommand command, DataRequestMonitor rm) { + final ICommandToken token = new ICommandToken() { + public ICommand getCommand() { + return command; + } + }; + // The MIVariableManager does not buffer commands itself, but sends them directly to the real // MICommandControl service. Therefore, we must immediately tell our calling cache that the command // has been sent, since we can never cancel it. Note that this removes any option of coalescing, // but coalescing was not applicable to variableObjects anyway. - processCommandSent(command); + processCommandSent(token); if (command instanceof ExprMetaGetVar) { @SuppressWarnings("unchecked") @@ -1512,6 +1519,7 @@ public class MIVariableManager implements ICommandControl { getData().getType(), !getData().isComplex())); drm.done(); + processCommandDone(token, drm.getData()); } }); } else if (command instanceof ExprMetaGetAttributes) { @@ -1530,6 +1538,7 @@ public class MIVariableManager implements ICommandControl { protected void handleSuccess() { drm.setData(new ExprMetaGetAttributesInfo(getData())); drm.done(); + processCommandDone(token, drm.getData()); } }); } @@ -1555,6 +1564,7 @@ public class MIVariableManager implements ICommandControl { drm.setData( new ExprMetaGetValueInfo(getData().getFormattedValue())); drm.done(); + processCommandDone(token, drm.getData()); } }); } @@ -1577,6 +1587,7 @@ public class MIVariableManager implements ICommandControl { protected void handleSuccess() { drm.setData(new ExprMetaGetChildrenInfo(getData())); drm.done(); + processCommandDone(token, drm.getData()); } }); } @@ -1598,6 +1609,7 @@ public class MIVariableManager implements ICommandControl { protected void handleSuccess() { drm.setData(new ExprMetaGetChildCountInfo(getData())); drm.done(); + processCommandDone(token, drm.getData()); } }); } @@ -1610,7 +1622,8 @@ public class MIVariableManager implements ICommandControl { rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Unexpected Expression Meta command", null)); //$NON-NLS-1$ rm.done(); - } + } + return token; } /* @@ -1621,7 +1634,7 @@ public class MIVariableManager implements ICommandControl { * (non-Javadoc) * @see org.eclipse.dd.mi.service.command.IDebuggerControl#removeCommand(org.eclipse.dd.mi.service.command.commands.ICommand) */ - public void removeCommand(ICommand command) { + public void removeCommand(ICommandToken token) { // It is impossible to remove a command from the MIVariableManager. // This should never be called, if we did things right. assert false; @@ -1637,19 +1650,24 @@ public class MIVariableManager implements ICommandControl { * (non-Javadoc) * @see org.eclipse.dd.mi.service.command.IDebuggerControl#cancelCommand(org.eclipse.dd.mi.service.command.commands.ICommand) */ - public void cancelCommand(ICommand command) {} public void addCommandListener(ICommandListener processor) { fCommandProcessors.add(processor); } public void removeCommandListener(ICommandListener processor) { fCommandProcessors.remove(processor); } public void addEventListener(IEventListener processor) {} public void removeEventListener(IEventListener processor) {} - private void processCommandSent(ICommand command) { + private void processCommandSent(ICommandToken token) { for (ICommandListener processor : fCommandProcessors) { - processor.commandSent(command); + processor.commandSent(token); } } + private void processCommandDone(ICommandToken token, ICommandResult result) { + for (ICommandListener processor : fCommandProcessors) { + processor.commandDone(token, result); + } + } + private void markAllOutOfDate() { MIRootVariableObject root; while ((root = updatedRootList.poll()) != null) { @@ -1679,5 +1697,4 @@ public class MIVariableManager implements ICommandControl { // The views will fully refresh on a MemoryChangedEvent markAllOutOfDate(); } - } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractCLIProcess.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractCLIProcess.java index 1fe0c72b4d7..6a0ecedc0be 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractCLIProcess.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractCLIProcess.java @@ -30,6 +30,7 @@ import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.debug.service.command.ICommand; import org.eclipse.dd.dsf.debug.service.command.ICommandListener; import org.eclipse.dd.dsf.debug.service.command.ICommandResult; +import org.eclipse.dd.dsf.debug.service.command.ICommandToken; import org.eclipse.dd.dsf.debug.service.command.IEventListener; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.mi.internal.MIPlugin; @@ -204,11 +205,12 @@ public abstract class AbstractCLIProcess extends Process } } - public void commandQueued(ICommand command) { + public void commandQueued(ICommandToken token) { // Ignore } - public void commandSent(ICommand command) { + public void commandSent(ICommandToken token) { + ICommand command = token.getCommand(); // Check if the command is a CLI command and if it did not originate from this class. if (command instanceof CLICommand && !(command instanceof ProcessCLICommand || command instanceof ProcessMIInterpreterExecConsole)) @@ -217,12 +219,13 @@ public abstract class AbstractCLIProcess extends Process } } - public void commandRemoved(ICommand command) { + public void commandRemoved(ICommandToken token) { // Ignore } - public void commandDone(ICommand command, ICommandResult result) { - if (command instanceof CLICommand && + public void commandDone(ICommandToken token, ICommandResult result) { + ICommand command = token.getCommand(); + if (token.getCommand() instanceof CLICommand && !(command instanceof ProcessCLICommand || command instanceof ProcessMIInterpreterExecConsole)) { fSuppressConsoleOutputCounter--; diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java index 62a6be29442..4fa55ea69cb 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java @@ -36,6 +36,7 @@ import org.eclipse.dd.dsf.debug.service.command.ICommand; import org.eclipse.dd.dsf.debug.service.command.ICommandControl; import org.eclipse.dd.dsf.debug.service.command.ICommandListener; import org.eclipse.dd.dsf.debug.service.command.ICommandResult; +import org.eclipse.dd.dsf.debug.service.command.ICommandToken; import org.eclipse.dd.dsf.debug.service.command.IEventListener; import org.eclipse.dd.dsf.service.AbstractDsfService; import org.eclipse.dd.dsf.service.DsfSession; @@ -182,15 +183,8 @@ public abstract class AbstractMIControl extends AbstractDsfService * @see org.eclipse.dd.dsf.debug.service.command.ICommandControl#addCommand(org.eclipse.dd.dsf.debug.service.command.ICommand, org.eclipse.dd.dsf.concurrent.RequestMonitor) */ - public void queueCommand(ICommand command, DataRequestMonitor rm) { + public ICommandToken queueCommand(final ICommand command, DataRequestMonitor rm) { - // If the command control stopped processing commands, just return an error immediately. - if (fStoppedCommandProcessing) { - rm.setStatus(genStatus("Connection is shut down")); //$NON-NLS-1$ - rm.done(); - return; - } - // Cast the command to MI Command type. This will cause a cast exception to be // thrown if the client did not give an MI command as an argument. @SuppressWarnings("unchecked") @@ -202,8 +196,12 @@ public abstract class AbstractMIControl extends AbstractDsfService DataRequestMonitor miDone = (DataRequestMonitor)rm; final CommandHandle handle = new CommandHandle(miCommand, miDone); - - if ( fRxCommands.size() > 3 ) { + + // If the command control stopped processing commands, just return an error immediately. + if (fStoppedCommandProcessing) { + rm.setStatus(genStatus("Connection is shut down")); //$NON-NLS-1$ + rm.done(); + } else if ( fRxCommands.size() > 3 ) { /* * We only allow three outstanding commands to be on the wire to the backend @@ -238,7 +236,7 @@ public abstract class AbstractMIControl extends AbstractDsfService CommandHandle cmdHandle = new CommandHandle( new MIThreadSelect(handle.fCommand.getContext(), fCurrentThreadId), null); fTxCommands.add(cmdHandle); - MIPlugin.debug(MIPlugin.getDebugTime() + " " + cmdHandle.getToken() + cmdHandle.getCommand()); //$NON-NLS-1$ + MIPlugin.debug(MIPlugin.getDebugTime() + " " + cmdHandle.getTokenId() + cmdHandle.getCommand()); //$NON-NLS-1$ } // Before the command is sent, Check the Stack level and send it to @@ -251,12 +249,13 @@ public abstract class AbstractMIControl extends AbstractDsfService CommandHandle cmdHandle = new CommandHandle( new MIStackSelectFrame(handle.fCommand.getContext(), fCurrentStackLevel), null); fTxCommands.add(cmdHandle); - MIPlugin.debug(MIPlugin.getDebugTime() + " " + cmdHandle.getToken() + cmdHandle.getCommand()); //$NON-NLS-1$ + MIPlugin.debug(MIPlugin.getDebugTime() + " " + cmdHandle.getTokenId() + cmdHandle.getCommand()); //$NON-NLS-1$ } fTxCommands.add(handle); } } + return handle; } /* @@ -267,12 +266,12 @@ public abstract class AbstractMIControl extends AbstractDsfService * (non-Javadoc) * @see org.eclipse.dd.mi.service.command.IDebuggerControl#removeCommand(org.eclipse.dd.mi.service.command.commands.ICommand) */ - public void removeCommand(ICommand command) { + public void removeCommand(ICommandToken token) { synchronized(fCommandQueue) { for ( CommandHandle handle : fCommandQueue ) { - if ( handle.getCommand().equals(command)) { + if ( handle.equals(token)) { fCommandQueue.remove(handle); final CommandHandle finalHandle = handle; @@ -287,18 +286,6 @@ public abstract class AbstractMIControl extends AbstractDsfService } } - /* - * This command allows the user to try and cancel commands which have been handed off to the - * backend. Some backends support this with extended GDB/MI commands. If the support is there - * then we will attempt it. Because of the bidirectional nature of the GDB/MI command stream - * there is no guarantee that this will work. The response to the command could be on its way - * back when the cancel command is being issued. - * - * (non-Javadoc) - * @see org.eclipse.dd.mi.service.command.IDebuggerControl#cancelCommand(org.eclipse.dd.mi.service.command.commands.ICommand) - */ - public void cancelCommand(ICommand command) {} - /* * Allows a user ( typically a cache manager ) to sign up a listener to monitor command queue * activity. @@ -339,19 +326,19 @@ public abstract class AbstractMIControl extends AbstractDsfService private void processCommandQueued(CommandHandle commandHandle) { for (ICommandListener processor : fCommandProcessors) { - processor.commandQueued(commandHandle.getCommand()); + processor.commandQueued(commandHandle); } } private void processCommandRemoved(CommandHandle commandHandle) { for (ICommandListener processor : fCommandProcessors) { - processor.commandRemoved(commandHandle.getCommand()); + processor.commandRemoved(commandHandle); } } private void processCommandSent(CommandHandle commandHandle) { - MIPlugin.debug(MIPlugin.getDebugTime() + " " + commandHandle.getToken() + commandHandle.getCommand()); //$NON-NLS-1$ + MIPlugin.debug(MIPlugin.getDebugTime() + " " + commandHandle.getTokenId() + commandHandle.getCommand()); //$NON-NLS-1$ for (ICommandListener processor : fCommandProcessors) { - processor.commandSent(commandHandle.getCommand()); + processor.commandSent(commandHandle); } } @@ -374,7 +361,7 @@ public abstract class AbstractMIControl extends AbstractDsfService * Tell the listeners we have completed this one. */ for (ICommandListener processor : fCommandProcessors) { - processor.commandDone(commandHandle == null ? null : commandHandle.getCommand(), result); + processor.commandDone(commandHandle, result); } } @@ -389,14 +376,13 @@ public abstract class AbstractMIControl extends AbstractDsfService * A global counter for all command, the token will be use to identify uniquely a command. * Unless the value wraps around which is unlikely. */ + private int fTokenIdCounter = 0 ; - private static int globalCounter = 0 ; - - private static synchronized int getUniqToken() { - int count = ++globalCounter; + private int getNewTokenId() { + int count = ++fTokenIdCounter; // If we ever wrap around. if (count <= 0) { - count = globalCounter = 1; + count = fTokenIdCounter = 1; } return count; } @@ -406,8 +392,8 @@ public abstract class AbstractMIControl extends AbstractDsfService * individual request. */ - public static class CommandHandle { - + private class CommandHandle implements ICommandToken { + private MICommand fCommand; private DataRequestMonitor fRequestMonitor; private int fTokenId ; @@ -415,12 +401,13 @@ public abstract class AbstractMIControl extends AbstractDsfService CommandHandle(MICommand c, DataRequestMonitor d) { fCommand = c; fRequestMonitor = d; - fTokenId = getUniqToken() ; + fTokenId = getNewTokenId() ; } public MICommand getCommand() { return fCommand; } public DataRequestMonitor getRequestMonitor() { return fRequestMonitor; } - public Integer getToken() { return fTokenId; } + public Integer getTokenId() { return fTokenId; } + //public String getThreadId() { return null; } public Integer getStackFrameId() { IFrameDMContext frameCtx = DMContexts.getAncestorOfType(fCommand.getContext(), IFrameDMContext.class); @@ -477,14 +464,14 @@ public abstract class AbstractMIControl extends AbstractDsfService /* * We note that this is an outstanding request at this point. */ - fRxCommands.put(commandHandle.getToken(), commandHandle); + fRxCommands.put(commandHandle.getTokenId(), commandHandle); } /* * Construct the new command and push this command out the pipeline. */ - String str = commandHandle.getToken() + commandHandle.getCommand().constructCommand(); + String str = commandHandle.getTokenId() + commandHandle.getCommand().constructCommand(); try { if (fOutputStream != null) { diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/CLIEventProcessor.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/CLIEventProcessor.java index c2af69c36d4..9beca3818fb 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/CLIEventProcessor.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/CLIEventProcessor.java @@ -24,9 +24,9 @@ import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; import org.eclipse.dd.dsf.debug.service.ISignals.ISignalsDMContext; -import org.eclipse.dd.dsf.debug.service.command.ICommand; import org.eclipse.dd.dsf.debug.service.command.ICommandListener; import org.eclipse.dd.dsf.debug.service.command.ICommandResult; +import org.eclipse.dd.dsf.debug.service.command.ICommandToken; import org.eclipse.dd.dsf.debug.service.command.IEventListener; import org.eclipse.dd.mi.service.command.commands.CLICommand; import org.eclipse.dd.mi.service.command.commands.MIInterpreterExecConsole; @@ -73,30 +73,30 @@ public class CLIEventProcessor fCommandControl.removeEventListener(this); } - public void commandSent(ICommand command) { - if (command instanceof CLICommand) { - processStateChanges( (CLICommand)command ); + public void commandSent(ICommandToken token) { + if (token.getCommand() instanceof CLICommand) { + processStateChanges( (CLICommand)token.getCommand() ); } - else if (command instanceof MIInterpreterExecConsole) { - processStateChanges( (MIInterpreterExecConsole)command ); + else if (token.getCommand() instanceof MIInterpreterExecConsole) { + processStateChanges( (MIInterpreterExecConsole)token.getCommand() ); } } - public void commandDone(ICommand command, ICommandResult result) { - if (command instanceof CLICommand) { - processSettingChanges( (CLICommand)command ); + public void commandDone(ICommandToken token, ICommandResult result) { + if (token.getCommand() instanceof CLICommand) { + processSettingChanges( (CLICommand)token.getCommand() ); } - else if (command instanceof MIInterpreterExecConsole) { - processSettingChanges( (MIInterpreterExecConsole)command ); + else if (token.getCommand() instanceof MIInterpreterExecConsole) { + processSettingChanges( (MIInterpreterExecConsole)token.getCommand() ); } fEventList.clear(); } - public void commandQueued(ICommand command) { + public void commandQueued(ICommandToken token) { // No action } - public void commandRemoved(ICommand command) { + public void commandRemoved(ICommandToken token) { // No action } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIInferiorProcess.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIInferiorProcess.java index 8455061d919..3e0c9e7eb54 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIInferiorProcess.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIInferiorProcess.java @@ -32,9 +32,9 @@ import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; import org.eclipse.dd.dsf.concurrent.Query; -import org.eclipse.dd.dsf.debug.service.command.ICommand; import org.eclipse.dd.dsf.debug.service.command.ICommandListener; import org.eclipse.dd.dsf.debug.service.command.ICommandResult; +import org.eclipse.dd.dsf.debug.service.command.ICommandToken; import org.eclipse.dd.dsf.debug.service.command.IEventListener; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.mi.internal.MIPlugin; @@ -387,22 +387,22 @@ public class MIInferiorProcess extends Process } } - public void commandQueued(ICommand command) { + public void commandQueued(ICommandToken token) { // No action } - public void commandSent(ICommand command) { - if (command instanceof CLICommand) { + public void commandSent(ICommandToken token) { + if (token.getCommand() instanceof CLICommand) { fSuppressTargetOutputCounter++; } } - public void commandRemoved(ICommand command) { + public void commandRemoved(ICommandToken token) { // No action } - public void commandDone(ICommand command, ICommandResult result) { - if (command instanceof CLICommand) { + public void commandDone(ICommandToken token, ICommandResult result) { + if (token.getCommand() instanceof CLICommand) { fSuppressTargetOutputCounter--; } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIRunControlEventProcessor.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIRunControlEventProcessor.java index c64069a42d9..23b9335dd83 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIRunControlEventProcessor.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIRunControlEventProcessor.java @@ -18,6 +18,7 @@ import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; import org.eclipse.dd.dsf.debug.service.command.ICommand; import org.eclipse.dd.dsf.debug.service.command.ICommandListener; import org.eclipse.dd.dsf.debug.service.command.ICommandResult; +import org.eclipse.dd.dsf.debug.service.command.ICommandToken; import org.eclipse.dd.dsf.debug.service.command.IEventListener; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.mi.internal.MIPlugin; @@ -177,19 +178,20 @@ public class MIRunControlEventProcessor return event; } - public void commandQueued(ICommand command) { + public void commandQueued(ICommandToken token) { // Do nothing. } - public void commandSent(ICommand command) { + public void commandSent(ICommandToken token) { // Do nothing. } - public void commandRemoved(ICommand command) { + public void commandRemoved(ICommandToken token) { // Do nothing. } - public void commandDone(ICommand cmd, ICommandResult result) { + public void commandDone(ICommandToken token, ICommandResult result) { + ICommand cmd = token.getCommand(); MIInfo cmdResult = (MIInfo) result ; MIOutput output = cmdResult.getMIOutput(); MIResultRecord rr = output.getMIResultRecord(); From f8934d49d715f5df05da243e00f5248d1ffc7461 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Wed, 2 Apr 2008 15:18:36 +0000 Subject: [PATCH 367/834] Comment no longer valid after fix of Bug 206932 --- .../src/org/eclipse/dd/mi/service/MIVariableManager.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java index 5419f125828..44c63630551 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java @@ -85,14 +85,6 @@ import org.eclipse.dd.mi.service.command.output.MIVarUpdateInfo; /** * Manages a list of variable objects as created through GDB/MI commands. * - * Note that for the moment, this class is inheriting from AbstractDsfService, - * although it does not register as a service. This class is only used by the Expression - * Service, and therefore, need not be a service of its own. - * However, to be able to implement ICommandControl, we automatically must implement - * IDsfService, so, that is why we extend AbstractDsfService. We must implement - * ICommandControl service, to be able to interface properly with the MICommandCache which - * is using this class. - * * This class is passed expression-meta-commands which have their own cache. * Therefore, we don't use the standard MICommandCache in this class. * In fact, we can't even use it, because many variableObject MI commands, From 6947c2f41b700d738a47289f266b4210fa5ddd17 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 2 Apr 2008 17:56:05 +0000 Subject: [PATCH 368/834] [225388] Added a CommandHandle.toString() implementation. --- .../org/eclipse/dd/mi/service/command/AbstractMIControl.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java index 4fa55ea69cb..ec0b560af14 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java @@ -422,6 +422,11 @@ public abstract class AbstractMIControl extends AbstractDsfService return execCtx.getThreadId(); return null; } + + @Override + public String toString() { + return Integer.toString(fTokenId) + fCommand; + } } /* From 07b2d9a32c66429cc72432e7a28eb92448afbad8 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 2 Apr 2008 18:29:00 +0000 Subject: [PATCH 369/834] [225384] Switch to the platform debug modules view. --- .../dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java index 91eb685c3e7..810bd611c00 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java @@ -10,7 +10,6 @@ *******************************************************************************/ package org.eclipse.dd.gdb.internal.ui.viewmodel; -import org.eclipse.cdt.debug.ui.ICDebugUIConstants; import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression.ExpressionVMProvider; import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.modules.ModulesVMProvider; @@ -52,7 +51,7 @@ public class GdbViewModelAdapter extends AbstractDMVMAdapter return new RegisterVMProvider(this, context, getSession()); } else if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(context.getId()) ) { return new ExpressionVMProvider(this, context, getSession()); - } else if (ICDebugUIConstants.ID_MODULES_VIEW.equals(context.getId()) ) { + } else if (IDebugUIConstants.ID_MODULE_VIEW.equals(context.getId()) ) { return new ModulesVMProvider(this, context, getSession()); } return null; From 723b0df7312b3b40748f55b782194133f1053f11 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 3 Apr 2008 17:56:22 +0000 Subject: [PATCH 370/834] [225610] Removed the IExpressionDMData.getStringValue() method. --- .../ui/viewmodel/variable/VariableVMNode.java | 12 ++++++++---- .../eclipse/dd/dsf/debug/service/IExpressions.java | 5 ----- .../dd/dsf/debug/service/IFormattedValues.java | 1 + 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/VariableVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/VariableVMNode.java index b07ff746078..160194a26a1 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/VariableVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/VariableVMNode.java @@ -386,6 +386,7 @@ public class VariableVMNode extends AbstractExpressionVMNode } // Fill the label/column with the properly formatted data value. + /* Commented out, to be replaced. See bug 225612. StringBuffer stringValueBuf = new StringBuffer(getData().getFormattedValue()); String stringValue = expressionDMData.getStringValue(); if(stringValue != null && stringValue.length() > 0) @@ -393,7 +394,8 @@ public class VariableVMNode extends AbstractExpressionVMNode stringValueBuf.append(" "); stringValueBuf.append(stringValue.length() > MAX_STRING_VALUE_LENGTH ? stringValue.substring(0, MAX_STRING_VALUE_LENGTH) : stringValue); } - update.setLabel(stringValueBuf.toString(), labelIndex); + update.setLabel(stringValueBuf.toString(), labelIndex);*/ + update.setLabel(getData().getFormattedValue(), labelIndex); // Color based on change history FormattedValueDMData oldData = (FormattedValueDMData) getDMVMProvider().getArchivedModelData( @@ -401,11 +403,13 @@ public class VariableVMNode extends AbstractExpressionVMNode IExpressionDMData oldDMData = (IExpressionDMData) getDMVMProvider().getArchivedModelData( VariableVMNode.this, update, dmc); - String oldStringValue = oldDMData == null ? null : oldDMData.getStringValue(); + /* Commented out, to be replaced. See bug 225612. + String oldStringValue = oldDMData == null ? null : oldDMData.getStringValue();*/ // highlight the value if either the value (address) has changed or the string (memory at the value) has changed - if ((oldData != null && !oldData.getFormattedValue().equals(getData().getFormattedValue())) - || (oldStringValue != null && !oldStringValue.equals(stringValue))) { + if ((oldData != null && !oldData.getFormattedValue().equals(getData().getFormattedValue()))) { + /* Commented out, to be replaced. See bug 225612. + || (oldStringValue != null && !oldStringValue.equals(stringValue))) {*/ update.setBackground( DebugUIPlugin.getPreferenceColor( IInternalDebugUIConstants.PREF_CHANGED_VALUE_BACKGROUND).getRGB(), diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java index c77145be767..e72d30f3739 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IExpressions.java @@ -106,11 +106,6 @@ public interface IExpressions extends IFormattedValues { */ String getTypeId(); - /** - * @return A string containing the value of the expression as returned by the debugger backend. - */ - String getStringValue(); - /** * @return A Map in which the keys are strings that are the names of enumerators in the enumeration * that is the value of this expression and the values are the integer values of the diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java index 3eb94571573..c7ddc2903ab 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java @@ -33,6 +33,7 @@ public interface IFormattedValues extends IDMService { public final static String NATURAL_FORMAT = "NATURAL.Format" ; //$NON-NLS-1$ public final static String BINARY_FORMAT = "BINARY.Format" ; //$NON-NLS-1$ public final static String DECIMAL_FORMAT = "DECIMAL.Format" ; //$NON-NLS-1$ + public final static String STRING_FORMAT = "STRING.Format" ; //$NON-NLS-1$ /** * Retrieves the formats that the given data is available in. From 6f7bbca839fef48ee22cc37bce848a6e80d04f36 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Thu, 3 Apr 2008 20:53:30 +0000 Subject: [PATCH 371/834] Fix compilation problem --- .../dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java index 810bd611c00..91eb685c3e7 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.gdb.internal.ui.viewmodel; +import org.eclipse.cdt.debug.ui.ICDebugUIConstants; import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression.ExpressionVMProvider; import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.modules.ModulesVMProvider; @@ -51,7 +52,7 @@ public class GdbViewModelAdapter extends AbstractDMVMAdapter return new RegisterVMProvider(this, context, getSession()); } else if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(context.getId()) ) { return new ExpressionVMProvider(this, context, getSession()); - } else if (IDebugUIConstants.ID_MODULE_VIEW.equals(context.getId()) ) { + } else if (ICDebugUIConstants.ID_MODULES_VIEW.equals(context.getId()) ) { return new ModulesVMProvider(this, context, getSession()); } return null; From 8049a7bb128bd9445aaa071c52349d9d77031b7a Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Thu, 3 Apr 2008 20:57:42 +0000 Subject: [PATCH 372/834] Previous commit was a mistake. This change requires M6 to compile. --- .../dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java index 91eb685c3e7..810bd611c00 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java @@ -10,7 +10,6 @@ *******************************************************************************/ package org.eclipse.dd.gdb.internal.ui.viewmodel; -import org.eclipse.cdt.debug.ui.ICDebugUIConstants; import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression.ExpressionVMProvider; import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.modules.ModulesVMProvider; @@ -52,7 +51,7 @@ public class GdbViewModelAdapter extends AbstractDMVMAdapter return new RegisterVMProvider(this, context, getSession()); } else if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(context.getId()) ) { return new ExpressionVMProvider(this, context, getSession()); - } else if (ICDebugUIConstants.ID_MODULES_VIEW.equals(context.getId()) ) { + } else if (IDebugUIConstants.ID_MODULE_VIEW.equals(context.getId()) ) { return new ModulesVMProvider(this, context, getSession()); } return null; From d25c62e7634b1d2e44b8ca0c828b8cd6a43eb8a2 Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Sat, 5 Apr 2008 02:14:07 +0000 Subject: [PATCH 373/834] Bugzilla 225606 --- .../dd/dsf/debug/service/IRegisters.java | 71 +++++++++++++------ .../eclipse/dd/mi/service/MIRegisters.java | 51 ++++++++++--- 2 files changed, 93 insertions(+), 29 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java index f96f134c295..98b21cc0e80 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java @@ -107,27 +107,6 @@ public interface IRegisters extends IFormattedValues { String getLongName(); } - /** - * Retrieves register group data for given context. - * @param dmc Context to retrieve data for. - * @param rm Request completion monitor. - */ - void getRegisterGroupData(IRegisterGroupDMContext dmc, DataRequestMonitor rm); - - /** - * Retrieves register data for given context. - * @param dmc Context to retrieve data for. - * @param rm Request completion monitor. - */ - void getRegisterData(IRegisterDMContext dmc , DataRequestMonitor rm); - - /** - * Retrieves bit field data for given context. - * @param dmc Context to retrieve data for. - * @param rm Request completion monitor. - */ - void getBitFieldData(IBitFieldDMContext dmc , DataRequestMonitor rm); - /** * Retrieves the list of register groups. * @param ctx Context for the returned data. @@ -151,6 +130,56 @@ public interface IRegisters extends IFormattedValues { */ void getBitFields(IDMContext ctx, DataRequestMonitor rm); + /** + * Retrieves a Register Group context. The given context could include a register + * group and an execution context or just an execution context. + * @param ctx Context for the returned data. + * @param name Name of group being requested + * @param rm Request completion monitor. + */ + void findRegisterGroup(IDMContext ctx, String name, DataRequestMonitor rm); + + /** + * Retrieves a Register context. The given context could include a register group and an execution + * context or just an execution context. + * @param ctx Context for the returned data. + * @param name Name of register being requested + * @param rm Request completion monitor. + */ + void findRegister(IDMContext ctx, String name, DataRequestMonitor rm); + + /** + * Retrieves bit field context. The given context could include a register and an execution + * context or just an execution context. + * @param ctx Context for the returned data. + * @param name Name of bit field being requested + * @param rm Request completion monitor. + */ + void findBitField(IDMContext ctx, String name, DataRequestMonitor rm); + + /** + * Retrieves register group data for given context. + * @param dmc Context to retrieve data for. + * @param rm Request completion monitor. + */ + void getRegisterGroupData(IRegisterGroupDMContext dmc, DataRequestMonitor rm); + + /** + * Retrieves register data for given context. + * @param dmc Context to retrieve data for. + * @param rm Request completion monitor. + */ + void getRegisterData(IRegisterDMContext dmc , DataRequestMonitor rm); + + /** + * Retrieves bit field data for given context. + * @param dmc Context to retrieve data for. + * @param rm Request completion monitor. + */ + void getBitFieldData(IBitFieldDMContext dmc , DataRequestMonitor rm); + + + /** * Writes a register value for a given register to the target * @param regCtx Context containing the register. diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRegisters.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRegisters.java index 568a477a0d6..002231d4410 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRegisters.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRegisters.java @@ -40,7 +40,6 @@ import org.eclipse.dd.mi.service.command.output.MIInfo; import org.eclipse.dd.mi.service.command.output.MIRegisterValue; import org.osgi.framework.BundleContext; - /** * *

              @@ -175,7 +174,7 @@ public class MIRegisters extends AbstractDsfService implements IRegisters { fRegisterNameCache = new CommandCache(getSession(), getServicesTracker().getService(ICommandControl.class)); /* - * Signup so we see events. We use these events to decide how to manage + * Sign up so we see events. We use these events to decide how to manage * any local caches we are providing as well as the lower level register * cache we create to get/set registers on the target. */ @@ -203,9 +202,9 @@ public class MIRegisters extends AbstractDsfService implements IRegisters { public void getModelData(IDMContext dmc, DataRequestMonitor rm) { /* * This is the method which is called when actual results need to be returned. We - * can be called either with a service DMC for which we return oureslves or we can + * can be called either with a service DMC for which we return ourselves or we can * be called with the DMC's we have handed out. If the latter is the case then we - * datamine by talking to the Debug Engine. + * data mine by talking to the Debug Engine. */ if (dmc instanceof MIRegisterGroupDMC) { @@ -396,14 +395,16 @@ public class MIRegisters extends AbstractDsfService implements IRegisters { * need to be flushed. These handlers maintain the state of the caches. */ - @DsfServiceEventHandler public void eventDispatched(IRunControl.IResumedDMEvent e) { + @DsfServiceEventHandler + public void eventDispatched(IRunControl.IResumedDMEvent e) { fRegisterValueCache.setContextAvailable(e.getDMContext(), false); if (e.getReason() != StateChangeReason.STEP) { fRegisterValueCache.reset(); } } - @DsfServiceEventHandler public void eventDispatched( + @DsfServiceEventHandler + public void eventDispatched( IRunControl.ISuspendedDMEvent e) { fRegisterValueCache.setContextAvailable(e.getDMContext(), true); fRegisterValueCache.reset(); @@ -414,6 +415,10 @@ public class MIRegisters extends AbstractDsfService implements IRegisters { fRegisterValueCache.reset(); } + private void generateRegisterChangedEvent(IRegisterDMContext dmc ) { + getSession().dispatchEvent(new RegisterChangedDMEvent(dmc), getProperties()); + } + /* * These are the public interfaces for this service. * @@ -562,12 +567,20 @@ public class MIRegisters extends AbstractDsfService implements IRegisters { rm.done(); } + /* + * (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IFormattedValues#getAvailableFormats(org.eclipse.dd.dsf.debug.service.IFormattedValues.IFormattedDataDMContext, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) + */ public void getAvailableFormats(IFormattedDataDMContext dmc, DataRequestMonitor rm) { rm.setData(new String[] { HEX_FORMAT, DECIMAL_FORMAT, OCTAL_FORMAT, BINARY_FORMAT, NATURAL_FORMAT }); rm.done(); } + /* + * (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IFormattedValues#getFormattedValueContext(org.eclipse.dd.dsf.debug.service.IFormattedValues.IFormattedDataDMContext, java.lang.String) + */ public FormattedValueDMContext getFormattedValueContext(IFormattedDataDMContext dmc, String formatId) { if ( dmc instanceof MIRegisterDMC ) { MIRegisterDMC regDmc = (MIRegisterDMC) dmc; @@ -575,9 +588,31 @@ public class MIRegisters extends AbstractDsfService implements IRegisters { } return null; } + + /* + * (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IRegisters#findRegisterGroup(org.eclipse.dd.dsf.datamodel.IDMContext, java.lang.String, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) + */ + public void findRegisterGroup(IDMContext ctx, String name, DataRequestMonitor rm) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, "Finding a Register Group context not supported", null)); //$NON-NLS-1$ + rm.done(); + } - private void generateRegisterChangedEvent(IRegisterDMContext dmc ) { - getSession().dispatchEvent(new RegisterChangedDMEvent(dmc), getProperties()); + /* + * (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IRegisters#findRegister(org.eclipse.dd.dsf.datamodel.IDMContext, java.lang.String, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) + */ + public void findRegister(IDMContext ctx, String name, DataRequestMonitor rm) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, "Finding a Register context not supported", null)); //$NON-NLS-1$ + rm.done(); } + /* + * (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IRegisters#findBitField(org.eclipse.dd.dsf.datamodel.IDMContext, java.lang.String, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) + */ + public void findBitField(IDMContext ctx, String name, DataRequestMonitor rm) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, "Finding a Register Group context not supported", null)); //$NON-NLS-1$ + rm.done(); + } } From 5b3e8b0827577fd60398dfc6e1764fa5667f16e2 Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Sat, 5 Apr 2008 02:15:54 +0000 Subject: [PATCH 374/834] Made a little more readable. --- .../org/eclipse/dd/examples/dsf/timers/TimersView.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersView.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersView.java index 27b96b3ddf3..8b1d5c2b56e 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersView.java +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersView.java @@ -125,12 +125,9 @@ public class TimersView extends ViewPart { // Create the flexible hierarchy content/label adapter. Then register // it with the session. fTimersVMAdapter = new TimersVMAdapter(fSession, fPresentationContext); - fSession.registerModelAdapter( - IElementContentProvider.class, fTimersVMAdapter); - fSession.registerModelAdapter( - IModelProxyFactory.class, fTimersVMAdapter); - fSession.registerModelAdapter( - IColumnPresentationFactory.class, fTimersVMAdapter); + fSession.registerModelAdapter(IElementContentProvider.class, fTimersVMAdapter); + fSession.registerModelAdapter(IModelProxyFactory.class, fTimersVMAdapter); + fSession.registerModelAdapter(IColumnPresentationFactory.class, fTimersVMAdapter); // Create the input object for the view. This object needs to return // the VM adapter through the IAdaptable interface when queried for the From 3b6ff0210d66b3f5dda3ef565d95e2ed8dddb2e2 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Sat, 5 Apr 2008 05:23:17 +0000 Subject: [PATCH 375/834] [225813] Add a new GDB-Launch feature --- .../feature.xml | 13 +- .../.project | 17 +++ .../build.properties | 1 + .../feature.properties | 126 ++++++++++++++++++ .../feature.xml | 27 ++++ .../license.html | 79 +++++++++++ .../feature.xml | 7 - 7 files changed, 260 insertions(+), 10 deletions(-) create mode 100644 features/org.eclipse.dd.dsf.gdb_launch-feature/.project create mode 100644 features/org.eclipse.dd.dsf.gdb_launch-feature/build.properties create mode 100644 features/org.eclipse.dd.dsf.gdb_launch-feature/feature.properties create mode 100644 features/org.eclipse.dd.dsf.gdb_launch-feature/feature.xml create mode 100644 features/org.eclipse.dd.dsf.gdb_launch-feature/license.html diff --git a/features/org.eclipse.dd.dsf.gdb-feature/feature.xml b/features/org.eclipse.dd.dsf.gdb-feature/feature.xml index 5816da5c375..52f83746e7b 100644 --- a/features/org.eclipse.dd.dsf.gdb-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.gdb-feature/feature.xml @@ -1,7 +1,7 @@ @@ -12,7 +12,7 @@ Debug Services Framework GDB-MI Implementation - + %copyright @@ -25,7 +25,7 @@ GDB-MI Implementation - + + + diff --git a/features/org.eclipse.dd.dsf.gdb_launch-feature/.project b/features/org.eclipse.dd.dsf.gdb_launch-feature/.project new file mode 100644 index 00000000000..b81f1d92ed1 --- /dev/null +++ b/features/org.eclipse.dd.dsf.gdb_launch-feature/.project @@ -0,0 +1,17 @@ + + + org.eclipse.dd.dsf.gdb_launch-feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/features/org.eclipse.dd.dsf.gdb_launch-feature/build.properties b/features/org.eclipse.dd.dsf.gdb_launch-feature/build.properties new file mode 100644 index 00000000000..64f93a9f0b7 --- /dev/null +++ b/features/org.eclipse.dd.dsf.gdb_launch-feature/build.properties @@ -0,0 +1 @@ +bin.includes = feature.xml diff --git a/features/org.eclipse.dd.dsf.gdb_launch-feature/feature.properties b/features/org.eclipse.dd.dsf.gdb_launch-feature/feature.properties new file mode 100644 index 00000000000..fc88e04d681 --- /dev/null +++ b/features/org.eclipse.dd.dsf.gdb_launch-feature/feature.properties @@ -0,0 +1,126 @@ +############################################################################### +# Copyright (c) 2006, 2007 Wind River Systems and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Ted Williams (Wind River) - initial API and implementation +############################################################################### + +# "copyright" property - text of the "Feature Update Copyright" +copyright=\ +Copyright (c) 2000, 2007 Wind River Systems and others.\n\ +All rights reserved. This program and the accompanying materials\n\ +are made available under the terms of the Eclipse Public License v1.0\n\ +which accompanies this distribution, and is available at\n\ +http://www.eclipse.org/legal/epl-v10.html\n\ +################ end of copyright property #################################### + +# "licenseURL" property - URL of the "Feature License" +# do not translate value - just change to point to a locale-specific HTML page +licenseURL=license.html + +# "license" property - text of the "Feature Update License" +# should be plain text version of license agreement pointed to be "licenseURL" +license=\ +* Eclipse Public License v1.0 (http://www.eclipse.org/legal/epl-v10.html)\n\ +\n\ +ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\ +March 17, 2005\n\ +\n\ +Usage Of Content\n\ +\n\ +THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\ +OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\ +USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\ +AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\ +NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\ +AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\ +AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\ +OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ +TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\ +OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ +BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\ +\n\ +Applicable Licenses\n\ +\n\ +Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ +is provided to you under the terms and conditions of the Eclipse Public\n\ +License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\ +Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\ +For purposes of the EPL, "Program" will mean the Content.\n\ +\n\ +Content includes, but is not limited to, source code, object code,\n\ +documentation and other files maintained in the Eclipse.org CVS\n\ +repository ("Repository") in CVS modules ("Modules") and made available\n\ +as downloadable archives ("Downloads").\n\ +\n\ + - Content may be structured and packaged into modules to facilitate delivering,\n\ + extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\ + plug-in fragments ("Fragments"), and features ("Features").\n\ + - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\ + in a directory named "plugins".\n\ + - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\ + Each Feature may be packaged as a sub-directory in a directory named "features".\n\ + Within a Feature, files named "feature.xml" may contain a list of the names and version\n\ + numbers of the Plug-ins and/or Fragments associated with that Feature.\n\ + - Features may also include other Features ("Included Features"). Within a Feature, files\n\ + named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\ +\n\ +Features may also include other Features ("Included Features"). Files named\n\ +"feature.xml" may contain a list of the names and version numbers of\n\ +Included Features.\n\ +\n\ +The terms and conditions governing Plug-ins and Fragments should be\n\ +contained in files named "about.html" ("Abouts"). The terms and\n\ +conditions governing Features and Included Features should be contained\n\ +in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\ +Licenses may be located in any directory of a Download or Module\n\ +including, but not limited to the following locations:\n\ +\n\ + - The top-level (root) directory\n\ + - Plug-in and Fragment directories\n\ + - Inside Plug-ins and Fragments packaged as JARs\n\ + - Sub-directories of the directory named "src" of certain Plug-ins\n\ + - Feature directories\n\ +\n\ +Note: if a Feature made available by the Eclipse Foundation is installed using the\n\ +Eclipse Update Manager, you must agree to a license ("Feature Update\n\ +License") during the installation process. If the Feature contains\n\ +Included Features, the Feature Update License should either provide you\n\ +with the terms and conditions governing the Included Features or inform\n\ +you where you can locate them. Feature Update Licenses may be found in\n\ +the "license" property of files named "feature.properties". Such Abouts,\n\ +Feature Licenses and Feature Update Licenses contain the terms and\n\ +conditions (or references to such terms and conditions) that govern your\n\ +use of the associated Content in that directory.\n\ +\n\ +THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\ +TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\ +SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ +\n\ + - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\ + - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\ + - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\ + - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\ + - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\ + - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\ +\n\ +IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\ +TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\ +is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\ +govern that particular Content.\n\ +\n\ +Cryptography\n\ +\n\ +Content may contain encryption software. The country in which you are\n\ +currently may have restrictions on the import, possession, and use,\n\ +and/or re-export to another country, of encryption software. BEFORE\n\ +using any encryption software, please check the country's laws,\n\ +regulations and policies concerning the import, possession, or use,\n\ +and re-export of encryption software, to see if this is permitted.\n\ +\n\ +Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n +########### end of license property ########################################## diff --git a/features/org.eclipse.dd.dsf.gdb_launch-feature/feature.xml b/features/org.eclipse.dd.dsf.gdb_launch-feature/feature.xml new file mode 100644 index 00000000000..6e32870853b --- /dev/null +++ b/features/org.eclipse.dd.dsf.gdb_launch-feature/feature.xml @@ -0,0 +1,27 @@ + + + + + Device Software Development Platform Project +Device Debug +Debug Services Framework +GDB Launch + + + + %copyright + + + + %license + + + + + + + diff --git a/features/org.eclipse.dd.dsf.gdb_launch-feature/license.html b/features/org.eclipse.dd.dsf.gdb_launch-feature/license.html new file mode 100644 index 00000000000..c6af966b61e --- /dev/null +++ b/features/org.eclipse.dd.dsf.gdb_launch-feature/license.html @@ -0,0 +1,79 @@ + + + + +Eclipse.org Software User Agreement + + + +

              Eclipse Foundation Software User Agreement

              +

              March 17, 2005

              + +

              Usage Of Content

              + +

              THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS + (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND + CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE + OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR + NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND + CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.

              + +

              Applicable Licenses

              + +

              Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0 + ("EPL"). A copy of the EPL is provided with this Content and is also available at http://www.eclipse.org/legal/epl-v10.html. + For purposes of the EPL, "Program" will mean the Content.

              + +

              Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse.org CVS repository ("Repository") in CVS + modules ("Modules") and made available as downloadable archives ("Downloads").

              + +
                +
              • Content may be structured and packaged into modules to facilitate delivering, extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and features ("Features").
              • +
              • Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java™ ARchive) in a directory named "plugins".
              • +
              • A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. Each Feature may be packaged as a sub-directory in a directory named "features". Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of the Plug-ins + and/or Fragments associated with that Feature.
              • +
              • Features may also include other Features ("Included Features"). Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of Included Features.
              • +
              + +

              The terms and conditions governing Plug-ins and Fragments should be contained in files named "about.html" ("Abouts"). The terms and conditions governing Features and +Included Features should be contained in files named "license.html" ("Feature Licenses"). Abouts and Feature Licenses may be located in any directory of a Download or Module +including, but not limited to the following locations:

              + +
                +
              • The top-level (root) directory
              • +
              • Plug-in and Fragment directories
              • +
              • Inside Plug-ins and Fragments packaged as JARs
              • +
              • Sub-directories of the directory named "src" of certain Plug-ins
              • +
              • Feature directories
              • +
              + +

              Note: if a Feature made available by the Eclipse Foundation is installed using the Eclipse Update Manager, you must agree to a license ("Feature Update License") during the +installation process. If the Feature contains Included Features, the Feature Update License should either provide you with the terms and conditions governing the Included Features or +inform you where you can locate them. Feature Update Licenses may be found in the "license" property of files named "feature.properties" found within a Feature. +Such Abouts, Feature Licenses, and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your use of the associated Content in +that directory.

              + +

              THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE +OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):

              + + + +

              IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License, or Feature Update License is provided, please +contact the Eclipse Foundation to determine what terms and conditions govern that particular Content.

              + +

              Cryptography

              + +

              Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to + another country, of encryption software. BEFORE using any encryption software, please check the country's laws, regulations and policies concerning the import, + possession, or use, and re-export of encryption software, to see if this is permitted.

              + +Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both. + + diff --git a/features/org.eclipse.dd.dsf.sdk-feature/feature.xml b/features/org.eclipse.dd.dsf.sdk-feature/feature.xml index 00cdaeddd1a..ea0f473c2f9 100644 --- a/features/org.eclipse.dd.dsf.sdk-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.sdk-feature/feature.xml @@ -59,11 +59,4 @@ Core SDK version="0.0.0" unpack="false"/> - - From f4c0b1b176408be73a59de1928d71c28507ecb80 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Sat, 5 Apr 2008 06:48:12 +0000 Subject: [PATCH 376/834] [225813] Add a new GDB-Launch feature --- .../feature.xml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/features/org.eclipse.dd.dsf.gdb_launch-feature/feature.xml b/features/org.eclipse.dd.dsf.gdb_launch-feature/feature.xml index 6e32870853b..d749ba07968 100644 --- a/features/org.eclipse.dd.dsf.gdb_launch-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.gdb_launch-feature/feature.xml @@ -16,7 +16,7 @@ GDB Launch %copyright - + %license @@ -24,4 +24,18 @@ GDB Launch + + + + From 6500ea99f54a77c841493d830fbbb10b09d3de51 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Sat, 5 Apr 2008 17:56:54 +0000 Subject: [PATCH 377/834] M6 --- features/org.eclipse.dd.dsf.gdb_launch-feature/feature.xml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/features/org.eclipse.dd.dsf.gdb_launch-feature/feature.xml b/features/org.eclipse.dd.dsf.gdb_launch-feature/feature.xml index d749ba07968..8bfc43d1117 100644 --- a/features/org.eclipse.dd.dsf.gdb_launch-feature/feature.xml +++ b/features/org.eclipse.dd.dsf.gdb_launch-feature/feature.xml @@ -31,11 +31,4 @@ GDB Launch version="0.0.0" unpack="false"/> - - From 117080e50d09cbfac355d12a11830bba32a5ee73 Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Sat, 5 Apr 2008 19:04:24 +0000 Subject: [PATCH 378/834] M6 --- plugins/org.eclipse.dd.gdb.ui/build.properties | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/org.eclipse.dd.gdb.ui/build.properties b/plugins/org.eclipse.dd.gdb.ui/build.properties index 91d219bb13a..786b1df9364 100644 --- a/plugins/org.eclipse.dd.gdb.ui/build.properties +++ b/plugins/org.eclipse.dd.gdb.ui/build.properties @@ -4,4 +4,3 @@ bin.includes = META-INF/,\ .,\ plugin.xml,\ about.html - \ No newline at end of file From d7ecf155dbcf5d26a9e1b370db5dd0d0552322dc Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Sat, 5 Apr 2008 19:06:12 +0000 Subject: [PATCH 379/834] M6 build --- .../org/eclipse/dd/gdb/internal/ui/launching/CDebuggerTab.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/CDebuggerTab.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/CDebuggerTab.java index c9bbe45ce37..514b5350e73 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/CDebuggerTab.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/CDebuggerTab.java @@ -336,7 +336,7 @@ public class CDebuggerTab extends AbstractCDebuggerTab { else if (fSessionType == SessionType.REMOTE) mode = IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE; if (!mode.equals(IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE) && !debugConfig.supportsMode(mode)) { - setErrorMessage(MessageFormat.format(LaunchMessages.getString("CDebuggerTab.Mode_not_supported"), new String[]{mode})); //$NON-NLS-1$ + setErrorMessage(MessageFormat.format(LaunchMessages.getString("CDebuggerTab.Mode_not_supported"), (Object[]) new String[]{mode})); //$NON-NLS-1$ return false; } if ( fStopInMain != null && fStopInMainSymbol != null ) { From 3631515ed8a795b9c438f5a547b8bd4e98cf6acc Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Sat, 5 Apr 2008 19:16:32 +0000 Subject: [PATCH 380/834] M6 missing icons --- plugins/org.eclipse.dd.gdb.launch/build.properties | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.gdb.launch/build.properties b/plugins/org.eclipse.dd.gdb.launch/build.properties index 7651071b534..515583b938f 100644 --- a/plugins/org.eclipse.dd.gdb.launch/build.properties +++ b/plugins/org.eclipse.dd.gdb.launch/build.properties @@ -4,4 +4,5 @@ bin.includes = plugin.xml,\ META-INF/,\ .,\ about.html,\ - src/ + src/,\ + icons/ From 06b2e66cb02b2397e1e2a37c1c3ac943a80ed6ae Mon Sep 17 00:00:00 2001 From: Ted Williams Date: Sat, 5 Apr 2008 19:22:06 +0000 Subject: [PATCH 381/834] M6 build --- plugins/org.eclipse.dd.gdb.launch/build.properties | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/org.eclipse.dd.gdb.launch/build.properties b/plugins/org.eclipse.dd.gdb.launch/build.properties index 515583b938f..2ca75b3c30c 100644 --- a/plugins/org.eclipse.dd.gdb.launch/build.properties +++ b/plugins/org.eclipse.dd.gdb.launch/build.properties @@ -4,5 +4,4 @@ bin.includes = plugin.xml,\ META-INF/,\ .,\ about.html,\ - src/,\ icons/ From 4d9b833a78372bf765689e29615838b6b133e62b Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Sat, 5 Apr 2008 19:40:00 +0000 Subject: [PATCH 382/834] [225820] Removed the unused Section interface. --- .../src/org/eclipse/dd/dsf/debug/service/IModules.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java index a1b7e8fd770..81d09842c4a 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IModules.java @@ -10,8 +10,6 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.service; -import java.math.BigInteger; - import org.eclipse.cdt.core.IAddress; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; @@ -66,13 +64,6 @@ public interface IModules extends IDsfService { long getSize(); } - /** i information */ - public interface Section { - String getName(); - IAddress getStartAddress(); - BigInteger getCount(); - } - /** Line information about a particular address */ public interface LineInfo { IAddress getAddress(); From bacca4af5cbce6bc75c3c89afc03bed05a0b3a44 Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Mon, 7 Apr 2008 13:27:50 +0000 Subject: [PATCH 383/834] Bugzilla 225959. --- .../dsf/ui/viewmodel/properties/PropertyBasedLabelProvider.java | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/PropertyBasedLabelProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/PropertyBasedLabelProvider.java index 08eff3de241..b3c6087f334 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/PropertyBasedLabelProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/PropertyBasedLabelProvider.java @@ -176,6 +176,7 @@ public class PropertyBasedLabelProvider for (ILabelUpdate update : labelUpdates) { update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, "Properties-based label provider " + this + " failed to generate a label, no properties provider registered for element: " + labelUpdates[0].getElement())); //$NON-NLS-1$ //$NON-NLS-2$ } + return; } String[] columnIds = labelUpdates[0].getColumnIds(); From cc8dc928992342196eb2a09c439ea85ed8ffd700 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Mon, 7 Apr 2008 17:32:19 +0000 Subject: [PATCH 384/834] Fix to the MIRunControl test. --- .../dd/tests/gdb/MIRunControlTest.java | 233 ++++++++---------- 1 file changed, 99 insertions(+), 134 deletions(-) diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRunControlTest.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRunControlTest.java index 7f65a32a858..ad84a806239 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRunControlTest.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/MIRunControlTest.java @@ -15,20 +15,16 @@ import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.core.runtime.IStatus; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.debug.service.IRunControl; -import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMData; import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent; import org.eclipse.dd.dsf.debug.service.IRunControl.IStartedDMEvent; import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason; import org.eclipse.dd.dsf.debug.service.IRunControl.StepType; -import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl; -import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControlDMContext; import org.eclipse.dd.mi.service.IMIExecutionDMContext; import org.eclipse.dd.mi.service.MIRunControl; -import org.eclipse.dd.mi.service.MIStack; import org.eclipse.dd.mi.service.command.events.MIStoppedEvent; import org.eclipse.dd.mi.service.command.output.MIInfo; import org.eclipse.dd.tests.gdb.framework.AsyncCompletionWaitor; @@ -53,17 +49,6 @@ public class MIRunControlTest extends BaseTestCase { private GDBControl fGDBCtrl; private MIRunControl fRunCtrl; - private MIStack fStack; - - /* - * Boolean variables for testing events. Test thread create event only when this is set to true - */ - private boolean fIsTestingThreadCreateEvent = false; - /* - * Boolean variables for error from events. Set to true only if there is an error in the event being tested. - */ - private boolean fIsEventError = false; - /* * Path to executable @@ -75,33 +60,17 @@ public class MIRunControlTest extends BaseTestCase { private static final String EXEC_NAME = "MultiThread.exe"; private static final String SOURCE_NAME = "MultiThread.cc"; - - /* - * Variable to wait for asynchronous call to complete - */ - private final AsyncCompletionWaitor fWait = new AsyncCompletionWaitor(); - @Before public void init() throws Exception { fServicesTracker = new DsfServicesTracker(TestsPlugin.getBundleContext(), getGDBLaunch().getSession().getId()); - /* - * Get the MIRunControl & MIStack service. - */ fGDBCtrl = fServicesTracker.getService(GDBControl.class); fRunCtrl = fServicesTracker.getService(MIRunControl.class); - fStack = fServicesTracker.getService(MIStack.class); - /* - * Add to the Listeners list - */ - getGDBLaunch().getSession().addServiceEventListener(this, null); } @After public void tearDown() { - fRunCtrl = null; - fStack = null; fServicesTracker.dispose(); } @@ -111,13 +80,12 @@ public class MIRunControlTest extends BaseTestCase { EXEC_PATH + EXEC_NAME); } - /* * For Multi-threaded application - In case of one thread, Thread id should start with 1. */ @Test public void getExecutionContext() throws InterruptedException{ - //TestsPlugin.debugMethod("getExecutionContext()"); + final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); /* * Create a request monitor */ @@ -126,9 +94,9 @@ public class MIRunControlTest extends BaseTestCase { @Override protected void handleCompleted() { if (isSuccess()) { - fWait.setReturnInfo(getData()); + wait.setReturnInfo(getData()); } - fWait.waitFinished(getStatus()); + wait.waitFinished(getStatus()); } }; @@ -140,8 +108,8 @@ public class MIRunControlTest extends BaseTestCase { fRunCtrl.getExecutionContexts(fGDBCtrl.getGDBDMContext(), rm); } }); - fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); - Assert.assertTrue(fWait.getMessage(), fWait.isOK()); + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + Assert.assertTrue(wait.getMessage(), wait.isOK()); /* * Get data from the Request Monitor @@ -150,16 +118,17 @@ public class MIRunControlTest extends BaseTestCase { // Context can not be null if(ctxts == null) - Assert.fail("Context returned is null. Atleast one context should have been returned"); - else{ + Assert.fail("Context returned is null. At least one context should have been returned"); + else { // Only one Context in this case if(ctxts.length > 1) - Assert.fail("Context returned canot be more than 1. This test case is for single context application."); + Assert.fail("Context returned can not be more than 1. This test case is for single context application."); + IMIExecutionDMContext dmc = (IMIExecutionDMContext)ctxts[0]; // Thread id for the main thread should be one Assert.assertEquals(1, dmc.getThreadId()); } - fWait.waitReset(); + wait.waitReset(); } @@ -169,7 +138,7 @@ public class MIRunControlTest extends BaseTestCase { */ @Test public void getExecutionContexts() throws InterruptedException{ - //TestsPlugin.debugMethod("getExecutionContexts()"); + final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); /* * Create a request monitor */ @@ -178,15 +147,18 @@ public class MIRunControlTest extends BaseTestCase { @Override protected void handleCompleted() { if (isSuccess()) { - fWait.setReturnInfo(getData()); + wait.setReturnInfo(getData()); } - fWait.waitFinished(getStatus()); + wait.waitFinished(getStatus()); } }; - /* - * Also Testing Thread create event. Set boolean variable to true - */ - fIsTestingThreadCreateEvent = true; + + // Prepare a waiter to make sure we have received the thread started event + final ServiceEventWaitor startedEventWaitor = + new ServiceEventWaitor( + getGDBLaunch().getSession(), + IStartedDMEvent.class); + try{ /* * Run till line for 2 threads to be created @@ -196,16 +168,20 @@ public class MIRunControlTest extends BaseTestCase { catch(Throwable t){ Assert.fail("Exception in SyncUtil.SyncRunToLine: " + t.getMessage()); } - /* - * Re-set the boolean variable for testing thread create event. - */ - fIsTestingThreadCreateEvent = false; - /* - * Check if error in thread create event - */ - if(fIsEventError){ - Assert.fail("Thread create event has failed."); + + // Make sure thread started event was received because it could arrive + // after the stopped event is received + IStartedDMEvent startedEvent = null; + try { + startedEvent = startedEventWaitor.waitForEvent(1000); + } catch (Exception e) { + Assert.fail("Timeout waiting for Thread create event"); } + + if (((IMIExecutionDMContext)startedEvent.getDMContext()).getThreadId() != 2) + Assert.fail("Thread create event has failed expected thread id 2 but got " + + ((IMIExecutionDMContext)startedEvent.getDMContext()).getThreadId()); + /* * Test getExecutionContexts for a valid container DMC */ @@ -214,9 +190,9 @@ public class MIRunControlTest extends BaseTestCase { fRunCtrl.getExecutionContexts(fGDBCtrl.getGDBDMContext(), rmExecutionCtxts); } }); - fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); - Assert.assertTrue(fWait.getMessage(), fWait.isOK()); - fWait.waitReset(); + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + Assert.assertTrue(wait.getMessage(), wait.isOK()); + wait.waitReset(); /* * Get data */ @@ -241,7 +217,7 @@ public class MIRunControlTest extends BaseTestCase { */ @Test public void getModelDataForThread() throws InterruptedException{ - //TestsPlugin.debugMethod("getModelDataForThread("); + final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); /* * Create a request monitor */ @@ -250,9 +226,9 @@ public class MIRunControlTest extends BaseTestCase { @Override protected void handleCompleted() { if (isSuccess()) { - fWait.setReturnInfo(getData()); + wait.setReturnInfo(getData()); } - fWait.waitFinished(getStatus()); + wait.waitFinished(getStatus()); } }; /* @@ -263,8 +239,8 @@ public class MIRunControlTest extends BaseTestCase { fRunCtrl.getExecutionData(fRunCtrl.createMIExecutionContext(fGDBCtrl.getGDBDMContext(), 1), rm); } }); - fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); - Assert.assertTrue(fWait.getMessage(), fWait.isOK()); + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + Assert.assertTrue(wait.getMessage(), wait.isOK()); IRunControl.IExecutionDMData data = rm.getData(); if(data == null) @@ -280,7 +256,7 @@ public class MIRunControlTest extends BaseTestCase { @Test public void getModelDataForThreadWhenStep() throws Throwable { - //TestsPlugin.debugMethod("getModelDataForThread()"); + final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); /* * Run till step returns */ @@ -291,9 +267,9 @@ public class MIRunControlTest extends BaseTestCase { @Override protected void handleCompleted() { if (isSuccess()) { - fWait.setReturnInfo(getData()); + wait.setReturnInfo(getData()); } - fWait.waitFinished(getStatus()); + wait.waitFinished(getStatus()); } }; /* @@ -304,8 +280,8 @@ public class MIRunControlTest extends BaseTestCase { fRunCtrl.getExecutionData(stoppedEvent.getDMContext(), rm); } }); - fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); - Assert.assertTrue(fWait.getMessage(), fWait.isOK()); + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + Assert.assertTrue(wait.getMessage(), wait.isOK()); IRunControl.IExecutionDMData data = rm.getData(); if(data == null) @@ -324,7 +300,7 @@ public class MIRunControlTest extends BaseTestCase { */ @Test public void getModelDataForThreadWhenBreakpoint() throws Throwable { - //TestsPlugin.debugMethod("getModelDataForThreadWhenBreakpoint()"); + final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); /* * Add a breakpoint */ @@ -340,9 +316,9 @@ public class MIRunControlTest extends BaseTestCase { @Override protected void handleCompleted() { if (isSuccess()) { - fWait.setReturnInfo(getData()); + wait.setReturnInfo(getData()); } - fWait.waitFinished(getStatus()); + wait.waitFinished(getStatus()); } }; fRunCtrl.getExecutor().submit(new Runnable() { @@ -350,8 +326,8 @@ public class MIRunControlTest extends BaseTestCase { fRunCtrl.getExecutionData(stoppedEvent.getDMContext(), rm); } }); - fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); - Assert.assertTrue(fWait.getMessage(), fWait.isOK()); + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + Assert.assertTrue(wait.getMessage(), wait.isOK()); IRunControl.IExecutionDMData data = rm.getData(); if(data == null) @@ -370,15 +346,16 @@ public class MIRunControlTest extends BaseTestCase { */ @Test public void getModelDataForContainer() throws InterruptedException{ - //TestsPlugin.debugMethod("getModelDataForContainer()"); - final DataRequestMonitor rm = + final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); + + final DataRequestMonitor rm = new DataRequestMonitor(fRunCtrl.getExecutor(), null) { @Override protected void handleCompleted() { if (isSuccess()) { - fWait.setReturnInfo(getData()); + wait.setReturnInfo(getData()); } - fWait.waitFinished(getStatus()); + wait.waitFinished(getStatus()); } }; @@ -387,8 +364,8 @@ public class MIRunControlTest extends BaseTestCase { fRunCtrl.getExecutionData(fGDBCtrl.getGDBDMContext(), rm); } }); - fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); - Assert.assertTrue(fWait.getMessage(), fWait.isOK()); + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + Assert.assertTrue(wait.getMessage(), wait.isOK()); IRunControl.IExecutionDMData data = rm.getData(); if(data == null) @@ -408,51 +385,38 @@ public class MIRunControlTest extends BaseTestCase { @Ignore @Test public void getExecutionContextsForInvalidContainerDMC() throws InterruptedException{ - //TestsPlugin.debug("getExecutionContextsForInvalidContainerDMC()"); - final DataRequestMonitor rm = + final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); + + final DataRequestMonitor rm = new DataRequestMonitor(fRunCtrl.getExecutor(), null) { @Override protected void handleCompleted() { if (isSuccess()) { - fWait.setReturnInfo(getData()); + wait.setReturnInfo(getData()); } - fWait.waitFinished(getStatus()); + wait.waitFinished(getStatus()); } }; - final IContainerDMContext ctxt = new GDBControlDMContext("-1", getClass().getName() + ":" + 1); +// final IContainerDMContext ctxt = new GDBControlDMContext("-1", getClass().getName() + ":" + 1); fRunCtrl.getExecutor().submit(new Runnable() { public void run() { // Pass an invalid dmc fRunCtrl.getExecutionContexts(fGDBCtrl.getGDBDMContext(), rm); } }); - fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); - Assert.assertTrue(fWait.getMessage(), !fWait.isOK()); + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + Assert.assertTrue(wait.getMessage(), !wait.isOK()); IStatus status = rm.getStatus(); Assert.assertEquals("Error message for invalid container", IStatus.ERROR, status.getSeverity()); } - /* - * Test Thread Create event for thread ID. Thread IDs should be GDB generated thread ids. - */ - @DsfServiceEventHandler - public void eventDispatched(IStartedDMEvent e) { - if(fIsTestingThreadCreateEvent){ - if(((IMIExecutionDMContext)e.getDMContext()).getThreadId() != 2) - /* - * Set variable if thread create event is unsuccesful - */ - fIsEventError = true; - } - } - /* * Cache after ContainerSuspendEvent should be re-set */ @Test public void cacheAfterContainerSuspendEvent() throws InterruptedException{ - //TestsPlugin.debugMethod("cacheAfterContainerSuspendEvent()"); + final IExecutionDMContext dmc = fRunCtrl.createMIExecutionContext(fGDBCtrl.getGDBDMContext(), 1); /* * Step to fire ContainerSuspendEvent @@ -473,13 +437,13 @@ public class MIRunControlTest extends BaseTestCase { //Also test Cache after ContainerResumeEvent @Test public void resume() throws InterruptedException{ - //TestsPlugin.debugMethod("resume()"); - + final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); + final DataRequestMonitor rm = new DataRequestMonitor(fRunCtrl.getExecutor(), null) { @Override protected void handleCompleted() { - fWait.waitFinished(getStatus()); + wait.waitFinished(getStatus()); //TestsPlugin.debug("handleCompleted over"); } }; @@ -493,7 +457,7 @@ public class MIRunControlTest extends BaseTestCase { fRunCtrl.resume(fGDBCtrl.getGDBDMContext(), rm); } }); - fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); try { eventWaitor.waitForEvent(ServiceEventWaitor.WAIT_FOREVER); @@ -502,10 +466,10 @@ public class MIRunControlTest extends BaseTestCase { e.printStackTrace(); return; } - if (fWait.isOK() == false) - Assert.assertTrue(fWait.getMessage(), false); + if (wait.isOK() == false) + Assert.assertTrue(wait.getMessage(), false); Assert.assertFalse("Target is suspended. It should have been running", fRunCtrl.isSuspended(fGDBCtrl.getGDBDMContext())); - fWait.waitReset(); + wait.waitReset(); } @@ -513,12 +477,13 @@ public class MIRunControlTest extends BaseTestCase { @Test public void resumeContainerContext() throws InterruptedException{ - //TestsPlugin.debugMethod("resumeContainerContext()"); - final DataRequestMonitor rm = + final AsyncCompletionWaitor wait = new AsyncCompletionWaitor(); + + final DataRequestMonitor rm = new DataRequestMonitor(fRunCtrl.getExecutor(), null) { @Override protected void handleCompleted() { - fWait.waitFinished(getStatus()); + wait.waitFinished(getStatus()); } }; @@ -532,7 +497,7 @@ public class MIRunControlTest extends BaseTestCase { fRunCtrl.resume(fGDBCtrl.getGDBDMContext(), rm); } }); - fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); + wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); try { eventWaitor.waitForEvent(ServiceEventWaitor.WAIT_FOREVER); //TestsPlugin.debug("DsfMIRunningEvent received"); @@ -542,10 +507,10 @@ public class MIRunControlTest extends BaseTestCase { return; } - if (fWait.isOK() == false) - Assert.assertTrue(fWait.getMessage(), false); + if (wait.isOK() == false) + Assert.assertTrue(wait.getMessage(), false); Assert.assertFalse("Target is suspended. It should have been running", fRunCtrl.isSuspended(fGDBCtrl.getGDBDMContext())); - fWait.waitReset(); + wait.waitReset(); } // PP: test no longer applies, the resume command now takes a strongly-typed execution context as an argument. @@ -557,7 +522,7 @@ public class MIRunControlTest extends BaseTestCase { // new DataRequestMonitor(fRunCtrl.getExecutor(), null) { // @Override // protected void handleCompleted() { -// fWait.waitFinished(getStatus()); +// wait.waitFinished(getStatus()); // } // }; // final ServiceEventWaitor eventWaitor = @@ -572,7 +537,7 @@ public class MIRunControlTest extends BaseTestCase { // fRunCtrl.resume(dmc, rm); // } // }); -// fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); +// wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); // // try { // eventWaitor.waitForEvent(ServiceEventWaitor.WAIT_FOREVER); @@ -582,10 +547,10 @@ public class MIRunControlTest extends BaseTestCase { // return; // } // -// if (fWait.isOK() == false) -// Assert.assertTrue(fWait.getMessage(), false); +// if (wait.isOK() == false) +// Assert.assertTrue(wait.getMessage(), false); // Assert.assertFalse("Target is suspended. It should have been running", fRunCtrl.isSuspended(fGDBCtrl.getGDBDMContext())); -// fWait.waitReset(); +// wait.waitReset(); // } // @Test @@ -596,10 +561,10 @@ public class MIRunControlTest extends BaseTestCase { // protected void handleCompleted() { // if (isSuccess()) { // assert true; -// fWait.setReturnInfo(getData()); +// wait.setReturnInfo(getData()); // } // System.out.println("Wait Finished called on getTHreads rm with status " + getStatus().getMessage()); -// fWait.waitFinished(getStatus()); +// wait.waitFinished(getStatus()); // } // }; // final MIExecutionDMC dmc = new MIExecutionDMC(fRunCtrl, 1); @@ -608,12 +573,12 @@ public class MIRunControlTest extends BaseTestCase { // fRunCtrl.resume(dmc, rm); // } // }); -// fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); -// if (fWait.isOK() == false) -// Assert.assertTrue(fWait.getMessage(), false); +// wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); +// if (wait.isOK() == false) +// Assert.assertTrue(wait.getMessage(), false); // System.out.println("Message from isSuspended " +fRunCtrl.isSuspended(dmc)); // Assert.assertFalse("Target is suspended. It should have been running", fRunCtrl.isSuspended(dmc)); -// fWait.waitReset(); +// wait.waitReset(); // // final DataRequestMonitor rmSuspend = // new DataRequestMonitor(fRunCtrl.getExecutor(), null) { @@ -621,10 +586,10 @@ public class MIRunControlTest extends BaseTestCase { // protected void handleCompleted() { // if (isSuccess()) { // assert true; -// fWait.setReturnInfo(getData()); +// wait.setReturnInfo(getData()); // } // System.out.println("Wait Finished called on getTHreads rm with status " + getStatus().getMessage()); -// fWait.waitFinished(getStatus()); +// wait.waitFinished(getStatus()); // } // }; // @@ -638,7 +603,7 @@ public class MIRunControlTest extends BaseTestCase { // fRunCtrl.suspend(dmc, rmSuspend); // } // }); -// fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); +// wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); // try { // eventWaitor.waitForEvent(ServiceEventWaitor.WAIT_FOREVER); // } catch (Exception e) { @@ -646,10 +611,10 @@ public class MIRunControlTest extends BaseTestCase { // e.printStackTrace(); // } // -// if (fWait.isOK() == false) -// Assert.assertTrue(fWait.getMessage(), false); +// if (wait.isOK() == false) +// Assert.assertTrue(wait.getMessage(), false); // System.out.println("Message from isSuspended !!! " +fRunCtrl.isSuspended(dmc)); // Assert.assertTrue("Target is running. It should have been suspended.", fRunCtrl.isSuspended(dmc)); -// fWait.waitReset(); +// wait.waitReset(); // } } From b14f86c07038b54b1acbb79c8ca83b92101f842a Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Tue, 8 Apr 2008 18:05:50 +0000 Subject: [PATCH 385/834] Bugzilla 226166 Exports action handlers. --- plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF index 4ede97ef39d..cb71e55f66e 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF @@ -26,6 +26,7 @@ Export-Package: org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch, org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.modules, org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat, + org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat.actions, org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.register, org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.update, org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.update.actions, From 9ffecad0c86130145f9ab72ba6c438cb02184006 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 8 Apr 2008 21:43:42 +0000 Subject: [PATCH 386/834] [225959] Added a call to complete updates in case of missing property provider. --- .../ui/viewmodel/properties/PropertyBasedLabelProvider.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/PropertyBasedLabelProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/PropertyBasedLabelProvider.java index b3c6087f334..82c2893c42c 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/PropertyBasedLabelProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/PropertyBasedLabelProvider.java @@ -174,7 +174,8 @@ public class PropertyBasedLabelProvider IElementPropertiesProvider propertiesProvider = getElementPropertiesProvider(labelUpdates[0].getElement()); if (propertiesProvider == null) { for (ILabelUpdate update : labelUpdates) { - update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, "Properties-based label provider " + this + " failed to generate a label, no properties provider registered for element: " + labelUpdates[0].getElement())); //$NON-NLS-1$ //$NON-NLS-2$ + update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, "Properties-based label provider " + this + " failed to generate a label, no properties provider registered for element: " + labelUpdates[0].getElement())); //$NON-NLS-1$ //$NON-NLS-2$ + update.done(); } return; } From 4093756b37c39b35d48734939b7d1b2f56e621c0 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Thu, 10 Apr 2008 14:16:51 +0000 Subject: [PATCH 387/834] Bug 226039 Read the gdbinit file as specified by the user. It does not specify at the command line as the CDT does it, but instead sources it as a GDB command. I believe this allows for easier specialization of the launch. --- .../launching/FinalLaunchSequence.java | 33 +++++++++++++++++++ .../service/command/GDBControl.java | 8 ++++- .../service/command/commands/CLISource.java | 27 +++++++++++++++ .../dd/tests/gdb/framework/BaseTestCase.java | 1 + 4 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLISource.java diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java index cd770d3c529..6aa82d22e21 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java @@ -32,6 +32,7 @@ import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl; import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl.SessionType; import org.eclipse.dd.mi.service.CSourceLookup; import org.eclipse.dd.mi.service.MIBreakpointsManager; +import org.eclipse.dd.mi.service.command.commands.CLISource; import org.eclipse.dd.mi.service.command.commands.MIBreakInsert; import org.eclipse.dd.mi.service.command.commands.MICommand; import org.eclipse.dd.mi.service.command.commands.MIExecContinue; @@ -59,6 +60,38 @@ public class FinalLaunchSequence extends Sequence { requestMonitor.done(); }}, + /* + * Source the gdbinit file specified in the launch + */ + new Step() { @Override + public void execute(final RequestMonitor requestMonitor) { + try { + final String gdbinitFile = fLaunch.getLaunchConfiguration().getAttribute(IMILaunchConfigurationConstants.ATTR_GDB_INIT, + IMILaunchConfigurationConstants.DEBUGGER_GDB_INIT_DEFAULT ); + if (gdbinitFile != null && gdbinitFile.length() > 0) { + fCommandControl.queueCommand( + new CLISource(fCommandControl.getControlDMContext(), gdbinitFile), + new DataRequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleCompleted() { + // If the gdbinitFile is the default, then it may not exist and we + // should not consider this an error. + // If it is not the default, then the user must have specified it and + // we want to warn the user if we can't find it. + if (!gdbinitFile.equals(IMILaunchConfigurationConstants.DEBUGGER_GDB_INIT_DEFAULT )) { + requestMonitor.setStatus(getStatus()); + } + requestMonitor.done(); + } + }); + } else { + requestMonitor.done(); + } + } catch (CoreException e) { + requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Cannot get gdbinit option", e)); //$NON-NLS-1$ + requestMonitor.done(); + } + }}, /* * Specify the executable file to be debugged. */ diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java index 09eee80da61..5c3f2417712 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java @@ -374,13 +374,19 @@ public class GDBControl extends AbstractMIControl { protected IStatus run(IProgressMonitor monitor) { List commandList = new ArrayList(); + // The goal here is to keep options to an absolute minimum. + // All configuration should be done in the launch sequence + // to allow for easy overriding. commandList.add(fGdbPath.toOSString()); commandList.add("--interpreter"); //$NON-NLS-1$ commandList.add("mi"); //$NON-NLS-1$ + // Don't read the gdbinit file here. It is read explicitly in + // the LaunchSequence to make it easier to customize. + commandList.add("--nx"); //$NON-NLS-1$ String[] commandLine = commandList.toArray(new String[commandList.size()]); - try { + try { fProcess = ProcessFactory.getFactory().exec(commandLine); } catch(IOException e) { String message = MessageFormat.format("Error while launching command", //$NON-NLS-1$ diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLISource.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLISource.java new file mode 100644 index 00000000000..503055abaaa --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLISource.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2008 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.mi.service.command.MIControlDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; + +/** + * + * source FILE + * + * Source a file of commands + * + */ +public class CLISource extends CLICommand { + public CLISource(MIControlDMContext ctx, String file) { + super(ctx, "source " + file); //$NON-NLS-1$ + } +} diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java index a6202a0fce5..cc3fe0ab2cc 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java @@ -58,6 +58,7 @@ public class BaseTestCase { attrs.put(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN, true); attrs.put(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN_SYMBOL, ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_SYMBOL_DEFAULT); attrs.put(IMILaunchConfigurationConstants.ATTR_DEBUG_NAME, "gdb"); + attrs.put(IMILaunchConfigurationConstants.ATTR_GDB_INIT, ".gdbinit"); } @Before From 8422bf48dd003978b3415330cfe075edf40744e9 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Thu, 10 Apr 2008 14:46:02 +0000 Subject: [PATCH 388/834] Bug 223076 Debug traces were printed for out-of-band events when they were processed (processEvent()) and again when the next ResultRecord is received (processCommandDone()). This fix only prints the ResultRecord in the processCommandDone() method. --- .../org/eclipse/dd/mi/service/command/AbstractMIControl.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java index ec0b560af14..32a9e2f04f0 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java @@ -350,7 +350,9 @@ public abstract class AbstractMIControl extends AbstractDsfService if ( result != null ) { MIInfo cmdResult = (MIInfo) result ; MIOutput output = cmdResult.getMIOutput(); - MIPlugin.debug(MIPlugin.getDebugTime() + " " + output + "\n"); //$NON-NLS-1$ //$NON-NLS-2$ + // Only print the result record and not the out-of-band records. + // Out-of-band records have already been printed in processEvent() + MIPlugin.debug(MIPlugin.getDebugTime() + " " + output.getMIResultRecord() + "\n"); //$NON-NLS-1$ //$NON-NLS-2$ } else { From ac0980848602e2fb0c67a71a6b4fa281a52e3a1a Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Sat, 12 Apr 2008 00:50:15 +0000 Subject: [PATCH 389/834] Bug 226691 We only support GDB 6.6 and higher, from what I can see, -interpreter-exec is always available (I tried with mi1 m2 and m3 on GDB 6.6). Therefore, we can simplify the launch by removing the CheckInterpreterConsoleStep. --- .../service/command/GDBCLIProcess.java | 4 +-- .../service/command/GDBControl.java | 25 +------------------ .../service/command/AbstractCLIProcess.java | 7 ++---- 3 files changed, 5 insertions(+), 31 deletions(-) diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBCLIProcess.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBCLIProcess.java index 10b95f8bb27..366c257538e 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBCLIProcess.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBCLIProcess.java @@ -24,8 +24,8 @@ import org.eclipse.dd.mi.service.command.AbstractCLIProcess; */ class GDBCLIProcess extends AbstractCLIProcess { - public GDBCLIProcess(GDBControl commandControl, boolean useExecConsole) throws IOException { - super(commandControl, useExecConsole); + public GDBCLIProcess(GDBControl commandControl) throws IOException { + super(commandControl); } diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java index 5c3f2417712..9eb3786b1c0 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java @@ -47,7 +47,6 @@ import org.eclipse.dd.mi.service.command.MIControlDMContext; import org.eclipse.dd.mi.service.command.MIInferiorProcess; import org.eclipse.dd.mi.service.command.MIRunControlEventProcessor; import org.eclipse.dd.mi.service.command.commands.MIGDBExit; -import org.eclipse.dd.mi.service.command.commands.MIInterpreterExecConsole; import org.eclipse.dd.mi.service.command.output.MIInfo; import org.eclipse.debug.core.DebugException; import org.osgi.framework.BundleContext; @@ -87,7 +86,6 @@ public class GDBControl extends AbstractMIControl { private SessionType fSessionType; private boolean fConnected = false; - private boolean fUseInterpreterConsole; private MonitorJob fMonitorJob; private IPath fGdbPath; @@ -131,7 +129,6 @@ public class GDBControl extends AbstractMIControl { new GDBProcessStep(InitializationShutdownStep.Direction.INITIALIZING), new MonitorJobStep(InitializationShutdownStep.Direction.INITIALIZING), new CommandMonitoringStep(InitializationShutdownStep.Direction.INITIALIZING), - new CheckInterpreterConsoleStep(InitializationShutdownStep.Direction.INITIALIZING), new CommandProcessorsStep(InitializationShutdownStep.Direction.INITIALIZING), new RegisterStep(InitializationShutdownStep.Direction.INITIALIZING), }; @@ -147,7 +144,6 @@ public class GDBControl extends AbstractMIControl { final Sequence.Step[] shutdownSteps = new Sequence.Step[] { new RegisterStep(InitializationShutdownStep.Direction.SHUTTING_DOWN), new CommandProcessorsStep(InitializationShutdownStep.Direction.SHUTTING_DOWN), - new CheckInterpreterConsoleStep(InitializationShutdownStep.Direction.SHUTTING_DOWN), new CommandMonitoringStep(InitializationShutdownStep.Direction.SHUTTING_DOWN), new MonitorJobStep(InitializationShutdownStep.Direction.SHUTTING_DOWN), new GDBProcessStep(InitializationShutdownStep.Direction.SHUTTING_DOWN), @@ -509,32 +505,13 @@ public class GDBControl extends AbstractMIControl { } } - protected class CheckInterpreterConsoleStep extends InitializationShutdownStep { - CheckInterpreterConsoleStep(Direction direction) { super(direction); } - - @Override - public void initialize(final RequestMonitor requestMonitor) { - MIInterpreterExecConsole cmd = new MIInterpreterExecConsole(fControlDmc, "echo"); //$NON-NLS-1$ - GDBControl.this.queueCommand( - cmd, - new DataRequestMonitor(getExecutor(), null) { - @Override - protected void handleCompleted() { - fUseInterpreterConsole = isSuccess(); - requestMonitor.done(); - } - } - ); - } - } - protected class CommandProcessorsStep extends InitializationShutdownStep { CommandProcessorsStep(Direction direction) { super(direction); } @Override public void initialize(final RequestMonitor requestMonitor) { try { - fCLIProcess = new GDBCLIProcess(GDBControl.this, fUseInterpreterConsole); + fCLIProcess = new GDBCLIProcess(GDBControl.this); } catch(IOException e) { requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, "Failed to create CLI Process", e)); //$NON-NLS-1$ diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractCLIProcess.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractCLIProcess.java index 6a0ecedc0be..e5041e85f56 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractCLIProcess.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractCLIProcess.java @@ -67,8 +67,6 @@ public abstract class AbstractCLIProcess extends Process private final PipedInputStream fMIInLogPipe; private final PipedOutputStream fMIOutLogPipe; - private final boolean fUseExecConsole; - private boolean fDisposed = false; /** @@ -88,10 +86,9 @@ public abstract class AbstractCLIProcess extends Process private int fPrompt = 1; // 1 --> Primary prompt "(gdb)"; 2 --> Secondary Prompt ">" @ConfinedToDsfExecutor("fSession#getExecutor") - public AbstractCLIProcess(AbstractMIControl commandControl, boolean useExecConsole) throws IOException { + public AbstractCLIProcess(AbstractMIControl commandControl) throws IOException { fSession = commandControl.getSession(); fCommandControl = commandControl; - fUseExecConsole = useExecConsole; commandControl.addEventListener(this); commandControl.addCommandListener(this); @@ -294,7 +291,7 @@ public abstract class AbstractCLIProcess extends Process if (secondary) { cmd = new RawCommand(getCommandControl().getControlDMContext(), str); } - else if (fUseExecConsole && ! CLIEventProcessor.isSteppingOperation(str)) + else if (! CLIEventProcessor.isSteppingOperation(str)) { cmd = new ProcessMIInterpreterExecConsole(getCommandControl().getControlDMContext(), str); } From 178f0659011ad6ffe334a54d751a53a0950a0495 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Sat, 12 Apr 2008 01:16:56 +0000 Subject: [PATCH 390/834] Bug 212916 Support for redirecting the inferior's input/output to a terminal. --- .../launching/FinalLaunchSequence.java | 21 ++++++++++++++ .../launching/ServicesLaunchSequence.java | 4 ++- .../service/command/GDBControl.java | 27 +++++++++++++++--- .../mi/service/command/MIInferiorProcess.java | 2 +- .../command/commands/MIInferiorTTYSet.java | 28 +++++++++++++++++++ 5 files changed, 76 insertions(+), 6 deletions(-) create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIInferiorTTYSet.java diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java index 6aa82d22e21..1521d46e93c 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java @@ -41,6 +41,7 @@ import org.eclipse.dd.mi.service.command.commands.MIFileExecFile; import org.eclipse.dd.mi.service.command.commands.MIFileSymbolFile; import org.eclipse.dd.mi.service.command.commands.MIGDBSetAutoSolib; import org.eclipse.dd.mi.service.command.commands.MIGDBSetSolibSearchPath; +import org.eclipse.dd.mi.service.command.commands.MIInferiorTTYSet; import org.eclipse.dd.mi.service.command.commands.MITargetSelect; import org.eclipse.dd.mi.service.command.output.MIBreakInsertInfo; import org.eclipse.dd.mi.service.command.output.MIInfo; @@ -60,6 +61,26 @@ public class FinalLaunchSequence extends Sequence { requestMonitor.done(); }}, + /* + * Specify connection of inferior input/output with a terminal. + */ + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + try { + boolean useTerminal = fLaunch.getLaunchConfiguration().getAttribute(ICDTLaunchConfigurationConstants.ATTR_USE_TERMINAL, true); + + if (useTerminal) { + fCommandControl.queueCommand( + new MIInferiorTTYSet(fCommandControl.getControlDMContext(), fCommandControl.getPtyName()), + new DataRequestMonitor(getExecutor(), requestMonitor)); + } else { + requestMonitor.done(); + } + } catch (CoreException e) { + requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Cannot get terminal option", e)); //$NON-NLS-1$ + requestMonitor.done(); + } + }}, /* * Source the gdbinit file specified in the launch */ diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/ServicesLaunchSequence.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/ServicesLaunchSequence.java index 8dc218b1a26..f267b647282 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/ServicesLaunchSequence.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/ServicesLaunchSequence.java @@ -43,9 +43,11 @@ public class ServicesLaunchSequence extends Sequence { @Override public void execute(RequestMonitor requestMonitor) { String debugMode = ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN; + boolean useTerminal = true; try { debugMode = fLaunch.getLaunchConfiguration().getAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN ); + useTerminal = fLaunch.getLaunchConfiguration().getAttribute(ICDTLaunchConfigurationConstants.ATTR_USE_TERMINAL, true); } catch (CoreException e) { } @@ -64,7 +66,7 @@ public class ServicesLaunchSequence extends Sequence { // // Create the connection. // - fCommandControl = new GDBControl(fSession, getGDBPath(), fExecPath, fSessionType, 30); + fCommandControl = new GDBControl(fSession, getGDBPath(), fExecPath, fSessionType, useTerminal, 30); fCommandControl.initialize(requestMonitor); } }, diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java index 9eb3786b1c0..ec3c3432c03 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java @@ -23,6 +23,7 @@ import java.util.List; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; +import org.eclipse.cdt.utils.pty.PTY; import org.eclipse.cdt.utils.spawner.ProcessFactory; import org.eclipse.cdt.utils.spawner.Spawner; import org.eclipse.core.runtime.IPath; @@ -97,16 +98,19 @@ public class GDBControl extends AbstractMIControl { private MIRunControlEventProcessor fMIEventProcessor; private CLIEventProcessor fCLICommandProcessor; private AbstractCLIProcess fCLIProcess; - private MIInferiorProcess fInferiorProcess; + private MIInferiorProcess fInferiorProcess = null; - public GDBControl(DsfSession session, IPath gdbPath, IPath execPath, SessionType type, int gdbLaunchTimeout) { + boolean fUseTerminal; + private PTY fPty; + + public GDBControl(DsfSession session, IPath gdbPath, IPath execPath, SessionType type, boolean useTerminal, int gdbLaunchTimeout) { super(session); fSessionType = type; fGdbPath = gdbPath; fExecPath = execPath; fGDBLaunchTimeout = gdbLaunchTimeout; fControlDmc = new GDBControlDMContext(session.getId(), getClass().getName() + ":" + ++fgInstanceCounter); //$NON-NLS-1$ - + fUseTerminal = useTerminal; } @Override @@ -257,6 +261,10 @@ public class GDBControl extends AbstractMIControl { public void getInferiorProcessId(DataRequestMonitor rm) { } + + public String getPtyName() { + return fPty.getSlaveName(); + } @DsfServiceEventHandler public void eventDispatched(ExitedEvent e) { @@ -518,8 +526,19 @@ public class GDBControl extends AbstractMIControl { requestMonitor.done(); return; } + + if (fUseTerminal) { + try { + fPty = new PTY(); + fInferiorProcess = new GDBInferiorProcess(GDBControl.this, fPty); + } catch (IOException e) { + } + } - fInferiorProcess = new GDBInferiorProcess(GDBControl.this, fProcess.getOutputStream()); + // If !fUseTerminal or IOException was caught + if (fInferiorProcess == null) + fInferiorProcess = new GDBInferiorProcess(GDBControl.this, fProcess.getOutputStream()); + fCLICommandProcessor = new CLIEventProcessor(GDBControl.this, fControlDmc, fInferiorProcess); fMIEventProcessor = new MIRunControlEventProcessor(GDBControl.this, fControlDmc); diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIInferiorProcess.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIInferiorProcess.java index 3e0c9e7eb54..a25455ddbc5 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIInferiorProcess.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIInferiorProcess.java @@ -291,7 +291,7 @@ public class MIInferiorProcess extends Process fInputStream.close(); } catch (IOException e) {} try { - fInputStreamPiped.close(); + if (fInputStreamPiped != null) fInputStreamPiped.close(); } catch (IOException e) {} try { fErrorStream.close(); diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIInferiorTTYSet.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIInferiorTTYSet.java new file mode 100644 index 00000000000..15c99586cb6 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIInferiorTTYSet.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2008 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.mi.service.command.MIControlDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; + + +/** + * -inferior-tty-set TTY + * + * Set terminal for future runs of the program being debugged. + */ +public class MIInferiorTTYSet extends MICommand +{ + public MIInferiorTTYSet(MIControlDMContext dmc, String tty) { + super(dmc, "-inferior-tty-set", null, new String[] {tty}); //$NON-NLS-1$ + } +} \ No newline at end of file From 2c82390e875e9e62ae38171b93cf5ffaa2423971 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Tue, 15 Apr 2008 16:38:17 +0000 Subject: [PATCH 391/834] Bug 202343 Launch for for Attaching to a running --- plugins/org.eclipse.dd.gdb.launch/plugin.xml | 23 ++++++- .../internal/ui/launching/CDebuggerTab.java | 2 +- .../GdbAttachLaunchConfigurationTabGroup.java | 36 +++++++++++ .../launching/FinalLaunchSequence.java | 60 ++++++++++++------- .../launching/GdbLaunchDelegate.java | 52 +++++++++++++--- .../service/command/commands/CLIAttach.java | 24 ++++++++ .../commands/MIFileExecAndSymbols.java | 35 +++++++++++ 7 files changed, 201 insertions(+), 31 deletions(-) create mode 100644 plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbAttachLaunchConfigurationTabGroup.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLIAttach.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIFileExecAndSymbols.java diff --git a/plugins/org.eclipse.dd.gdb.launch/plugin.xml b/plugins/org.eclipse.dd.gdb.launch/plugin.xml index b6505cd3a7d..2d39667f867 100644 --- a/plugins/org.eclipse.dd.gdb.launch/plugin.xml +++ b/plugins/org.eclipse.dd.gdb.launch/plugin.xml @@ -7,7 +7,7 @@ delegate="org.eclipse.dd.gdb.internal.provisional.launching.GdbLaunchDelegate" public="true" sourcePathComputerId="org.eclipse.cdt.debug.core.sourcePathComputer" - name="Local C/C++ Application (Experimental - DSF)" + name="C/C++ Local Application (Experimental - DSF)" id="org.eclipse.dd.gdb.launch.localCLaunch" modes="debug"> @@ -15,7 +15,16 @@ delegate="org.eclipse.dd.gdb.internal.provisional.launching.GdbLaunchDelegate" id="org.eclipse.dd.gdb.launch.remoteCLaunch" modes="debug" - name="Remote C/C++ Application (Experimental - DSF)" + name="C/C++ Remote Application (Experimental - DSF)" + public="true" + sourceLocatorId="org.eclipse.cdt.debug.core.sourceLocator" + sourcePathComputerId="org.eclipse.cdt.debug.core.sourcePathComputer"> + + @@ -33,6 +42,11 @@ id="org.eclipse.dd.gdb.launch.remoteRunLaunchTabGroup" type="org.eclipse.dd.gdb.launch.remoteCLaunch"> + + @@ -46,5 +60,10 @@ icon="icons/full/obj16/c_app.gif" id="org.eclipse.dd.gdb.launch.remoteRunLaunchImage"> + + diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/CDebuggerTab.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/CDebuggerTab.java index 514b5350e73..a381b9d2b8c 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/CDebuggerTab.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/CDebuggerTab.java @@ -217,7 +217,7 @@ public class CDebuggerTab extends AbstractCDebuggerTab { (mode.equals(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN) && debugConfigs[i].getName().equals("gdb/mi") && debugConfigs[i].supportsMode(mode)) || //$NON-NLS-1$ (mode.equals(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_ATTACH) - && debugConfigs[i].getName().equals("gdb Debugger") && debugConfigs[i].supportsMode(mode))) { //$NON-NLS-1$ + && debugConfigs[i].getName().equals("gdb/mi") && debugConfigs[i].supportsMode(mode))) { //$NON-NLS-1$ String debuggerPlatform = debugConfigs[i].getPlatform(); if (validatePlatform(config, debugConfigs[i])) { list.add(debugConfigs[i]); diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbAttachLaunchConfigurationTabGroup.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbAttachLaunchConfigurationTabGroup.java new file mode 100644 index 00000000000..6f19c451d0f --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbAttachLaunchConfigurationTabGroup.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2008 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.gdb.internal.ui.launching; + +import org.eclipse.cdt.launch.ui.CMainTab; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl.SessionType; +import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup; +import org.eclipse.debug.ui.CommonTab; +import org.eclipse.debug.ui.ILaunchConfigurationDialog; +import org.eclipse.debug.ui.ILaunchConfigurationTab; +import org.eclipse.debug.ui.sourcelookup.SourceLookupTab; + +public class GdbAttachLaunchConfigurationTabGroup extends AbstractLaunchConfigurationTabGroup { + + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.ILaunchConfigurationTabGroup#createTabs(org.eclipse.debug.ui.ILaunchConfigurationDialog, java.lang.String) + */ + public void createTabs(ILaunchConfigurationDialog dialog, String mode) { + ILaunchConfigurationTab[] tabs = new ILaunchConfigurationTab[] { + new CMainTab(true), + new CDebuggerTab(SessionType.ATTACH), + new SourceLookupTab(), + new CommonTab() + }; + setTabs(tabs); + } +} diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java index 1521d46e93c..6d68d6cdc5e 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java @@ -18,6 +18,7 @@ import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector; import org.eclipse.cdt.debug.mi.core.IGDBServerMILaunchConfigurationConstants; import org.eclipse.cdt.debug.mi.core.IMILaunchConfigurationConstants; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; @@ -37,11 +38,11 @@ import org.eclipse.dd.mi.service.command.commands.MIBreakInsert; import org.eclipse.dd.mi.service.command.commands.MICommand; import org.eclipse.dd.mi.service.command.commands.MIExecContinue; import org.eclipse.dd.mi.service.command.commands.MIExecRun; -import org.eclipse.dd.mi.service.command.commands.MIFileExecFile; -import org.eclipse.dd.mi.service.command.commands.MIFileSymbolFile; +import org.eclipse.dd.mi.service.command.commands.MIFileExecAndSymbols; import org.eclipse.dd.mi.service.command.commands.MIGDBSetAutoSolib; import org.eclipse.dd.mi.service.command.commands.MIGDBSetSolibSearchPath; import org.eclipse.dd.mi.service.command.commands.MIInferiorTTYSet; +import org.eclipse.dd.mi.service.command.commands.CLIAttach; import org.eclipse.dd.mi.service.command.commands.MITargetSelect; import org.eclipse.dd.mi.service.command.output.MIBreakInsertInfo; import org.eclipse.dd.mi.service.command.output.MIInfo; @@ -66,6 +67,11 @@ public class FinalLaunchSequence extends Sequence { */ new Step() { @Override public void execute(RequestMonitor requestMonitor) { + if (fSessionType == SessionType.ATTACH) { + requestMonitor.done(); + return; + } + try { boolean useTerminal = fLaunch.getLaunchConfiguration().getAttribute(ICDTLaunchConfigurationConstants.ATTR_USE_TERMINAL, true); @@ -114,24 +120,19 @@ public class FinalLaunchSequence extends Sequence { } }}, /* - * Specify the executable file to be debugged. + * Specify the executable file to be debugged and read the symbol table. */ new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - fCommandControl.queueCommand( - new MIFileExecFile(fCommandControl.getControlDMContext(), - fCommandControl.getExecutablePath().toOSString()), - new DataRequestMonitor(getExecutor(), requestMonitor)); - }}, - /* - * Read symbol table. - */ - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - fCommandControl.queueCommand( - new MIFileSymbolFile(fCommandControl.getControlDMContext(), - fCommandControl.getExecutablePath().toOSString()), - new DataRequestMonitor(getExecutor(), requestMonitor)); + public void execute(final RequestMonitor requestMonitor) { + final IPath execPath = fCommandControl.getExecutablePath(); + if (execPath != null && !execPath.isEmpty()) { + fCommandControl.queueCommand( + new MIFileExecAndSymbols(fCommandControl.getControlDMContext(), + execPath.toOSString()), + new DataRequestMonitor(getExecutor(), requestMonitor)); + } else { + requestMonitor.done(); + } }}, /* * Tell GDB to automatically load or not the shared library symbols @@ -185,7 +186,8 @@ public class FinalLaunchSequence extends Sequence { locator.getSourceContainers(), requestMonitor); }}, /* - * If remote debugging, connect to target + * If remote debugging, connect to target. + * If attach session, perform the attach. */ new Step() { private boolean fTcpConnection; @@ -241,7 +243,7 @@ public class FinalLaunchSequence extends Sequence { } return true; } - + @Override public void execute(final RequestMonitor requestMonitor) { if (fSessionType == SessionType.REMOTE) { @@ -263,6 +265,10 @@ public class FinalLaunchSequence extends Sequence { fSerialDevice), new DataRequestMonitor(getExecutor(), requestMonitor)); } + } else if (fSessionType == SessionType.ATTACH) { + fCommandControl.queueCommand( + new CLIAttach(fCommandControl.getControlDMContext(), fPid), + new DataRequestMonitor(getExecutor(), requestMonitor)); } else { requestMonitor.done(); } @@ -314,6 +320,11 @@ public class FinalLaunchSequence extends Sequence { @Override public void execute(final RequestMonitor requestMonitor) { + if (fSessionType == SessionType.ATTACH) { + requestMonitor.done(); + return; + } + final MICommand execCommand; if (fSessionType == SessionType.REMOTE) { // When doing remote debugging, we use -exec-continue instead of -exec-run @@ -349,13 +360,20 @@ public class FinalLaunchSequence extends Sequence { GdbLaunch fLaunch; SessionType fSessionType; + int fPid; GDBControl fCommandControl; public FinalLaunchSequence(DsfExecutor executor, GdbLaunch launch, SessionType type) { super(executor); fLaunch = launch; - fSessionType = type; + fSessionType = type; + } + + // If a pid is specified, it is for an ATTACH type + public FinalLaunchSequence(DsfExecutor executor, GdbLaunch launch, int attachToPid) { + this(executor, launch, SessionType.ATTACH); + fPid = attachToPid; } diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java index 20671367bfe..ded518d0d37 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java @@ -61,7 +61,7 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate { public final static String GDB_DEBUG_MODEL_ID = "org.eclipse.dd.gdb"; //$NON-NLS-1$ private SessionType fSessionType; - + /* (non-Javadoc) * @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#launch(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.debug.core.ILaunch, org.eclipse.core.runtime.IProgressMonitor) */ @@ -107,23 +107,42 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate } final GdbLaunch launch = (GdbLaunch)l; - if (fSessionType == SessionType.REMOTE) { monitor.subTask( "Debugging remote C/C++ application" ); //$NON-NLS-1$ } else { monitor.subTask( "Debugging local C/C++ application" ); //$NON-NLS-1$ } + IPath exePath = verifyProgramPath( config ); ICProject project = verifyCProject( config ); if ( exePath != null ) { verifyBinary( project, exePath ); } - setDefaultSourceLocator(launch, config); - monitor.worked( 1 ); - + // If we are attaching, get the process id now, so as to avoid starting the launch + // and canceling it if the user does not put the pid properly. + int pid = -1; + if (fSessionType == SessionType.ATTACH) { + try { + // have we already been given the pid (maybe from a JUnit test launch or something) + pid = config.getAttribute(ICDTLaunchConfigurationConstants.ATTR_ATTACH_PROCESS_ID, -1); + } catch (CoreException e) { + // do nothing and fall to below + } + + if (pid == -1) { + pid = promptForProcessID(config); + } + if (pid == -1) { + throw new DebugException(new Status(IStatus.CANCEL, GdbPlugin.PLUGIN_ID, + LaunchMessages.getString("LocalAttachLaunchDelegate.No_Process_ID_selected"))); //$NON-NLS-1$ + } + } + + setDefaultSourceLocator(launch, config); + // Create and invoke the launch sequence to create the debug control and services final ServicesLaunchSequence servicesLaunchSequence = new ServicesLaunchSequence(launch.getSession(), launch, exePath); @@ -165,8 +184,12 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate } // Create and invoke the final launch sequence to setup GDB - final FinalLaunchSequence finalLaunchSequence = - new FinalLaunchSequence(launch.getSession().getExecutor(), launch, fSessionType); + final FinalLaunchSequence finalLaunchSequence; + if (fSessionType == SessionType.ATTACH) { + finalLaunchSequence = new FinalLaunchSequence(launch.getSession().getExecutor(), launch, pid); + } else { + finalLaunchSequence = new FinalLaunchSequence(launch.getSession().getExecutor(), launch, fSessionType); + } launch.getSession().getExecutor().execute(finalLaunchSequence); try { finalLaunchSequence.get(); @@ -200,6 +223,21 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate } } + // Copied from the CDT + protected int promptForProcessID(ILaunchConfiguration config) throws CoreException { + IStatus fPromptStatus = new Status(IStatus.INFO, "org.eclipse.debug.ui", 200, "", null); //$NON-NLS-1$//$NON-NLS-2$ + IStatus processPrompt = new Status(IStatus.INFO, "org.eclipse.cdt.launch", 100, "", null); //$NON-NLS-1$//$NON-NLS-2$ + // consult a status handler + IStatusHandler prompter = DebugPlugin.getDefault().getStatusHandler(fPromptStatus); + if (prompter != null) { + Object result = prompter.handleStatus(processPrompt, config); + if (result instanceof Integer) { + return ((Integer)result).intValue(); + } + } + return -1; + } + /* (non-Javadoc) * @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#getPluginID() diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLIAttach.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLIAttach.java new file mode 100644 index 00000000000..be79c4538c8 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLIAttach.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2008 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; + +/** + * This command connects to a remote target. + */ +public class CLIAttach extends CLICommand { + + public CLIAttach(IDMContext ctx, int pid) { + super(ctx, "attach " + Integer.toString(pid)); //$NON-NLS-1$ + } +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIFileExecAndSymbols.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIFileExecAndSymbols.java new file mode 100644 index 00000000000..3a5b63acc01 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIFileExecAndSymbols.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2008 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.mi.service.command.commands; + +import org.eclipse.dd.mi.service.command.MIControlDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; + + +/** + * -file-exec-and-symbols [FILE] + * + * Specify the executable file to be debugged. Unlike `-file-exec-and-symbols', + * the symbol table is not read from this file. If used without argument, GDB + * clears the information about the executable file. No output is produced, + * except a completion notification. + */ +public class MIFileExecAndSymbols extends MICommand +{ + public MIFileExecAndSymbols(MIControlDMContext dmc, String file) { + super(dmc, "-file-exec-and-symbols", null, new String[] {file}); //$NON-NLS-1$ + } + + public MIFileExecAndSymbols(MIControlDMContext dmc) { + super(dmc, "-file-exec-and-symbols"); //$NON-NLS-1$ + } +} From a6a82b3a2c8f2ef9eb708db9b7c72be5deeb4ecc Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Thu, 17 Apr 2008 19:22:14 +0000 Subject: [PATCH 392/834] Bugzilla 227629. --- .../provisional/launching/FinalLaunchSequence.java | 8 +++++++- .../internal/provisional/service/command/GDBControl.java | 7 ++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java index 6d68d6cdc5e..b6e345bca81 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java @@ -76,9 +76,15 @@ public class FinalLaunchSequence extends Sequence { boolean useTerminal = fLaunch.getLaunchConfiguration().getAttribute(ICDTLaunchConfigurationConstants.ATTR_USE_TERMINAL, true); if (useTerminal) { + String pytName = fCommandControl.getPtyName(); + if ( pytName != null ) { fCommandControl.queueCommand( - new MIInferiorTTYSet(fCommandControl.getControlDMContext(), fCommandControl.getPtyName()), + new MIInferiorTTYSet(fCommandControl.getControlDMContext(), pytName), new DataRequestMonitor(getExecutor(), requestMonitor)); + } + else { + requestMonitor.done(); + } } else { requestMonitor.done(); } diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java index ec3c3432c03..49cd3bcff93 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java @@ -263,7 +263,12 @@ public class GDBControl extends AbstractMIControl { } public String getPtyName() { - return fPty.getSlaveName(); + if ( fPty != null ) { + return fPty.getSlaveName(); + } + else { + return null; + } } @DsfServiceEventHandler From 8d74f0dc4bd847ec5c6ce4fb4cf41656090516fe Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 18 Apr 2008 18:41:48 +0000 Subject: [PATCH 393/834] [227643] Switched to use ILabelUpdate.getColumnIds() instead of IPresentationContext.getColumns(). --- .../provisional/ui/viewmodel/launch/StackFramesVMNode.java | 2 +- .../provisional/ui/viewmodel/modules/ModulesVMNode.java | 2 +- .../ui/viewmodel/register/RegisterBitFieldVMNode.java | 2 +- .../ui/viewmodel/register/RegisterGroupVMNode.java | 2 +- .../provisional/ui/viewmodel/register/RegisterVMNode.java | 2 +- .../provisional/ui/viewmodel/variable/VariableVMNode.java | 4 ++-- .../src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMNode.java | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/StackFramesVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/StackFramesVMNode.java index aa89b9e9cbd..046b2830e2f 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/StackFramesVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/StackFramesVMNode.java @@ -200,7 +200,7 @@ public class StackFramesVMNode extends AbstractDMVMNode * If columns are configured, call the protected methods to * fill in column values. */ - String[] localColumns = update.getPresentationContext().getColumns(); + String[] localColumns = update.getColumnIds(); if (localColumns == null) localColumns = new String[] { null }; for (int i = 0; i < localColumns.length; i++) { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/modules/ModulesVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/modules/ModulesVMNode.java index 2714b2d606b..cdcef5106ba 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/modules/ModulesVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/modules/ModulesVMNode.java @@ -109,7 +109,7 @@ public class ModulesVMNode extends AbstractDMVMNode * If columns are configured, call the protected methods to * fill in column values. */ - String[] localColumns = update.getPresentationContext().getColumns(); + String[] localColumns = update.getColumnIds(); if (localColumns == null) localColumns = new String[] { null }; for (int i = 0; i < localColumns.length; i++) { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterBitFieldVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterBitFieldVMNode.java index 9abb624b0a6..794f05b64ac 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterBitFieldVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterBitFieldVMNode.java @@ -299,7 +299,7 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode * which need data extraction they need to be added in both "for" * loops. */ - String[] localColumns = update.getPresentationContext().getColumns(); + String[] localColumns = update.getColumnIds(); if (localColumns == null) localColumns = new String[] { IDebugVMConstants.COLUMN_ID__NAME }; boolean weAreExtractingFormattedData = false; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterGroupVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterGroupVMNode.java index 6c93c0ad4cd..0aaef9ffd5a 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterGroupVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterGroupVMNode.java @@ -196,7 +196,7 @@ public class RegisterGroupVMNode extends AbstractExpressionVMNode * If columns are configured, call the protected methods to * fill in column values. */ - String[] localColumns = update.getPresentationContext().getColumns(); + String[] localColumns = update.getColumnIds(); if (localColumns == null) localColumns = new String[] { null }; for (int i = 0; i < localColumns.length; i++) { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterVMNode.java index 22d0980ac67..e89abf4a8d3 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterVMNode.java @@ -301,7 +301,7 @@ public class RegisterVMNode extends AbstractExpressionVMNode * which need data extraction they need to be added in both "for" * loops. */ - String[] localColumns = update.getPresentationContext().getColumns(); + String[] localColumns = update.getColumnIds(); if (localColumns == null) localColumns = new String[] { IDebugVMConstants.COLUMN_ID__NAME }; boolean weAreExtractingFormattedData = false; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/VariableVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/VariableVMNode.java index 160194a26a1..c106b6f146a 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/VariableVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/VariableVMNode.java @@ -238,7 +238,7 @@ public class VariableVMNode extends AbstractExpressionVMNode * one or more variables at that given instance in time are not evaluatable. They * may be out of scope and will come back into scope later. */ - String[] localColumns = update.getPresentationContext().getColumns(); + String[] localColumns = update.getColumnIds(); if (localColumns == null) localColumns = new String[] { IDebugVMConstants.COLUMN_ID__NAME }; @@ -266,7 +266,7 @@ public class VariableVMNode extends AbstractExpressionVMNode // processing flag so we know we have further work to do. If there are more columns // which need data extraction they need to be added in both "for" loops. - String[] localColumns = update.getPresentationContext().getColumns(); + String[] localColumns = update.getColumnIds(); if (localColumns == null) localColumns = new String[] { IDebugVMConstants.COLUMN_ID__NAME }; diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMNode.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMNode.java index cb7ed0723ea..f52dc404d36 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMNode.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMNode.java @@ -89,7 +89,7 @@ abstract public class AbstractVMNode implements IVMNode { ((IChildrenCountUpdate)update).setChildCount(0); } else if (update instanceof ILabelUpdate) { ILabelUpdate labelUpdate = (ILabelUpdate)update; - String[] columns = labelUpdate.getPresentationContext().getColumns(); + String[] columns = labelUpdate.getColumnIds(); for (int i = 0; i < (columns != null ? columns.length : 1); i++) { labelUpdate.setLabel("...", i); //$NON-NLS-1$ } From 8bced60c03a0ccd9ad9ddd06dfe86f224b6dcded Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Fri, 18 Apr 2008 20:00:25 +0000 Subject: [PATCH 394/834] Bug 223364 ProcessCommandQueued should not be called when de-queuing --- .../org/eclipse/dd/mi/service/command/AbstractMIControl.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java index 32a9e2f04f0..1c040aaf715 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java @@ -716,9 +716,8 @@ public abstract class AbstractMIControl extends AbstractDsfService if ( fCommandQueue.size() > 0 ) { CommandHandle comHandle = fCommandQueue.remove(0); if ( comHandle != null ) { - processCommandQueued(comHandle); - processCommandSent(comHandle); - fTxCommands.add(comHandle); + processCommandSent(comHandle); + fTxCommands.add(comHandle); } } } From 31d07ac3ccb8cfa2a86eb64ba069fb685b27f8d8 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 18 Apr 2008 20:17:49 +0000 Subject: [PATCH 395/834] [212839] Added "Type" column to the registers view. --- .../ui/viewmodel/register/MessagesForRegisterVM.java | 2 ++ .../ui/viewmodel/register/RegisterColumnPresentation.java | 4 +++- .../provisional/ui/viewmodel/register/messages.properties | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/MessagesForRegisterVM.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/MessagesForRegisterVM.java index d71f175acd1..434f0af14c0 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/MessagesForRegisterVM.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/MessagesForRegisterVM.java @@ -9,6 +9,8 @@ public class MessagesForRegisterVM extends NLS { public static String RegisterColumnPresentation_name; + public static String RegisterColumnPresentation_type; + public static String RegisterColumnPresentation_value; static { // initialize resource bundle diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterColumnPresentation.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterColumnPresentation.java index 8daddc7b060..9aa8e5eb2f3 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterColumnPresentation.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterColumnPresentation.java @@ -32,13 +32,15 @@ public class RegisterColumnPresentation implements IColumnPresentation { // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getAvailableColumns() public String[] getAvailableColumns() { - return new String[] { IDebugVMConstants.COLUMN_ID__NAME, IDebugVMConstants.COLUMN_ID__VALUE, IDebugVMConstants.COLUMN_ID__DESCRIPTION, }; + return new String[] { IDebugVMConstants.COLUMN_ID__NAME, IDebugVMConstants.COLUMN_ID__TYPE, IDebugVMConstants.COLUMN_ID__VALUE, IDebugVMConstants.COLUMN_ID__DESCRIPTION, }; } // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getHeader(java.lang.String) public String getHeader(String id) { if (IDebugVMConstants.COLUMN_ID__NAME.equals(id)) { return MessagesForRegisterVM.RegisterColumnPresentation_name; + } else if (IDebugVMConstants.COLUMN_ID__TYPE.equals(id)) { + return MessagesForRegisterVM.RegisterColumnPresentation_type; } else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(id)) { return MessagesForRegisterVM.RegisterColumnPresentation_value; } else if (IDebugVMConstants.COLUMN_ID__DESCRIPTION.equals(id)) { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/messages.properties b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/messages.properties index 5b6ea684c42..81b12d88c81 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/messages.properties +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/messages.properties @@ -1,3 +1,4 @@ RegisterColumnPresentation_name=Name +RegisterColumnPresentation_type=Type RegisterColumnPresentation_value=Value RegisterColumnPresentation_description=Description From 241d941438362e87f6363b90a12e2346aa762208 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Mon, 21 Apr 2008 18:08:53 +0000 Subject: [PATCH 396/834] Bug 226931 Support for Restart button. The steps to restarting the inferior are the following: 1- Create a new PTY and tell GDB to use it 2- Create a new MIInferiorProcess object which uses the new PTY 2.5- Have the CLIEventProcessor use the new MIInferiorProcess 3- Restart the inferior using -exec-run 4- Remove the previous inferior Process from the launch 5- Add the new inferior Process to the launch (which will trigger the use of the new PTY streams) This change supports the Restart function, including the above steps to perform the proper cleanup. The code to start the inferior has been extracted from the FinalLaunchSequence and put in GDBControl to allow sharing between start and restart. Also, the code to create the CLI and inferior process objects has been extracted from the GdbLaunchDelegate and put in GDBControl to to allow sharing between start and restart. There only interface change that is not in a provisional interface is the addition of resetInferior() to CLIEventprocessor which is backwards compatible. --- .../dd/gdb/internal/ui/GdbAdapterFactory.java | 7 + .../ui/actions/GdbRestartCommand.java | 126 ++++++++++++ .../launching/FinalLaunchSequence.java | 113 +---------- .../provisional/launching/GdbLaunch.java | 54 +++++ .../launching/GdbLaunchDelegate.java | 38 +--- .../launching/ServicesLaunchSequence.java | 4 +- .../service/command/GDBControl.java | 184 +++++++++++++++--- .../mi/service/command/CLIEventProcessor.java | 6 +- .../dd/tests/gdb/framework/BaseTestCase.java | 1 - .../gdb/launching/TestLaunchDelegate.java | 33 +--- 10 files changed, 372 insertions(+), 194 deletions(-) create mode 100644 plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/actions/GdbRestartCommand.java diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java index 0936f428377..4e55d701597 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java @@ -14,6 +14,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; +import org.eclipse.cdt.debug.core.model.IRestart; import org.eclipse.core.runtime.IAdapterFactory; import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.dsf.concurrent.ThreadSafe; @@ -28,6 +29,7 @@ import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.gdb.internal.provisional.launching.GdbLaunch; import org.eclipse.dd.gdb.internal.provisional.launching.GdbLaunchDelegate; import org.eclipse.dd.gdb.internal.ui.actions.DsfTerminateCommand; +import org.eclipse.dd.gdb.internal.ui.actions.GdbRestartCommand; import org.eclipse.dd.gdb.internal.ui.viewmodel.GdbViewModelAdapter; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; @@ -67,6 +69,7 @@ public class GdbAdapterFactory final DsfStepReturnCommand fStepReturnCommand; final DsfSuspendCommand fSuspendCommand; final DsfResumeCommand fResumeCommand; + final GdbRestartCommand fRestartCommand; final DsfTerminateCommand fTerminateCommand; final IDebugModelProvider fDebugModelProvider; final DsfSuspendTrigger fSuspendTrigger; @@ -89,6 +92,7 @@ public class GdbAdapterFactory fStepReturnCommand = new DsfStepReturnCommand(session); fSuspendCommand = new DsfSuspendCommand(session); fResumeCommand = new DsfResumeCommand(session); + fRestartCommand = new GdbRestartCommand(session, fLaunch); fTerminateCommand = new DsfTerminateCommand(session); fSuspendTrigger = new DsfSuspendTrigger(session, fLaunch); session.registerModelAdapter(IStepIntoHandler.class, fStepIntoCommand); @@ -96,6 +100,7 @@ public class GdbAdapterFactory session.registerModelAdapter(IStepReturnHandler.class, fStepReturnCommand); session.registerModelAdapter(ISuspendHandler.class, fSuspendCommand); session.registerModelAdapter(IResumeHandler.class, fResumeCommand); + session.registerModelAdapter(IRestart.class, fRestartCommand); session.registerModelAdapter(ITerminateHandler.class, fTerminateCommand); fDebugModelProvider = new IDebugModelProvider() { @@ -127,12 +132,14 @@ public class GdbAdapterFactory session.unregisterModelAdapter(IStepReturnHandler.class); session.unregisterModelAdapter(ISuspendHandler.class); session.unregisterModelAdapter(IResumeHandler.class); + session.unregisterModelAdapter(IRestart.class); session.unregisterModelAdapter(ITerminateHandler.class); fStepIntoCommand.dispose(); fStepOverCommand.dispose(); fStepReturnCommand.dispose(); fSuspendCommand.dispose(); fResumeCommand.dispose(); + fRestartCommand.dispose(); fTerminateCommand.dispose(); fSuspendTrigger.dispose(); } diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/actions/GdbRestartCommand.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/actions/GdbRestartCommand.java new file mode 100644 index 00000000000..d1edb35d70f --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/actions/GdbRestartCommand.java @@ -0,0 +1,126 @@ +/******************************************************************************* + * 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.gdb.internal.ui.actions; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.atomic.AtomicReference; + +import org.eclipse.cdt.debug.core.model.IRestart; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.Query; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.gdb.internal.provisional.launching.GdbLaunch; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl; +import org.eclipse.dd.gdb.internal.ui.GdbUIPlugin; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.model.IProcess; + +public class GdbRestartCommand implements IRestart { + private final DsfExecutor fExecutor; + private final DsfServicesTracker fTracker; + private final GdbLaunch fLaunch; + + public GdbRestartCommand(DsfSession session, GdbLaunch launch) { + fExecutor = session.getExecutor(); + fLaunch = launch; + fTracker = new DsfServicesTracker(GdbUIPlugin.getBundleContext(), session.getId()); + } + + public void dispose() { + fTracker.dispose(); + } + + // Run control may not be available after a connection is terminated and shut down. + public boolean canRestart() { + Query canRestart = new Query() { + @Override + protected void execute(DataRequestMonitor rm) { + GDBControl gdbControl = fTracker.getService(GDBControl.class); + if (gdbControl != null) { + rm.setData(gdbControl.canRestart()); + } else { + rm.setData(false); + } + + rm.done(); + } + }; + + fExecutor.execute(canRestart); + try { + return canRestart.get(); + } catch (InterruptedException e1) { + } catch (ExecutionException e1) { + } + return false; + } + + + public void restart() throws DebugException + { + final AtomicReference execPathRef = new AtomicReference(); + Query restartQuery = new Query() { + @Override + protected void execute(final DataRequestMonitor rm) { + final GDBControl gdbControl = fTracker.getService(GDBControl.class); + if (gdbControl != null) { + execPathRef.set(gdbControl.getExecutablePath()); + gdbControl.initInferiorInputOutput(new RequestMonitor(fExecutor, rm) { + @Override + protected void handleSuccess() { + gdbControl.createInferiorProcess(); + gdbControl.getCLICommandProcessor().resetInferior(gdbControl.getInferiorProcess()); + gdbControl.restart(fLaunch, rm); + } + }); + } else { + rm.done(); + } + } + }; + + fExecutor.execute(restartQuery); + try { + restartQuery.get(); + } catch (InterruptedException e1) { + } catch (ExecutionException e1) { + } + + // Now that we restarted the inferior, we must add it to our launch + // we must do this here because we cannot do it in the executor, or else + // it deadlocks + // We must first remove the old inferior from our launch (since it uses + // the same name and we use that name to find the old one) + // + // Remove + String inferiorLabel = execPathRef.get().lastSegment(); + + IProcess[] launchProcesses = fLaunch.getProcesses(); + for (IProcess p : launchProcesses) { + if (p.getLabel().equals(inferiorLabel)) { + fLaunch.removeProcess(p); + break; + } + } + // Add + try { + fLaunch.addInferiorProcess(inferiorLabel); + } catch (CoreException e) { + throw new DebugException(e.getStatus()); + } + } +} + diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java index b6e345bca81..ac4e421aef6 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java @@ -13,7 +13,6 @@ package org.eclipse.dd.gdb.internal.provisional.launching; import java.util.ArrayList; import java.util.List; -import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector; import org.eclipse.cdt.debug.mi.core.IGDBServerMILaunchConfigurationConstants; import org.eclipse.cdt.debug.mi.core.IMILaunchConfigurationConstants; @@ -25,28 +24,19 @@ import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfExecutor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.concurrent.Sequence; -import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; -import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.gdb.internal.GdbPlugin; import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl; import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl.SessionType; import org.eclipse.dd.mi.service.CSourceLookup; import org.eclipse.dd.mi.service.MIBreakpointsManager; +import org.eclipse.dd.mi.service.command.commands.CLIAttach; import org.eclipse.dd.mi.service.command.commands.CLISource; -import org.eclipse.dd.mi.service.command.commands.MIBreakInsert; -import org.eclipse.dd.mi.service.command.commands.MICommand; -import org.eclipse.dd.mi.service.command.commands.MIExecContinue; -import org.eclipse.dd.mi.service.command.commands.MIExecRun; import org.eclipse.dd.mi.service.command.commands.MIFileExecAndSymbols; import org.eclipse.dd.mi.service.command.commands.MIGDBSetAutoSolib; import org.eclipse.dd.mi.service.command.commands.MIGDBSetSolibSearchPath; -import org.eclipse.dd.mi.service.command.commands.MIInferiorTTYSet; -import org.eclipse.dd.mi.service.command.commands.CLIAttach; import org.eclipse.dd.mi.service.command.commands.MITargetSelect; -import org.eclipse.dd.mi.service.command.output.MIBreakInsertInfo; import org.eclipse.dd.mi.service.command.output.MIInfo; -import org.eclipse.debug.core.DebugException; public class FinalLaunchSequence extends Sequence { @@ -58,41 +48,13 @@ public class FinalLaunchSequence extends Sequence { public void execute(RequestMonitor requestMonitor) { DsfServicesTracker tracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), fLaunch.getSession().getId()); fCommandControl = tracker.getService(GDBControl.class); + if (fCommandControl == null) { + requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Cannot obtain GDBControl service", null)); //$NON-NLS-1$ + } tracker.dispose(); requestMonitor.done(); }}, - /* - * Specify connection of inferior input/output with a terminal. - */ - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - if (fSessionType == SessionType.ATTACH) { - requestMonitor.done(); - return; - } - - try { - boolean useTerminal = fLaunch.getLaunchConfiguration().getAttribute(ICDTLaunchConfigurationConstants.ATTR_USE_TERMINAL, true); - - if (useTerminal) { - String pytName = fCommandControl.getPtyName(); - if ( pytName != null ) { - fCommandControl.queueCommand( - new MIInferiorTTYSet(fCommandControl.getControlDMContext(), pytName), - new DataRequestMonitor(getExecutor(), requestMonitor)); - } - else { - requestMonitor.done(); - } - } else { - requestMonitor.done(); - } - } catch (CoreException e) { - requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Cannot get terminal option", e)); //$NON-NLS-1$ - requestMonitor.done(); - } - }}, /* * Source the gdbinit file specified in the launch */ @@ -278,7 +240,6 @@ public class FinalLaunchSequence extends Sequence { } else { requestMonitor.done(); } - } }, /* @@ -292,74 +253,12 @@ public class FinalLaunchSequence extends Sequence { bpmService.startTrackingBreakpoints(fCommandControl.getGDBDMContext(), requestMonitor); }}, /* - * If needed, insert breakpoint at main and run to it. + * Start the program. */ new Step() { - private boolean fStopInMain = false; - private String fStopSymbol = null; - - /** - * @return The return value actually indicates whether the get operation succeeded, - * not whether to stop. - */ - private boolean readStopAtMain(RequestMonitor requestMonitor) { - try { - fStopInMain = fLaunch.getLaunchConfiguration().getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN, false ); - } catch (CoreException e) { - requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Cannot retrieve the entry point symbol", e)); //$NON-NLS-1$ - requestMonitor.done(); - return false; - } - return true; - } - - private boolean readStopSymbol(RequestMonitor requestMonitor) { - try { - fStopSymbol = fLaunch.getLaunchConfiguration().getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN_SYMBOL, ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_SYMBOL_DEFAULT ); - } catch (CoreException e) { - requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.CONFIGURATION_INVALID, "Cannot retrieve the entry point symbol", e)); //$NON-NLS-1$ - requestMonitor.done(); - return false; - } - return true; - } - @Override public void execute(final RequestMonitor requestMonitor) { - if (fSessionType == SessionType.ATTACH) { - requestMonitor.done(); - return; - } - - final MICommand execCommand; - if (fSessionType == SessionType.REMOTE) { - // When doing remote debugging, we use -exec-continue instead of -exec-run - execCommand = new MIExecContinue((IContainerDMContext)fCommandControl.getControlDMContext()); - } else { - execCommand = new MIExecRun((IContainerDMContext)fCommandControl.getControlDMContext(), new String[0]); - } - - if (!readStopAtMain(requestMonitor)) return; - if (!fStopInMain) { - // Just start the program. - fCommandControl.queueCommand(execCommand, new DataRequestMonitor(getExecutor(), requestMonitor)); - } else { - if (!readStopSymbol(requestMonitor)) return; - - // Insert a breakpoint at the requested stop symbol. - fCommandControl.queueCommand( - new MIBreakInsert( - (IBreakpointsTargetDMContext)fCommandControl.getControlDMContext(), - true, false, null, 0, fStopSymbol, 0), - new DataRequestMonitor(getExecutor(), requestMonitor) { - @Override - protected void handleSuccess() { - - // After the break-insert is done, execute the -exec-run or -exec-continue command. - fCommandControl.queueCommand(execCommand, new DataRequestMonitor(getExecutor(), requestMonitor)); - } - }); - } + fCommandControl.start(fLaunch, requestMonitor); } }, }; diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunch.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunch.java index da3885bea29..b5c797a9ae4 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunch.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunch.java @@ -10,7 +10,10 @@ *******************************************************************************/ package org.eclipse.dd.gdb.internal.provisional.launching; +import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.atomic.AtomicReference; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; @@ -31,7 +34,10 @@ import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.gdb.internal.GdbPlugin; import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl; +import org.eclipse.dd.mi.service.command.AbstractCLIProcess; +import org.eclipse.dd.mi.service.command.MIInferiorProcess; import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.Launch; import org.eclipse.debug.core.model.ISourceLocator; @@ -91,6 +97,54 @@ public class GdbLaunch extends Launch public DsfSession getSession() { return fSession; } + public void addInferiorProcess(String label) throws CoreException { + try { + // Add the "inferior" process object to the launch. + final AtomicReference inferiorProcessRef = new AtomicReference(); + getDsfExecutor().submit( new Callable() { + public Object call() throws CoreException { + GDBControl gdb = fTracker.getService(GDBControl.class); + if (gdb != null) { + inferiorProcessRef.set(gdb.getInferiorProcess()); + } + return null; + } + }).get(); + + DebugPlugin.newProcess(this, inferiorProcessRef.get(), label); + } catch (InterruptedException e) { + throw new CoreException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, 0, "Interrupted while waiting for get process callable.", e)); //$NON-NLS-1$ + } catch (ExecutionException e) { + throw (CoreException)e.getCause(); + } catch (RejectedExecutionException e) { + throw new CoreException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, 0, "Debugger shut down before launch was completed.", e)); //$NON-NLS-1$ + } + } + + public void addCLIProcess(String label) throws CoreException { + try { + // Add the CLI process object to the launch. + final AtomicReference cliProcessRef = new AtomicReference(); + getDsfExecutor().submit( new Callable() { + public Object call() throws CoreException { + GDBControl gdb = fTracker.getService(GDBControl.class); + if (gdb != null) { + cliProcessRef.set(gdb.getCLIProcess()); + } + return null; + } + }).get(); + + DebugPlugin.newProcess(this, cliProcessRef.get(), label); + } catch (InterruptedException e) { + throw new CoreException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, 0, "Interrupted while waiting for get process callable.", e)); //$NON-NLS-1$ + } catch (ExecutionException e) { + throw (CoreException)e.getCause(); + } catch (RejectedExecutionException e) { + throw new CoreException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, 0, "Debugger shut down before launch was completed.", e)); //$NON-NLS-1$ + } + } + /////////////////////////////////////////////////////////////////////////// // IServiceEventListener @DsfServiceEventHandler public void eventDispatched(GDBControl.ExitedEvent event) { diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java index ded518d0d37..e589ee9310a 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java @@ -15,7 +15,6 @@ import java.io.IOException; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.atomic.AtomicReference; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; @@ -38,8 +37,6 @@ import org.eclipse.dd.gdb.internal.GdbPlugin; import org.eclipse.dd.gdb.internal.provisional.IGDBLaunchConfigurationConstants; import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl; import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl.SessionType; -import org.eclipse.dd.mi.service.command.AbstractCLIProcess; -import org.eclipse.dd.mi.service.command.MIInferiorProcess; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; @@ -155,41 +152,22 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Error in services launch sequence", e1.getCause())); //$NON-NLS-1$ } + // The initializeControl method should be called after the GdbControl class has + // be initialized (in the ServicesLaunchSequence above.) This is because it is the + // GdbControl class that will trigger the launch cleanup through a GDBControl.ExitedEvent launch.initializeControl(); // Add the CLI and "inferior" process objects to the launch. - final AtomicReference cliProcessRef = new AtomicReference(); - final AtomicReference inferiorProcessRef = new AtomicReference(); - try { - launch.getDsfExecutor().submit( new Callable() { - public Object call() throws CoreException { - DsfServicesTracker tracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), launch.getSession().getId()); - GDBControl gdb = tracker.getService(GDBControl.class); - if (gdb != null) { - cliProcessRef.set(gdb.getCLIProcess()); - inferiorProcessRef.set(gdb.getInferiorProcess()); - } - tracker.dispose(); - return null; - } - }).get(); - launch.addProcess(DebugPlugin.newProcess(launch, cliProcessRef.get(), "gdb")); //$NON-NLS-1$ - launch.addProcess(DebugPlugin.newProcess(launch, inferiorProcessRef.get(), exePath.lastSegment())); - } catch (InterruptedException e) { - throw new CoreException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, 0, "Interrupted while waiting for get process callable.", e)); //$NON-NLS-1$ - } catch (ExecutionException e) { - throw (CoreException)e.getCause(); - } catch (RejectedExecutionException e) { - throw new CoreException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, 0, "Debugger shut down before launch was completed.", e)); //$NON-NLS-1$ - } - + launch.addCLIProcess("gdb"); //$NON-NLS-1$ + launch.addInferiorProcess(exePath.lastSegment()); + // Create and invoke the final launch sequence to setup GDB final FinalLaunchSequence finalLaunchSequence; if (fSessionType == SessionType.ATTACH) { finalLaunchSequence = new FinalLaunchSequence(launch.getSession().getExecutor(), launch, pid); } else { finalLaunchSequence = new FinalLaunchSequence(launch.getSession().getExecutor(), launch, fSessionType); - } + } launch.getSession().getExecutor().execute(finalLaunchSequence); try { finalLaunchSequence.get(); @@ -332,7 +310,7 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate // the source lookup adapter. ISourceLocator locator = getSourceLocator(configuration); - return new GdbLaunch(configuration, mode, locator); + return new GdbLaunch(configuration, mode, locator); } private ISourceLocator getSourceLocator(ILaunchConfiguration configuration) throws CoreException { diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/ServicesLaunchSequence.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/ServicesLaunchSequence.java index f267b647282..8dc218b1a26 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/ServicesLaunchSequence.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/ServicesLaunchSequence.java @@ -43,11 +43,9 @@ public class ServicesLaunchSequence extends Sequence { @Override public void execute(RequestMonitor requestMonitor) { String debugMode = ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN; - boolean useTerminal = true; try { debugMode = fLaunch.getLaunchConfiguration().getAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN ); - useTerminal = fLaunch.getLaunchConfiguration().getAttribute(ICDTLaunchConfigurationConstants.ATTR_USE_TERMINAL, true); } catch (CoreException e) { } @@ -66,7 +64,7 @@ public class ServicesLaunchSequence extends Sequence { // // Create the connection. // - fCommandControl = new GDBControl(fSession, getGDBPath(), fExecPath, fSessionType, useTerminal, 30); + fCommandControl = new GDBControl(fSession, getGDBPath(), fExecPath, fSessionType, 30); fCommandControl.initialize(requestMonitor); } }, diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java index 49cd3bcff93..650fb83207a 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java @@ -23,9 +23,11 @@ import java.util.List; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; +import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.cdt.utils.pty.PTY; import org.eclipse.cdt.utils.spawner.ProcessFactory; import org.eclipse.cdt.utils.spawner.Spawner; +import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; @@ -41,13 +43,20 @@ import org.eclipse.dd.dsf.debug.service.command.ICommandControl; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.gdb.internal.GdbPlugin; +import org.eclipse.dd.gdb.internal.provisional.launching.GdbLaunch; import org.eclipse.dd.mi.service.command.AbstractCLIProcess; import org.eclipse.dd.mi.service.command.AbstractMIControl; import org.eclipse.dd.mi.service.command.CLIEventProcessor; import org.eclipse.dd.mi.service.command.MIControlDMContext; import org.eclipse.dd.mi.service.command.MIInferiorProcess; import org.eclipse.dd.mi.service.command.MIRunControlEventProcessor; +import org.eclipse.dd.mi.service.command.commands.MIBreakInsert; +import org.eclipse.dd.mi.service.command.commands.MICommand; +import org.eclipse.dd.mi.service.command.commands.MIExecContinue; +import org.eclipse.dd.mi.service.command.commands.MIExecRun; import org.eclipse.dd.mi.service.command.commands.MIGDBExit; +import org.eclipse.dd.mi.service.command.commands.MIInferiorTTYSet; +import org.eclipse.dd.mi.service.command.output.MIBreakInsertInfo; import org.eclipse.dd.mi.service.command.output.MIInfo; import org.eclipse.debug.core.DebugException; import org.osgi.framework.BundleContext; @@ -100,17 +109,15 @@ public class GDBControl extends AbstractMIControl { private AbstractCLIProcess fCLIProcess; private MIInferiorProcess fInferiorProcess = null; - boolean fUseTerminal; private PTY fPty; - public GDBControl(DsfSession session, IPath gdbPath, IPath execPath, SessionType type, boolean useTerminal, int gdbLaunchTimeout) { + public GDBControl(DsfSession session, IPath gdbPath, IPath execPath, SessionType type, int gdbLaunchTimeout) { super(session); fSessionType = type; fGdbPath = gdbPath; fExecPath = execPath; fGDBLaunchTimeout = gdbLaunchTimeout; fControlDmc = new GDBControlDMContext(session.getId(), getClass().getName() + ":" + ++fgInstanceCounter); //$NON-NLS-1$ - fUseTerminal = useTerminal; } @Override @@ -133,6 +140,7 @@ public class GDBControl extends AbstractMIControl { new GDBProcessStep(InitializationShutdownStep.Direction.INITIALIZING), new MonitorJobStep(InitializationShutdownStep.Direction.INITIALIZING), new CommandMonitoringStep(InitializationShutdownStep.Direction.INITIALIZING), + new InferiorInputOutputInitStep(InitializationShutdownStep.Direction.INITIALIZING), new CommandProcessorsStep(InitializationShutdownStep.Direction.INITIALIZING), new RegisterStep(InitializationShutdownStep.Direction.INITIALIZING), }; @@ -148,6 +156,7 @@ public class GDBControl extends AbstractMIControl { final Sequence.Step[] shutdownSteps = new Sequence.Step[] { new RegisterStep(InitializationShutdownStep.Direction.SHUTTING_DOWN), new CommandProcessorsStep(InitializationShutdownStep.Direction.SHUTTING_DOWN), + new InferiorInputOutputInitStep(InitializationShutdownStep.Direction.SHUTTING_DOWN), new CommandMonitoringStep(InitializationShutdownStep.Direction.SHUTTING_DOWN), new MonitorJobStep(InitializationShutdownStep.Direction.SHUTTING_DOWN), new GDBProcessStep(InitializationShutdownStep.Direction.SHUTTING_DOWN), @@ -228,6 +237,136 @@ public class GDBControl extends AbstractMIControl { } ); } + + /* + * This method does the necessary work to setup the input/output streams for the + * inferior process, by either preparing the PTY to be used, to simply leaving + * the PTY null, which indicates that the input/output streams of the CLI shoud + * be used instead; this decision is based on the type of session. + */ + public void initInferiorInputOutput(final RequestMonitor requestMonitor) { + if (fSessionType == SessionType.ATTACH || fSessionType == SessionType.REMOTE) { + // These types do not use a PTY + fPty = null; + requestMonitor.done(); + } else { + // These types always use a PTY + try { + fPty = new PTY(); + + // Tell GDB to use this PTY + queueCommand( + new MIInferiorTTYSet(fControlDmc, fPty.getSlaveName()), + new DataRequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleFailure() { + // We were not able to tell GDB to use the PTY + // so we won't use it at all. + fPty = null; + requestMonitor.done(); + } + }); + } catch (IOException e) { + fPty = null; + requestMonitor.done(); + } + } + } + + + public boolean canRestart() { + if (fSessionType == SessionType.ATTACH) return false; + + // Before GDB6.8, the Linux gdbserver would restart a new + // process when getting a -exec-run but the communication + // with GDB had a bug and everything hung. + // with GDB6.8 the program restarts properly one time, + // but on a second attempt, gdbserver crashes. + // So, lets just turn off the Restart for Remote debugging + if (fSessionType == SessionType.REMOTE) return false; + + return true; + } + + /* + * Start the program. + */ + public void start(GdbLaunch launch, final RequestMonitor requestMonitor) { + startOrRestart(launch, false, requestMonitor); + } + + /* + * Before restarting the inferior, we must re-initialize its input/output streams + * and create a new inferior process object. Then we can restart the inferior. + */ + public void restart(final GdbLaunch launch, final RequestMonitor requestMonitor) { + startOrRestart(launch, true, requestMonitor); + } + + /* + * Insert breakpoint at entry if set, and start or restart the program. + */ + protected void startOrRestart(final GdbLaunch launch, boolean restart, final RequestMonitor requestMonitor) { + if (fSessionType == SessionType.ATTACH) { + // When attaching to a running process, we do not need to set a breakpoint or + // start the program; it is left up to the user. + requestMonitor.done(); + return; + } + + final MICommand execCommand; + if (fSessionType == SessionType.REMOTE) { + // When doing remote debugging, we use -exec-continue instead of -exec-run + execCommand = new MIExecContinue(fControlDmc); + } else { + execCommand = new MIExecRun(fControlDmc, new String[0]); + } + + boolean stopInMain = false; + try { + stopInMain = launch.getLaunchConfiguration().getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN, false ); + } catch (CoreException e) { + requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Cannot retrieve stop at entry point boolean", e)); //$NON-NLS-1$ + requestMonitor.done(); + return; + } + + if (!stopInMain) { + // Just start the program. + queueCommand(execCommand, new DataRequestMonitor(getExecutor(), requestMonitor)); + } else { + String stopSymbol = null; + try { + stopSymbol = launch.getLaunchConfiguration().getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN_SYMBOL, ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_SYMBOL_DEFAULT ); + } catch (CoreException e) { + requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.CONFIGURATION_INVALID, "Cannot retrieve the entry point symbol", e)); //$NON-NLS-1$ + requestMonitor.done(); + return; + } + + // Insert a breakpoint at the requested stop symbol. + queueCommand( + new MIBreakInsert(fControlDmc, true, false, null, 0, stopSymbol, 0), + new DataRequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleSuccess() { + // After the break-insert is done, execute the -exec-run or -exec-continue command. + queueCommand(execCommand, new DataRequestMonitor(getExecutor(), requestMonitor)); + } + }); + } + } + + /* + * This method creates a new inferior process object based on the current Pty or output stream. + */ + public void createInferiorProcess() { + if (fPty == null) { + fInferiorProcess = new GDBInferiorProcess(GDBControl.this, fProcess.getOutputStream()); + } else { + fInferiorProcess = new GDBInferiorProcess(GDBControl.this, fPty); + } + } public boolean isConnected() { return fInferiorProcess.getState() != MIInferiorProcess.State.TERMINATED && fConnected; @@ -249,6 +388,10 @@ public class GDBControl extends AbstractMIControl { return fInferiorProcess; } + public CLIEventProcessor getCLICommandProcessor() { + return fCLICommandProcessor; + } + public boolean isGDBExited() { return fMonitorJob != null && fMonitorJob.fExited; } @@ -261,15 +404,6 @@ public class GDBControl extends AbstractMIControl { public void getInferiorProcessId(DataRequestMonitor rm) { } - - public String getPtyName() { - if ( fPty != null ) { - return fPty.getSlaveName(); - } - else { - return null; - } - } @DsfServiceEventHandler public void eventDispatched(ExitedEvent e) { @@ -517,6 +651,20 @@ public class GDBControl extends AbstractMIControl { requestMonitor.done(); } } + + protected class InferiorInputOutputInitStep extends InitializationShutdownStep { + InferiorInputOutputInitStep(Direction direction) { super(direction); } + + @Override + protected void initialize(final RequestMonitor requestMonitor) { + initInferiorInputOutput(requestMonitor); + } + + @Override + protected void shutdown(RequestMonitor requestMonitor) { + requestMonitor.done(); + } + } protected class CommandProcessorsStep extends InitializationShutdownStep { CommandProcessorsStep(Direction direction) { super(direction); } @@ -532,18 +680,8 @@ public class GDBControl extends AbstractMIControl { return; } - if (fUseTerminal) { - try { - fPty = new PTY(); - fInferiorProcess = new GDBInferiorProcess(GDBControl.this, fPty); - } catch (IOException e) { - } - } + createInferiorProcess(); - // If !fUseTerminal or IOException was caught - if (fInferiorProcess == null) - fInferiorProcess = new GDBInferiorProcess(GDBControl.this, fProcess.getOutputStream()); - fCLICommandProcessor = new CLIEventProcessor(GDBControl.this, fControlDmc, fInferiorProcess); fMIEventProcessor = new MIRunControlEventProcessor(GDBControl.this, fControlDmc); diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/CLIEventProcessor.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/CLIEventProcessor.java index 9beca3818fb..ee1ca9735b6 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/CLIEventProcessor.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/CLIEventProcessor.java @@ -50,7 +50,7 @@ public class CLIEventProcessor implements ICommandListener, IEventListener { private final AbstractMIControl fCommandControl; - private final MIInferiorProcess fInferior; + private MIInferiorProcess fInferior; private final IContainerDMContext fContainerDmc; private final List fEventList = new LinkedList(); @@ -73,6 +73,10 @@ public class CLIEventProcessor fCommandControl.removeEventListener(this); } + public void resetInferior(MIInferiorProcess inferior) { + fInferior = inferior; + } + public void commandSent(ICommandToken token) { if (token.getCommand() instanceof CLICommand) { processStateChanges( (CLICommand)token.getCommand() ); diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java index cc3fe0ab2cc..5cce87ca0a3 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/framework/BaseTestCase.java @@ -54,7 +54,6 @@ public class BaseTestCase { // Setup information for the launcher attrs.put(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, DEFAULT_TEST_APP); - attrs.put(ICDTLaunchConfigurationConstants.ATTR_USE_TERMINAL, true); attrs.put(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN, true); attrs.put(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN_SYMBOL, ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_SYMBOL_DEFAULT); attrs.put(IMILaunchConfigurationConstants.ATTR_DEBUG_NAME, "gdb"); diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java index 19b72fb7cd6..89c266f6f17 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java @@ -17,7 +17,6 @@ import java.io.IOException; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.atomic.AtomicReference; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.cdt.launch.AbstractCLaunchDelegate; @@ -41,8 +40,6 @@ import org.eclipse.dd.gdb.internal.provisional.launching.GdbLaunch; import org.eclipse.dd.gdb.internal.provisional.launching.ServicesLaunchSequence; import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl; import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl.SessionType; -import org.eclipse.dd.mi.service.command.AbstractCLIProcess; -import org.eclipse.dd.mi.service.command.MIInferiorProcess; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; @@ -123,34 +120,12 @@ public class TestLaunchDelegate extends AbstractCLaunchDelegate launch.initializeControl(); // Add the CLI and "inferior" process objects to the launch. - final AtomicReference cliProcessRef = new AtomicReference(); - final AtomicReference inferiorProcessRef = new AtomicReference(); - try { - launch.getDsfExecutor().submit( new Callable() { - public Object call() throws CoreException { - DsfServicesTracker tracker = new DsfServicesTracker(TestsPlugin.getBundleContext(), launch.getSession().getId()); - GDBControl gdb = tracker.getService(GDBControl.class); - if (gdb != null) { - cliProcessRef.set(gdb.getCLIProcess()); - inferiorProcessRef.set(gdb.getInferiorProcess()); - } - tracker.dispose(); - return null; - } - }).get(); - launch.addProcess(DebugPlugin.newProcess(launch, cliProcessRef.get(), "gdb")); //$NON-NLS-1$ - launch.addProcess(DebugPlugin.newProcess(launch, inferiorProcessRef.get(), exePath.lastSegment())); - } catch (InterruptedException e) { - throw new CoreException(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, 0, "Interrupted while waiting for get process callable.", e)); //$NON-NLS-1$ - } catch (ExecutionException e) { - throw (CoreException)e.getCause(); - } catch (RejectedExecutionException e) { - throw new CoreException(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, 0, "Debugger shut down before launch was completed.", e)); //$NON-NLS-1$ - } - + launch.addCLIProcess("gdb"); //$NON-NLS-1$ + launch.addInferiorProcess(exePath.lastSegment()); + // Create and invoke the final launch sequence to setup GDB final FinalLaunchSequence finalLaunchSequence = - new FinalLaunchSequence(launch.getSession().getExecutor(), launch, SessionType.RUN); + new FinalLaunchSequence(launch.getSession().getExecutor(), launch, SessionType.RUN); launch.getSession().getExecutor().execute(finalLaunchSequence); try { finalLaunchSequence.get(); From 0d04616e1d00b15cce4d3decf1a9abe14282ae06 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Mon, 21 Apr 2008 18:21:17 +0000 Subject: [PATCH 397/834] Bug 226931 Since the use of a terminal is determined by the type of launch and is no longer an option for the user, it should be removed from the launch tab. --- .../ui/launching/GdbAttachLaunchConfigurationTabGroup.java | 2 +- .../ui/launching/GdbLocalRunLaunchConfigurationTabGroup.java | 2 +- .../ui/launching/GdbRemoteRunLaunchConfigurationTabGroup.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbAttachLaunchConfigurationTabGroup.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbAttachLaunchConfigurationTabGroup.java index 6f19c451d0f..bc8e2fa1add 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbAttachLaunchConfigurationTabGroup.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbAttachLaunchConfigurationTabGroup.java @@ -26,7 +26,7 @@ public class GdbAttachLaunchConfigurationTabGroup extends AbstractLaunchConfigur */ public void createTabs(ILaunchConfigurationDialog dialog, String mode) { ILaunchConfigurationTab[] tabs = new ILaunchConfigurationTab[] { - new CMainTab(true), + new CMainTab(), new CDebuggerTab(SessionType.ATTACH), new SourceLookupTab(), new CommonTab() diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbLocalRunLaunchConfigurationTabGroup.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbLocalRunLaunchConfigurationTabGroup.java index 0b02972e1c3..a7ccb8fca28 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbLocalRunLaunchConfigurationTabGroup.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbLocalRunLaunchConfigurationTabGroup.java @@ -25,7 +25,7 @@ public class GdbLocalRunLaunchConfigurationTabGroup extends AbstractLaunchConfig */ public void createTabs(ILaunchConfigurationDialog dialog, String mode) { ILaunchConfigurationTab[] tabs = new ILaunchConfigurationTab[] { - new CMainTab(true), + new CMainTab(), new CDebuggerTab(SessionType.RUN), new SourceLookupTab(), new CommonTab() diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbRemoteRunLaunchConfigurationTabGroup.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbRemoteRunLaunchConfigurationTabGroup.java index fb5689b894f..0d36dc3537f 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbRemoteRunLaunchConfigurationTabGroup.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbRemoteRunLaunchConfigurationTabGroup.java @@ -26,7 +26,7 @@ public class GdbRemoteRunLaunchConfigurationTabGroup extends AbstractLaunchConfi */ public void createTabs(ILaunchConfigurationDialog dialog, String mode) { ILaunchConfigurationTab[] tabs = new ILaunchConfigurationTab[] { - new CMainTab(true), + new CMainTab(), new CDebuggerTab(SessionType.REMOTE), new SourceLookupTab(), new CommonTab() From ca383d57de3c430f188fb77f1b6921d777376a64 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 22 Apr 2008 05:09:50 +0000 Subject: [PATCH 398/834] [228148] Fixed an NPE exposed by timing changes in services initialization. --- .../org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java index 3dcb478854d..bc566c454b6 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java @@ -56,7 +56,7 @@ public abstract class DsfCommandRunnable extends DsfRunnable { } if (getContext() == null) { fRequest.setStatus(makeError("Selected object does not support run control.", null)); //$NON-NLS-1$ - } else if (getRunControl() == null) { + } else if (getRunControl() == null || getStepQueueMgr() == null) { fRequest.setStatus(makeError("Run Control not available", null)); //$NON-NLS-1$ } else { doExecute(); From 945d38717041a9bdc3b79e52f8f1674e23f0f91b Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Tue, 22 Apr 2008 19:25:58 +0000 Subject: [PATCH 399/834] After the weekly meeting, this cleanup was suggested. It uses the Future class to extract the data we want. --- .../provisional/launching/GdbLaunch.java | 56 ++++++++++--------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunch.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunch.java index b5c797a9ae4..3e2bddda835 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunch.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunch.java @@ -12,8 +12,8 @@ package org.eclipse.dd.gdb.internal.provisional.launching; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.atomic.AtomicReference; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; @@ -98,20 +98,21 @@ public class GdbLaunch extends Launch public DsfSession getSession() { return fSession; } public void addInferiorProcess(String label) throws CoreException { - try { - // Add the "inferior" process object to the launch. - final AtomicReference inferiorProcessRef = new AtomicReference(); - getDsfExecutor().submit( new Callable() { - public Object call() throws CoreException { - GDBControl gdb = fTracker.getService(GDBControl.class); - if (gdb != null) { - inferiorProcessRef.set(gdb.getInferiorProcess()); - } - return null; - } - }).get(); - - DebugPlugin.newProcess(this, inferiorProcessRef.get(), label); + try { + // Add the "inferior" process object to the launch. + Future future = + getDsfExecutor().submit( new Callable() { + public MIInferiorProcess call() throws CoreException { + GDBControl gdb = fTracker.getService(GDBControl.class); + if (gdb != null) { + return gdb.getInferiorProcess(); + } + return null; + } + }); + MIInferiorProcess inferiorProc = future.get(); + + DebugPlugin.newProcess(this, inferiorProc, label); } catch (InterruptedException e) { throw new CoreException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, 0, "Interrupted while waiting for get process callable.", e)); //$NON-NLS-1$ } catch (ExecutionException e) { @@ -124,18 +125,19 @@ public class GdbLaunch extends Launch public void addCLIProcess(String label) throws CoreException { try { // Add the CLI process object to the launch. - final AtomicReference cliProcessRef = new AtomicReference(); - getDsfExecutor().submit( new Callable() { - public Object call() throws CoreException { - GDBControl gdb = fTracker.getService(GDBControl.class); - if (gdb != null) { - cliProcessRef.set(gdb.getCLIProcess()); - } - return null; - } - }).get(); - - DebugPlugin.newProcess(this, cliProcessRef.get(), label); + Future future = + getDsfExecutor().submit( new Callable() { + public AbstractCLIProcess call() throws CoreException { + GDBControl gdb = fTracker.getService(GDBControl.class); + if (gdb != null) { + return gdb.getCLIProcess(); + } + return null; + } + }); + AbstractCLIProcess cliProc = future.get(); + + DebugPlugin.newProcess(this, cliProc, label); } catch (InterruptedException e) { throw new CoreException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, 0, "Interrupted while waiting for get process callable.", e)); //$NON-NLS-1$ } catch (ExecutionException e) { From eeb0105c4d314e9527a24a63af43f5ba5766a759 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Tue, 22 Apr 2008 19:28:31 +0000 Subject: [PATCH 400/834] A little more cleanup. --- .../gdb/internal/provisional/launching/GdbLaunch.java | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunch.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunch.java index 3e2bddda835..2d3245e60aa 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunch.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunch.java @@ -12,7 +12,6 @@ package org.eclipse.dd.gdb.internal.provisional.launching; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; import java.util.concurrent.RejectedExecutionException; import org.eclipse.core.runtime.CoreException; @@ -100,7 +99,7 @@ public class GdbLaunch extends Launch public void addInferiorProcess(String label) throws CoreException { try { // Add the "inferior" process object to the launch. - Future future = + MIInferiorProcess inferiorProc = getDsfExecutor().submit( new Callable() { public MIInferiorProcess call() throws CoreException { GDBControl gdb = fTracker.getService(GDBControl.class); @@ -109,8 +108,7 @@ public class GdbLaunch extends Launch } return null; } - }); - MIInferiorProcess inferiorProc = future.get(); + }).get(); DebugPlugin.newProcess(this, inferiorProc, label); } catch (InterruptedException e) { @@ -125,7 +123,7 @@ public class GdbLaunch extends Launch public void addCLIProcess(String label) throws CoreException { try { // Add the CLI process object to the launch. - Future future = + AbstractCLIProcess cliProc = getDsfExecutor().submit( new Callable() { public AbstractCLIProcess call() throws CoreException { GDBControl gdb = fTracker.getService(GDBControl.class); @@ -134,8 +132,7 @@ public class GdbLaunch extends Launch } return null; } - }); - AbstractCLIProcess cliProc = future.get(); + }).get(); DebugPlugin.newProcess(this, cliProc, label); } catch (InterruptedException e) { From fe347ce364068c04b80f4848e68e021de5a73e37 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Tue, 22 Apr 2008 19:42:07 +0000 Subject: [PATCH 401/834] Added annotation @ThreadSafeAndProhibitedFromDsfExecutor. --- .../dd/gdb/internal/provisional/launching/GdbLaunch.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunch.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunch.java index 2d3245e60aa..bdf7c66b2f0 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunch.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunch.java @@ -28,6 +28,7 @@ import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.concurrent.Sequence; import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.dd.dsf.concurrent.ThreadSafeAndProhibitedFromDsfExecutor; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; @@ -96,6 +97,7 @@ public class GdbLaunch extends Launch public DsfSession getSession() { return fSession; } + @ThreadSafeAndProhibitedFromDsfExecutor("getDsfExecutor()") public void addInferiorProcess(String label) throws CoreException { try { // Add the "inferior" process object to the launch. @@ -120,6 +122,7 @@ public class GdbLaunch extends Launch } } + @ThreadSafeAndProhibitedFromDsfExecutor("getDsfExecutor()") public void addCLIProcess(String label) throws CoreException { try { // Add the CLI process object to the launch. From 3b275318fd9ac27f8a023fc67562d27017132fb3 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 23 Apr 2008 16:42:15 +0000 Subject: [PATCH 402/834] [228458] Cleaned up old and unused expression parsing methods. --- .../ui/viewmodel/register/RegisterGroupVMNode.java | 10 ---------- .../ui/viewmodel/register/RegisterVMNode.java | 12 ------------ 2 files changed, 22 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterGroupVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterGroupVMNode.java index 0aaef9ffd5a..6656656ca67 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterGroupVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterGroupVMNode.java @@ -287,16 +287,6 @@ public class RegisterGroupVMNode extends AbstractExpressionVMNode return null; } - public int getExpressionLength(String expression) { - if (expression.startsWith("$$\"")) { //$NON-NLS-1$ - int secondQuoteIdx = expression.indexOf('"', "$$\"".length()); //$NON-NLS-1$ - if (secondQuoteIdx > 0) { - return secondQuoteIdx + 1; - } - } - return -1; - } - public int getDeltaFlagsForExpression(IExpression expression, Object event) { if (event instanceof IRunControl.ISuspendedDMEvent) { return IModelDelta.CONTENT; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterVMNode.java index e89abf4a8d3..edac0877436 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterVMNode.java @@ -466,18 +466,6 @@ public class RegisterVMNode extends AbstractExpressionVMNode return null; } - public int getExpressionLength(String expression) { - if (expression.charAt(0) == '$' && Character.isLetterOrDigit(expression.charAt(1))) { - int length = 1; - while( length < expression.length() && Character.isLetterOrDigit(expression.charAt(length)) ) { - length++; - } - return length; - } else { - return -1; - } - } - @Override protected void testElementForExpression(Object element, IExpression expression, final DataRequestMonitor rm) { if (!(element instanceof IDMVMContext)) { From 7fa8caa54f964a94f2e29f84e37cd6af66430177 Mon Sep 17 00:00:00 2001 From: Francois Chouinard Date: Thu, 24 Apr 2008 15:19:28 +0000 Subject: [PATCH 403/834] Fix for bug228308 --- .../debug/model/DsfMemoryBlockRetrieval.java | 20 +++-------- .../provisional/launching/GdbLaunch.java | 33 +++++++++++++++++-- .../launching/GdbLaunchDelegate.java | 30 ----------------- .../launching/ShutdownSequence.java | 29 ---------------- 4 files changed, 36 insertions(+), 76 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java index bc5bad8d61a..b0cdc7c0ac2 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java @@ -40,7 +40,6 @@ import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryDMContext; import org.eclipse.dd.dsf.service.DsfServices; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; -import org.eclipse.dd.dsf.service.DsfSession.SessionEndedListener; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; @@ -74,7 +73,7 @@ import org.w3c.dom.NodeList; * code will still be functional after some trivial adjustments. * */ -public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBlockRetrievalExtension, SessionEndedListener +public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBlockRetrievalExtension { private final String fModelId; private final DsfSession fSession; @@ -164,9 +163,6 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl fWordSize = 1; // Get this from the launch configuration fSupportsValueModification = true; // Get this from the launch configuration fSupportBaseAddressModification = false; // Get this from the launch configuration - - // So we are notified on exit and can save the memory blocks - DsfSession.addSessionEndedListener(this); } /////////////////////////////////////////////////////////////////////////// @@ -266,17 +262,11 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl } } - /** - * On session exit, save the memory blocks in the launch configuration - */ - public void sessionEnded(DsfSession session) { - DsfSession.removeSessionEndedListener(this); - saveMemoryBlocks(); - } - // FIXME: Each retrieval overwrites the previous one :-( - // FIXME: Racing condition :-( - synchronize on launch config enough? - // FIXME: Make it a Job? + // In theory, we should make this a Job since we are writing to the file system. + // However, this would cause the same racing condition as Bug228308. Finally, we + // don't care too much about the UI responsiveness since we are in the process of + // shutting down :-) public void saveMemoryBlocks() { try { ILaunchConfigurationWorkingCopy wc = fLaunchConfig.getWorkingCopy(); diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunch.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunch.java index bdf7c66b2f0..e5e23be05c5 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunch.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunch.java @@ -29,6 +29,8 @@ import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.concurrent.Sequence; import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.concurrent.ThreadSafeAndProhibitedFromDsfExecutor; +import org.eclipse.dd.dsf.debug.model.DsfMemoryBlockRetrieval; +import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryDMContext; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; @@ -40,6 +42,7 @@ import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.Launch; +import org.eclipse.debug.core.model.IMemoryBlockRetrieval; import org.eclipse.debug.core.model.ISourceLocator; import org.eclipse.debug.core.model.ITerminate; @@ -55,7 +58,8 @@ public class GdbLaunch extends Launch private DsfServicesTracker fTracker; private boolean fInitialized = false; private boolean fShutDown = false; - + + private DsfMemoryBlockRetrieval fMemRetrieval; public GdbLaunch(ILaunchConfiguration launchConfiguration, String mode, ISourceLocator locator) { super(launchConfiguration, mode, locator); @@ -74,7 +78,6 @@ public class GdbLaunch extends Launch public void initializeControl() throws CoreException { - Runnable initRunnable = new DsfRunnable() { public void run() { fTracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), fSession.getId()); @@ -93,6 +96,28 @@ public class GdbLaunch extends Launch } catch (ExecutionException e) { new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Error initializing launch", e); //$NON-NLS-1$ } + + // Create a memory retrieval and register it with the session + try { + fExecutor.submit( new Callable() { + public Object call() throws CoreException { + GDBControl gdbControl = fTracker.getService(GDBControl.class); + if (gdbControl != null) { + fMemRetrieval = new DsfMemoryBlockRetrieval( + GdbLaunchDelegate.GDB_DEBUG_MODEL_ID, getLaunchConfiguration(), fSession); + fSession.registerModelAdapter(IMemoryBlockRetrieval.class, fMemRetrieval); + fMemRetrieval.initialize((IMemoryDMContext) gdbControl.getControlDMContext()); + } + return null; + } + }).get(); + } catch (InterruptedException e) { + throw new CoreException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, 0, "Interrupted while waiting for get process callable.", e)); //$NON-NLS-1$ + } catch (ExecutionException e) { + throw (CoreException)e.getCause(); + } catch (RejectedExecutionException e) { + throw new CoreException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, 0, "Debugger shut down before launch was completed.", e)); //$NON-NLS-1$ + } } public DsfSession getSession() { return fSession; } @@ -208,6 +233,10 @@ public class GdbLaunch extends Launch fTracker.dispose(); fTracker = null; DsfSession.endSession(fSession); + + // DsfMemoryBlockRetrieval.saveMemoryBlocks(); + fMemRetrieval.saveMemoryBlocks(); + // endSession takes a full dispatch to distribute the // session-ended event, finish step only after the dispatch. fExecutor.shutdown(); diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java index e589ee9310a..cc56582f33f 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java @@ -12,9 +12,7 @@ package org.eclipse.dd.gdb.internal.provisional.launching; import java.io.File; import java.io.IOException; -import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; -import java.util.concurrent.RejectedExecutionException; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; @@ -30,12 +28,8 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.ThreadSafe; -import org.eclipse.dd.dsf.debug.model.DsfMemoryBlockRetrieval; -import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryDMContext; -import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.gdb.internal.GdbPlugin; import org.eclipse.dd.gdb.internal.provisional.IGDBLaunchConfigurationConstants; -import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl; import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl.SessionType; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.DebugPlugin; @@ -44,7 +38,6 @@ import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchManager; import org.eclipse.debug.core.IStatusHandler; import org.eclipse.debug.core.model.ILaunchConfigurationDelegate2; -import org.eclipse.debug.core.model.IMemoryBlockRetrieval; import org.eclipse.debug.core.model.IPersistableSourceLocator; import org.eclipse.debug.core.model.ISourceLocator; import org.eclipse.debug.core.sourcelookup.IPersistableSourceLocator2; @@ -176,29 +169,6 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate } catch (ExecutionException e1) { throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Error in final launch sequence", e1.getCause())); //$NON-NLS-1$ } - // Create a memory retrieval and register it with session - try { - launch.getDsfExecutor().submit( new Callable() { - public Object call() throws CoreException { - DsfServicesTracker tracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), launch.getSession().getId()); - GDBControl gdbControl = tracker.getService(GDBControl.class); - if (gdbControl != null) { - IMemoryBlockRetrieval memRetrieval = new DsfMemoryBlockRetrieval( - GDB_DEBUG_MODEL_ID, config, launch.getSession()); - launch.getSession().registerModelAdapter(IMemoryBlockRetrieval.class, memRetrieval); - ((DsfMemoryBlockRetrieval) memRetrieval).initialize((IMemoryDMContext)gdbControl.getControlDMContext()); - } - tracker.dispose(); - return null; - } - }).get(); - } catch (InterruptedException e) { - throw new CoreException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, 0, "Interrupted while waiting for get process callable.", e)); //$NON-NLS-1$ - } catch (ExecutionException e) { - throw (CoreException)e.getCause(); - } catch (RejectedExecutionException e) { - throw new CoreException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, 0, "Debugger shut down before launch was completed.", e)); //$NON-NLS-1$ - } } // Copied from the CDT diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/ShutdownSequence.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/ShutdownSequence.java index 8a59da52f77..db0692398b8 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/ShutdownSequence.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/ShutdownSequence.java @@ -75,35 +75,6 @@ public class ShutdownSequence extends Sequence { public void execute(RequestMonitor requestMonitor) { shutdownService(MIRegisters.class, requestMonitor); } -// TODO: As Pawel about the necessity of this step -// Not clear on the purpose of this step since the next one does it also -// (stopTrackingBreakpoints() is called as part of the shutdown method) -// Besides, the run control is already gone so removing breakpoints from -// the back-end is bound to fail... -// }, new Step() { -// @Override -// public void execute(final RequestMonitor requestMonitor) { -// MIBreakpointsManager bpm = fTracker.getService(MIBreakpointsManager.class); -// GDBControl commandControl = fTracker.getService(GDBControl.class); -// if (bpm != null && commandControl != null) { -// bpm.stopTrackingBreakpoints( -// commandControl.getGDBDMContext(), -// new RequestMonitor(getExecutor(), requestMonitor) { -// @Override -// protected void handleCompleted() { -// // If un-installing breakpoints fails, log the error but continue shutting down. -// if (!isSuccess) { -// DsfGdbPlugin.getDefault().getLog().log(getStatus()); -// } -// requestMonitor.done(); -// } -// }); -// } else { -// requestMonitor.setStatus(new Status(IStatus.ERROR, DsfGdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, -// "Needed services not found.", null)); //$NON-NLS-1$ -// requestMonitor.done(); -// } -// } }, new Step() { @Override public void execute(RequestMonitor requestMonitor) { From bf9f5fbabd84bca349c0636064bef3ae7b0bbd9b Mon Sep 17 00:00:00 2001 From: Francois Chouinard Date: Thu, 24 Apr 2008 17:40:22 +0000 Subject: [PATCH 404/834] Fix for Bug228706 --- .../dd/dsf/debug/model/DsfMemoryBlockRetrieval.java | 11 ++++++----- .../src/org/eclipse/dd/mi/service/MIBreakpoints.java | 1 - .../eclipse/dd/mi/service/MIBreakpointsManager.java | 9 +++------ .../breakpoint/actions/MILogActionEnabler.java | 2 -- .../breakpoint/actions/MIResumeActionEnabler.java | 3 --- 5 files changed, 9 insertions(+), 17 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java index b0cdc7c0ac2..87d2a8aa9ce 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java @@ -102,9 +102,9 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl // DSF stuff fModelId = modelId; - // FIXME: Currently memory contexts are differentiated by sessionID - // so there is no way to guarantee the memory blocks will be reinstated - // in the correct memory space. + // FIXME: (Bug228573) Currently memory contexts are differentiated by + // sessionID so there is no way to guarantee the memory blocks will be + // reinstated in the correct memory space. // Need a way to create deterministically the context ID from a unique // target, ideally from the launch configuration (or derived from it). // For the time being, just put some constant. This will work until we @@ -240,7 +240,7 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl } // Process the block list specific to this memory context - // FIXME: We only process the first entry... + // FIXME: (Bug228573) We only process the first entry... if (root.getAttribute(ATTR_EXPRESSION_LIST_CONTEXT).equals(fContextString)) { List blocks = new ArrayList(); NodeList expressionList = root.getChildNodes(); @@ -262,7 +262,8 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl } } - // FIXME: Each retrieval overwrites the previous one :-( + // FIXME: (Bug228573) Each retrieval overwrites the previous one :-( + // In theory, we should make this a Job since we are writing to the file system. // However, this would cause the same racing condition as Bug228308. Finally, we // don't care too much about the UI responsiveness since we are in the process of diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpoints.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpoints.java index 5b456c20950..0303374c2c6 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpoints.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpoints.java @@ -272,7 +272,6 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints @DsfServiceEventHandler public void eventDispatched(MIGDBExitEvent e) { - // TODO: Remove the installed breakpoints from the back-end } /////////////////////////////////////////////////////////////////////////// diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointsManager.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointsManager.java index a13de5f8fce..3e24bebb8f5 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointsManager.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointsManager.java @@ -1186,7 +1186,7 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo // Identify the platform breakpoint final ICBreakpoint breakpoint = findPlatformBreakpoint(number); - // FIXME: Temporary hack to have a context + // FIXME: (Bug228703) Temporary hack to have a context Object[] contexts = fTargetBPs.keySet().toArray(); final IBreakpointsTargetDMContext context = (IBreakpointsTargetDMContext) contexts[0]; @@ -1195,7 +1195,6 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo { setSystem(true); } @Override protected IStatus run(IProgressMonitor monitor) { - // FIXME: Rename MyAdaptableType to something more relevant fBreakpointActionManager.executeActions(breakpoint, new BreakpointActionAdapter(getExecutor(), getServicesTracker(), context)); return Status.OK_STATUS; }; @@ -1204,10 +1203,8 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo // Helper function to locate the platform breakpoint corresponding // to the target breakpoint/watchpoint that was just hit - // FIXME: Need a way to identify the correct context where the BP was hit - // because it impacts the action (expression evaluation and resume delay). - // This means that the Breakpoint/WatchpointHitEvent will need to - // provide some extra info... + + // FIXME: (Bug228703) Need a way to identify the correct context where the BP was hit private ICBreakpoint findPlatformBreakpoint(int targetBreakpointID) { Set targets = fTargetBPs.keySet(); for (IBreakpointsTargetDMContext target : targets) { diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/breakpoint/actions/MILogActionEnabler.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/breakpoint/actions/MILogActionEnabler.java index fc96c6a26c1..22c6bc3efc7 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/breakpoint/actions/MILogActionEnabler.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/breakpoint/actions/MILogActionEnabler.java @@ -35,8 +35,6 @@ public class MILogActionEnabler implements ILogActionEnabler { public MILogActionEnabler(DsfExecutor executor, DsfServicesTracker serviceTracker, IDMContext context) { fExecutor = executor; fServiceTracker = serviceTracker; - // FIXME: Although it looks optimistic, we know it works - // How can we guarantee that it always will? fContext = (IBreakpointsTargetDMContext) context; } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/breakpoint/actions/MIResumeActionEnabler.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/breakpoint/actions/MIResumeActionEnabler.java index 1334f9e167f..4d84799c7b5 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/breakpoint/actions/MIResumeActionEnabler.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/breakpoint/actions/MIResumeActionEnabler.java @@ -21,7 +21,6 @@ import org.eclipse.dd.dsf.service.DsfServicesTracker; public class MIResumeActionEnabler implements IResumeActionEnabler { - @SuppressWarnings("unused") private final DsfExecutor fExecutor; private final DsfServicesTracker fServiceTracker; private final IExecutionDMContext fContext; @@ -29,8 +28,6 @@ public class MIResumeActionEnabler implements IResumeActionEnabler { public MIResumeActionEnabler(DsfExecutor executor, DsfServicesTracker serviceTracker, IDMContext context) { fExecutor = executor; fServiceTracker = serviceTracker; - // FIXME: Although it looks optimistic, we know it works - // How can we guarantee that it always will? fContext = (IExecutionDMContext) context; } From 41f3028662a5b126de159a8dde4093c2d212b029 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Fri, 25 Apr 2008 15:20:13 +0000 Subject: [PATCH 405/834] Bug 228265 Update GdbLaunchDelegate to no longer require anything from org.eclipse.cdt.launch. Also triggers a build when necessary before launching, as the CDT does. Also introduces a LaunchMessages class which uses a resourceBundle for launch messages that has been added as org.eclipse.dd.gdb.internal.provisional.launching.LaunchMessages --- .../org.eclipse.dd.gdb/META-INF/MANIFEST.MF | 3 +- .../launching/GdbLaunchDelegate.java | 385 +++++++++++++----- .../provisional/launching/LaunchMessages.java | 46 +++ .../launching/LaunchMessages.properties | 159 ++++++++ 4 files changed, 479 insertions(+), 114 deletions(-) create mode 100644 plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/LaunchMessages.java create mode 100644 plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/LaunchMessages.properties diff --git a/plugins/org.eclipse.dd.gdb/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.gdb/META-INF/MANIFEST.MF index a1b50984b49..3862e66e04f 100644 --- a/plugins/org.eclipse.dd.gdb/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.gdb/META-INF/MANIFEST.MF @@ -12,8 +12,7 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.debug.core, org.eclipse.cdt.core, org.eclipse.cdt.debug.core, - org.eclipse.cdt.debug.mi.core, - org.eclipse.cdt.launch + org.eclipse.cdt.debug.mi.core Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: J2SE-1.5 Export-Package: org.eclipse.dd.gdb.internal.provisional, diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java index cc56582f33f..70894c74c5a 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java @@ -1,31 +1,41 @@ /******************************************************************************* - * Copyright (c) 2004, 2006 QNX Software Systems and others. + * Copyright (c) 2008 QNX Software 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: - * QNX Software Systems - Initial API and implementation + * QNX Software Systems - Initial API and implementation + * Windriver and Ericsson - Updated for DSF *******************************************************************************/ package org.eclipse.dd.gdb.internal.provisional.launching; -import java.io.File; +import java.io.FileNotFoundException; import java.io.IOException; +import java.util.ArrayList; +import java.util.HashSet; import java.util.concurrent.ExecutionException; +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.IBinaryParser; +import org.eclipse.cdt.core.ICExtensionReference; +import org.eclipse.cdt.core.IBinaryParser.IBinaryObject; +import org.eclipse.cdt.core.model.ICModelMarker; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; -import org.eclipse.cdt.launch.AbstractCLaunchDelegate; -import org.eclipse.cdt.launch.internal.ui.LaunchMessages; -import org.eclipse.cdt.launch.internal.ui.LaunchUIPlugin; -import org.eclipse.cdt.utils.pty.PTY; -import org.eclipse.cdt.utils.spawner.ProcessFactory; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.gdb.internal.GdbPlugin; @@ -40,22 +50,19 @@ import org.eclipse.debug.core.IStatusHandler; import org.eclipse.debug.core.model.ILaunchConfigurationDelegate2; import org.eclipse.debug.core.model.IPersistableSourceLocator; import org.eclipse.debug.core.model.ISourceLocator; +import org.eclipse.debug.core.model.LaunchConfigurationDelegate; import org.eclipse.debug.core.sourcelookup.IPersistableSourceLocator2; /** - * The launch configuration delegate for the CDI debugger session types. + * The shared launch configuration delegate for the DSF/GDB debugger. + * This delegate supports all configuration types (local, remote, attach, etc) */ @ThreadSafe -public class GdbLaunchDelegate extends AbstractCLaunchDelegate +public class GdbLaunchDelegate extends LaunchConfigurationDelegate implements ILaunchConfigurationDelegate2 { public final static String GDB_DEBUG_MODEL_ID = "org.eclipse.dd.gdb"; //$NON-NLS-1$ - private SessionType fSessionType; - /* (non-Javadoc) - * @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#launch(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.debug.core.ILaunch, org.eclipse.core.runtime.IProgressMonitor) - */ - @Override public void launch( ILaunchConfiguration config, String mode, ILaunch launch, IProgressMonitor monitor ) throws CoreException { if ( monitor == null ) { monitor = new NullProgressMonitor(); @@ -70,21 +77,9 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate if ( monitor.isCanceled() ) { return; } - try { - String debugMode = config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN ); - if (debugMode.equals(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN)) { - fSessionType = SessionType.RUN; - } else if (debugMode.equals(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_ATTACH)) { - fSessionType = SessionType.ATTACH; - } else if (debugMode.equals(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_CORE)) { - fSessionType = SessionType.CORE; - } else if (debugMode.equals(IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE)) { - fSessionType = SessionType.REMOTE; - } else { - fSessionType = SessionType.RUN; - } - launchDebugSession( config, launch, monitor ); + try { + launchDebugSession( config, launch, monitor ); } finally { monitor.done(); @@ -95,9 +90,11 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate if ( monitor.isCanceled() ) { return; } + + SessionType sessionType = getSessionType(config); final GdbLaunch launch = (GdbLaunch)l; - if (fSessionType == SessionType.REMOTE) { + if (sessionType == SessionType.REMOTE) { monitor.subTask( "Debugging remote C/C++ application" ); //$NON-NLS-1$ } else { monitor.subTask( "Debugging local C/C++ application" ); //$NON-NLS-1$ @@ -114,7 +111,7 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate // If we are attaching, get the process id now, so as to avoid starting the launch // and canceling it if the user does not put the pid properly. int pid = -1; - if (fSessionType == SessionType.ATTACH) { + if (sessionType == SessionType.ATTACH) { try { // have we already been given the pid (maybe from a JUnit test launch or something) pid = config.getAttribute(ICDTLaunchConfigurationConstants.ATTR_ATTACH_PROCESS_ID, -1); @@ -130,8 +127,6 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate LaunchMessages.getString("LocalAttachLaunchDelegate.No_Process_ID_selected"))); //$NON-NLS-1$ } } - - setDefaultSourceLocator(launch, config); // Create and invoke the launch sequence to create the debug control and services final ServicesLaunchSequence servicesLaunchSequence = @@ -156,10 +151,10 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate // Create and invoke the final launch sequence to setup GDB final FinalLaunchSequence finalLaunchSequence; - if (fSessionType == SessionType.ATTACH) { + if (sessionType == SessionType.ATTACH) { finalLaunchSequence = new FinalLaunchSequence(launch.getSession().getExecutor(), launch, pid); } else { - finalLaunchSequence = new FinalLaunchSequence(launch.getSession().getExecutor(), launch, fSessionType); + finalLaunchSequence = new FinalLaunchSequence(launch.getSession().getExecutor(), launch, sessionType); } launch.getSession().getExecutor().execute(finalLaunchSequence); try { @@ -171,6 +166,23 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate } } + private SessionType getSessionType(ILaunchConfiguration config) { + try { + String debugMode = config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN ); + if (debugMode.equals(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN)) { + return SessionType.RUN; + } else if (debugMode.equals(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_ATTACH)) { + return SessionType.ATTACH; + } else if (debugMode.equals(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_CORE)) { + return SessionType.CORE; + } else if (debugMode.equals(IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE)) { + return SessionType.REMOTE; + } + } catch (CoreException e) { + } + return SessionType.RUN; + } + // Copied from the CDT protected int promptForProcessID(ILaunchConfiguration config) throws CoreException { IStatus fPromptStatus = new Status(IStatus.INFO, "org.eclipse.debug.ui", 200, "", null); //$NON-NLS-1$//$NON-NLS-2$ @@ -186,92 +198,17 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate return -1; } - - /* (non-Javadoc) - * @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#getPluginID() - */ - @Override - protected String getPluginID() { - return LaunchUIPlugin.getUniqueIdentifier(); - } - - /** - * Performs a runtime exec on the given command line in the context of the - * specified working directory, and returns the resulting process. If the - * current runtime does not support the specification of a working - * directory, the status handler for error code - * ERR_WORKING_DIRECTORY_NOT_SUPPORTED is queried to see if - * the exec should be re-executed without specifying a working directory. - * - * @param cmdLine - * the command line - * @param workingDirectory - * the working directory, or null - * @return the resulting process or null if the exec is - * cancelled - * @see Runtime - */ - protected Process exec( String[] cmdLine, String[] environ, File workingDirectory, boolean usePty ) throws CoreException { - Process p = null; - try { - if ( workingDirectory == null ) { - p = ProcessFactory.getFactory().exec( cmdLine, environ ); - } - else { - if ( usePty && PTY.isSupported() ) { - p = ProcessFactory.getFactory().exec( cmdLine, environ, workingDirectory, new PTY() ); - } - else { - p = ProcessFactory.getFactory().exec( cmdLine, environ, workingDirectory ); - } - } - } - catch( IOException e ) { - if ( p != null ) { - p.destroy(); - } - abort( "Error starting process.", e, ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR ); //$NON-NLS-1$ - } - catch( NoSuchMethodError e ) { - // attempting launches on 1.2.* - no ability to set working - // directory - IStatus status = new Status( IStatus.ERROR, LaunchUIPlugin.getUniqueIdentifier(), ICDTLaunchConfigurationConstants.ERR_WORKING_DIRECTORY_NOT_SUPPORTED, LaunchMessages.getString( "LocalDsfLaunchDelegate.9" ), e ); //$NON-NLS-1$ - IStatusHandler handler = DebugPlugin.getDefault().getStatusHandler( status ); - if ( handler != null ) { - Object result = handler.handleStatus( status, this ); - if ( result instanceof Boolean && ((Boolean)result).booleanValue() ) { - p = exec( cmdLine, environ, null, usePty ); - } - } - } - return p; - } - /* (non-Javadoc) * @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#preLaunchCheck(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.core.runtime.IProgressMonitor) */ @Override public boolean preLaunchCheck( ILaunchConfiguration config, String mode, IProgressMonitor monitor ) throws CoreException { // no pre launch check for core file - if ( mode.equals( ILaunchManager.DEBUG_MODE ) ) { - if ( ICDTLaunchConfigurationConstants.DEBUGGER_MODE_CORE.equals( config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN ) ) ) - return true; - } + if (mode.equals(ILaunchManager.DEBUG_MODE) && getSessionType(config) == SessionType.CORE) return true; + return super.preLaunchCheck( config, mode, monitor ); } - /////////////////////////////////////////////////////////////////////////// - // ILaunchConfigurationDelegate2 - @Override - public boolean buildForLaunch(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException { - return false; - } - - @Override - public boolean finalLaunchCheck(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException { - return true; - } - @Override public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) throws CoreException { // Need to configure the source locator before creating the launch @@ -303,4 +240,228 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate } return null; } + + /** + * Throws a core exception with an error status object built from the given + * message, lower level exception, and error code. + * + * @param message + * the status message + * @param exception + * lower level exception associated with the error, or + * null if none + * @param code + * error code + */ + protected void abort(String message, Throwable exception, int code) throws CoreException { + MultiStatus status = new MultiStatus(GdbPlugin.PLUGIN_ID, code, message, exception); + status.add(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, code, exception == null ? "" : exception.getLocalizedMessage(), //$NON-NLS-1$ + exception)); + throw new CoreException(status); + } + + public static ICProject getCProject(ILaunchConfiguration configuration) throws CoreException { + String projectName = getProjectName(configuration); + if (projectName != null) { + projectName = projectName.trim(); + if (projectName.length() > 0) { + IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); + ICProject cProject = CCorePlugin.getDefault().getCoreModel().create(project); + if (cProject != null && cProject.exists()) { + return cProject; + } + } + } + return null; + } + + public static String getProjectName(ILaunchConfiguration configuration) throws CoreException { + return configuration.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME, (String)null); + } + + public static String getProgramName(ILaunchConfiguration configuration) throws CoreException { + return configuration.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, (String)null); + } + + public static IPath getProgramPath(ILaunchConfiguration configuration) throws CoreException { + String path = getProgramName(configuration); + if (path == null) { + return null; + } + return new Path(path); + } + + protected ICProject verifyCProject(ILaunchConfiguration config) throws CoreException { + String name = getProjectName(config); + if (name == null) { + abort(LaunchMessages.getString("AbstractCLaunchDelegate.C_Project_not_specified"), null, //$NON-NLS-1$ + ICDTLaunchConfigurationConstants.ERR_UNSPECIFIED_PROJECT); + } + ICProject cproject = getCProject(config); + if (cproject == null) { + IProject proj = ResourcesPlugin.getWorkspace().getRoot().getProject(name); + if (!proj.exists()) { + abort( + LaunchMessages.getFormattedString("AbstractCLaunchDelegate.Project_NAME_does_not_exist", name), null, //$NON-NLS-1$ + ICDTLaunchConfigurationConstants.ERR_NOT_A_C_PROJECT); + } else if (!proj.isOpen()) { + abort(LaunchMessages.getFormattedString("AbstractCLaunchDelegate.Project_NAME_is_closed", name), null, //$NON-NLS-1$ + ICDTLaunchConfigurationConstants.ERR_NOT_A_C_PROJECT); + } + abort(LaunchMessages.getString("AbstractCLaunchDelegate.Not_a_C_CPP_project"), null, //$NON-NLS-1$ + ICDTLaunchConfigurationConstants.ERR_NOT_A_C_PROJECT); + } + return cproject; + } + + protected IPath verifyProgramPath(ILaunchConfiguration config) throws CoreException { + ICProject cproject = verifyCProject(config); + IPath programPath = getProgramPath(config); + if (programPath == null || programPath.isEmpty()) { + return null; + } + if (!programPath.isAbsolute()) { + IFile wsProgramPath = cproject.getProject().getFile(programPath); + programPath = wsProgramPath.getLocation(); + } + if (!programPath.toFile().exists()) { + abort( + LaunchMessages.getString("AbstractCLaunchDelegate.Program_file_does_not_exist"), //$NON-NLS-1$ + new FileNotFoundException( + LaunchMessages.getFormattedString( + "AbstractCLaunchDelegate.PROGRAM_PATH_not_found", programPath.toOSString())), //$NON-NLS-1$ + ICDTLaunchConfigurationConstants.ERR_PROGRAM_NOT_EXIST); + } + return programPath; + } + + /** + * @param project + * @param exePath + * @return + * @throws CoreException + */ + protected IBinaryObject verifyBinary(ICProject proj, IPath exePath) throws CoreException { + ICExtensionReference[] parserRef = CCorePlugin.getDefault().getBinaryParserExtensions(proj.getProject()); + for (int i = 0; i < parserRef.length; i++) { + try { + IBinaryParser parser = (IBinaryParser)parserRef[i].createExtension(); + IBinaryObject exe = (IBinaryObject)parser.getBinary(exePath); + if (exe != null) { + return exe; + } + } catch (ClassCastException e) { + } catch (IOException e) { + } + } + IBinaryParser parser = CCorePlugin.getDefault().getDefaultBinaryParser(); + try { + return (IBinaryObject)parser.getBinary(exePath); + } catch (ClassCastException e) { + } catch (IOException e) { + } + Throwable exception = new FileNotFoundException(LaunchMessages.getFormattedString( + "AbstractCLaunchDelegate.Program_is_not_a_recongnized_executable", exePath.toOSString())); //$NON-NLS-1$ + int code = ICDTLaunchConfigurationConstants.ERR_PROGRAM_NOT_BINARY; + MultiStatus status = new MultiStatus(GdbPlugin.PLUGIN_ID, code, + LaunchMessages.getString("AbstractCLaunchDelegate.Program_is_not_a_recongnized_executable"), exception); //$NON-NLS-1$ + status.add(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, code, exception == null ? "" : exception.getLocalizedMessage(), //$NON-NLS-1$ + exception)); + throw new CoreException(status); + } + + /** + * Recursively creates a set of projects referenced by the current project + * + * @param proj + * The current project + * @param referencedProjSet + * A set of referenced projects + * @throws CoreException + * if an error occurs while getting referenced projects from the + * current project + */ + private HashSet getReferencedProjectSet(IProject proj, HashSet referencedProjSet) throws CoreException { + // The top project is a reference too and it must be added at the top to avoid cycles + referencedProjSet.add(proj); + + IProject[] projects = proj.getReferencedProjects(); + for (IProject refProject : projects) { + if (refProject.exists() && !referencedProjSet.contains(refProject)) { + getReferencedProjectSet(refProject, referencedProjSet); + } + } + return referencedProjSet; + } + + /** + * Returns the order list of projects to build before launching. + * Used in buildForLaunch() + */ + @Override + protected IProject[] getBuildOrder(ILaunchConfiguration configuration, String mode) throws CoreException { + IProject[] orderedProjects = null; + ArrayList orderedProjList = null; + + ICProject cProject = getCProject(configuration); + if (cProject != null) { + HashSet projectSet = getReferencedProjectSet(cProject.getProject(), new HashSet()); + + String[] orderedNames = ResourcesPlugin.getWorkspace().getDescription().getBuildOrder(); + if (orderedNames != null) { + //Projects may not be in the build order but should still be built if selected + ArrayList unorderedProjects = new ArrayList(projectSet.size()); + unorderedProjects.addAll(projectSet); + orderedProjList = new ArrayList(projectSet.size()); + + for (String projectName : orderedNames) { + for (IProject proj : unorderedProjects) { + if (proj.getName().equals(projectName)) { + orderedProjList.add(proj); + unorderedProjects.remove(proj); + break; + } + } + } + + // Add any remaining projects to the end of the list + orderedProjList.addAll(unorderedProjects); + + orderedProjects = orderedProjList.toArray(new IProject[orderedProjList.size()]); + } else { + // Try the project prerequisite order then + IProject[] projects = projectSet.toArray(new IProject[projectSet.size()]); + orderedProjects = ResourcesPlugin.getWorkspace().computeProjectOrder(projects).projects; + } + } + return orderedProjects; + } + + /* Used in finalLaunchCheck() */ + @Override + protected IProject[] getProjectsForProblemSearch(ILaunchConfiguration configuration, String mode) throws CoreException { + return getBuildOrder(configuration, mode); + } + + /** + * Searches for compile errors in the specified project + * Used in finalLaunchCheck() + * @param proj + * The project to search + * @return true if compile errors exist, otherwise false + */ + + @Override + protected boolean existsProblems(IProject proj) throws CoreException { + IMarker[] markers = proj.findMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE); + if (markers.length > 0) { + for (IMarker marker : markers) { + Integer severity = (Integer)marker.getAttribute(IMarker.SEVERITY); + if (severity != null) { + return severity.intValue() >= IMarker.SEVERITY_ERROR; + } + } + } + return false; + } } diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/LaunchMessages.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/LaunchMessages.java new file mode 100644 index 00000000000..20aa9814a57 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/LaunchMessages.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2008 QNX Software 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: + * QNX Software Systems - initial API and implementation + * Ericsson - Update for DSF + *******************************************************************************/ +package org.eclipse.dd.gdb.internal.provisional.launching; + +import java.text.MessageFormat; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +public class LaunchMessages { + + private static final String BUNDLE_NAME = "org.eclipse.dd.gdb.internal.provisional.launching.LaunchMessages";//$NON-NLS-1$ + + private static ResourceBundle RESOURCE_BUNDLE = null; + + static { + try { + RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME); + } + catch (MissingResourceException x) { + } + } + + private LaunchMessages() {} + + public static String getFormattedString(String key, String arg) { + return MessageFormat.format(getString(key), (Object[])new String[]{arg}); + } + + public static String getFormattedString(String key, String[] args) { + return MessageFormat.format(getString(key), (Object[])args); + } + + public static String getString(String key) { + if (RESOURCE_BUNDLE == null) return '!' + key + '!'; + return RESOURCE_BUNDLE.getString(key); + } +} diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/LaunchMessages.properties b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/LaunchMessages.properties new file mode 100644 index 00000000000..ad12c5f5d98 --- /dev/null +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/LaunchMessages.properties @@ -0,0 +1,159 @@ +############################################################################### +# Copyright (c) 2008 QNX Software 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: +# QNX Software Systems - Initial API and implementation +# Monta Vista - Joanne Woo - Bug 87556 +# Nokia - Ken Ryall - Bug 118894 +############################################################################### + +AbstractCLaunchDelegate.Debugger_not_installed=CDT Debugger not installed +AbstractCLaunchDelegate.C_Project_not_specified=C Project not specified +AbstractCLaunchDelegate.Not_a_C_CPP_project=Project is not a C/C++ project +AbstractCLaunchDelegate.Program_file_not_specified=Program file not specified +AbstractCLaunchDelegate.Program_file_does_not_exist=Program file does not exist +AbstractCLaunchDelegate.PROGRAM_PATH_not_found={0} not found +AbstractCLaunchDelegate.Working_directory_does_not_exist=Working directory does not exist +AbstractCLaunchDelegate.WORKINGDIRECTORY_PATH_not_found=The working directory {0} does not exist. +AbstractCLaunchDelegate.Project_NAME_does_not_exist=Project {0} does not exist +AbstractCLaunchDelegate.Project_NAME_is_closed=Project {0} is closed +AbstractCLaunchDelegate.Debugger_Process=Debugger Process +AbstractCLaunchDelegate.building_projects=Building prerequisite project list +AbstractCLaunchDelegate.building=Building +AbstractCLaunchDelegate.searching_for_errors=Searching for compile errors +AbstractCLaunchDelegate.searching_for_errors_in=Searching for compile errors in +AbstractCLaunchDelegate.20=Building prerequisite project list +AbstractCLaunchDelegate.Program_is_not_a_recongnized_executable=Program is not a recognized executable. + +LocalRunLaunchDelegate.Launching_Local_C_Application=Launching Local C/C++ Application +LocalRunLaunchDelegate.Failed_setting_runtime_option_though_debugger=Failed to set program arguments, environment or working directory. +LocalRunLaunchDelegate.Error_starting_process=Error starting process +LocalRunLaunchDelegate.Does_not_support_working_dir=Eclipse runtime does not support working directory + +LocalAttachLaunchDelegate.Attaching_to_Local_C_Application=Attaching to Local C/C++ Application +LocalAttachLaunchDelegate.No_Process_ID_selected=No Process ID selected +LocalAttachLaunchDelegate.Select_Process=Select Process +LocalAttachLaunchDelegate.Platform_cannot_list_processes=Current platform does not support listing processes +LocalAttachLaunchDelegate.Select_Process_to_attach_debugger_to=Select a Process to attach debugger to: +LocalAttachLaunchDelegate.CDT_Launch_Error=CDT Launch Error + +CoreFileLaunchDelegate.Launching_postmortem_debugger=Launching postmortem debugger +CoreFileLaunchDelegate.No_Corefile_selected=No Corefile selected +CoreFileLaunchDelegate.No_Shell_available_in_Launch=No Shell available in Launch +CoreFileLaunchDelegate.Select_Corefile=Select Corefile +CoreFileLaunchDelegate.Corefile_not_accessible=Core file is not accessible. +CoreFileLaunchDelegate.Corefile_not_readable=Core file does not exist or is not readable. +CoreFileLaunchDelegate.postmortem_debugging_failed=Post-mortem debugging failed + +CApplicationLaunchShortcut.Application_Launcher=Application Launcher +CApplicationLaunchShortcut.ChooseConfigToDebug=Choose a debug configuration to debug +CApplicationLaunchShortcut.ChooseConfigToRun=Choose a configuration to run +CApplicationLaunchShortcut.CLocalApplication=C Local Application +CApplicationLaunchShortcut.ChooseLocalAppToDebug=Choose a local application to debug +CApplicationLaunchShortcut.ChooseLocalAppToRun=Choose a local application to run +CApplicationLaunchShortcut.Launch_failed_no_binaries=Launch failed no binaries +CApplicationLaunchShortcut.LaunchFailed=Launch failed +CApplicationLaunchShortcut.LaunchDebugConfigSelection=Launch Debug Configuration Selection +CApplicationLaunchShortcut.LaunchConfigSelection=Launch Configuration Selection +CApplicationLaunchShortcut.Invalid_launch_mode_1=Invalid launch mode +CApplicationLaunchShortcut.Invalid_launch_mode_2=Invalid launch mode. +CApplicationLaunchShortcut.Invalid_launch_mode_3=Invalid launch mode. +CApplicationLaunchShortcut.ChooseLaunchConfigToDebug=Choose a launch configuration to debug +CApplicationLaunchShortcut.ChooseLaunchConfigToRun=Choose a launch configuration to run +CApplicationLaunchShortcut.Launch_failed_no_project_selected=Launch failed no project selected + +AbstractCDebuggerTab.No_debugger_available=No debugger available +AbstractCDebuggerTab.Debugger=Debugger +AbstractCDebuggerTab.ErrorLoadingDebuggerPage=Error Loading Debugger UI Component. + +LaunchUIPlugin.Error=Error + +CMainTab.Project_required=Project required +CMainTab.Enter_project_before_searching_for_program=Project must first be entered before searching for a program +CMainTab.Program_Selection=Program Selection +CMainTab.Enter_project_before_browsing_for_program=Project must first be entered before browsing for a program +CMainTab.Program_selection=Program selection +CMainTab.Selection_must_be_file=Selection must be a file +CMainTab.Selection_must_be_binary_file=Selection must be a binary file +CMainTab.Project_Selection=Project Selection +CMainTab.Choose_project_to_constrain_search_for_program=Choose a &project to constrain the search for a program +CMainTab.Project_not_specified=Project not specified +CMainTab.Program_not_specified=Program not specified +CMainTab.Project_must_be_opened=Project must be opened +CMainTab.Program_does_not_exist=Program does not exist +CMainTab.Main=Main +CMainTab.&ProjectColon=&Project: +CMainTab.C/C++_Application=C/C++ Application: +CMainTab.Search...=Searc&h Project... +CMainTab.Choose_program_to_run=Choose a &program to run: +CMainTab.Choose_program_to_run_from_NAME=Choose a program to run from {0}: +CMainTab.UseTerminal=Connect process input & output to a terminal. +CMainTab.Program_is_not_a_recongnized_executable=Program is not a recognized executable. + +CDebuggerTab.Advanced_Options_Dialog_Title=Advanced Options +CDebuggerTab.Stop_at_main_on_startup=Stop on startup at: +CDebuggerTab.Automatically_track_values_of=Automatically track the values of +CDebuggerTab.Stop_on_startup_at_can_not_be_empty=The "Stop on startup at" field can not be empty. +CDebuggerTab.Debugger_Options=Debugger Options +CDebuggerTab.Mode_not_supported=Mode ''{0}'' is not supported by selected debugger +CDebuggerTab.Advanced=Advanced... +CDebuggerTab.Variables=Variables +CDebuggerTab.Registers=Registers +CDebuggerTab.No_debugger_available=No debugger available +CDebuggerTab.CPU_is_not_supported=The CPU is not supported by selected debugger. +CDebuggerTab.Platform_is_not_supported=The project platform is not supported by the selected debugger. + +CoreFileDebuggerTab.No_debugger_available=No debugger available +CoreFileDebuggerTab.platform_is_not_supported=The project platform is not supported by the selected debugger. + +CEnvironmentTab.Edit_Variable=Edit Variable +CEnvironmentTab.New_Variable=New Variable +CEnvironmentTab.NameColon=Name: +CEnvironmentTab.ValueColon=Value: +CEnvironmentTab.Name=Name +CEnvironmentTab.Value=Value +CEnvironmentTab.New...=New... +CEnvironmentTab.Import...=Import... +CEnvironmentTab.Edit...=Edit... +CEnvironmentTab.Remove=Remove +CEnvironmentTab.Environment=Environment +CEnvironmentTab.Existing_Environment_Variable=Existing Environment Variable +CEnvironmentTab.Environment_variable_NAME_exists=Environment variable \" {0} \" exists.\nDo you want to overwrite? + +CArgumentsTab.C/C++_Program_Arguments=Program arguments: +CArgumentsTab.Arguments=Arguments +CArgumentsTab.Variables=Variables... + +WorkingDirectoryBlock.4=Select a &workspace relative working directory: +WorkingDirectoryBlock.7=Select a working directory for the launch configuration: +WorkingDirectoryBlock.0=W&orkspace... +WorkingDirectoryBlock.Working_Directory_8=Working Directory +WorkingDirectoryBlock.Working_directory=Working directory: +WorkingDirectoryBlock.10=Working directory does not exist +WorkingDirectoryBlock.Use_default=Use de&fault +WorkingDirectoryBlock.17=Variabl&es... +WorkingDirectoryBlock.1=File S&ystem... +WorkingDirectoryBlock.Exception_occurred_reading_configuration___15=Exception occurred reading configuration: + +Launch.common.Exception_occurred_reading_configuration_EXCEPTION=Exception occurred reading configuration {0} +Launch.common.DebuggerColon=Debugger: +Launch.common.BinariesColon=Binaries: +Launch.common.QualifierColon=Qualifier: +Launch.common.Browse_1=&Browse... +Launch.common.Browse_2=B&rowse... +Launch.common.Project_does_not_exist=Project does not exist +LocalCDILaunchDelegate.0=Launching Local C/C++ Application +LocalCDILaunchDelegate.1=Launching debugger session +LocalCDILaunchDelegate.2=Debugging local C/C++ application +LocalCDILaunchDelegate.3=Attaching to Local C/C++ Application +LocalCDILaunchDelegate.4=No Process ID selected. +LocalCDILaunchDelegate.5=Launching postmortem debugger session +LocalCDILaunchDelegate.6=No core file selected +LocalCDILaunchDelegate.7=Core file does not exist or is not readable. +LocalCDILaunchDelegate.8=Error starting process. +LocalCDILaunchDelegate.9=Eclipse runtime does not support working directory. +LocalCDILaunchDelegate.10=Failed to set program arguments, environment or working directory. From b3bd94ab7037bad1dea71feca77903670aa22448 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Fri, 25 Apr 2008 16:48:31 +0000 Subject: [PATCH 406/834] Bug 228265 Removed dependencies to org.eclipse.cdt.launch from org.eclipse.dd.gdb.tests Also cleanup of launch of JUnit tests. --- .../META-INF/MANIFEST.MF | 1 - .../gdb/launching/TestLaunchDelegate.java | 164 ++---------------- 2 files changed, 10 insertions(+), 155 deletions(-) diff --git a/plugins/org.eclipse.dd.tests.gdb/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.tests.gdb/META-INF/MANIFEST.MF index ab27099db8c..a6bb4590501 100644 --- a/plugins/org.eclipse.dd.tests.gdb/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.tests.gdb/META-INF/MANIFEST.MF @@ -9,7 +9,6 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.dd.dsf, org.eclipse.dd.dsf.debug, org.eclipse.cdt.core, - org.eclipse.cdt.launch, org.eclipse.cdt.debug.core, org.eclipse.dd.mi, org.junit4, diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java index 89c266f6f17..f16ba60c8c4 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java @@ -10,20 +10,11 @@ *******************************************************************************/ package org.eclipse.dd.tests.gdb.launching; -import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; -import java.io.IOException; -import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; -import java.util.concurrent.RejectedExecutionException; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; -import org.eclipse.cdt.launch.AbstractCLaunchDelegate; -import org.eclipse.cdt.launch.internal.ui.LaunchMessages; -import org.eclipse.cdt.launch.internal.ui.LaunchUIPlugin; -import org.eclipse.cdt.utils.pty.PTY; -import org.eclipse.cdt.utils.spawner.ProcessFactory; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; @@ -32,39 +23,26 @@ import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.ThreadSafe; -import org.eclipse.dd.dsf.debug.model.DsfMemoryBlockRetrieval; -import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryDMContext; -import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.gdb.internal.provisional.launching.FinalLaunchSequence; import org.eclipse.dd.gdb.internal.provisional.launching.GdbLaunch; import org.eclipse.dd.gdb.internal.provisional.launching.ServicesLaunchSequence; -import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl; import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl.SessionType; import org.eclipse.debug.core.DebugException; -import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchManager; -import org.eclipse.debug.core.IStatusHandler; import org.eclipse.debug.core.model.ILaunchConfigurationDelegate2; -import org.eclipse.debug.core.model.IMemoryBlockRetrieval; -import org.eclipse.debug.core.model.IPersistableSourceLocator; -import org.eclipse.debug.core.model.ISourceLocator; -import org.eclipse.debug.core.sourcelookup.IPersistableSourceLocator2; +import org.eclipse.debug.core.model.LaunchConfigurationDelegate; /** - * The launch configuration delegate for the CDI debugger session types. + * The launch configuration delegate for the DSF GDB JUnit tests. */ @ThreadSafe -public class TestLaunchDelegate extends AbstractCLaunchDelegate +public class TestLaunchDelegate extends LaunchConfigurationDelegate implements ILaunchConfigurationDelegate2 { public final static String GDB_DEBUG_MODEL_ID = "org.eclipse.dd.tests.gdb"; //$NON-NLS-1$ - - /* (non-Javadoc) - * @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#launch(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.debug.core.ILaunch, org.eclipse.core.runtime.IProgressMonitor) - */ - @Override + public void launch( ILaunchConfiguration config, String mode, ILaunch launch, IProgressMonitor monitor ) throws CoreException { if ( monitor == null ) { monitor = new NullProgressMonitor(); @@ -96,16 +74,12 @@ public class TestLaunchDelegate extends AbstractCLaunchDelegate } final GdbLaunch launch = (GdbLaunch)l; - monitor.subTask("Debugging using GDB/MI reference for DSF"); //$NON-NLS-1$ + monitor.subTask("DSF GDB/MI reference JUnit tests"); //$NON-NLS-1$ IPath exePath = new Path(getProgramName(config)); verifyBinary(exePath); - setDefaultSourceLocator(launch, config); - monitor.worked( 1 ); - // Create and invoke the launch sequence to create the debug control and services - // Create and invoke the launch sequence to create the debug control and services final ServicesLaunchSequence servicesLaunchSequence = new ServicesLaunchSequence(launch.getSession(), launch, exePath); launch.getSession().getExecutor().execute(servicesLaunchSequence); @@ -134,29 +108,6 @@ public class TestLaunchDelegate extends AbstractCLaunchDelegate } catch (ExecutionException e1) { throw new DebugException(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Error in final launch sequence", e1.getCause())); //$NON-NLS-1$ } - // Create a memory retrieval and register it with session - try { - launch.getDsfExecutor().submit( new Callable() { - public Object call() throws CoreException { - DsfServicesTracker tracker = new DsfServicesTracker(TestsPlugin.getBundleContext(), launch.getSession().getId()); - GDBControl gdbControl = tracker.getService(GDBControl.class); - if (gdbControl != null) { - IMemoryBlockRetrieval memRetrieval = new DsfMemoryBlockRetrieval( - GDB_DEBUG_MODEL_ID, config, launch.getSession()); - launch.getSession().registerModelAdapter(IMemoryBlockRetrieval.class, memRetrieval); - ((DsfMemoryBlockRetrieval) memRetrieval).initialize((IMemoryDMContext)gdbControl.getControlDMContext()); - } - tracker.dispose(); - return null; - } - }).get(); - } catch (InterruptedException e) { - throw new CoreException(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, 0, "Interrupted while waiting for get process callable.", e)); //$NON-NLS-1$ - } catch (ExecutionException e) { - throw (CoreException)e.getCause(); - } catch (RejectedExecutionException e) { - throw new CoreException(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, 0, "Debugger shut down before launch was completed.", e)); //$NON-NLS-1$ - } } /* @@ -168,88 +119,16 @@ public class TestLaunchDelegate extends AbstractCLaunchDelegate } catch (Exception e) { Throwable exception = new FileNotFoundException(exePath.toOSString() + " does not exist"); //$NON-NLS-1$ int code = ICDTLaunchConfigurationConstants.ERR_PROGRAM_NOT_BINARY; - throw new CoreException(new Status(IStatus.ERROR, getPluginID(), code, exception == null ? "" : exception.getLocalizedMessage(), //$NON-NLS-1$ + throw new CoreException(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, code, exception == null ? "" : exception.getLocalizedMessage(), //$NON-NLS-1$ exception)); } } - - /* (non-Javadoc) - * @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#getPluginID() - */ - @Override - protected String getPluginID() { - return LaunchUIPlugin.getUniqueIdentifier(); - } - - /** - * Performs a runtime exec on the given command line in the context of the - * specified working directory, and returns the resulting process. If the - * current runtime does not support the specification of a working - * directory, the status handler for error code - * ERR_WORKING_DIRECTORY_NOT_SUPPORTED is queried to see if - * the exec should be re-executed without specifying a working directory. - * - * @param cmdLine - * the command line - * @param workingDirectory - * the working directory, or null - * @return the resulting process or null if the exec is - * cancelled - * @see Runtime - */ - protected Process exec( String[] cmdLine, String[] environ, File workingDirectory, boolean usePty ) throws CoreException { - Process p = null; - try { - if ( workingDirectory == null ) { - p = ProcessFactory.getFactory().exec( cmdLine, environ ); - } - else { - if ( usePty && PTY.isSupported() ) { - p = ProcessFactory.getFactory().exec( cmdLine, environ, workingDirectory, new PTY() ); - } - else { - p = ProcessFactory.getFactory().exec( cmdLine, environ, workingDirectory ); - } - } - } - catch( IOException e ) { - if ( p != null ) { - p.destroy(); - } - abort( "Error starting process.", e, ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR ); //$NON-NLS-1$ - } - catch( NoSuchMethodError e ) { - // attempting launches on 1.2.* - no ability to set working - // directory - IStatus status = new Status( IStatus.ERROR, LaunchUIPlugin.getUniqueIdentifier(), ICDTLaunchConfigurationConstants.ERR_WORKING_DIRECTORY_NOT_SUPPORTED, LaunchMessages.getString( "LocalDsfLaunchDelegate.9" ), e ); //$NON-NLS-1$ - IStatusHandler handler = DebugPlugin.getDefault().getStatusHandler( status ); - if ( handler != null ) { - Object result = handler.handleStatus( status, this ); - if ( result instanceof Boolean && ((Boolean)result).booleanValue() ) { - p = exec( cmdLine, environ, null, usePty ); - } - } - } - return p; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#preLaunchCheck(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.core.runtime.IProgressMonitor) - */ @Override public boolean preLaunchCheck( ILaunchConfiguration config, String mode, IProgressMonitor monitor ) throws CoreException { - // no pre launch check for core file - if ( mode.equals( ILaunchManager.DEBUG_MODE ) ) { - if ( ICDTLaunchConfigurationConstants.DEBUGGER_MODE_CORE.equals( config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN ) ) ) - return true; - } return super.preLaunchCheck( config, mode, monitor ); -// return true; } - /////////////////////////////////////////////////////////////////////////// - // ILaunchConfigurationDelegate2 @Override public boolean buildForLaunch(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException { return false; @@ -262,33 +141,10 @@ public class TestLaunchDelegate extends AbstractCLaunchDelegate @Override public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) throws CoreException { - // Need to configure the source locator before creating the launch - // because once the launch is created and added to launch manager, - // the adapters will be created for the whole session, including - // the source lookup adapter. - ISourceLocator locator = getSourceLocator(configuration); - - return new GdbLaunch(configuration, mode, locator); + return new GdbLaunch(configuration, mode, null); } - - private ISourceLocator getSourceLocator(ILaunchConfiguration configuration) throws CoreException { - String type = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_ID, (String)null); - if (type == null) { - type = configuration.getType().getSourceLocatorId(); - } - if (type != null) { - IPersistableSourceLocator locator = DebugPlugin.getDefault().getLaunchManager().newSourceLocator(type); - String memento = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_MEMENTO, (String)null); - if (memento == null) { - locator.initializeDefaults(configuration); - } else { - if(locator instanceof IPersistableSourceLocator2) - ((IPersistableSourceLocator2)locator).initializeFromMemento(memento, configuration); - else - locator.initializeFromMemento(memento); - } - return locator; - } - return null; + + private static String getProgramName(ILaunchConfiguration configuration) throws CoreException { + return configuration.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, (String)null); } } From 0eb5614e9661876b0e85632d14c8f1b1768a002a Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Fri, 25 Apr 2008 16:53:33 +0000 Subject: [PATCH 407/834] Cleanup of comment --- .../gdb/internal/provisional/launching/GdbLaunchDelegate.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java index 70894c74c5a..546cf6b05ee 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java @@ -198,9 +198,6 @@ public class GdbLaunchDelegate extends LaunchConfigurationDelegate return -1; } - /* (non-Javadoc) - * @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#preLaunchCheck(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.core.runtime.IProgressMonitor) - */ @Override public boolean preLaunchCheck( ILaunchConfiguration config, String mode, IProgressMonitor monitor ) throws CoreException { // no pre launch check for core file From 383e01aec2faaaebdb17bd94e737b07f40055d73 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 25 Apr 2008 16:59:57 +0000 Subject: [PATCH 408/834] [208476] Added queuing of events to the View Model cache. --- .../expression/ExpressionVMProvider.java | 9 ++ .../register/RegisterVMProvider.java | 10 ++ .../variable/VariableVMProvider.java | 9 ++ .../dsf/ui/viewmodel/AbstractVMProvider.java | 116 ++++++++++++++++-- .../DefaultVMModelProxyStrategy.java | 17 +-- .../update/AbstractCachingVMProvider.java | 30 +---- .../ui/viewmodel/launch/LaunchVMProvider.java | 23 ++++ 7 files changed, 161 insertions(+), 53 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/ExpressionVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/ExpressionVMProvider.java index 536b1aeab30..81dbad87923 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/ExpressionVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/ExpressionVMProvider.java @@ -22,6 +22,7 @@ import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.register.SyncR import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.update.BreakpointHitUpdatePolicy; import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.variable.SyncVariableDataAccess; import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.variable.VariableVMNode; +import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; import org.eclipse.dd.dsf.ui.viewmodel.DefaultVMContentProviderStrategy; @@ -326,4 +327,12 @@ public class ExpressionVMProvider extends AbstractDMVMProvider } handleEvent(new ExpressionsChangedEvent(type, rootElements)); } + + @Override + protected boolean canSkipHandlingEvent(Object newEvent, Object eventToSkip) { + // To optimize the performance of the view when stepping rapidly, skip all + // other events when a suspended event is received, including older suspended + // events. + return newEvent instanceof ISuspendedDMEvent; + } } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterVMProvider.java index 06f08e1ed0e..6d63f52debc 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterVMProvider.java @@ -12,6 +12,7 @@ package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.register; import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat.FormattedValuePreferenceStore; import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.update.BreakpointHitUpdatePolicy; +import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; import org.eclipse.dd.dsf.ui.viewmodel.IRootVMNode; @@ -99,4 +100,13 @@ public class RegisterVMProvider extends AbstractDMVMProvider public void propertyChange(PropertyChangeEvent event) { handleEvent(event); } + + @Override + protected boolean canSkipHandlingEvent(Object newEvent, Object eventToSkip) { + // To optimize the performance of the view when stepping rapidly, skip all + // other events when a suspended event is received, including older suspended + // events. + return newEvent instanceof ISuspendedDMEvent; + } + } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/VariableVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/VariableVMProvider.java index 226d543c45a..a80bef9ec58 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/VariableVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/VariableVMProvider.java @@ -10,6 +10,7 @@ package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.variable; import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat.FormattedValuePreferenceStore; import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.update.BreakpointHitUpdatePolicy; +import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; import org.eclipse.dd.dsf.ui.viewmodel.IRootVMNode; @@ -82,4 +83,12 @@ public class VariableVMProvider extends AbstractDMVMProvider return new IVMUpdatePolicy[] { new AutomaticUpdatePolicy(), new ManualUpdatePolicy(), new BreakpointHitUpdatePolicy() }; } + @Override + protected boolean canSkipHandlingEvent(Object newEvent, Object eventToSkip) { + // To optimize the performance of the view when stepping rapidly, skip all + // other events when a suspended event is received, including older suspended + // events. + return newEvent instanceof ISuspendedDMEvent; + } + } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java index c6a14553935..1ff99595544 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java @@ -15,12 +15,14 @@ import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.ListIterator; import java.util.Map; import java.util.concurrent.RejectedExecutionException; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfExecutor; import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.ui.concurrent.DisplayDsfExecutor; import org.eclipse.dd.dsf.ui.concurrent.ViewerDataRequestMonitor; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; @@ -123,6 +125,13 @@ abstract public class AbstractVMProvider implements IVMProvider */ private IRootVMNode fRootNode; + private class ModelProxyEventQueue { + private boolean fProcessingEvent = false; + private List fEventQueue = new LinkedList(); + } + + private Map fEventQueues = new HashMap(); + /** * Constructs the view model provider for given DSF session. The * constructor is thread-safe to allow VM provider to be constructed @@ -198,24 +207,109 @@ abstract public class AbstractVMProvider implements IVMProvider public void handleEvent(final Object event) { for (final IVMModelProxy proxyStrategy : getActiveModelProxies()) { if (proxyStrategy.isDeltaEvent(event)) { - proxyStrategy.createDelta( - event, - new DataRequestMonitor(getExecutor(), null) { - @Override - public void handleCompleted() { - if (isSuccess()) { - proxyStrategy.fireModelChanged(getData()); + if (!fEventQueues.containsKey(proxyStrategy)) { + fEventQueues.put(proxyStrategy, new ModelProxyEventQueue()); + } + final ModelProxyEventQueue queue = fEventQueues.get(proxyStrategy); + if (queue.fProcessingEvent) { + if (!queue.fEventQueue.isEmpty()) { + for (ListIterator itr = queue.fEventQueue.listIterator(queue.fEventQueue.size() - 1); itr.hasPrevious();) { + Object eventToSkip = itr.previous(); + if (canSkipHandlingEvent(event, eventToSkip)) { + itr.remove(); + } else { + break; } } - @Override public String toString() { - return "Result of a delta for event: '" + event.toString() + "' in VMP: '" + this + "'" + "\n" + getData().toString(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - } - }); + } + queue.fEventQueue.add(event); + } else { + doHandleEvent(queue, proxyStrategy, event); + } + } + } + + // Clean up model proxies that were removed. + List activeProxies = getActiveModelProxies(); + for (Iterator itr = fEventQueues.keySet().iterator(); itr.hasNext();) { + if (!activeProxies.contains(itr.next())) { + itr.remove(); } } } + + private void doHandleEvent(final ModelProxyEventQueue queue, final IVMModelProxy proxyStrategy, final Object event) { + queue.fProcessingEvent = true; + handleEvent( + proxyStrategy, event, + new RequestMonitor(getExecutor(), null) { + @Override + protected void handleCompleted() { + queue.fProcessingEvent = false; + if (!queue.fEventQueue.isEmpty()) { + doHandleEvent(queue, proxyStrategy, queue.fEventQueue.remove(0)); + } + } + }); + } + /** + * Handles the given event for the given proxy strategy. + *

              + * This method is called by the base {@link #handleEvent(Object)} + * implementation to handle the given event using the given model proxy. + * The default implementation of this method checks whether the given + * proxy is active and if the proxy is active, it is called to generate the + * delta which is then sent to the viewer. + *

              + * @param proxyStrategy Model proxy strategy to use to process this event. + * @param event Event to process. + * @param rm Request monitor to call when processing the event is + * completed. + */ + protected void handleEvent(final IVMModelProxy proxyStrategy, final Object event, RequestMonitor rm) { + if (!proxyStrategy.isDisposed()) { + proxyStrategy.createDelta( + event, + new DataRequestMonitor(getExecutor(), rm) { + @Override + public void handleCompleted() { + if (isSuccess()) { + proxyStrategy.fireModelChanged(getData()); + } + super.handleCompleted(); + } + @Override public String toString() { + return "Result of a delta for event: '" + event.toString() + "' in VMP: '" + this + "'" + "\n" + getData().toString(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } + }); + } else { + rm.done(); + } + } + /** + * Determines whether processing of a given event can be skipped. This + * method is called when there are multiple events waiting to be processed + * by the provider. As new events are received from the model, they are + * compared with the events in the queue using this method, events at the + * end of the queue are tested for removal. If this method returns that a + * given event can be skipped in favor of the new event, the skipped event + * is removed from the queue. This process is repeated with the new event + * until an event which cannot be stopped is found or the queue goes empty. + *

              + * This method may be overriden by specific view model provider + * implementations extending this abstract class. + *

              + * @param newEvent New event that was received from the model. + * @param eventToSkip Event which is currently at the end of the queue. + * @return True if the event at the end of the queue can be skipped in + * favor of the new event. + */ + protected boolean canSkipHandlingEvent(Object newEvent, Object eventToSkip) { + return false; + } + public IRootVMNode getRootVMNode() { return fRootNode; } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMModelProxyStrategy.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMModelProxyStrategy.java index 9267f413caa..0e3dd13cb16 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMModelProxyStrategy.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMModelProxyStrategy.java @@ -336,8 +336,6 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy { new DataRequestMonitor>(getVMProvider().getExecutor(), null) { @Override protected void handleCompleted() { - if (isDisposed()) return; - // Check for an empty list of elements. If it's empty then we // don't have to call the children nodes, so return here. // No need to propagate error, there's no means or need to display it. @@ -449,13 +447,7 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy { } final MultiRequestMonitor elementsDeltasMultiRequestMon = - new MultiRequestMonitor(getVMProvider().getExecutor(), null) { - @Override - protected void handleCompleted() { - if (isDisposed()) return; - requestMonitor.done(); - } - }; + new MultiRequestMonitor(getVMProvider().getExecutor(), requestMonitor); // For each element from this node, create a new delta, // and then call all the child nodes to build their delta. @@ -508,8 +500,6 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy { new DataRequestMonitor>(getVMProvider().getExecutor(), null) { @Override protected void handleCompleted() { - if (isDisposed()) return; - final CountingRequestMonitor multiRm = new CountingRequestMonitor(getVMProvider().getExecutor(), requestMonitor); int multiRmCount = 0; @@ -562,11 +552,6 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy { final Integer[] counts = new Integer[childNodes.length]; final MultiRequestMonitor childrenCountMultiRequestMon = new MultiRequestMonitor(getVMProvider().getExecutor(), rm) { - @Override - protected void handleCompleted() { - if (isDisposed()) return; - super.handleCompleted(); - } @Override protected void handleSuccess() { Map data = new HashMap(); diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java index fd564c17be6..fc9296d2de6 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java @@ -21,6 +21,7 @@ import java.util.concurrent.Executor; import org.eclipse.core.runtime.IStatus; import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMData; import org.eclipse.dd.dsf.datamodel.IDMService; @@ -555,39 +556,16 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa } @Override - public void handleEvent(final Object event) { + protected void handleEvent(final IVMModelProxy proxyStrategy, final Object event, RequestMonitor rm) { IElementUpdateTester elementTester = getActiveUpdatePolicy().getTesterTester(event); List flushKeys = new LinkedList(); - List proxies = new LinkedList(); - for (final IVMModelProxy proxyStrategy : getActiveModelProxies()) { - if (proxyStrategy.isDeltaEvent(event)) { - flushKeys.add(new FlushMarkerKey(proxyStrategy.getRootElement(), elementTester)); - proxies.add(proxyStrategy); - } - } + flushKeys.add(new FlushMarkerKey(proxyStrategy.getRootElement(), elementTester)); flush(flushKeys); - for (final IVMModelProxy proxyStrategy : proxies) { - if (!proxyStrategy.isDisposed() && proxyStrategy.isDeltaEvent(event)) { - proxyStrategy.createDelta( - event, - new DataRequestMonitor(getExecutor(), null) { - @Override - public void handleCompleted() { - - if (isSuccess()) { - proxyStrategy.fireModelChanged(getData()); - } - } - @Override public String toString() { - return "Result of a delta for event: '" + event.toString() + "' in VMP: '" + this + "'" + "\n" + getData().toString(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - } - }); - } - } + super.handleEvent(proxyStrategy, event, rm); } /** diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/LaunchVMProvider.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/LaunchVMProvider.java index 48f526cd4d0..84e0cd40b09 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/LaunchVMProvider.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/LaunchVMProvider.java @@ -14,10 +14,14 @@ package org.eclipse.dd.gdb.internal.ui.viewmodel.launch; import java.util.concurrent.RejectedExecutionException; import org.eclipse.dd.dsf.concurrent.ThreadSafe; +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.debug.internal.provisional.ui.viewmodel.launch.LaunchRootVMNode; import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch.StackFramesVMNode; import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch.StandardProcessVMNode; import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch.LaunchRootVMNode.LaunchesEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; import org.eclipse.dd.dsf.ui.viewmodel.IRootVMNode; @@ -126,4 +130,23 @@ public class LaunchVMProvider extends AbstractDMVMProvider // shut down. } } + + @Override + protected boolean canSkipHandlingEvent(Object newEvent, Object eventToSkip) { + // To optimize view performance when stepping rapidly, skip events that came + // before the last suspended events. However, the debug view can get suspended + // events for different threads, so make sure to skip only the events if they + // were in the same hierarchy as the last suspended event. + if (newEvent instanceof ISuspendedDMEvent && eventToSkip instanceof IDMEvent) { + IDMContext newEventDmc = ((IDMEvent)newEvent).getDMContext(); + IDMContext eventToSkipDmc = ((IDMEvent)eventToSkip).getDMContext(); + + if (newEventDmc.equals(eventToSkipDmc) || DMContexts.isAncestorOf(eventToSkipDmc, newEventDmc)) { + return true; + } + } + + return false; + } + } From db9befed962928ae79dc86f902ecb99c81aa226e Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Fri, 25 Apr 2008 18:01:20 +0000 Subject: [PATCH 409/834] Bugzilla entries 203904 , 205975 , 204927. --- .../pda/ui/viewmodel/PDAVMAdapter.java | 5 +- .../pda/launch/PDAServicesInitSequence.java | 8 + .../launch/PDAServicesShutdownSequence.java | 9 +- .../dd/examples/pda/service/PDARegisters.java | 1062 +++++++++++++++++ 4 files changed, 1082 insertions(+), 2 deletions(-) create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARegisters.java diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java index 0059b7dbd8e..99bb3adf8eb 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java @@ -12,6 +12,7 @@ package org.eclipse.dd.examples.pda.ui.viewmodel; import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression.ExpressionVMProvider; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.register.RegisterVMProvider; import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.variable.VariableVMProvider; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMAdapter; @@ -44,7 +45,9 @@ public class PDAVMAdapter extends AbstractDMVMAdapter return new VariableVMProvider(this, context, getSession()); } else if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(context.getId()) ) { return new ExpressionVMProvider(this, context, getSession()); - } + } else if (IDebugUIConstants.ID_REGISTER_VIEW.equals(context.getId()) ) { + return new RegisterVMProvider(this, context, getSession()); + } return null; } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java index c13ff5b33be..ec15010f9fc 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java @@ -19,6 +19,7 @@ import org.eclipse.dd.examples.pda.service.PDABreakpointAttributeTranslator; import org.eclipse.dd.examples.pda.service.PDABreakpoints; import org.eclipse.dd.examples.pda.service.PDACommandControl; import org.eclipse.dd.examples.pda.service.PDAExpressions; +import org.eclipse.dd.examples.pda.service.PDARegisters; import org.eclipse.dd.examples.pda.service.PDARunControl; import org.eclipse.dd.examples.pda.service.PDAStack; @@ -96,6 +97,13 @@ public class PDAServicesInitSequence extends Sequence { new PDAExpressions(fSession).initialize(requestMonitor); } }, + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + // Start the service to track expressions. + new PDARegisters(fSession).initialize(requestMonitor); + } + }, new Step() { @Override public void execute(RequestMonitor requestMonitor) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java index f73fe7108d4..43a674abe1c 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java @@ -24,6 +24,7 @@ import org.eclipse.dd.examples.pda.PDAPlugin; import org.eclipse.dd.examples.pda.service.PDABreakpoints; import org.eclipse.dd.examples.pda.service.PDACommandControl; import org.eclipse.dd.examples.pda.service.PDAExpressions; +import org.eclipse.dd.examples.pda.service.PDARegisters; import org.eclipse.dd.examples.pda.service.PDARunControl; import org.eclipse.dd.examples.pda.service.PDAStack; @@ -61,7 +62,13 @@ public class PDAServicesShutdownSequence extends Sequence { public void execute(RequestMonitor requestMonitor) { shutdownService(PDAExpressions.class, requestMonitor); } - }, + }, + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(PDARegisters.class, requestMonitor); + } + }, new Step() { @Override public void execute(RequestMonitor requestMonitor) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARegisters.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARegisters.java new file mode 100644 index 00000000000..58ab8952edc --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARegisters.java @@ -0,0 +1,1062 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service; + +import java.math.BigInteger; +import java.util.Hashtable; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.AbstractDMContext; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.IRegisters; +import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; +import org.eclipse.dd.dsf.service.AbstractDsfService; +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.examples.pda.PDAPlugin; +import org.osgi.framework.BundleContext; + +/** + * + */ +public class PDARegisters extends AbstractDsfService implements IRegisters { + + /* + * Internal control variables. + */ + public PDARegisters(DsfSession session) + { + super(session); + } + + /* + * (non-Javadoc) + * @see org.eclipse.dd.dsf.service.AbstractDsfService#getBundleContext() + */ + @Override + protected BundleContext getBundleContext() + { + return PDAPlugin.getBundleContext(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.dd.dsf.service.AbstractDsfService#initialize(org.eclipse.dd.dsf.concurrent.RequestMonitor) + */ + @Override + public void initialize(final RequestMonitor requestMonitor) { + super.initialize( + new RequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleSuccess() { + doInitialize(requestMonitor); + }}); + } + + private void doInitialize(RequestMonitor requestMonitor) { + /* + * Sign up so we see events. We use these events to decide how to manage + * any local caches we are providing as well as the lower level register + * cache we create to get/set registers on the target. + */ + getSession().addServiceEventListener(this, null); + + /* + * Make ourselves known so clients can use us. + */ + register(new String[]{IRegisters.class.getName(), PDARegisters.class.getName()}, new Hashtable()); + + requestMonitor.done(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.dd.dsf.service.AbstractDsfService#shutdown(org.eclipse.dd.dsf.concurrent.RequestMonitor) + */ + @Override + public void shutdown(RequestMonitor requestMonitor) + { + unregister(); + getSession().removeServiceEventListener(this); + super.shutdown(requestMonitor); + } + + /* + * These are the public interfaces for this service. + * + * (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IRegisters#getRegisterGroups(org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext, org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) + */ + public void getRegisterGroups(IDMContext ctx, DataRequestMonitor rm ) { + PDAProgramDMContext frameDmc = DMContexts.getAncestorOfType(ctx, PDAProgramDMContext.class); + if (frameDmc == null) { + rm.setStatus( new Status( IStatus.ERROR , PDAPlugin.PLUGIN_ID , INVALID_HANDLE , "Container context not found", null ) ) ; //$NON-NLS-1$ + rm.done(); + return; + } + + MIRegisterGroupDMC generalGroupDMC = new MIRegisterGroupDMC( this , frameDmc, 0 , "General" ) ; //$NON-NLS-1$ + MIRegisterGroupDMC analysisGroupDMC = new MIRegisterGroupDMC( this , frameDmc, 0 , "Analysis" ) ; //$NON-NLS-1$ + + rm.setData( new MIRegisterGroupDMC[] { generalGroupDMC, analysisGroupDMC } ) ; + rm.done() ; + } + + /* + * (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IRegisters#getRegisters(org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) + */ + public void getRegisters(final IDMContext dmc, final DataRequestMonitor rm) { + final MIRegisterGroupDMC groupDmc = DMContexts.getAncestorOfType(dmc, MIRegisterGroupDMC.class); + if ( groupDmc == null ) { + rm.setStatus( new Status( IStatus.ERROR , PDAPlugin.PLUGIN_ID , INVALID_HANDLE , "RegisterGroup context not found", null ) ) ; //$NON-NLS-1$ + rm.done(); + return; + } + + final IFrameDMContext containerDmc = DMContexts.getAncestorOfType(dmc, IFrameDMContext.class); + if ( containerDmc == null ) { + rm.setStatus( new Status( IStatus.ERROR , PDAPlugin.PLUGIN_ID , INVALID_HANDLE , "Container context not found" , null ) ) ; //$NON-NLS-1$ + rm.done(); + return; + } + + String[] names = null;; + + if ( groupDmc.getName().equals( "General") ) { + + names = new String[] { "pc" , + "sp" , + "status" , + "stackdepth" , + "stack[0]" , + "stack[1]" , + "stack[2]" , + "stack[3]" , + "stack[4]" , + "stack[5]" } ; + } + else if ( groupDmc.getName().equals( "Analysis") ) { + + names = new String[] { "total-instructions" , + "add-instructions" , + "call-instructions" , + "dec-instructions" , + "dup-instructions" , + "halt-instructions" , + "output-instructions" , + "pop-instructions" , + "push-instructions" , + "return-instructions" , + "var-instructions" } ; + } + else { + rm.setStatus(new Status(IStatus.ERROR , PDAPlugin.PLUGIN_ID , INTERNAL_ERROR , "Invalid group = " + groupDmc , null)); //$NON-NLS-1$ + rm.done(); + } + + IExecutionDMContext executionDmc = DMContexts.getAncestorOfType(dmc, IExecutionDMContext.class); + + if(executionDmc == null) + rm.setData(makeRegisterDMCs(groupDmc, names)); + else + rm.setData(makeRegisterDMCs(groupDmc, executionDmc, names)); + rm.done(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IRegisters#getBitFields(org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) + */ + public void getBitFields( IDMContext regDmc , DataRequestMonitor rm ) { + + MIRegisterDMC registerDmc = DMContexts.getAncestorOfType(regDmc, MIRegisterDMC.class); + + if ( registerDmc == null ) { + rm.setStatus( new Status( IStatus.ERROR , PDAPlugin.PLUGIN_ID , INVALID_HANDLE , "No register in context: " + regDmc , null ) ) ; //$NON-NLS-1$ + rm.done(); + return; + } + + MIBitFieldDMC[] bitFieldDMCs = null; + + if ( registerDmc.getName().equals( "status") ) { + bitFieldDMCs = new MIBitFieldDMC[4]; + bitFieldDMCs[ 0 ] = new MIBitFieldDMC( PDARegisters.this, registerDmc, 0, "BITS_00_07" ) ; //$NON-NLS-1$ + bitFieldDMCs[ 1 ] = new MIBitFieldDMC( PDARegisters.this, registerDmc, 1, "BITS_08_15" ) ; //$NON-NLS-1$ + bitFieldDMCs[ 2 ] = new MIBitFieldDMC( PDARegisters.this, registerDmc, 2, "BITS_16_23" ) ; //$NON-NLS-1$ + bitFieldDMCs[ 3 ] = new MIBitFieldDMC( PDARegisters.this, registerDmc, 3, "BITS_24_31" ) ; //$NON-NLS-1$ + } + else { + bitFieldDMCs = new MIBitFieldDMC[0]; + } + + rm.setData(bitFieldDMCs) ; + rm.done(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IRegisters#writeRegister(org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext, java.lang.String, java.lang.String, org.eclipse.dd.dsf.concurrent.RequestMonitor) + */ + public void writeRegister(IRegisterDMContext regCtx, final String regValue, final String formatId, final RequestMonitor rm) { + MIRegisterGroupDMC grpDmc = DMContexts.getAncestorOfType(regCtx, MIRegisterGroupDMC.class); + if ( grpDmc == null ) { + rm.setStatus( new Status( IStatus.ERROR , PDAPlugin.PLUGIN_ID , INVALID_HANDLE , "RegisterGroup context not found" , null ) ) ; //$NON-NLS-1$ + rm.done(); + return; + } + + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, NOT_SUPPORTED, "Register is read only at this time", null)); //$NON-NLS-1$ + rm.done(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IRegisters#writeBitField(org.eclipse.dd.dsf.debug.service.IRegisters.IBitFieldDMContext, java.lang.String, java.lang.String, org.eclipse.dd.dsf.concurrent.RequestMonitor) + */ + public void writeBitField(IBitFieldDMContext bitFieldCtx, String bitFieldValue, String formatId, RequestMonitor rm) { + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, NOT_SUPPORTED, "Writing bit field not supported", null)); //$NON-NLS-1$ + rm.done(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IRegisters#writeBitField(org.eclipse.dd.dsf.debug.service.IRegisters.IBitFieldDMContext, org.eclipse.dd.dsf.debug.service.IRegisters.IMnemonic, org.eclipse.dd.dsf.concurrent.RequestMonitor) + */ + public void writeBitField(IBitFieldDMContext bitFieldCtx, IMnemonic mnemonic, RequestMonitor rm) { + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, NOT_SUPPORTED, "Writing bit field not supported", null)); //$NON-NLS-1$ + rm.done(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IFormattedValues#getAvailableFormats(org.eclipse.dd.dsf.debug.service.IFormattedValues.IFormattedDataDMContext, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) + */ + public void getAvailableFormats(IFormattedDataDMContext dmc, DataRequestMonitor rm) { + + rm.setData(new String[] { HEX_FORMAT, DECIMAL_FORMAT, OCTAL_FORMAT, BINARY_FORMAT, NATURAL_FORMAT }); + rm.done(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IFormattedValues#getFormattedValueContext(org.eclipse.dd.dsf.debug.service.IFormattedValues.IFormattedDataDMContext, java.lang.String) + */ + public FormattedValueDMContext getFormattedValueContext(IFormattedDataDMContext dmc, String formatId) { + if ( dmc instanceof MIRegisterDMC ) { + MIRegisterDMC regDmc = (MIRegisterDMC) dmc; + return( new FormattedValueDMContext( this, regDmc, formatId)); + } + else if ( dmc instanceof MIBitFieldDMC ) { + MIBitFieldDMC bitFieldDmc = (MIBitFieldDMC) dmc; + return( new FormattedValueDMContext( this, bitFieldDmc, formatId)); + } + + return null; + } + + /* + * (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IRegisters#findRegisterGroup(org.eclipse.dd.dsf.datamodel.IDMContext, java.lang.String, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) + */ + public void findRegisterGroup(IDMContext ctx, String name, DataRequestMonitor rm) { + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, NOT_SUPPORTED, "Finding a Register Group context not supported", null)); //$NON-NLS-1$ + rm.done(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IRegisters#findRegister(org.eclipse.dd.dsf.datamodel.IDMContext, java.lang.String, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) + */ + public void findRegister(IDMContext ctx, String name, DataRequestMonitor rm) { + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, NOT_SUPPORTED, "Finding a Register context not supported", null)); //$NON-NLS-1$ + rm.done(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IRegisters#findBitField(org.eclipse.dd.dsf.datamodel.IDMContext, java.lang.String, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) + */ + public void findBitField(IDMContext ctx, String name, DataRequestMonitor rm) { + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, NOT_SUPPORTED, "Finding a Register Group context not supported", null)); //$NON-NLS-1$ + rm.done(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.dd.dsf.datamodel.IDMService#getModelData(org.eclipse.dd.dsf.datamodel.IDMContext, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) + */ + @SuppressWarnings("unchecked") + public void getModelData(IDMContext dmc, DataRequestMonitor rm) { + /* + * This is the method which is called when actual results need to be returned. We + * can be called either with a service DMC for which we return ourselves or we can + * be called with the DMC's we have handed out. If the latter is the case then we + * data mine by talking to the Debug Engine. + */ + + if (dmc instanceof MIRegisterGroupDMC) { + getRegisterGroupData((MIRegisterGroupDMC)dmc, (DataRequestMonitor)rm); + } else if (dmc instanceof MIRegisterDMC) { + getRegisterData((MIRegisterDMC)dmc, (DataRequestMonitor)rm); + } else if (dmc instanceof MIBitFieldDMC) { + getBitFieldData((MIBitFieldDMC) dmc, (DataRequestMonitor)rm); + } else if (dmc instanceof FormattedValueDMContext) { + getFormattedExpressionValue((FormattedValueDMContext)dmc, (DataRequestMonitor)rm); + } else { + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, -1, "Unknown DMC type", null)); //$NON-NLS-1$ + rm.done(); + } + } + + /* + * (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IFormattedValues#getFormattedExpressionValue(org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) + */ + public void getFormattedExpressionValue(FormattedValueDMContext dmc, DataRequestMonitor rm) { + if (dmc.getParents().length == 1 && dmc.getParents()[0] instanceof MIRegisterDMC) { + getRegisterDataValue( (MIRegisterDMC) dmc.getParents()[0], dmc.getFormatID(), rm); + } + else if (dmc.getParents().length == 1 && dmc.getParents()[0] instanceof MIBitFieldDMC) { + getBitFieldDataValue( (MIBitFieldDMC) dmc.getParents()[0], dmc.getFormatID(), rm); + } else { + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ + rm.done(); + } + } + + /* + * (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IRegisters#getRegisterGroupData(org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) + */ + public void getRegisterGroupData(IRegisterGroupDMContext regGroupDmc, DataRequestMonitor rm) { + + MIRegisterGroupDMC groupDmc = (MIRegisterGroupDMC) regGroupDmc; + + /* + * Register group layout : + * + * + General + * + Analysis + */ + + if ( groupDmc.getName().equals( "General" ) ) { + rm.setData( new RegisterGroupData( "General", "General Purpose Control Registers") ) ; //$NON-NLS-1$ //$NON-NLS-2$ + } + else if ( groupDmc.getName().equals( "Analysis" ) ) { + rm.setData( new RegisterGroupData( "Analysis", "Code Analysis Registers") ) ; //$NON-NLS-1$ //$NON-NLS-2$ + } + else { + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown register group", null)); //$NON-NLS-1$ + } + + rm.done(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IRegisters#getRegisterData(org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) + */ + public void getRegisterData(IRegisterDMContext regDmc , DataRequestMonitor rm) { + if (regDmc instanceof MIRegisterDMC) { + MIRegisterDMC pdaRegDmc = (MIRegisterDMC)regDmc; + String regName = pdaRegDmc.getName(); + String regDesc = BLANK_STRING; + boolean foundReg = false; + boolean isWriteable = false ; + + if ( regName.equalsIgnoreCase( "pc" ) ) { foundReg = true ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "sp" ) ) { foundReg = true ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "status" ) ) { foundReg = true ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stackdepth" ) ) { foundReg = true ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[0]" ) ) { foundReg = true ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[1]" ) ) { foundReg = true ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[2]" ) ) { foundReg = true ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[3]" ) ) { foundReg = true ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[4]" ) ) { foundReg = true ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[5]" ) ) { foundReg = true ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "total-instructions" ) ) { foundReg = true ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "add-instructions" ) ) { foundReg = true ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "call-instructions" ) ) { foundReg = true ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "dec-instructions" ) ) { foundReg = true ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "dup-instructions" ) ) { foundReg = true ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "halt-instructions" ) ) { foundReg = true ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "output-instructions" ) ) { foundReg = true ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "pop-instructions" ) ) { foundReg = true ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "push-instructions" ) ) { foundReg = true ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "return-instructions" ) ) { foundReg = true ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "var-instructions" ) ) { foundReg = true ; } //$NON-NLS-1$ + + if ( regName.equalsIgnoreCase( "pc" ) ) { isWriteable = false ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "sp" ) ) { isWriteable = false ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "status" ) ) { isWriteable = false ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stackdepth" ) ) { isWriteable = false ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[0]" ) ) { isWriteable = false ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[1]" ) ) { isWriteable = false ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[2]" ) ) { isWriteable = false ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[3]" ) ) { isWriteable = false ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[4]" ) ) { isWriteable = false ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[5]" ) ) { isWriteable = false ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "total-instructions" ) ) { isWriteable = false ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "add-instructions" ) ) { isWriteable = false ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "call-instructions" ) ) { isWriteable = false ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "dec-instructions" ) ) { isWriteable = false ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "dup-instructions" ) ) { isWriteable = false ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "halt-instructions" ) ) { isWriteable = false ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "output-instructions" ) ) { isWriteable = false ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "pop-instructions" ) ) { isWriteable = false ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "push-instructions" ) ) { isWriteable = false ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "return-instructions" ) ) { isWriteable = false ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "var-instructions" ) ) { isWriteable = false ; } //$NON-NLS-1$ + + if ( regName.equalsIgnoreCase( "pc" ) ) { regDesc = "Program Counter" ; } //$NON-NLS-1$ //$NON-NLS-2$ + else if ( regName.equalsIgnoreCase( "sp" ) ) { regDesc = "Stack Pointer" ; } //$NON-NLS-1$ //$NON-NLS-2$ + else if ( regName.equalsIgnoreCase( "status" ) ) { regDesc = "CPU Status" ; } //$NON-NLS-1$ //$NON-NLS-2$ + else if ( regName.equalsIgnoreCase( "stackdepth" ) ) { regDesc = "Current depth of the pushdown stack" ; } //$NON-NLS-1$ //$NON-NLS-2$ + else if ( regName.equalsIgnoreCase( "stack[0]" ) ) { regDesc = "Stack entry" ; } //$NON-NLS-1$ //$NON-NLS-2$ + else if ( regName.equalsIgnoreCase( "stack[1]" ) ) { regDesc = "Stack entry" ; } //$NON-NLS-1$ //$NON-NLS-2$ + else if ( regName.equalsIgnoreCase( "stack[2]" ) ) { regDesc = "Stack entry" ; } //$NON-NLS-1$ //$NON-NLS-2$ + else if ( regName.equalsIgnoreCase( "stack[3]" ) ) { regDesc = "Stack entry" ; } //$NON-NLS-1$ //$NON-NLS-2$ + else if ( regName.equalsIgnoreCase( "stack[4]" ) ) { regDesc = "Stack entry" ; } //$NON-NLS-1$ //$NON-NLS-2$ + else if ( regName.equalsIgnoreCase( "stack[5]" ) ) { regDesc = "Stack entry" ; } //$NON-NLS-1$ //$NON-NLS-2$ + else if ( regName.equalsIgnoreCase( "total-instructions" ) ) { regDesc = "Total # of instructions in the current program" ; } //$NON-NLS-1$ //$NON-NLS-2$ + else if ( regName.equalsIgnoreCase( "add-instructions" ) ) { regDesc = "# of 'addr' instructions in the current program" ; } //$NON-NLS-1$ //$NON-NLS-2$ + else if ( regName.equalsIgnoreCase( "call-instructions" ) ) { regDesc = "# of 'call' instructions in the current program" ; } //$NON-NLS-1$ //$NON-NLS-2$ + else if ( regName.equalsIgnoreCase( "dec-instructions" ) ) { regDesc = "# of 'dec' instructions in the current program" ; } //$NON-NLS-1$ //$NON-NLS-2$ + else if ( regName.equalsIgnoreCase( "dup-instructions" ) ) { regDesc = "# of 'dup' instructions in the current program" ; } //$NON-NLS-1$ //$NON-NLS-2$ + else if ( regName.equalsIgnoreCase( "halt-instructions" ) ) { regDesc = "# of 'halt' instructions in the current program" ; } //$NON-NLS-1$ //$NON-NLS-2$ + else if ( regName.equalsIgnoreCase( "output-instructions" ) ) { regDesc = "# of 'output' instructions in the current program" ; } //$NON-NLS-1$ //$NON-NLS-2$ + else if ( regName.equalsIgnoreCase( "pop-instructions" ) ) { regDesc = "# of 'pop' instructions in the current program" ; } //$NON-NLS-1$ //$NON-NLS-2$ + else if ( regName.equalsIgnoreCase( "push-instructions" ) ) { regDesc = "# of 'push' instructions in the current program" ; } //$NON-NLS-1$ //$NON-NLS-2$ + else if ( regName.equalsIgnoreCase( "return-instructions" ) ) { regDesc = "# of 'return' instructions in the current program" ; } //$NON-NLS-1$ //$NON-NLS-2$ + else if ( regName.equalsIgnoreCase( "var-instructions" ) ) { regDesc = "# of 'var' instructions in the current program" ; } //$NON-NLS-1$ //$NON-NLS-2$ + + if ( foundReg ) { + rm.setData(new RegisterData(regName, regDesc, false, isWriteable)); + rm.done(); + } + else { + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown register", null)); //$NON-NLS-1$ + rm.done(); + } + } else { + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown DMC type", null)); //$NON-NLS-1$ + rm.done(); + } + } + + /* + * (non-Javadoc) + * @see org.eclipse.dd.dsf.debug.service.IRegisters#getBitFieldData(org.eclipse.dd.dsf.debug.service.IRegisters.IBitFieldDMContext, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) + */ + public void getBitFieldData(IBitFieldDMContext dmc, DataRequestMonitor rm) { + + MIBitFieldDMC bitFieldDmc = (MIBitFieldDMC) dmc; + IMnemonic[] EmptyMnemonic = new IMnemonic[0]; + BitFieldData bData = null; + + if ( bitFieldDmc.getName().equals( "BITS_00_07" ) ) { + + bData = new BitFieldData( bitFieldDmc.getName(), "Status Bits 00 - 07", new BigInteger( "0" ) , true, true, true, false, false, false, false, false); + + IBitGroup[] bitGroups = new IBitGroup[1]; + + BitGroupData bGroup = new BitGroupData(); + + bGroup.setBitCount(8); + bGroup.setStartBit(0); + + bitGroups[0] = bGroup; + + bData.addBitGroups(bitGroups); + bData.addMnemonics(EmptyMnemonic); + } + else if ( bitFieldDmc.getName().equals( "BITS_08_15" ) ) { + + bData = new BitFieldData( bitFieldDmc.getName(), "Status Bits 08 - 15", new BigInteger( "0" ) , true, true, true, false, false, false, false, false); + + IBitGroup[] bitGroups = new IBitGroup[1]; + + BitGroupData bGroup = new BitGroupData(); + + bGroup.setBitCount(8); + bGroup.setStartBit(8); + + bitGroups[0] = bGroup; + + bData.addBitGroups(bitGroups); + bData.addMnemonics(EmptyMnemonic); + } + else if ( bitFieldDmc.getName().equals( "BITS_16_23" ) ) { + + bData = new BitFieldData( bitFieldDmc.getName(), "Status Bits 16 - 23", new BigInteger( "0" ) , true, true, true, false, false, false, false, false); + + IBitGroup[] bitGroups = new IBitGroup[1]; + + BitGroupData bGroup = new BitGroupData(); + + bGroup.setBitCount(8); + bGroup.setStartBit(16); + + bitGroups[0] = bGroup; + + bData.addBitGroups(bitGroups); + bData.addMnemonics(EmptyMnemonic); + } + else if ( bitFieldDmc.getName().equals( "BITS_24_31" ) ) { + + bData = new BitFieldData( bitFieldDmc.getName(), "Status Bits 24 - 31", new BigInteger( "255" ) , true, true, true, false, false, false, false, false); + + IBitGroup[] bitGroups = new IBitGroup[1]; + + BitGroupData bGroup = new BitGroupData(); + + bGroup.setBitCount(8); + bGroup.setStartBit(24); + + bitGroups[0] = bGroup; + + bData.addBitGroups(bitGroups); + bData.addMnemonics(EmptyMnemonic); + } + + rm.setData(bData); + rm.done(); + } + + private void getRegisterDataValue( final MIRegisterDMC regDmc, final String formatId, final DataRequestMonitor rm) { + IExecutionDMContext miExecDmc = DMContexts.getAncestorOfType(regDmc, IExecutionDMContext.class); + if(miExecDmc == null){ + // Set value to blank if execution dmc is not present + rm.setData( new FormattedValueDMData( BLANK_STRING ) ); + rm.done(); + return; + } + + String regName = regDmc.getName() ; + String value = BLANK_STRING; + + if ( HEX_FORMAT.equals( formatId ) || NATURAL_FORMAT.equals( formatId ) ) { + + if ( regName.equalsIgnoreCase( "pc" ) ) { value = "0x00000043" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "sp" ) ) { value = "0x000000C6" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "status" ) ) { value = "0x000000FF" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stackdepth" ) ) { value = "0x00000005" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[0]" ) ) { value = "0x0000000A" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[1]" ) ) { value = "0x00000025" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[2]" ) ) { value = "0x00000066" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[3]" ) ) { value = "0x0000008D" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[4]" ) ) { value = "0x000000A9" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[5]" ) ) { value = "0x000000C6" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "total-instructions" ) ) { value = "0x00000226" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "add-instructions" ) ) { value = "0x0000000A" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "call-instructions" ) ) { value = "0x00000014" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "dec-instructions" ) ) { value = "0x0000001E" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "dup-instructions" ) ) { value = "0x00000028" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "halt-instructions" ) ) { value = "0x00000032" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "output-instructions" ) ) { value = "0x0000003C" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "pop-instructions" ) ) { value = "0x00000046" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "push-instructions" ) ) { value = "0x00000050" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "return-instructions" ) ) { value = "0x0000005A" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "var-instructions" ) ) { value = "0x00000064" ; } //$NON-NLS-1$ + + rm.setData( new FormattedValueDMData( value ) ); + rm.done(); + return; + } + + if ( OCTAL_FORMAT.equals( formatId ) ) { + + if ( regName.equalsIgnoreCase( "pc" ) ) { value = "00000103" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "sp" ) ) { value = "00000306" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "status" ) ) { value = "00000400" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stackdepth" ) ) { value = "00000005" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[0]" ) ) { value = "00000012" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[1]" ) ) { value = "00000045" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[2]" ) ) { value = "00000146" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[3]" ) ) { value = "00000215" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[4]" ) ) { value = "00000251" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[5]" ) ) { value = "00000306" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "total-instructions" ) ) { value = "00001046" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "add-instructions" ) ) { value = "00000012" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "call-instructions" ) ) { value = "00000024" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "dec-instructions" ) ) { value = "00000036" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "dup-instructions" ) ) { value = "00000050" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "halt-instructions" ) ) { value = "00000062" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "output-instructions" ) ) { value = "00000074" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "pop-instructions" ) ) { value = "00000106" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "push-instructions" ) ) { value = "00000120" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "return-instructions" ) ) { value = "00000132" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "var-instructions" ) ) { value = "00000144" ; } //$NON-NLS-1$ + + rm.setData( new FormattedValueDMData( value ) ); + rm.done(); + return; + } + + if ( BINARY_FORMAT.equals( formatId ) ) { + + if ( regName.equalsIgnoreCase( "pc" ) ) { value = "0b00000000000000000000000001000011" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "sp" ) ) { value = "0b00000000000000000000000011000110" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "status" ) ) { value = "0b00000000000000000000001001010101" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stackdepth" ) ) { value = "0b00000000000000000000000000000101" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[0]" ) ) { value = "0b00000000000000000000000000001010" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[1]" ) ) { value = "0b00000000000000000000000000100101" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[2]" ) ) { value = "0b00000000000000000000000001100110" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[3]" ) ) { value = "0b00000000000000000000000010001101" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[4]" ) ) { value = "0b00000000000000000000000010101001" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[5]" ) ) { value = "0b00000000000000000000000011000110" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "total-instructions" ) ) { value = "0b00000000000000000000001000100110" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "add-instructions" ) ) { value = "0b00000000000000000000000000001010" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "call-instructions" ) ) { value = "0b00000000000000000000000000010100" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "dec-instructions" ) ) { value = "0b00000000000000000000000000011110" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "dup-instructions" ) ) { value = "0b00000000000000000000000000101000" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "halt-instructions" ) ) { value = "0b00000000000000000000000000110010" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "output-instructions" ) ) { value = "0b00000000000000000000000000111100" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "pop-instructions" ) ) { value = "0b00000000000000000000000001000110" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "push-instructions" ) ) { value = "0b00000000000000000000000001010000" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "return-instructions" ) ) { value = "0b00000000000000000000000001011010" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "var-instructions" ) ) { value = "0b00000000000000000000000001100100" ; } //$NON-NLS-1$ + + rm.setData( new FormattedValueDMData( value ) ); + rm.done(); + return; + } + + if ( DECIMAL_FORMAT.equals( formatId ) ) { + + if ( regName.equalsIgnoreCase( "pc" ) ) { value = "67" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "sp" ) ) { value = "198" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "status" ) ) { value = "256" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stackdepth" ) ) { value = "5" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[0]" ) ) { value = "10" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[1]" ) ) { value = "37" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[2]" ) ) { value = "102" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[3]" ) ) { value = "141" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[4]" ) ) { value = "169" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "stack[5]" ) ) { value = "198" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "total-instructions" ) ) { value = "550" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "add-instructions" ) ) { value = "10" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "call-instructions" ) ) { value = "20" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "dec-instructions" ) ) { value = "30" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "dup-instructions" ) ) { value = "40" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "halt-instructions" ) ) { value = "50" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "output-instructions" ) ) { value = "60" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "pop-instructions" ) ) { value = "70" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "push-instructions" ) ) { value = "80" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "return-instructions" ) ) { value = "90" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "var-instructions" ) ) { value = "100" ; } //$NON-NLS-1$ + + rm.setData( new FormattedValueDMData( value ) ); + rm.done(); + return; + } + + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown number format", null)); //$NON-NLS-1$ + rm.done(); + } + + private void getBitFieldDataValue( final MIBitFieldDMC regDmc, final String formatId, final DataRequestMonitor rm) { + IExecutionDMContext miExecDmc = DMContexts.getAncestorOfType(regDmc, IExecutionDMContext.class); + if(miExecDmc == null){ + // Set value to blank if execution dmc is not present + rm.setData( new FormattedValueDMData( BLANK_STRING ) ); + rm.done(); + return; + } + + String regName = regDmc.getName() ; + String value = BLANK_STRING; + + if ( HEX_FORMAT.equals( formatId ) || NATURAL_FORMAT.equals( formatId ) ) { + + if ( regName.equalsIgnoreCase( "BITS_00_07" ) ) { value = "0x00" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "BITS_08_15" ) ) { value = "0x00" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "BITS_16_23" ) ) { value = "0x00" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "BITS_24_31" ) ) { value = "0xFF" ; } //$NON-NLS-1$ + + rm.setData( new FormattedValueDMData( value ) ); + rm.done(); + return; + } + + if ( OCTAL_FORMAT.equals( formatId ) ) { + + if ( regName.equalsIgnoreCase( "BITS_00_07" ) ) { value = "0000" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "BITS_08_15" ) ) { value = "0000" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "BITS_16_23" ) ) { value = "0000" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "BITS_24_31" ) ) { value = "0377" ; } //$NON-NLS-1$ + + rm.setData( new FormattedValueDMData( value ) ); + rm.done(); + return; + } + + if ( BINARY_FORMAT.equals( formatId ) ) { + + if ( regName.equalsIgnoreCase( "BITS_00_07" ) ) { value = "0b00000000" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "BITS_08_15" ) ) { value = "0b00000000" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "BITS_16_23" ) ) { value = "0b00000000" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "BITS_24_31" ) ) { value = "0b11111111" ; } //$NON-NLS-1$ + + rm.setData( new FormattedValueDMData( value ) ); + rm.done(); + return; + } + + if ( DECIMAL_FORMAT.equals( formatId ) ) { + + if ( regName.equalsIgnoreCase( "BITS_00_07" ) ) { value = "0" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "BITS_08_15" ) ) { value = "0" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "BITS_16_23" ) ) { value = "0" ; } //$NON-NLS-1$ + else if ( regName.equalsIgnoreCase( "BITS_24_31" ) ) { value = "255" ; } //$NON-NLS-1$ + + rm.setData( new FormattedValueDMData( value ) ); + rm.done(); + return; + } + + rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown number format", null)); //$NON-NLS-1$ + rm.done(); + } + + private static final String BLANK_STRING = ""; //$NON-NLS-1$ + + /* + * Support class used to construct Register Group DMCs. + */ + + private static class MIRegisterGroupDMC extends AbstractDMContext implements IRegisterGroupDMContext { + + private int fGroupNo; + private String fGroupName; + + public MIRegisterGroupDMC(PDARegisters service, PDAProgramDMContext execDmc, int groupNo, String groupName) { + super(service.getSession().getId(), new IDMContext[] { execDmc }); + fGroupNo = groupNo; + fGroupName = groupName; + } + + public int getGroupNo() { return fGroupNo; } + public String getName() { return fGroupName; } + + @Override + public boolean equals(Object other) { + return ((super.baseEquals(other)) && (((MIRegisterGroupDMC) other).fGroupNo == fGroupNo) && + (((MIRegisterGroupDMC) other).fGroupName.equals(fGroupName))); + } + + @Override + public int hashCode() { return super.baseHashCode() ^ fGroupNo; } + @Override + public String toString() { return baseToString() + ".group[" + fGroupNo + "]"; } //$NON-NLS-1$ //$NON-NLS-2$ + } + + /* + * Support class used to construct Register DMCs. + */ + + private static class MIRegisterDMC extends AbstractDMContext implements IRegisterDMContext { + + private int fRegNo; + private String fRegName; + + public MIRegisterDMC(PDARegisters service, MIRegisterGroupDMC group, int regNo, String regName) { + super(service.getSession().getId(), + new IDMContext[] { group }); + fRegNo = regNo; + fRegName = regName; + } + + public MIRegisterDMC(PDARegisters service, MIRegisterGroupDMC group, IExecutionDMContext execDmc, int regNo, String regName) { + super(service.getSession().getId(), new IDMContext[] { execDmc, group }); + fRegNo = regNo; + fRegName = regName; + } + + public int getRegNo() { return fRegNo; } + public String getName() { return fRegName; } + + @Override + public boolean equals(Object other) { + return ((super.baseEquals(other)) && (((MIRegisterDMC) other).fRegNo == fRegNo) && + (((MIRegisterDMC) other).fRegName.equals(fRegName))); + } + + @Override + public int hashCode() { return super.baseHashCode() ^ fRegNo; } + @Override + public String toString() { return baseToString() + ".register[" + fRegNo + "]"; } //$NON-NLS-1$ //$NON-NLS-2$ + } + + /* + * Support class used to construct BitField DMCs. + */ + private static class MIBitFieldDMC extends AbstractDMContext implements IBitFieldDMContext { + + private int fBitFieldNo; + private String fBitFieldName; + + public MIBitFieldDMC(PDARegisters service, MIRegisterDMC reg, int bitFieldNo, String bitFieldName) { + super(service.getSession().getId(), new IDMContext[] { reg }); + + fBitFieldNo = bitFieldNo; + fBitFieldName = bitFieldName; + } + + /* + * Getters. + */ + public int getBitFieldNo() { return fBitFieldNo; } + public String getName() { return fBitFieldName; } + + /* + * Required common manipulation routines. + */ + @Override + public boolean equals(Object other) { + if (other instanceof MIBitFieldDMC) { + + MIBitFieldDMC dmc = (MIBitFieldDMC) other; + + return( (super.baseEquals(other)) && + (dmc.fBitFieldNo == fBitFieldNo) && + (dmc.fBitFieldName.equals(fBitFieldName))); + } else { + return false; + } + } + + @Override + public int hashCode() { return super.baseHashCode() + fBitFieldName.hashCode(); } + @Override + public String toString() { return baseToString() + ".BitField[" + fBitFieldNo + "]"; } //$NON-NLS-1$ //$NON-NLS-2$ + } + + static class RegisterGroupData implements IRegisterGroupDMData { + + private String fGrpName; + private String fGrpDesc; + + public RegisterGroupData( String grpName, String desc ) { + fGrpName = grpName; + fGrpDesc = desc; + } + public String getName() { return fGrpName; } + public String getDescription() { return fGrpDesc; } + } + + static class RegisterData implements IRegisterDMData { + + private String fRegName; + private String fRegDesc; + private boolean fIsFloat; + private boolean fIsWriteable; + + public RegisterData(String regName, String regDesc, boolean isFloat, boolean isWriteable ) { + + fRegName = regName; + fRegDesc = regDesc; + fIsFloat = isFloat; + fIsWriteable = isWriteable; + } + + public boolean isReadable() { return true; } + public boolean isReadOnce() { return false; } + public boolean isWriteable() { return fIsWriteable; } + public boolean isWriteOnce() { return false; } + public boolean hasSideEffects() { return false; } + public boolean isVolatile() { return true; } + + public boolean isFloat() { return fIsFloat; } + public String getName() { return fRegName; } + public String getDescription() { return fRegDesc; } + } + + /* + * Used to create the a list of register data model contexts given a string list. + */ + private MIRegisterDMC[] makeRegisterDMCs(MIRegisterGroupDMC groupDmc, String[] regNames) { + return makeRegisterDMCs(groupDmc, null, regNames); + } + + /* + * Used to create the a list of register data model contexts given a string list. + */ + private MIRegisterDMC[] makeRegisterDMCs(MIRegisterGroupDMC groupDmc, IExecutionDMContext execDmc, String[] regNames) { + MIRegisterDMC[] regDmcList = new MIRegisterDMC[regNames.length]; + int regNo = 0 ; + for (String regName : regNames) { + if(execDmc != null) + regDmcList[regNo] = new MIRegisterDMC(this, groupDmc, execDmc, regNo, regName); + else + regDmcList[regNo] = new MIRegisterDMC(this, groupDmc, regNo, regName); + regNo++; + } + + return regDmcList; + } + + private class BitGroupData implements IBitGroup { + + private int fStartBit = 0; + private int fBitCount = 0; + + public void setStartBit( int startbit ) { + fStartBit = startbit; + } + + public void setBitCount( int bitcount ) { + fBitCount = bitcount; + } + + public int startBit() { return fStartBit; } + public int bitCount() { return fBitCount; } + } + + private class MnemonicData implements IMnemonic { + + private String fShortName; + private String fLongName; + private BigInteger fValue; + private int fNumBits; + + public void setShortName( String name ) { fShortName = name; } + public void setLongName( String name ) { fLongName = name; } + public void setValue( BigInteger value ) { fValue = value; } + public void setNumBits( int numBits ) { fNumBits = numBits; } + + public String getShortName() { return fShortName; } + public String getLongName() { return fLongName; } + + public BigInteger getValue() { return fValue; } + public int getBitCount() { return fNumBits; } + + @Override + public boolean equals( Object element ) { + if ( element instanceof MnemonicData ) { + MnemonicData mnem = (MnemonicData) element; + return ( mnem.fShortName.equals( fShortName ) ) && + ( mnem.fLongName.equals( fLongName ) ) && + ( mnem.fValue.equals( fValue ) ) && + ( mnem.fNumBits == fNumBits ); + } + return false ; + } + } + + private class BitFieldData implements IBitFieldDMData { + + private String fRegName; + private String fDesc; + private IBitGroup[] fBitGroups; + private IMnemonic[] fMnemonics; + private boolean fIsZeroBasedNumbering; + private boolean fIsZeroBitLeftMost; + private boolean fIsReadable; + private boolean fIsReadOnce; + private boolean fIsWriteable; + private boolean fIsWriteOnce; + private boolean fHasSideEffects; + private boolean fIsFloat; + private BigInteger fValue; + + public BitFieldData(String regName, String desc, BigInteger value, + boolean isZeroBasedNumbering, boolean isZeroBitLeftMost, boolean isReadable, + boolean isReadOnce, boolean isWriteable, boolean isWriteOnce, + boolean hasSideEffects, boolean isFloat ) { + + fRegName = regName; + fDesc = desc; + fValue = value; + fIsZeroBasedNumbering = isZeroBasedNumbering; + fIsZeroBitLeftMost = isZeroBitLeftMost; + fIsReadable = isReadable; + fIsReadOnce = isReadOnce; + fIsWriteable = isWriteable; + fIsWriteOnce = isWriteOnce; + fHasSideEffects = hasSideEffects; + fIsFloat = isFloat; + } + + public void addBitGroups( IBitGroup[] groups ) { fBitGroups = groups; } + public void addMnemonics( IMnemonic[] mnemonics ) { fMnemonics = mnemonics; } + + public IBitGroup[] getBitGroup() { return fBitGroups; } + public IMnemonic[] getMnemonics() { return fMnemonics; } + + public boolean isZeroBasedNumbering() { return fIsZeroBasedNumbering; } + public boolean isZeroBitLeftMost() { return fIsZeroBitLeftMost; } + public boolean isReadable() { return fIsReadable; } + public boolean isReadOnce() { return fIsReadOnce; } + public boolean isWriteable() { return fIsWriteable; } + public boolean isWriteOnce() { return fIsWriteOnce; } + public boolean hasSideEffects() { return fHasSideEffects; } + public boolean isFloat() { return fIsFloat; } + + public String getName() { return fRegName; } + public String getDescription() { return fDesc; } + + public IMnemonic getCurrentMnemonicValue() { + + for ( IMnemonic mnem : fMnemonics ) { + if ( ((MnemonicData) mnem).fValue.equals( fValue ) ){ + return mnem; + } + } + return null; + } + } + + /* + * Event handling section. These event handlers control the caching state of the + * register caches. This service creates several cache objects. Not all of which + * need to be flushed. These handlers maintain the state of the caches. + */ + + public static class RegisterChangedDMEvent implements IRegisters.IRegisterChangedDMEvent { + + private final IRegisterDMContext fRegisterDmc; + + RegisterChangedDMEvent(IRegisterDMContext registerDMC) { + fRegisterDmc = registerDMC; + } + + public IRegisterDMContext getDMContext() { + return fRegisterDmc; + } + } + + @DsfServiceEventHandler + public void eventDispatched(IRunControl.IResumedDMEvent e) { + } + + @DsfServiceEventHandler + public void eventDispatched( + IRunControl.ISuspendedDMEvent e) { + } + + @DsfServiceEventHandler + public void eventDispatched(final IRegisters.IRegisterChangedDMEvent e) { + } + + @SuppressWarnings("unused") + private void generateRegisterChangedEvent(IRegisterDMContext dmc ) { + getSession().dispatchEvent(new RegisterChangedDMEvent(dmc), getProperties()); + } +} From 34314195bd16e01549cb0089e22f9b647e471db5 Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Fri, 25 Apr 2008 18:09:34 +0000 Subject: [PATCH 410/834] Bugzillas 203094 , 205975 , 204927 --- .../ExpressionColumnPresentation.java | 5 +- .../expression/ExpressionVMProvider.java | 21 +++- .../register/RegisterBitFieldVMNode.java | 103 +++++++++++------- .../register/RegisterGroupVMNode.java | 25 +++-- .../ui/viewmodel/register/RegisterVMNode.java | 99 ++++++++++------- .../ui/viewmodel/variable/VariableVMNode.java | 14 ++- .../detail/MessagesForNumberFormatDetail.java | 2 +- 7 files changed, 168 insertions(+), 101 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/ExpressionColumnPresentation.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/ExpressionColumnPresentation.java index 311b8f36301..af035df047f 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/ExpressionColumnPresentation.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/ExpressionColumnPresentation.java @@ -60,16 +60,13 @@ public class ExpressionColumnPresentation implements IColumnPresentation { return null; } - - // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getInitialColumns() public String[] getInitialColumns() { - return new String[] { IDebugVMConstants.COLUMN_ID__EXPRESSION, IDebugVMConstants.COLUMN_ID__VALUE }; + return new String[] { IDebugVMConstants.COLUMN_ID__NAME, IDebugVMConstants.COLUMN_ID__TYPE, IDebugVMConstants.COLUMN_ID__VALUE }; } // @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#isOptional() public boolean isOptional() { return true; } - } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/ExpressionVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/ExpressionVMProvider.java index 81dbad87923..b55c5c30807 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/ExpressionVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/expression/ExpressionVMProvider.java @@ -16,6 +16,8 @@ import java.util.Set; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat.FormattedValuePreferenceStore; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat.IFormattedValuePreferenceStore; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.register.RegisterBitFieldVMNode; import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.register.RegisterGroupVMNode; import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.register.RegisterVMNode; import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.register.SyncRegisterDataAccess; @@ -178,10 +180,12 @@ public class ExpressionVMProvider extends AbstractDMVMProvider } /** - * Configures the nodes of this provider. This method may be overriden by + * Configures the nodes of this provider. This method may be over-ridden by * sub classes to create an alternate configuration in this provider. */ protected void configureLayout() { + + IFormattedValuePreferenceStore prefStore = FormattedValuePreferenceStore.getDefault(); /* * Allocate the synchronous data providers. @@ -195,7 +199,7 @@ public class ExpressionVMProvider extends AbstractDMVMProvider IRootVMNode rootNode = new RootDMVMNode(this); /* - * Now the Overarching management node. + * Now the Over-arching management node. */ ExpressionManagerVMNode expressionManagerNode = new ExpressionManagerVMNode(this); addChildNodes(rootNode, new IVMNode[] {expressionManagerNode}); @@ -205,20 +209,25 @@ public class ExpressionVMProvider extends AbstractDMVMProvider */ IExpressionVMNode registerGroupNode = new RegisterGroupVMNode(this, getSession(), syncRegDataAccess); - IExpressionVMNode registerNode = new RegisterVMNode(FormattedValuePreferenceStore.getDefault(), this, getSession(), syncRegDataAccess); + IExpressionVMNode registerNode = new RegisterVMNode(prefStore, this, getSession(), syncRegDataAccess); addChildNodes(registerGroupNode, new IExpressionVMNode[] {registerNode}); + /* + * Create the next level which is the bit-field level. + */ + IVMNode bitFieldNode = new RegisterBitFieldVMNode(prefStore, this, getSession(), syncRegDataAccess); + addChildNodes(registerNode, new IVMNode[] { bitFieldNode }); + /* * Create the support for the SubExpressions. Anything which is brought into the expressions * view comes in as a fully qualified expression so we go directly to the SubExpression layout * node. */ - IExpressionVMNode variableNode = - new VariableVMNode(FormattedValuePreferenceStore.getDefault(), this, getSession(), syncvarDataAccess); + IExpressionVMNode variableNode = new VariableVMNode(prefStore, this, getSession(), syncvarDataAccess); addChildNodes(variableNode, new IExpressionVMNode[] {variableNode}); /* - * Tell the expression node which subnodes it will directly support. It is very important + * Tell the expression node which sub-nodes it will directly support. It is very important * that the variables node be the last in this chain. The model assumes that there is some * form of metalanguage expression syntax which each of the nodes evaluates and decides if * they are dealing with it or not. The variables node assumes that the expression is fully diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterBitFieldVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterBitFieldVMNode.java index 794f05b64ac..57c706a8438 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterBitFieldVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterBitFieldVMNode.java @@ -117,6 +117,9 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode return element instanceof BitFieldVMC; } + /** + * Expected format: GRP( GroupName ).REG( RegisterName ).BFLD( BitFieldname ) + */ public String createWatchExpression(Object element) throws CoreException { IRegisterGroupDMData groupData = fDataAccess.getRegisterGroupDMData(element); IRegisterDMData registerData = fDataAccess.getRegisterDMData(element); @@ -124,15 +127,14 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode if (groupData != null && registerData != null && bitFieldData != null) { StringBuffer exprBuf = new StringBuffer(); - exprBuf.append("$$\""); //$NON-NLS-1$ - exprBuf.append(groupData.getName()); - exprBuf.append('"'); - exprBuf.append('$'); - exprBuf.append(registerData.getName()); - exprBuf.append('.'); - exprBuf.append(bitFieldData.getName()); + + exprBuf.append("GRP( "); exprBuf.append(groupData.getName()); exprBuf.append(" )"); //$NON-NLS-1$ //$NON-NLS-2$ + exprBuf.append(".REG( "); exprBuf.append(registerData.getName()); exprBuf.append(" )"); //$NON-NLS-1$ //$NON-NLS-2$ + exprBuf.append(".BFLD( "); exprBuf.append(bitFieldData.getName()); exprBuf.append(" )"); //$NON-NLS-1$ //$NON-NLS-2$ + return exprBuf.toString(); } + return null; } } @@ -503,6 +505,61 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode } } + /** + * Expected format: GRP( GroupName ).REG( RegisterName ).BFLD( BitFieldname ) + */ + + public boolean canParseExpression(IExpression expression) { + return parseExpressionForBitFieldName(expression.getExpressionText()) != null; + } + + private String parseExpressionForBitFieldName(String expression) { + + if (expression.startsWith("GRP(")) { //$NON-NLS-1$ + + /* + * Get the group portion. + */ + int startIdx = "GRP(".length(); //$NON-NLS-1$ + int endIdx = expression.indexOf(')', startIdx); + String remaining = expression.substring(endIdx+1); + if ( ! remaining.startsWith(".REG(") ) { //$NON-NLS-1$ + return null; + } + + /* + * Get the register portion. + */ + startIdx = ".REG(".length(); //$NON-NLS-1$ + endIdx = remaining.indexOf(')', startIdx); + remaining = remaining.substring(endIdx+1); + + /* + * Get the bit-field portion. + */ + if ( ! remaining.startsWith(".BFLD(") ) { //$NON-NLS-1$ + return null; + } + startIdx = ".BFLD(".length(); //$NON-NLS-1$ + endIdx = remaining.indexOf(')', startIdx); + String bitFieldName = remaining.substring(startIdx, endIdx); + + /* + * Make sure there is nothing following. If there is then this + * is not a properly formed expression and we do not claim it. + */ + remaining = remaining.substring( endIdx + 1); + + if ( remaining.length() != 0 ) { + return null; + } + + return bitFieldName.trim(); + } + + return null; + } + @Override protected void testElementForExpression(Object element, IExpression expression, final DataRequestMonitor rm) { if (!(element instanceof IDMVMContext)) { @@ -545,38 +602,6 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode } } - public boolean canParseExpression(IExpression expression) { - return parseExpressionForBitFieldName(expression.getExpressionText()) != null; - } - - /** - * Expected format: $$"Group Name"$Register_Name.Bit_Field_Name - */ - private String parseExpressionForBitFieldName(String expression) { - if (expression.startsWith("$$\"")) { //$NON-NLS-1$ - int secondQuoteIdx = expression.indexOf('"', "$$\"".length()); //$NON-NLS-1$ - if (secondQuoteIdx > 0) { - String registerSubString = expression.substring(secondQuoteIdx + 1); - if (registerSubString.length() != 0 && - registerSubString.charAt(0) == '$' && - Character.isLetterOrDigit(registerSubString.charAt(1))) - { - int registerEnd = 1; - while ( registerEnd < registerSubString.length() && - Character.isLetterOrDigit(registerSubString.charAt(registerEnd)) ) - { - registerEnd++; - } - if ((registerEnd + 1) < registerSubString.length() && '.' == registerSubString.charAt(registerEnd)) { - return registerSubString.substring(registerEnd + 1); - } - } - } - } - return null; - } - - @Override protected void associateExpression(Object element, IExpression expression) { if (element instanceof BitFieldVMC) { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterGroupVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterGroupVMNode.java index 6656656ca67..b3b1c5f7494 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterGroupVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterGroupVMNode.java @@ -102,13 +102,16 @@ public class RegisterGroupVMNode extends AbstractExpressionVMNode return element instanceof RegisterGroupVMC; } + /** + * Expected format: Group(GroupName) + */ public String createWatchExpression(Object element) throws CoreException { IRegisterGroupDMData groupData = fSyncRegisterDataAccess.getRegisterGroupDMData(element); if (groupData != null) { StringBuffer exprBuf = new StringBuffer(); - exprBuf.append("$$\""); //$NON-NLS-1$ + exprBuf.append("GRP( "); //$NON-NLS-1$ exprBuf.append(groupData.getName()); - exprBuf.append('"'); + exprBuf.append(" )"); //$NON-NLS-1$ return exprBuf.toString(); } @@ -275,15 +278,19 @@ public class RegisterGroupVMNode extends AbstractExpressionVMNode } /** - * Expected format: $$"Group Name"$Register_Name.Bit_Field_Name + * Expected format: Group(GroupName) */ private String parseExpressionForGroupName(String expression) { - if (expression.startsWith("$$\"")) { //$NON-NLS-1$ - int secondQuoteIdx = expression.indexOf('"', "$$\"".length()); //$NON-NLS-1$ - if (secondQuoteIdx > 0) { - return expression.substring(3, secondQuoteIdx); - } - } + if (expression.startsWith("GRP(")) { //$NON-NLS-1$ + /* + * Extract the group name. + */ + int startIdx = "GRP(".length(); //$NON-NLS-1$ + int endIdx = expression.indexOf(')', startIdx); + String groupName = expression.substring(startIdx, endIdx); + return groupName.trim(); + } + return null; } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterVMNode.java index edac0877436..710e9a1613e 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterVMNode.java @@ -114,16 +114,19 @@ public class RegisterVMNode extends AbstractExpressionVMNode return element instanceof RegisterVMC; } + /** + * Expected format: GRP( GroupName ).REG( RegisterName ) + */ public String createWatchExpression(Object element) throws CoreException { IRegisterGroupDMData groupData = fSyncRegisterDataAccess.getRegisterGroupDMData(element); IRegisterDMData registerData = fSyncRegisterDataAccess.getRegisterDMData(element); + if (groupData != null && registerData != null) { - StringBuffer exprBuf = new StringBuffer(); - exprBuf.append("$$\""); //$NON-NLS-1$ - exprBuf.append(groupData.getName()); - exprBuf.append('"'); - exprBuf.append('$'); - exprBuf.append(registerData.getName()); + StringBuffer exprBuf = new StringBuffer(); + + exprBuf.append("GRP( "); exprBuf.append(groupData.getName()); exprBuf.append(" )"); //$NON-NLS-1$ //$NON-NLS-2$ + exprBuf.append(".REG( "); exprBuf.append(registerData.getName()); exprBuf.append(" )"); //$NON-NLS-1$ //$NON-NLS-2$ + return exprBuf.toString(); } @@ -380,15 +383,15 @@ public class RegisterVMNode extends AbstractExpressionVMNode } public int getDeltaFlags(Object e) { - // In theory we want each node to act independently in terms of events. It might be - // the case that we would only have elements of this type at the root level. It is - // the case that the current layout model always starts with the GROUPS followed by - // REGISTERS followed by BITFIELDS. But if we do this when a run-control event has - // occured we generate a DELTA for every element, which can create a massive list - // of entries all of which say update the entire view. So for now we will just have - // the GROUP LAYOUT node do this. Later we need to revisit the logic and make sure - // there is a way for the nodes to operate independently and efficiently. - // + /* In theory we want each node to act independently in terms of events. It might be + * the case that we would only have elements of this type at the root level. It is + * the case that the current layout model always starts with the GROUPS followed by + * REGISTERS followed by BITFIELDS. But if we do this when a run-control event has + * occured we generate a DELTA for every element, which can create a massive list + * of entries all of which say update the entire view. So for now we will just have + * the GROUP LAYOUT node do this. Later we need to revisit the logic and make sure + * there is a way for the nodes to operate independently and efficiently. + */ if (e instanceof IRunControl.ISuspendedDMEvent) { return IModelDelta.CONTENT; } @@ -436,36 +439,56 @@ public class RegisterVMNode extends AbstractExpressionVMNode rm.done(); } - + + /** + * Expected format: GRP( GroupName ).REG( RegisterName ) + * or: $RegisterName + */ + public boolean canParseExpression(IExpression expression) { return parseExpressionForRegisterName(expression.getExpressionText()) != null; } - - /** - * Expected format: $$"Group Name"$Register_Name.Bit_Field_Name - */ + private String parseExpressionForRegisterName(String expression) { - if (expression.startsWith("$$\"")) { //$NON-NLS-1$ - int secondQuoteIdx = expression.indexOf('"', "$$\"".length()); //$NON-NLS-1$ - if (secondQuoteIdx > 0) { - String registerSubString = expression.substring(secondQuoteIdx + 1); - if (registerSubString.length() != 0 && - registerSubString.charAt(0) == '$' && - Character.isLetterOrDigit(registerSubString.charAt(1))) - { - int registerEnd = 1; - while ( registerEnd < registerSubString.length() && - Character.isLetterOrDigit(registerSubString.charAt(registerEnd)) ) - { - registerEnd++; - } - return registerSubString.substring(1, registerEnd); - } + if (expression.startsWith("GRP(")) { //$NON-NLS-1$ + /* + * Get the group portion. + */ + int startIdx = "GRP(".length(); //$NON-NLS-1$ + int endIdx = expression.indexOf(')', startIdx); + String remaining = expression.substring(endIdx+1); + if ( ! remaining.startsWith(".REG(") ) { //$NON-NLS-1$ + return null; } - } + + /* + * Get the register portion. + */ + startIdx = ".REG(".length(); //$NON-NLS-1$ + endIdx = remaining.indexOf(')', startIdx); + String regName = remaining.substring(startIdx,endIdx); + return regName.trim(); + } + else if ( expression.startsWith("$") ) { //$NON-NLS-1$ + /* + * At this point I am leaving this code here to represent the register case. To do this + * correctly would be to use the findRegister function and upgrade the register service + * to deal with registers that do not have a specified group parent context. I do not + * have the time for this right now. So by saying we do not handle this the Expression + * VM node will take it and pass it to the debug engine as a generic expression. Most + * debug engines ( GDB included ) have an inherent knowledge of the core registers as + * part of their expression evaluation and will respond with a flat value for the reg. + * This is not totally complete in that you should be able to express a register which + * has bit fields for example and the bit fields should be expandable in the expression + * view. With this method it will just appear to have a single value and no sub-fields. + * I will file a defect/enhancement for this to mark it. This comment will act as the + * place-holder for the future work. + */ + return null; + } + return null; } - @Override protected void testElementForExpression(Object element, IExpression expression, final DataRequestMonitor rm) { if (!(element instanceof IDMVMContext)) { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/VariableVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/VariableVMNode.java index c106b6f146a..d3a923c03d8 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/VariableVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/VariableVMNode.java @@ -442,10 +442,16 @@ public class VariableVMNode extends AbstractExpressionVMNode } public boolean canParseExpression(IExpression expression) { - // Indicate that we can parse any expression that does not start with - // the reserved '$' and '#' characters. - String expressionText = expression.getExpressionText(); - return !expressionText.startsWith("$") && !expressionText.startsWith("#"); + // At this point we are going to say we will allow anything as an expression. + // Since the evaluation of VM Node implementations searches in the order of + // registration and we always make sure we register the VariableVMNode last, + // we know that the other possible handlers have passed the expression by. So + // we are going to say OK and let the expression evaluation of whatever debug + // backend is connected to decide. This does not allow us to put up any good + // diagnostic error message ( instead the error will come from the backend ). + // But it does allow for the most flexibility + + return true; } @Override diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/viewmodel/numberformat/detail/MessagesForNumberFormatDetail.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/viewmodel/numberformat/detail/MessagesForNumberFormatDetail.java index db569450015..0d643a5160a 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/viewmodel/numberformat/detail/MessagesForNumberFormatDetail.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/viewmodel/numberformat/detail/MessagesForNumberFormatDetail.java @@ -3,7 +3,7 @@ package org.eclipse.dd.dsf.debug.internal.ui.viewmodel.numberformat.detail; import org.eclipse.osgi.util.NLS; class MessagesForNumberFormatDetail extends NLS { - private static final String BUNDLE_NAME = "org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat.detail.messages"; //$NON-NLS-1$ + private static final String BUNDLE_NAME = "org.eclipse.dd.dsf.debug.internal.ui.viewmodel.numberformat.detail.messages"; //$NON-NLS-1$ public static String NumberFormatDetailPane_name; public static String NumberFormatDetailPane_description; From dc95d5a7f73cefe97ac55a57aa5ed35ba0a6efbb Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Mon, 28 Apr 2008 19:40:06 +0000 Subject: [PATCH 411/834] Bug 228265 Cleanup to have an internal utility class --- .../launching/GdbLaunchDelegate.java | 304 ++++++++++-------- 1 file changed, 161 insertions(+), 143 deletions(-) diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java index 546cf6b05ee..e0d22abd5b2 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java @@ -100,12 +100,13 @@ public class GdbLaunchDelegate extends LaunchConfigurationDelegate monitor.subTask( "Debugging local C/C++ application" ); //$NON-NLS-1$ } - IPath exePath = verifyProgramPath( config ); - ICProject project = verifyCProject( config ); - if ( exePath != null ) { - verifyBinary( project, exePath ); - } - + // First verify we are dealing with a proper project. + ICProject project = LaunchUtils.verifyCProject(config); + // Now verify we know the program to debug. + IPath exePath = LaunchUtils.verifyProgramPath(config, project); + // Finally, make sure the program is a proper binary. + LaunchUtils.verifyBinary(config, exePath); + monitor.worked( 1 ); // If we are attaching, get the process id now, so as to avoid starting the launch @@ -183,7 +184,6 @@ public class GdbLaunchDelegate extends LaunchConfigurationDelegate return SessionType.RUN; } - // Copied from the CDT protected int promptForProcessID(ILaunchConfiguration config) throws CoreException { IStatus fPromptStatus = new Status(IStatus.INFO, "org.eclipse.debug.ui", 200, "", null); //$NON-NLS-1$//$NON-NLS-2$ IStatus processPrompt = new Status(IStatus.INFO, "org.eclipse.cdt.launch", 100, "", null); //$NON-NLS-1$//$NON-NLS-2$ @@ -199,11 +199,11 @@ public class GdbLaunchDelegate extends LaunchConfigurationDelegate } @Override - public boolean preLaunchCheck( ILaunchConfiguration config, String mode, IProgressMonitor monitor ) throws CoreException { + public boolean preLaunchCheck(ILaunchConfiguration config, String mode, IProgressMonitor monitor) throws CoreException { // no pre launch check for core file if (mode.equals(ILaunchManager.DEBUG_MODE) && getSessionType(config) == SessionType.CORE) return true; - return super.preLaunchCheck( config, mode, monitor ); + return super.preLaunchCheck(config, mode, monitor); } @Override @@ -238,135 +238,6 @@ public class GdbLaunchDelegate extends LaunchConfigurationDelegate return null; } - /** - * Throws a core exception with an error status object built from the given - * message, lower level exception, and error code. - * - * @param message - * the status message - * @param exception - * lower level exception associated with the error, or - * null if none - * @param code - * error code - */ - protected void abort(String message, Throwable exception, int code) throws CoreException { - MultiStatus status = new MultiStatus(GdbPlugin.PLUGIN_ID, code, message, exception); - status.add(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, code, exception == null ? "" : exception.getLocalizedMessage(), //$NON-NLS-1$ - exception)); - throw new CoreException(status); - } - - public static ICProject getCProject(ILaunchConfiguration configuration) throws CoreException { - String projectName = getProjectName(configuration); - if (projectName != null) { - projectName = projectName.trim(); - if (projectName.length() > 0) { - IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); - ICProject cProject = CCorePlugin.getDefault().getCoreModel().create(project); - if (cProject != null && cProject.exists()) { - return cProject; - } - } - } - return null; - } - - public static String getProjectName(ILaunchConfiguration configuration) throws CoreException { - return configuration.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME, (String)null); - } - - public static String getProgramName(ILaunchConfiguration configuration) throws CoreException { - return configuration.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, (String)null); - } - - public static IPath getProgramPath(ILaunchConfiguration configuration) throws CoreException { - String path = getProgramName(configuration); - if (path == null) { - return null; - } - return new Path(path); - } - - protected ICProject verifyCProject(ILaunchConfiguration config) throws CoreException { - String name = getProjectName(config); - if (name == null) { - abort(LaunchMessages.getString("AbstractCLaunchDelegate.C_Project_not_specified"), null, //$NON-NLS-1$ - ICDTLaunchConfigurationConstants.ERR_UNSPECIFIED_PROJECT); - } - ICProject cproject = getCProject(config); - if (cproject == null) { - IProject proj = ResourcesPlugin.getWorkspace().getRoot().getProject(name); - if (!proj.exists()) { - abort( - LaunchMessages.getFormattedString("AbstractCLaunchDelegate.Project_NAME_does_not_exist", name), null, //$NON-NLS-1$ - ICDTLaunchConfigurationConstants.ERR_NOT_A_C_PROJECT); - } else if (!proj.isOpen()) { - abort(LaunchMessages.getFormattedString("AbstractCLaunchDelegate.Project_NAME_is_closed", name), null, //$NON-NLS-1$ - ICDTLaunchConfigurationConstants.ERR_NOT_A_C_PROJECT); - } - abort(LaunchMessages.getString("AbstractCLaunchDelegate.Not_a_C_CPP_project"), null, //$NON-NLS-1$ - ICDTLaunchConfigurationConstants.ERR_NOT_A_C_PROJECT); - } - return cproject; - } - - protected IPath verifyProgramPath(ILaunchConfiguration config) throws CoreException { - ICProject cproject = verifyCProject(config); - IPath programPath = getProgramPath(config); - if (programPath == null || programPath.isEmpty()) { - return null; - } - if (!programPath.isAbsolute()) { - IFile wsProgramPath = cproject.getProject().getFile(programPath); - programPath = wsProgramPath.getLocation(); - } - if (!programPath.toFile().exists()) { - abort( - LaunchMessages.getString("AbstractCLaunchDelegate.Program_file_does_not_exist"), //$NON-NLS-1$ - new FileNotFoundException( - LaunchMessages.getFormattedString( - "AbstractCLaunchDelegate.PROGRAM_PATH_not_found", programPath.toOSString())), //$NON-NLS-1$ - ICDTLaunchConfigurationConstants.ERR_PROGRAM_NOT_EXIST); - } - return programPath; - } - - /** - * @param project - * @param exePath - * @return - * @throws CoreException - */ - protected IBinaryObject verifyBinary(ICProject proj, IPath exePath) throws CoreException { - ICExtensionReference[] parserRef = CCorePlugin.getDefault().getBinaryParserExtensions(proj.getProject()); - for (int i = 0; i < parserRef.length; i++) { - try { - IBinaryParser parser = (IBinaryParser)parserRef[i].createExtension(); - IBinaryObject exe = (IBinaryObject)parser.getBinary(exePath); - if (exe != null) { - return exe; - } - } catch (ClassCastException e) { - } catch (IOException e) { - } - } - IBinaryParser parser = CCorePlugin.getDefault().getDefaultBinaryParser(); - try { - return (IBinaryObject)parser.getBinary(exePath); - } catch (ClassCastException e) { - } catch (IOException e) { - } - Throwable exception = new FileNotFoundException(LaunchMessages.getFormattedString( - "AbstractCLaunchDelegate.Program_is_not_a_recongnized_executable", exePath.toOSString())); //$NON-NLS-1$ - int code = ICDTLaunchConfigurationConstants.ERR_PROGRAM_NOT_BINARY; - MultiStatus status = new MultiStatus(GdbPlugin.PLUGIN_ID, code, - LaunchMessages.getString("AbstractCLaunchDelegate.Program_is_not_a_recongnized_executable"), exception); //$NON-NLS-1$ - status.add(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, code, exception == null ? "" : exception.getLocalizedMessage(), //$NON-NLS-1$ - exception)); - throw new CoreException(status); - } - /** * Recursively creates a set of projects referenced by the current project * @@ -381,7 +252,7 @@ public class GdbLaunchDelegate extends LaunchConfigurationDelegate private HashSet getReferencedProjectSet(IProject proj, HashSet referencedProjSet) throws CoreException { // The top project is a reference too and it must be added at the top to avoid cycles referencedProjSet.add(proj); - + IProject[] projects = proj.getReferencedProjects(); for (IProject refProject : projects) { if (refProject.exists() && !referencedProjSet.contains(refProject)) { @@ -400,7 +271,7 @@ public class GdbLaunchDelegate extends LaunchConfigurationDelegate IProject[] orderedProjects = null; ArrayList orderedProjList = null; - ICProject cProject = getCProject(configuration); + ICProject cProject = LaunchUtils.verifyCProject(configuration); if (cProject != null) { HashSet projectSet = getReferencedProjectSet(cProject.getProject(), new HashSet()); @@ -420,7 +291,7 @@ public class GdbLaunchDelegate extends LaunchConfigurationDelegate } } } - + // Add any remaining projects to the end of the list orderedProjList.addAll(unorderedProjects); @@ -439,7 +310,7 @@ public class GdbLaunchDelegate extends LaunchConfigurationDelegate protected IProject[] getProjectsForProblemSearch(ILaunchConfiguration configuration, String mode) throws CoreException { return getBuildOrder(configuration, mode); } - + /** * Searches for compile errors in the specified project * Used in finalLaunchCheck() @@ -447,7 +318,6 @@ public class GdbLaunchDelegate extends LaunchConfigurationDelegate * The project to search * @return true if compile errors exist, otherwise false */ - @Override protected boolean existsProblems(IProject proj) throws CoreException { IMarker[] markers = proj.findMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE); @@ -461,4 +331,152 @@ public class GdbLaunchDelegate extends LaunchConfigurationDelegate } return false; } + + private static class LaunchUtils { + /** + * Verify the following things about the project: + * - is a valid project name given + * - does the project exist + * - is the project open + * - is the project a C/C++ project + */ + public static ICProject verifyCProject(ILaunchConfiguration configuration) throws CoreException { + String name = getProjectName(configuration); + if (name == null) { + abort(LaunchMessages.getString("AbstractCLaunchDelegate.C_Project_not_specified"), null, //$NON-NLS-1$ + ICDTLaunchConfigurationConstants.ERR_UNSPECIFIED_PROJECT); + } + ICProject cproject = getCProject(configuration); + if (cproject == null) { + IProject proj = ResourcesPlugin.getWorkspace().getRoot().getProject(name); + if (!proj.exists()) { + abort( + LaunchMessages.getFormattedString("AbstractCLaunchDelegate.Project_NAME_does_not_exist", name), null, //$NON-NLS-1$ + ICDTLaunchConfigurationConstants.ERR_NOT_A_C_PROJECT); + } else if (!proj.isOpen()) { + abort(LaunchMessages.getFormattedString("AbstractCLaunchDelegate.Project_NAME_is_closed", name), null, //$NON-NLS-1$ + ICDTLaunchConfigurationConstants.ERR_NOT_A_C_PROJECT); + } + abort(LaunchMessages.getString("AbstractCLaunchDelegate.Not_a_C_CPP_project"), null, //$NON-NLS-1$ + ICDTLaunchConfigurationConstants.ERR_NOT_A_C_PROJECT); + } + return cproject; + } + + + /** + * Verify that program name of the configuration can be found as a file. + * + * @return Absolute path of the program location + */ + public static IPath verifyProgramPath(ILaunchConfiguration configuration, ICProject cproject) throws CoreException { + String programName = configuration.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, (String)null); + if (programName == null) { + abort(LaunchMessages.getString("AbstractCLaunchDelegate.Program_file_not_specified"), null, //$NON-NLS-1$ + ICDTLaunchConfigurationConstants.ERR_NOT_A_C_PROJECT); + } + + IPath programPath = new Path(programName); + if (programPath.isEmpty()) { + abort(LaunchMessages.getString("AbstractCLaunchDelegate.Program_file_does_not_exist"), null, //$NON-NLS-1$ + ICDTLaunchConfigurationConstants.ERR_NOT_A_C_PROJECT); + } + + if (!programPath.isAbsolute()) { + // Find the specified program within the specified project + IFile wsProgramPath = cproject.getProject().getFile(programPath); + programPath = wsProgramPath.getLocation(); + } + + if (!programPath.toFile().exists()) { + abort(LaunchMessages.getString("AbstractCLaunchDelegate.Program_file_does_not_exist"), //$NON-NLS-1$ + new FileNotFoundException( + LaunchMessages.getFormattedString("AbstractCLaunchDelegate.PROGRAM_PATH_not_found", //$NON-NLS-1$ + programPath.toOSString())), + ICDTLaunchConfigurationConstants.ERR_PROGRAM_NOT_EXIST); + } + + return programPath; + } + + + /** + * Verify that the executable path points to a valid binary file. + * + * @return An object representing the binary file. + */ + public static IBinaryObject verifyBinary(ILaunchConfiguration configuration, IPath exePath) throws CoreException { + ICExtensionReference[] parserRefs = CCorePlugin.getDefault().getBinaryParserExtensions(getCProject(configuration).getProject()); + for (ICExtensionReference parserRef : parserRefs) { + try { + IBinaryParser parser = (IBinaryParser)parserRef.createExtension(); + IBinaryObject exe = (IBinaryObject)parser.getBinary(exePath); + if (exe != null) { + return exe; + } + } catch (ClassCastException e) { + } catch (IOException e) { + } + } + + IBinaryParser parser = CCorePlugin.getDefault().getDefaultBinaryParser(); + try { + return (IBinaryObject)parser.getBinary(exePath); + } catch (ClassCastException e) { + } catch (IOException e) { + } + + abort(LaunchMessages.getString("AbstractCLaunchDelegate.Program_is_not_a_recognized_executable"), //$NON-NLS-1$ + new FileNotFoundException( + LaunchMessages.getFormattedString("AbstractCLaunchDelegate.Program_is_not_a_recognized_executable", //$NON-NLS-1$ + exePath.toOSString())), + ICDTLaunchConfigurationConstants.ERR_PROGRAM_NOT_BINARY); + + return null; + } + + /** + * Throws a core exception with an error status object built from the given + * message, lower level exception, and error code. + * + * @param message + * the status message + * @param exception + * lower level exception associated with the error, or + * null if none + * @param code + * error code + */ + private static void abort(String message, Throwable exception, int code) throws CoreException { + MultiStatus status = new MultiStatus(GdbPlugin.PLUGIN_ID, code, message, exception); + status.add(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, code, + exception == null ? "" : exception.getLocalizedMessage(), //$NON-NLS-1$ + exception)); + throw new CoreException(status); + } + + /** + * Returns an ICProject based on the project name provided in the configuration. + * First look for a project by name, and then confirm it is a C/C++ project. + */ + private static ICProject getCProject(ILaunchConfiguration configuration) throws CoreException { + String projectName = getProjectName(configuration); + if (projectName != null) { + projectName = projectName.trim(); + if (projectName.length() > 0) { + IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); + ICProject cProject = CCorePlugin.getDefault().getCoreModel().create(project); + if (cProject != null && cProject.exists()) { + return cProject; + } + } + } + return null; + } + + private static String getProjectName(ILaunchConfiguration configuration) throws CoreException { + return configuration.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME, (String)null); + } + } + } From 688c32b7436b4efcb412fad8cf98da67bc8dee27 Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Tue, 29 Apr 2008 15:23:58 +0000 Subject: [PATCH 412/834] Bugzilla 197358 --- .../org.eclipse.dd.dsf.debug.ui/plugin.xml | 153 ++++++++++++++++++ 1 file changed, 153 insertions(+) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml index 7bee3bc9d1c..c7dec8bb485 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml +++ b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml @@ -107,6 +107,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Date: Tue, 29 Apr 2008 16:51:33 +0000 Subject: [PATCH 413/834] Bugzilla 206561. --- .../src/org/eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java index 03d907edec6..a2c294d9086 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java @@ -150,7 +150,11 @@ public class VMViewerUpdate implements IViewerUpdate { public TreePath getElementPath() { return fElementPath; } public IPresentationContext getPresentationContext() { return fPresentationContext; } public IStatus getStatus() { return fRequestMonitor.getStatus(); } - public void setStatus(IStatus status) { fRequestMonitor.setStatus(status); } + public void setStatus(IStatus status) { + if ( isCanceled() ) { + fRequestMonitor.cancel(); + } + fRequestMonitor.setStatus(status); } public boolean isCanceled() { if (fClientUpdate != null) { From c067bd385f6a4161384df7915040c8f106725d35 Mon Sep 17 00:00:00 2001 From: Randy Rohrbach Date: Tue, 29 Apr 2008 17:24:20 +0000 Subject: [PATCH 414/834] Bugzilla 204992 & 205735 --- .../register/RegisterBitFieldVMNode.java | 76 ++++++++++++++++++- .../register/RegisterGroupVMNode.java | 4 + .../ui/viewmodel/register/RegisterVMNode.java | 60 +++++++++++++-- .../ui/viewmodel/variable/VariableVMNode.java | 14 +++- 4 files changed, 143 insertions(+), 11 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterBitFieldVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterBitFieldVMNode.java index 57c706a8438..0d29ee3042e 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterBitFieldVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterBitFieldVMNode.java @@ -47,13 +47,18 @@ import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext; import org.eclipse.debug.core.model.IExpression; +import org.eclipse.debug.internal.ui.DebugPluginImages; +import org.eclipse.debug.internal.ui.DebugUIPlugin; +import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementEditor; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapter2; +import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.ComboBoxCellEditor; @@ -216,7 +221,7 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode /* * Format has been validated. Get the formatted value. */ - FormattedValueDMContext valueDmc = regService.getFormattedValueContext(dmc, finalFormatId); + final FormattedValueDMContext valueDmc = regService.getFormattedValueContext(dmc, finalFormatId); getDMVMProvider().getModelData( RegisterBitFieldVMNode.this, update, regService, valueDmc, @@ -224,8 +229,14 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode @Override public void handleCompleted() { if (!isSuccess()) { - handleFailedUpdate(update); - return; + if (getStatus().getCode() == IDsfStatusConstants.INVALID_STATE) { + update.setLabel("...", labelIndex); //$NON-NLS-1$ + } else { + update.setLabel("Error: " + getStatus().getMessage(), labelIndex); //$NON-NLS-1$ + } + update.setFontData(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0], labelIndex); + update.done(); + return; } /* @@ -239,6 +250,17 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode else { update.setLabel(getData().getFormattedValue() , labelIndex); } + + update.setFontData(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0], labelIndex); + + // color based on change history + + FormattedValueDMData oldData = (FormattedValueDMData) getDMVMProvider().getArchivedModelData( + RegisterBitFieldVMNode.this, update, valueDmc); + if(oldData != null && !oldData.getFormattedValue().equals(getData().getFormattedValue())) { + update.setBackground( + DebugUIPlugin.getPreferenceColor(IInternalDebugUIConstants.PREF_CHANGED_VALUE_BACKGROUND).getRGB(), labelIndex); + } update.done(); } }, @@ -288,7 +310,50 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode assert getStatus().isOK() || getStatus().getCode() != IDsfStatusConstants.INTERNAL_ERROR || getStatus().getCode() != IDsfStatusConstants.NOT_SUPPORTED; - handleFailedUpdate(update); + /* + * Instead of just failing this outright we are going to attempt to do more here. + * Failing it outright causes the view to display ... for all columns in the line + * and this is uninformative about what is happening. We may be trying to show a + * register whos retrieval has been cancelled by the lower level. Perhaps because + * we are stepping extremely fast and state changes cause the register service to + * return these requests without ever sending them to the debug engine. + * + */ + String[] localColumns = update.getPresentationContext().getColumns(); + if (localColumns == null) + localColumns = new String[] { IDebugVMConstants.COLUMN_ID__NAME }; + + for (int idx = 0; idx < localColumns.length; idx++) { + if (IDebugVMConstants.COLUMN_ID__NAME.equals(localColumns[idx])) { + /* + * This used to be easy in that the DMC contained the name. Which allowed us + * to display the register name and an error message across from it. Now that + * name must come from the data and we could not retrieve the data we do not + * have anything intelligent to show here. I think this is going to look very + * ugly and will need to be worked on. We know the service has the name with + * it, it is just the dynamic part which cannot be obtained ( as explained in + * comments above ). + */ + update.setLabel("Unknown name", idx); //$NON-NLS-1$ + update.setImageDescriptor(DebugPluginImages.getImageDescriptor(IDebugUIConstants.IMG_OBJS_REGISTER), idx); + } else if (IDebugVMConstants.COLUMN_ID__TYPE.equals(localColumns[idx])) { + update.setLabel("", idx); //$NON-NLS-1$ + } else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(localColumns[idx])) { + if (getStatus().getCode() == IDsfStatusConstants.INVALID_STATE) { + update.setLabel("...", idx); //$NON-NLS-1$ + } else { + update.setLabel("Error: " + getStatus().getMessage(), idx); //$NON-NLS-1$ + } + } else if (IDebugVMConstants.COLUMN_ID__DESCRIPTION.equals(localColumns[idx])) { + update.setLabel("...", idx); //$NON-NLS-1$ + } else if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(localColumns[idx])) { + update.setLabel("", idx); //$NON-NLS-1$ + } + + update.setFontData(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0], idx); + } + + update.done(); return; } @@ -336,6 +401,8 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode update.setLabel(getData().getName(), idx); } } + + update.setFontData(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0], idx); } if ( ! weAreExtractingFormattedData ) { @@ -345,6 +412,7 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode if (IDebugVMConstants.COLUMN_ID__VALUE.equals(localColumns[idx])) { updateFormattedRegisterValue(update, idx, dmc, getData() ); } + update.setFontData(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0], idx); } } } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterGroupVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterGroupVMNode.java index b3b1c5f7494..52a93c95a77 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterGroupVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterGroupVMNode.java @@ -38,6 +38,7 @@ import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext; import org.eclipse.debug.core.model.IExpression; import org.eclipse.debug.internal.ui.DebugPluginImages; +import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementEditor; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; @@ -46,6 +47,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapter2; +import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.ICellModifier; import org.eclipse.jface.viewers.TextCellEditor; @@ -215,6 +217,8 @@ public class RegisterGroupVMNode extends AbstractExpressionVMNode protected void fillColumnLabel(IRegisterGroupDMContext dmContext, IRegisterGroupDMData dmData, String columnId, int idx, ILabelUpdate update) { + update.setFontData(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0], idx); + if (IDebugVMConstants.COLUMN_ID__NAME.equals(columnId)) { update.setLabel(dmData.getName(), idx); update.setImageDescriptor(DebugPluginImages.getImageDescriptor(IDebugUIConstants.IMG_OBJS_REGISTER_GROUP), idx); diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterVMNode.java index 710e9a1613e..f58ff9a74db 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/register/RegisterVMNode.java @@ -53,6 +53,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapter2; +import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.ICellModifier; @@ -226,7 +227,13 @@ public class RegisterVMNode extends AbstractExpressionVMNode @Override public void handleCompleted() { if (!isSuccess()) { - handleFailedUpdate(update); + if (getStatus().getCode() == IDsfStatusConstants.INVALID_STATE) { + update.setLabel("...", labelIndex); //$NON-NLS-1$ + } else { + update.setLabel("Error: " + getStatus().getMessage(), labelIndex); //$NON-NLS-1$ + } + update.setFontData(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0], labelIndex); + update.done(); return; } /* @@ -240,10 +247,9 @@ public class RegisterVMNode extends AbstractExpressionVMNode RegisterVMNode.this, update, valueDmc); if(oldData != null && !oldData.getFormattedValue().equals(getData().getFormattedValue())) { update.setBackground( - DebugUIPlugin.getPreferenceColor( - IInternalDebugUIConstants.PREF_CHANGED_VALUE_BACKGROUND).getRGB(), - labelIndex); + DebugUIPlugin.getPreferenceColor(IInternalDebugUIConstants.PREF_CHANGED_VALUE_BACKGROUND).getRGB(), labelIndex); } + update.setFontData(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0], labelIndex); update.done(); } }, @@ -291,7 +297,50 @@ public class RegisterVMNode extends AbstractExpressionVMNode assert getStatus().isOK() || getStatus().getCode() != IDsfStatusConstants.INTERNAL_ERROR || getStatus().getCode() != IDsfStatusConstants.NOT_SUPPORTED; - handleFailedUpdate(update); + /* + * Instead of just failing this outright we are going to attempt to do more here. + * Failing it outright causes the view to display ... for all columns in the line + * and this is uninformative about what is happening. We may be trying to show a + * register whos retrieval has been cancelled by the lower level. Perhaps because + * we are stepping extremely fast and state changes cause the register service to + * return these requests without ever sending them to the debug engine. + * + */ + String[] localColumns = update.getPresentationContext().getColumns(); + if (localColumns == null) + localColumns = new String[] { IDebugVMConstants.COLUMN_ID__NAME }; + + for (int idx = 0; idx < localColumns.length; idx++) { + if (IDebugVMConstants.COLUMN_ID__NAME.equals(localColumns[idx])) { + /* + * This used to be easy in that the DMC contained the name. Which allowed us + * to display the register name and an error message across from it. Now that + * name must come from the data and we could not retrieve the data we do not + * have anything intelligent to show here. I think this is going to look very + * ugly and will need to be worked on. We know the service has the name with + * it, it is just the dynamic part which cannot be obtained ( as explained in + * comments above ). + */ + update.setLabel("Unknown name", idx); //$NON-NLS-1$ + update.setImageDescriptor(DebugPluginImages.getImageDescriptor(IDebugUIConstants.IMG_OBJS_REGISTER), idx); + } else if (IDebugVMConstants.COLUMN_ID__TYPE.equals(localColumns[idx])) { + update.setLabel("", idx); //$NON-NLS-1$ + } else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(localColumns[idx])) { + if (getStatus().getCode() == IDsfStatusConstants.INVALID_STATE) { + update.setLabel("...", idx); //$NON-NLS-1$ + } else { + update.setLabel("Error: " + getStatus().getMessage(), idx); //$NON-NLS-1$ + } + } else if (IDebugVMConstants.COLUMN_ID__DESCRIPTION.equals(localColumns[idx])) { + update.setLabel("...", idx); //$NON-NLS-1$ + } else if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(localColumns[idx])) { + update.setLabel("", idx); //$NON-NLS-1$ + } + + update.setFontData(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0], idx); + } + + update.done(); return; } @@ -310,6 +359,7 @@ public class RegisterVMNode extends AbstractExpressionVMNode boolean weAreExtractingFormattedData = false; for (int idx = 0; idx < localColumns.length; idx++) { + update.setFontData(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0], idx); if (IDebugVMConstants.COLUMN_ID__NAME.equals(localColumns[idx])) { update.setLabel(getData().getName(), idx); update.setImageDescriptor(DebugPluginImages.getImageDescriptor(IDebugUIConstants.IMG_OBJS_REGISTER), idx); diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/VariableVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/VariableVMNode.java index d3a923c03d8..924aa52b57e 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/VariableVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/variable/VariableVMNode.java @@ -58,6 +58,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapter2; +import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.ICellModifier; @@ -254,8 +255,10 @@ public class VariableVMNode extends AbstractExpressionVMNode } else if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(localColumns[idx])) { update.setLabel(dmc.getExpression(), idx); } + update.setFontData(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0], idx); } + update.done(); return; } @@ -290,6 +293,7 @@ public class VariableVMNode extends AbstractExpressionVMNode update.setLabel(getData().getName(), idx); } } + update.setFontData(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0], idx); } if ( ! weAreExtractingFormattedData ) { @@ -299,6 +303,7 @@ public class VariableVMNode extends AbstractExpressionVMNode if (IDebugVMConstants.COLUMN_ID__VALUE.equals(localColumns[idx])) { updateFormattedExpressionValue(update, idx, dmc, getData()); } + update.setFontData(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0], idx); } } } @@ -331,7 +336,9 @@ public class VariableVMNode extends AbstractExpressionVMNode @Override public void handleCompleted() { if (!isSuccess()) { - handleFailedUpdate(update); + update.setLabel("Format information not available", labelIndex); + update.setFontData(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0], labelIndex); + update.done(); return; } @@ -381,7 +388,9 @@ public class VariableVMNode extends AbstractExpressionVMNode @Override public void handleCompleted() { if (!isSuccess()) { - handleFailedUpdate(update); + update.setLabel("Error : " + getStatus().getMessage(), labelIndex); + update.setFontData(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0], labelIndex); + update.done(); return; } @@ -396,6 +405,7 @@ public class VariableVMNode extends AbstractExpressionVMNode } update.setLabel(stringValueBuf.toString(), labelIndex);*/ update.setLabel(getData().getFormattedValue(), labelIndex); + update.setFontData(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0], labelIndex); // Color based on change history FormattedValueDMData oldData = (FormattedValueDMData) getDMVMProvider().getArchivedModelData( From 5474268d37c3eab35e36cfe70d8a98b9a5cd4cd7 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Tue, 29 Apr 2008 20:09:48 +0000 Subject: [PATCH 415/834] Bug 223076 Generate tokenId when needed and printout debug traces when MI command is actually sent. --- .../mi/service/command/AbstractMIControl.java | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java index 1c040aaf715..1de0c9848f1 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java @@ -215,7 +215,7 @@ public abstract class AbstractMIControl extends AbstractDsfService /* * We are putting this one on the wire. We need to add it to the waiting list so - * the user has the chance to cancel it when we tell them we are acknowleding it + * the user has the chance to cancel it when we tell them we are acknowledging it * has been officially accepted. They could choose to cancel it before we go and * send it. That is why we put it into the QUEUE and then check to see if it is * still there. @@ -235,8 +235,8 @@ public abstract class AbstractMIControl extends AbstractDsfService fCurrentThreadId = handle.getThreadId().intValue(); CommandHandle cmdHandle = new CommandHandle( new MIThreadSelect(handle.fCommand.getContext(), fCurrentThreadId), null); + cmdHandle.generateTokenId(); fTxCommands.add(cmdHandle); - MIPlugin.debug(MIPlugin.getDebugTime() + " " + cmdHandle.getTokenId() + cmdHandle.getCommand()); //$NON-NLS-1$ } // Before the command is sent, Check the Stack level and send it to @@ -248,10 +248,11 @@ public abstract class AbstractMIControl extends AbstractDsfService fCurrentStackLevel = handle.getStackFrameId().intValue(); CommandHandle cmdHandle = new CommandHandle( new MIStackSelectFrame(handle.fCommand.getContext(), fCurrentStackLevel), null); + cmdHandle.generateTokenId(); fTxCommands.add(cmdHandle); - MIPlugin.debug(MIPlugin.getDebugTime() + " " + cmdHandle.getTokenId() + cmdHandle.getCommand()); //$NON-NLS-1$ } - fTxCommands.add(handle); + handle.generateTokenId(); + fTxCommands.add(handle); } } @@ -336,7 +337,6 @@ public abstract class AbstractMIControl extends AbstractDsfService } private void processCommandSent(CommandHandle commandHandle) { - MIPlugin.debug(MIPlugin.getDebugTime() + " " + commandHandle.getTokenId() + commandHandle.getCommand()); //$NON-NLS-1$ for (ICommandListener processor : fCommandProcessors) { processor.commandSent(commandHandle); } @@ -403,11 +403,15 @@ public abstract class AbstractMIControl extends AbstractDsfService CommandHandle(MICommand c, DataRequestMonitor d) { fCommand = c; fRequestMonitor = d; - fTokenId = getNewTokenId() ; + fTokenId = -1; // Only initialize to a real value when needed } public MICommand getCommand() { return fCommand; } public DataRequestMonitor getRequestMonitor() { return fRequestMonitor; } + // This method allows us to generate the token Id when we area actually going to use + // it. It is meant to help order the token ids based on when commands will actually + // be sent + public void generateTokenId() { fTokenId = getNewTokenId(); } public Integer getTokenId() { return fTokenId; } //public String getThreadId() { return null; } @@ -435,7 +439,7 @@ public abstract class AbstractMIControl extends AbstractDsfService * This is the transmitter thread. When a command is given to this thread it has been * considered to be sent, even if it has not actually been sent yet. This assumption * makes it easier from state management. Whomever fill this pipeline handles all of - * the required state notofication ( callbacks ). This thread simply physically gives + * the required state notification ( callbacks ). This thread simply physically gives * the message to the backend. */ @@ -478,12 +482,17 @@ public abstract class AbstractMIControl extends AbstractDsfService * Construct the new command and push this command out the pipeline. */ - String str = commandHandle.getTokenId() + commandHandle.getCommand().constructCommand(); + final String str = commandHandle.getTokenId() + commandHandle.getCommand().constructCommand(); try { if (fOutputStream != null) { fOutputStream.write(str.getBytes()); fOutputStream.flush(); + getExecutor().execute(new DsfRunnable() { + public void run() { + MIPlugin.debug(MIPlugin.getDebugTime() + " " + str); //$NON-NLS-1$ + } + }); } } catch (IOException e) { // Shutdown thread in case of IO error. @@ -717,6 +726,7 @@ public abstract class AbstractMIControl extends AbstractDsfService CommandHandle comHandle = fCommandQueue.remove(0); if ( comHandle != null ) { processCommandSent(comHandle); + comHandle.generateTokenId(); fTxCommands.add(comHandle); } } From cc153db8ba4515daf07b94ad95a4d568058b03d0 Mon Sep 17 00:00:00 2001 From: Francois Chouinard Date: Tue, 29 Apr 2008 21:26:59 +0000 Subject: [PATCH 416/834] Implementation of the DSF Disassembly View (bug227743) --- plugins/org.eclipse.dd.dsf.debug.ui/.options | 1 + .../META-INF/MANIFEST.MF | 14 +- .../icons/disassembly.gif | Bin 0 -> 145 bytes .../plugin.properties | 19 +- .../org.eclipse.dd.dsf.debug.ui/plugin.xml | 83 +- .../debug/internal/ui/DsfDebugUIPlugin.java | 15 +- .../ui/disassembly/AbstractImageRegistry.java | 143 + .../ui/disassembly/AddressRulerColumn.java | 191 + .../disassembly/DisassemblyDropAdapter.java | 121 + .../ui/disassembly/DisassemblyEditor.java | 117 + .../DisassemblyHyperlinkDetector.java | 100 + .../disassembly/DisassemblyImageRegistry.java | 69 + .../ui/disassembly/DisassemblyMessages.java | 98 + .../DisassemblyMessages.properties | 89 + .../ui/disassembly/DisassemblyPart.java | 3442 +++++++++++++++++ .../disassembly/DisassemblyRulerColumn.java | 985 +++++ .../ui/disassembly/DisassemblyTextHover.java | 148 + .../ui/disassembly/DisassemblyView.java | 110 + .../ui/disassembly/DisassemblyViewer.java | 283 ++ .../DisassemblyViewerConfiguration.java | 131 + .../ui/disassembly/EditionFinderJob.java | 105 + .../FunctionOffsetRulerColumn.java | 69 + .../IDisassemblyHelpContextIds.java | 24 + .../ui/disassembly/IDisassemblyPart.java | 102 + .../ui/disassembly/SourceColorerJob.java | 78 + .../actions/AbstractDisassemblyAction.java | 63 + ...tractDisassemblyBreakpointRulerAction.java | 77 + .../AbstractDisassemblyRulerAction.java | 41 + ...bstractDisassemblyRulerActionDelegate.java | 167 + .../actions/ActionGotoAddress.java | 65 + .../actions/ActionGotoProgramCounter.java | 26 + .../disassembly/actions/ActionGotoSymbol.java | 59 + .../actions/ActionOpenPreferences.java | 29 + .../BreakpointPropertiesRulerAction.java | 82 + ...eakpointPropertiesRulerActionDelegate.java | 30 + .../actions/TextOperationAction.java | 58 + .../ui/disassembly/model/Addr2Line.java | 25 + .../model/AddressRangePosition.java | 66 + .../model/BreakpointsAnnotationModel.java | 229 ++ .../model/DisassemblyDocument.java | 1423 +++++++ .../model/DisassemblyPosition.java | 49 + .../model/DisassemblyWithSourcePosition.java | 52 + .../ui/disassembly/model/ErrorPosition.java | 40 + .../ui/disassembly/model/LabelPosition.java | 32 + .../model/SourceDocumentProvider.java | 116 + .../disassembly/model/SourceEditorInput.java | 35 + .../ui/disassembly/model/SourceFileInfo.java | 187 + .../ui/disassembly/model/SourcePosition.java | 50 + .../disassembly/model/SourceReadingJob.java | 80 + .../DisassemblyPreferenceConstants.java | 84 + .../DisassemblyPreferencePage.java | 313 ++ .../CSourcePresentationCreator.java | 349 ++ .../disassembly/presentation/CSourceTag.java | 207 + .../presentation/CSourceTagProvider.java | 95 + .../presentation/DisassemblyIPAnnotation.java | 79 + .../ISourcePresentationCreator.java | 35 + .../presentation/ISourceRange.java | 30 + .../disassembly/presentation/ISourceTag.java | 83 + .../presentation/ISourceTagListener.java | 24 + .../presentation/ISourceTagProvider.java | 49 + .../SourcePresentationCreatorFactory.java | 25 + .../SourceTagDamagerRepairer.java | 374 ++ .../ui/disassembly/text/IFileRider.java | 119 + .../ui/disassembly/text/REDDocument.java | 46 + .../internal/ui/disassembly/text/REDFile.java | 480 +++ .../ui/disassembly/text/REDFileRider.java | 149 + .../internal/ui/disassembly/text/REDRun.java | 149 + .../ui/disassembly/text/REDTextStore.java | 874 +++++ .../ui/disassembly/text/StringRider.java | 100 + .../ui/disassembly/text/StringTextStore.java | 70 + .../internal/ui/disassembly/util/HSL.java | 111 + .../disassembly/util/StorageEditorInput.java | 112 + .../service/command/output/MIInstruction.java | 21 +- 73 files changed, 13585 insertions(+), 11 deletions(-) create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/.options create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/icons/disassembly.gif create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/AbstractImageRegistry.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/AddressRulerColumn.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyDropAdapter.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyEditor.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyHyperlinkDetector.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyImageRegistry.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyMessages.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyMessages.properties create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyPart.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyRulerColumn.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyTextHover.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyView.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyViewer.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyViewerConfiguration.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/EditionFinderJob.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/FunctionOffsetRulerColumn.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/IDisassemblyHelpContextIds.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/IDisassemblyPart.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/SourceColorerJob.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/AbstractDisassemblyAction.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/AbstractDisassemblyBreakpointRulerAction.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/AbstractDisassemblyRulerAction.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/AbstractDisassemblyRulerActionDelegate.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/ActionGotoAddress.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/ActionGotoProgramCounter.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/ActionGotoSymbol.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/ActionOpenPreferences.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/BreakpointPropertiesRulerAction.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/BreakpointPropertiesRulerActionDelegate.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/TextOperationAction.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/Addr2Line.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/AddressRangePosition.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/BreakpointsAnnotationModel.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/DisassemblyDocument.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/DisassemblyPosition.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/DisassemblyWithSourcePosition.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/ErrorPosition.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/LabelPosition.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/SourceDocumentProvider.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/SourceEditorInput.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/SourceFileInfo.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/SourcePosition.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/SourceReadingJob.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/preferences/DisassemblyPreferenceConstants.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/preferences/DisassemblyPreferencePage.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/presentation/CSourcePresentationCreator.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/presentation/CSourceTag.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/presentation/CSourceTagProvider.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/presentation/DisassemblyIPAnnotation.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/presentation/ISourcePresentationCreator.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/presentation/ISourceRange.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/presentation/ISourceTag.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/presentation/ISourceTagListener.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/presentation/ISourceTagProvider.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/presentation/SourcePresentationCreatorFactory.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/presentation/SourceTagDamagerRepairer.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/text/IFileRider.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/text/REDDocument.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/text/REDFile.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/text/REDFileRider.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/text/REDRun.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/text/REDTextStore.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/text/StringRider.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/text/StringTextStore.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/util/HSL.java create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/util/StorageEditorInput.java diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/.options b/plugins/org.eclipse.dd.dsf.debug.ui/.options new file mode 100644 index 00000000000..b38dd1e13cc --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/.options @@ -0,0 +1 @@ +org.eclipse.dd.dsf.debug.ui/debug = false diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF index cb71e55f66e..b6129e300b3 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF @@ -1,7 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 -Bundle-Name: Debug Services Framework Debug UI -Bundle-Vendor: Eclipse.org +Bundle-Name: %pluginName +Bundle-Vendor: %providerName Bundle-SymbolicName: org.eclipse.dd.dsf.debug.ui; singleton:=true Bundle-Version: 1.0.0.qualifier Bundle-Activator: org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin @@ -18,7 +18,15 @@ Require-Bundle: org.eclipse.ui, org.eclipse.dd.dsf.ui, org.eclipse.dd.dsf.debug, org.eclipse.cdt.core, - org.eclipse.cdt.debug.ui + org.eclipse.cdt.debug.core, + org.eclipse.cdt.debug.ui, + org.eclipse.jface.text;bundle-version="3.4.0", + org.eclipse.ui.editors;bundle-version="3.4.0", + org.eclipse.ui.workbench.texteditor;bundle-version="3.4.0", + org.eclipse.ui.ide;bundle-version="3.4.0", + org.eclipse.cdt.ui;bundle-version="5.0.0", + org.eclipse.core.expressions;bundle-version="3.4.0", + org.eclipse.core.filesystem;bundle-version="1.2.0" Bundle-ActivationPolicy: lazy Export-Package: org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel, diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/icons/disassembly.gif b/plugins/org.eclipse.dd.dsf.debug.ui/icons/disassembly.gif new file mode 100644 index 0000000000000000000000000000000000000000..34f5290474b745d4113b3405d617c6606d012a82 GIT binary patch literal 145 zcmZ?wbhEHb6krfw*v!CSZ$IBYe!qSF{$-~=9Jq7f|Ns9Cc!AeDh9;!5RQrpe}6y literal 0 HcmV?d00001 diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.properties b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.properties index d7b098572ef..20d921a68b9 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.properties +++ b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2006 Wind River Systems and others. +# Copyright (c) 2006, 2008 Wind River Systems and others. # All rights reserved. This program and the accompanying materials # are made available under the terms of the Eclipse Public License v1.0 # which accompanies this distribution, and is available at @@ -8,6 +8,21 @@ # Contributors: # Wind River Systems - initial API and implementation ############################################################################### -pluginName=DSDP/DD Debugger Services Framework (DSF) Debug UI +pluginName=Debug Services Framework Debug UI providerName=Eclipse.org +# disassembly +disassemblyPreferencePage.name = DSF Disassembly +disassemblyView.name= DSF Disassembly + +command.gotoPC.name=Go to Program Counter +command.gotoPC.description=Navigate to current program counter +command.gotoAddress.name=Go to Address... +command.gotoAddress.description=Navigate to address +command.gotoSymbol.name=Go to Symbol... +command.gotoSymbol.description=Navigate to symbolic address + +commandContext.name= In DSF Disassembly +commandContext.description= When debugging in assembly mode + +action.breakpointProperties.label = Breakpoint Properties... diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml index c7dec8bb485..21b6f155b7c 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml +++ b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml @@ -278,5 +278,86 @@ id="org.eclipse.dd.dsf.debug.ui.viewmodel.moduleDetailPaneFactory"> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/DsfDebugUIPlugin.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/DsfDebugUIPlugin.java index 5e20f049521..144b4d90fa8 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/DsfDebugUIPlugin.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/DsfDebugUIPlugin.java @@ -1,5 +1,6 @@ package org.eclipse.dd.dsf.debug.internal.ui; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.SourceDocumentProvider; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.ui.plugin.AbstractUIPlugin; import org.osgi.framework.BundleContext; @@ -17,8 +18,11 @@ public class DsfDebugUIPlugin extends AbstractUIPlugin { private static DsfDebugUIPlugin plugin; // BundleContext of this plugin - private static BundleContext fgBundleContext; - + private static BundleContext fgBundleContext; + + // The document provider for source documents in the disassembly. + private SourceDocumentProvider fSourceDocumentProvider; + /** * The constructor */ @@ -35,6 +39,7 @@ public class DsfDebugUIPlugin extends AbstractUIPlugin { plugin = this; fgBundleContext = context; + fSourceDocumentProvider = new SourceDocumentProvider(); } /* @@ -43,6 +48,8 @@ public class DsfDebugUIPlugin extends AbstractUIPlugin { */ @Override public void stop(BundleContext context) throws Exception { + fSourceDocumentProvider.dispose(); + fSourceDocumentProvider = null; plugin = null; super.stop(context); } @@ -75,4 +82,8 @@ public class DsfDebugUIPlugin extends AbstractUIPlugin { public static ImageDescriptor getImageDescriptor(String path) { return imageDescriptorFromPlugin(PLUGIN_ID, path); } + + public static SourceDocumentProvider getSourceDocumentProvider() { + return getDefault().fSourceDocumentProvider; + } } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/AbstractImageRegistry.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/AbstractImageRegistry.java new file mode 100644 index 00000000000..2f4aedcb834 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/AbstractImageRegistry.java @@ -0,0 +1,143 @@ +/******************************************************************************* + * Copyright (c) 2007, 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Plugin; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.ImageRegistry; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.graphics.Image; +import org.osgi.framework.Bundle; + + +/** + * Abstract image registry that allows for defining fallback paths for images. + */ +public abstract class AbstractImageRegistry extends ImageRegistry { + private HashMap fPlugins = new HashMap(); + private HashMap fLocations = new HashMap(); + private URL fBaseUrl; + + protected AbstractImageRegistry(Plugin plugin) { + fBaseUrl = plugin.getBundle().getEntry("/"); //$NON-NLS-1$ + } + + /** + * Defines the key for a local image, that must be found below the icons directory + * in the plugin. + * @param key Key by which the image can be referred by. + * @param dir Directory relative to icons/ + * @param name The name of the file defining the icon. The name will be used as + * key. + */ + protected void localImage(String key, String dir, String name) { + if (dir== null || dir.equals(""))//$NON-NLS-1$ + fLocations.put(key, new String[] {"icons/" + name}); //$NON-NLS-1$ + else + fLocations.put(key, new String[] {"icons/" + dir + "/" + name}); //$NON-NLS-1$ //$NON-NLS-2$ + } + + /** + * Defines the key for a non-local image, that must be found below the icons directory + * of some plugin. + * @param key Key by which the image can be referred by. + * @param plugin The plugin id, where the icon is searched. + * @param dirs A couple of directories below icons/ in the plugin. If loading fails, + * the next dir will be taken as fallback. + * @param name The name of the file defining the icon. The name will be used as + * key. + */ + protected void externalImage(String key, String plugin, String[] dirs, String name) { + if (plugin != null) { + fPlugins.put(key, plugin); + } + String[] locations = new String[dirs.length]; + for (int i = 0; i < dirs.length; i++) { + String dir = dirs[i]; + if (dir== null || dir.equals(""))//$NON-NLS-1$ + locations[i] = "icons/" + name; //$NON-NLS-1$ + else + locations[i] = "icons/" + dir + "/" + name; //$NON-NLS-1$ //$NON-NLS-2$ + } + fLocations.put(key, locations); + } + + // overrider + @Override + final public Image get(String key) { + Image i = super.get(key); + if (i != null) { + return i; + } + + ImageDescriptor d = createFileImageDescriptor(key); + if (d != null) { + put(key, d); + return super.get(key); + } + return null; + } + + // overrider + @Override + final public ImageDescriptor getDescriptor(String key) { + ImageDescriptor d = super.getDescriptor(key); + if (d != null) { + return d; + } + + d = createFileImageDescriptor(key); + if (d != null) { + put(key, d); + return d; + } + return null; + } + + private ImageDescriptor createFileImageDescriptor(String key) { + URL url = fBaseUrl; + String pluginId = fPlugins.get(key); + if (pluginId != null) { + Bundle bundle= Platform.getBundle(pluginId); + if (bundle != null) { + url = bundle.getEntry("/"); //$NON-NLS-1$ + } + } + String[] locations= fLocations.get(key); + if (locations != null) { + for (int i = 0; i < locations.length; i++) { + String loc = locations[i]; + URL full; + try { + full = new URL(url, loc); + ImageDescriptor candidate = ImageDescriptor.createFromURL(full); + if (candidate != null && candidate.getImageData() != null) { + return candidate; + } + } catch (MalformedURLException e) { + DsfDebugUIPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, "Malformed Icon URL", e)); //$NON-NLS-1$ + } catch (SWTException e) { + // try the next one. + } + } + } + return null; + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/AddressRulerColumn.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/AddressRulerColumn.java new file mode 100644 index 00000000000..df91c158d50 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/AddressRulerColumn.java @@ -0,0 +1,191 @@ +/******************************************************************************* + * Copyright (c) 2007, 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly; + +import java.math.BigInteger; + +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.AddressRangePosition; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.DisassemblyDocument; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.SourceFileInfo; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.SourcePosition; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.source.IAnnotationHover; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.jface.text.source.IVerticalRulerInfo; +import org.eclipse.jface.text.source.IVerticalRulerInfoExtension; +import org.eclipse.jface.text.source.IVerticalRulerListener; +import org.eclipse.swt.SWT; + +/** + * A vertical ruler column to display the instruction address. + */ +public class AddressRulerColumn extends DisassemblyRulerColumn implements IVerticalRulerInfo, IVerticalRulerInfoExtension, IAnnotationHover { + + private int fRadix; + private boolean fShowRadixPrefix; + private String fRadixPrefix; + private int fNumberOfDigits; + private int fAddressSize; + + /** + * Default constructor. + */ + public AddressRulerColumn() { + super(SWT.LEFT); + setShowRadixPrefix(true); + setAddressSize(32); + setRadix(16); + } + + /* + * @see com.windriver.ide.disassembly.views.DisassemblyRulerColumn#createDisplayString(int) + */ + @Override + protected String createDisplayString(int line) { + DisassemblyDocument doc = (DisassemblyDocument)getParentRuler().getTextViewer().getDocument(); + int offset; + try { + offset = doc.getLineOffset(line); + AddressRangePosition pos = doc.getDisassemblyPosition(offset); + if (pos != null && pos.length > 0 && pos.offset == offset) { + if (pos.fValid) { + return getAddressText(pos.fAddressOffset); + } else { + return DOTS.substring(0, computeNumberOfCharacters()); + } + } + SourcePosition srcPos = doc.getSourcePosition(offset); + if (srcPos != null && srcPos.fValid && srcPos.length > 0) { + int srcLine; + int nLines; + if (srcPos.fFileInfo.fSource == null) { + srcLine = srcPos.fLine; + nLines = srcLine+1; + } else { + int delta = offset-srcPos.offset; + int baseOffset = srcPos.fFileInfo.fSource.getLineOffset(srcPos.fLine); + srcLine = srcPos.fFileInfo.fSource.getLineOfOffset(baseOffset+delta); + nLines = srcPos.fFileInfo.fSource.getNumberOfLines(); + } + String digitStr = Integer.toString(srcLine+1); + int maxDigits = (int)(Math.log(nLines)/Math.log(10))+1; + return SPACES.substring(0, maxDigits-digitStr.length())+digitStr; + } + } catch (BadLocationException e) { + // silently ignored + } + return ""; //$NON-NLS-1$ + } + + /* + * @see com.windriver.ide.disassembly.views.DisassemblyRulerColumn#computeNumberOfCharacters() + */ + @Override + protected int computeNumberOfCharacters() { + return fNumberOfDigits + (fRadixPrefix != null ? fRadixPrefix.length() : 0) + 1; + } + + public void setAddressSize(int bits) { + fAddressSize= bits; + calculateNumberOfDigits(); + } + + public void setRadix(int radix) { + fRadix= radix; + calculateNumberOfDigits(); + setShowRadixPrefix(fShowRadixPrefix); + } + + private void calculateNumberOfDigits() { + fNumberOfDigits= BigInteger.ONE.shiftLeft(fAddressSize).subtract(BigInteger.ONE).toString(fRadix).length(); + } + + public void setShowRadixPrefix(boolean showRadixPrefix) { + fShowRadixPrefix = showRadixPrefix; + if (!fShowRadixPrefix) { + fRadixPrefix = null; + } else if (fRadix == 16) { + fRadixPrefix = "0x"; //$NON-NLS-1$ + } else if (fRadix == 8) { + fRadixPrefix = "0"; //$NON-NLS-1$ + } else { + fRadixPrefix = null; + } + } + + private String getAddressText(BigInteger address) { + StringBuffer buf = new StringBuffer(fNumberOfDigits + 3); + if (fRadixPrefix != null) { + buf.append(fRadixPrefix); + } + String str = address.toString(fRadix); + for (int i=str.length(); i fStore = new ArrayList(); + + private static String add(String plugin, String[] dirs, String name) { + String key = plugin+'/'+dirs[0]+'/'+name; + fStore.add(new Object[] {key, plugin, dirs, name}); + return key; + } + + private static final String ORG_ECLIPSE_DEBUG_UI_PLUGIN_ID = "org.eclipse.debug.ui"; //$NON-NLS-1$ + private static final String ORG_ECLIPSE_UI_PLUGIN_ID = "org.eclipse.ui"; //$NON-NLS-1$ + + public static final String ICON_ToggleBreakpoint = add(ORG_ECLIPSE_DEBUG_UI_PLUGIN_ID, new String[] { "full/obj16"}, "brkp_obj.gif"); //$NON-NLS-1$ //$NON-NLS-2$ + public static final String ICON_Refresh_enabled = add(ORG_ECLIPSE_UI_PLUGIN_ID, new String[] {"full/elcl16"}, "refresh_nav.gif"); //$NON-NLS-1$ //$NON-NLS-2$ + public static final String ICON_Refresh_disabled = add(ORG_ECLIPSE_UI_PLUGIN_ID, new String[] {"full/dlcl16"}, "refresh_nav.gif"); //$NON-NLS-1$ //$NON-NLS-2$ + public static final String ICON_Copy_enabled = add(ORG_ECLIPSE_UI_PLUGIN_ID, new String[] {"full/etool16"}, "copy_edit.gif"); //$NON-NLS-1$ //$NON-NLS-2$ + public static final String ICON_Copy_disabled = add(ORG_ECLIPSE_UI_PLUGIN_ID, new String[] {"full/dtool16"}, "copy_edit.gif"); //$NON-NLS-1$ //$NON-NLS-2$ + + private static DisassemblyImageRegistry INSTANCE= new DisassemblyImageRegistry(DsfDebugUIPlugin.getDefault()); + + DisassemblyImageRegistry(Plugin plugin) { + super(plugin); + initialize(); + } + + void initialize() { + for (Iterator iter = fStore.iterator(); iter.hasNext();) { + Object[] element = iter.next(); + if (element.length == 2) { + String dir= (String) element[0]; + String name= (String) element[1]; + localImage(name, dir, name); + } else { + String key = (String) element[0]; + String plugin= (String) element[1]; + String[] dirs= (String[]) element[2]; + String name= (String) element[3]; + externalImage(key, plugin, dirs, name); + } + } + } + + public static ImageDescriptor getImageDescriptor(String key) { + return INSTANCE.getDescriptor(key); + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyMessages.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyMessages.java new file mode 100644 index 00000000000..241f34de10d --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyMessages.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright (c) 2007, 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly; + +import org.eclipse.osgi.util.NLS; + +public final class DisassemblyMessages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.dd.dsf.debug.internal.ui.disassembly.DisassemblyMessages";//$NON-NLS-1$ + + private DisassemblyMessages() { + // Do not instantiate + } + + public static String Disassembly_action_ShowAddresses_label; + public static String Disassembly_action_ShowFunctionOffsets_label; + public static String Disassembly_action_ShowDisassembly_label; + public static String Disassembly_action_ShowSource_label; + public static String Disassembly_action_ShowSymbols_label; + public static String Disassembly_action_ShowSimplified_label; + public static String Disassembly_action_SourceSteppingMode_error; + public static String Disassembly_action_SourceSteppingMode_label; + public static String Disassembly_action_AssemblySteppingMode_label; + public static String Disassembly_action_RunToHere_label; + public static String Disassembly_action_SetPCToHere_label; + public static String Disassembly_action_GotoPC_label; + public static String Disassembly_action_GotoPC_tooltip; + public static String Disassembly_action_GotoAddress_label; + public static String Disassembly_action_GotoSymbol_label; + public static String Disassembly_action_Copy_label; + public static String Disassembly_action_SelectAll_label; + public static String Disassembly_action_BreakpointProperties_label; + public static String Disassembly_action_RemoveBreakpoint_label; + public static String Disassembly_action_AddBreakpoint_label; + public static String Disassembly_action_AddHWBreakpoint_label; + public static String Disassembly_action_AddTracepoint_label; + public static String Disassembly_action_DisableBreakpoint_label; + public static String Disassembly_action_EnableBreakpoint_label; + public static String Disassembly_action_WatchExpression_label; + public static String Disassembly_action_ShowInMemory_label; + public static String Disassembly_action_RefreshView_label; + public static String Disassembly_action_OpenPreferences_label; + public static String Disassembly_GotoAddressDialog_title; + public static String Disassembly_GotoAddressDialog_label; + public static String Disassembly_GotoAddressDialog_error_invalid_address; + public static String Disassembly_GotoAddressDialog_error_not_a_number; + public static String Disassembly_GotoSymbolDialog_title; + public static String Disassembly_GotoSymbolDialog_label; + public static String Disassembly_message_notConnected; + public static String Disassembly_log_error_retrieveFrameAddress; + public static String Disassembly_log_error_locateFile; + public static String Disassembly_log_error_accessLineInfo; + public static String Disassembly_log_error_noFileInfo; + public static String Disassembly_log_error_fileTooLarge; + public static String Disassembly_log_error_readFile; + public static String Disassembly_log_error_createVersion; + public static String Disassembly_log_error_retrieveDisassembly; + public static String Disassembly_log_error_showDisassembly; + public static String Disassembly_log_error_invalidSymbol; + public static String DisassemblyPreferencePage_startAddress; + public static String DisassemblyPreferencePage_endAddress; + public static String DisassemblyPreferencePage_addressRadix; + public static String DisassemblyPreferencePage_instructionRadix; + public static String DisassemblyPreferencePage_showAddressRadix; + public static String DisassemblyPreferencePage_showSource; + public static String DisassemblyPreferencePage_showSymbols; + public static String DisassemblyPreferencePage_simplifiedMnemonics; + public static String DisassemblyPreferencePage_error_not_a_number; + public static String DisassemblyPreferencePage_error_negative_number; + public static String DisassemblyPreferencePage_radix_octal; + public static String DisassemblyPreferencePage_radix_decimal; + public static String DisassemblyPreferencePage_radix_hexadecimal; + public static String DisassemblyPreferencePage_showFunctionOffsets; + public static String DisassemblyPreferencePage_showAddress; + public static String DisassemblyPreferencePage_useSourceOnlyMode; + public static String DisassemblyPreferencePage_useSourceOnlyMode_noteTtitle; + public static String DisassemblyPreferencePage_useSourceOnlyMode_noteMessage; + public static String DisassemblyPreferencePage_avoidReadBeforePC; + public static String DisassemblyIPAnnotation_primary; + public static String DisassemblyIPAnnotation_secondary; + public static String SourceReadingJob_name; + public static String SourceColorerJob_name; + public static String EditionFinderJob_name; + public static String EditionFinderJob_task_get_timestamp; + public static String EditionFinderJob_task_search_history; + + static { + NLS.initializeMessages(BUNDLE_NAME, DisassemblyMessages.class); + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyMessages.properties b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyMessages.properties new file mode 100644 index 00000000000..479808236de --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyMessages.properties @@ -0,0 +1,89 @@ +########################################################################## +# Copyright (c) 2007, 2008 Wind River Systems and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Wind River Systems - initial API and implementation +########################################################################## + +Disassembly_action_ShowAddresses_label=Show Addresses +Disassembly_action_ShowFunctionOffsets_label=Show Function Offsets +Disassembly_action_ShowDisassembly_label=Show Disassembly of Source +Disassembly_action_ShowSource_label=Show Source +Disassembly_action_ShowSymbols_label=Show Symbols +Disassembly_action_ShowSimplified_label=Show Simplified Instructions +Disassembly_action_SourceSteppingMode_error=Cannot open editor for file +Disassembly_action_SourceSteppingMode_label=Source Stepping Mode +Disassembly_action_AssemblySteppingMode_label=Assembly Stepping Mode +Disassembly_action_RunToHere_label=Run to Here +Disassembly_action_SetPCToHere_label=Set PC to Here +Disassembly_action_GotoPC_label=Go to Program Counter +Disassembly_action_GotoPC_tooltip=Go to Current Program Counter +Disassembly_action_GotoAddress_label=Go to Address... +Disassembly_action_GotoSymbol_label=Go to Symbol... +Disassembly_action_Copy_label=&Copy +Disassembly_action_SelectAll_label=Select &All +Disassembly_action_BreakpointProperties_label=Breakpoint Properties... +Disassembly_action_RemoveBreakpoint_label=Remove Breakpoint +Disassembly_action_AddBreakpoint_label=Add Breakpoint +Disassembly_action_AddHWBreakpoint_label=Add Hardware Breakpoint +Disassembly_action_AddTracepoint_label=Add Tracepoint... +Disassembly_action_DisableBreakpoint_label=Disable Breakpoint +Disassembly_action_EnableBreakpoint_label=Enable Breakpoint +Disassembly_action_WatchExpression_label=Watch Expression +Disassembly_action_ShowInMemory_label=Show In Memory View +Disassembly_action_RefreshView_label=Re&fresh View +Disassembly_action_OpenPreferences_label=&Preferences... + +Disassembly_GotoAddressDialog_title=Go to Address +Disassembly_GotoAddressDialog_label=Address: +Disassembly_GotoAddressDialog_error_invalid_address=Invalid address +Disassembly_GotoAddressDialog_error_not_a_number=Not a valid number format + +Disassembly_GotoSymbolDialog_title=Go to Symbol +Disassembly_GotoSymbolDialog_label=Symbol: + +Disassembly_message_notConnected=No debug context + +Disassembly_log_error_retrieveFrameAddress=Error retrieving frame address +Disassembly_log_error_locateFile=Unable to locate file:\ +Disassembly_log_error_accessLineInfo=Error accessing line information for:\ +Disassembly_log_error_noFileInfo=Debug information not found for:\ +Disassembly_log_error_fileTooLarge=Source file is too large to retrieve line information:\ +Disassembly_log_error_readFile=Cannot read source file:\ +Disassembly_log_error_createVersion=Cannot create version +Disassembly_log_error_retrieveDisassembly=Cannot retrieve disassembly for:\ +Disassembly_log_error_showDisassembly=Error opening Disassembly +Disassembly_log_error_invalidSymbol=Cannot evaluate symbolic address ''{0}'' + +DisassemblyPreferencePage_startAddress=Start address +DisassemblyPreferencePage_endAddress=End address +DisassemblyPreferencePage_addressRadix=Address display format +DisassemblyPreferencePage_instructionRadix=Instruction display format +DisassemblyPreferencePage_showAddressRadix=Force radix prefixes +DisassemblyPreferencePage_showSource=Show source +DisassemblyPreferencePage_showSymbols=Show symbols +DisassemblyPreferencePage_simplifiedMnemonics=Use simplified instruction mnemonics +DisassemblyPreferencePage_error_not_a_number=Not a valid number format +DisassemblyPreferencePage_error_negative_number=Address cannot be negative +DisassemblyPreferencePage_radix_octal=Octal +DisassemblyPreferencePage_radix_decimal=Decimal +DisassemblyPreferencePage_radix_hexadecimal=Hexadecimal +DisassemblyPreferencePage_showFunctionOffsets=Show function offsets +DisassemblyPreferencePage_showAddress=Show instruction address +DisassemblyPreferencePage_useSourceOnlyMode=Use Disassembly Viewer when debugging in source stepping mode +DisassemblyPreferencePage_useSourceOnlyMode_noteTtitle=Note: +DisassemblyPreferencePage_useSourceOnlyMode_noteMessage=When this option is enabled, the Disassembly Viewer will be used to display source locations in a special "source-only" mode, instead of using the normal Source Editor. +DisassemblyPreferencePage_avoidReadBeforePC=Do not disassemble code before current program counter + +DisassemblyIPAnnotation_primary=Debug Current Instruction Pointer +DisassemblyIPAnnotation_secondary=Debug Call Stack + +SourceReadingJob_name=Reading source file +SourceColorerJob_name=Coloring source file +EditionFinderJob_name=Finding best match for source file +EditionFinderJob_task_get_timestamp=Retrieving module timestamp +EditionFinderJob_task_search_history=Searching local history diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyPart.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyPart.java new file mode 100644 index 00000000000..fef238139e6 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyPart.java @@ -0,0 +1,3442 @@ +/******************************************************************************* + * Copyright (c) 2007, 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly; + +import java.io.File; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.concurrent.ExecutionException; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.core.CDIDebugModel; +import org.eclipse.cdt.debug.core.model.ICBreakpoint; +import org.eclipse.cdt.internal.ui.dnd.TextViewerDragAdapter; +import org.eclipse.cdt.utils.Addr64; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IStorage; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.ListenerList; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.Query; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions.AbstractDisassemblyAction; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions.ActionGotoAddress; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions.ActionGotoProgramCounter; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions.ActionGotoSymbol; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions.ActionOpenPreferences; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions.TextOperationAction; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.Addr2Line; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.AddressRangePosition; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.BreakpointsAnnotationModel; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.DisassemblyDocument; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.DisassemblyPosition; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.ErrorPosition; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.LabelPosition; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.SourceFileInfo; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.SourcePosition; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.preferences.DisassemblyPreferenceConstants; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.presentation.DisassemblyIPAnnotation; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.util.HSL; +import org.eclipse.dd.dsf.debug.service.IDisassembly; +import org.eclipse.dd.dsf.debug.service.IExpressions; +import org.eclipse.dd.dsf.debug.service.IFormattedValues; +import org.eclipse.dd.dsf.debug.service.IInstruction; +import org.eclipse.dd.dsf.debug.service.IMixedInstruction; +import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.ISourceLookup; +import org.eclipse.dd.dsf.debug.service.IStack; +import org.eclipse.dd.dsf.debug.service.IDisassembly.IDisassemblyDMContext; +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExitedDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent; +import org.eclipse.dd.dsf.debug.service.ISourceLookup.ISourceLookupDMContext; +import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; +import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMData; +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.DsfSession.SessionEndedListener; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.IBreakpointManager; +import org.eclipse.debug.core.model.IBreakpoint; +import org.eclipse.debug.core.model.ISuspendResume; +import org.eclipse.debug.core.sourcelookup.containers.LocalFileStorage; +import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.debug.ui.actions.IRunToLineTarget; +import org.eclipse.debug.ui.actions.IToggleBreakpointsTarget; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.GroupMarker; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.commands.ActionHandler; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.PreferenceConverter; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.BadPositionCategoryException; +import org.eclipse.jface.text.IFindReplaceTarget; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextOperationTarget; +import org.eclipse.jface.text.ITextPresentationListener; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.text.ITextViewerExtension; +import org.eclipse.jface.text.IViewportListener; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.Region; +import org.eclipse.jface.text.TextPresentation; +import org.eclipse.jface.text.source.Annotation; +import org.eclipse.jface.text.source.AnnotationModel; +import org.eclipse.jface.text.source.AnnotationRulerColumn; +import org.eclipse.jface.text.source.CompositeRuler; +import org.eclipse.jface.text.source.IAnnotationAccess; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.jface.text.source.IAnnotationModelExtension; +import org.eclipse.jface.text.source.IOverviewRuler; +import org.eclipse.jface.text.source.ISharedTextColors; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.jface.text.source.IVerticalRuler; +import org.eclipse.jface.text.source.IVerticalRulerColumn; +import org.eclipse.jface.text.source.IVerticalRulerExtension; +import org.eclipse.jface.text.source.IVerticalRulerInfo; +import org.eclipse.jface.text.source.OverviewRuler; +import org.eclipse.jface.text.source.SourceViewerConfiguration; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyleRange; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.DragSource; +import org.eclipse.swt.dnd.DropTarget; +import org.eclipse.swt.dnd.FileTransfer; +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IPartListener2; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchPartReference; +import org.eclipse.ui.IWorkbenchPartSite; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.actions.ActionFactory; +import org.eclipse.ui.contexts.IContextActivation; +import org.eclipse.ui.contexts.IContextService; +import org.eclipse.ui.editors.text.EditorsUI; +import org.eclipse.ui.handlers.IHandlerActivation; +import org.eclipse.ui.handlers.IHandlerService; +import org.eclipse.ui.ide.IGotoMarker; +import org.eclipse.ui.part.WorkbenchPart; +import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants; +import org.eclipse.ui.texteditor.AnnotationPreference; +import org.eclipse.ui.texteditor.ChainedPreferenceStore; +import org.eclipse.ui.texteditor.DefaultMarkerAnnotationAccess; +import org.eclipse.ui.texteditor.ITextEditorActionConstants; +import org.eclipse.ui.texteditor.IUpdate; +import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds; +import org.eclipse.ui.texteditor.MarkerAnnotationPreferences; +import org.eclipse.ui.texteditor.SimpleMarkerAnnotation; +import org.eclipse.ui.texteditor.SourceViewerDecorationSupport; + +/** + * DisassemblyPart + */ +public abstract class DisassemblyPart extends WorkbenchPart implements IDisassemblyPart, IViewportListener, ITextPresentationListener { + + private final static boolean DEBUG = DsfDebugUIPlugin.getDefault().isDebugging(); + + /** + * Annotation model attachment key for breakpoint annotations. + */ + private final static String BREAKPOINT_ANNOTATIONS= "breakpoints"; //$NON-NLS-1$ + + private final static BigInteger PC_UNKNOWN = BigInteger.valueOf(-1); + private final static BigInteger PC_RUNNING = BigInteger.valueOf(-2); + + /** Preference key for highlighting current line. */ + private final static String CURRENT_LINE = AbstractDecoratedTextEditorPreferenceConstants.EDITOR_CURRENT_LINE; + /** Preference key for highlight color of current line. */ + private final static String CURRENT_LINE_COLOR = AbstractDecoratedTextEditorPreferenceConstants.EDITOR_CURRENT_LINE_COLOR; + + /** The width of the vertical ruler. */ + protected final static int VERTICAL_RULER_WIDTH = 12; + + /** High water mark for cache */ + private final static int fgHighWaterMark = 500; + /** Low water mark for cache */ + private final static int fgLowWaterMark = 100; + + private static final String COMMAND_ID_GOTO_ADDRESS = "org.eclipse.dd.dsf.debug.ui.disassembly.commands.gotoAddress"; //$NON-NLS-1$ + private static final String COMMAND_ID_GOTO_PC = "org.eclipse.dd.dsf.debug.ui.disassembly.commands.gotoPC"; //$NON-NLS-1$ + private static final String COMMAND_ID_GOTO_SYMBOL = "org.eclipse.dd.dsf.debug.ui.disassembly.commands.gotoSymbol"; //$NON-NLS-1$ +// private static final String COMMAND_ID_TOGGLE_BREAKPOINT = "org.eclipse.debug.ui.commands.ToggleBreakpoint"; //$NON-NLS-1$ +// private static final String COMMAND_ID_RUN_TO_LINE = "org.eclipse.debug.ui.commands.RunToLine"; //$NON-NLS-1$ +// private static final String COMMAND_ID_TOGGLE_STEPPING_MODE = "org.eclipse.dd.dsf.debug.ui.debug.ui.menu.showDisassemblyAction"; //$NON-NLS-1$ + + private static final String KEY_BINDING_CONTEXT_DISASSEMBLY = "org.eclipse.dd.dsf.debug.ui.disassembly.context"; //$NON-NLS-1$ + + protected DisassemblyViewer fViewer; + + protected AbstractDisassemblyAction fActionGotoPC; + protected AbstractDisassemblyAction fActionGotoAddress; + private AbstractDisassemblyAction fActionGotoSymbol; + private AbstractDisassemblyAction fActionToggleBreakpoint; + protected AbstractDisassemblyAction fActionToggleSource; + private AbstractDisassemblyAction fActionToggleFunctionColumn; + private AbstractDisassemblyAction fActionToggleSymbols; + private AbstractDisassemblyAction fActionRefreshView; + private Action fActionOpenPreferences; + private AbstractDisassemblyAction fActionToggleAddressColumn; + private AbstractDisassemblyAction fActionToggleBreakpointEnablement; + + protected DisassemblyDocument fDocument; + private IAnnotationAccess fAnnotationAccess; + private AnnotationRulerColumn fAnnotationRulerColumn; + private MarkerAnnotationPreferences fAnnotationPreferences; + private IPreferenceStore fPreferenceStore; + private IOverviewRuler fOverviewRuler; + private final ListenerList fRulerContextMenuListeners= new ListenerList(ListenerList.IDENTITY); + private SourceViewerDecorationSupport fDecorationSupport; + private Font fFont; + private IVerticalRuler fVerticalRuler; + private IFindReplaceTarget fFindReplaceTarget; + private IPropertyChangeListener fPropertyChangeListener= new PropertyChangeListener(); + private Color fInstructionColor; + private Color fErrorColor; + private Color fSourceColor; + private Color fLabelColor; + private Control fRedrawControl; + private Point fContextClickLocation; + private RGB fPCAnnotationRGB; + private Composite fComposite; + + private DropTarget fDropTarget; + private DragSource fDragSource; + private TextViewerDragAdapter fDragSourceAdapter; + private DisassemblyDropAdapter fDropTargetAdapter; + + private FunctionOffsetRulerColumn fOpcodeRulerColumn; + private AddressRulerColumn fAddressRulerColumn; + + private BigInteger fStartAddress; + private BigInteger fEndAddress; + private int fAddressSize= 32; + + private volatile boolean fUpdatePending; + private BigInteger fPCAddress; + private BigInteger fGotoAddressPending= PC_UNKNOWN; + private BigInteger fFocusAddress= PC_UNKNOWN; + private int fBufferZone; + private IExecutionDMContext fTargetContext; + private String fDebugSessionId; + private int fTargetFrame; + private DisassemblyIPAnnotation fPCAnnotation; + private DisassemblyIPAnnotation fSecondaryPCAnnotation; + private boolean fPCAnnotationUpdatePending; + private ArrayList fPendingPCUpdates = new ArrayList(5); + private Position fScrollPos; + private int fScrollLine; + private Position fFocusPos; + private BigInteger fFrameAddress= PC_UNKNOWN; + protected Map fGlobalActions = new HashMap(); + private List fSelectionActions = new ArrayList(); + private List fStateDependentActions = new ArrayList(); + private boolean fSourceOnlyMode; + private boolean fShowSource; + private boolean fShowOpcodes; + private boolean fShowSymbols; + private Map fFile2Storage = new HashMap(); + private boolean fShowDisassembly; + private LinkedList fPCHistory = new LinkedList(); + private int fPCHistorySizeMax = 4; + private boolean fGotoFramePending; + + private String fPCAnnotationColorKey; + + private ArrayList fRunnableQueue = new ArrayList(); + + protected IPartListener2 fPartListener = + new IPartListener2() { + public void partActivated(IWorkbenchPartReference partRef) { + } + public void partBroughtToTop(IWorkbenchPartReference partRef) { + } + public void partClosed(IWorkbenchPartReference partRef) { + } + public void partDeactivated(IWorkbenchPartReference partRef) { + } + public void partOpened(IWorkbenchPartReference partRef) { + } + public void partHidden(IWorkbenchPartReference partRef) { + if (partRef.getPart(false) == DisassemblyPart.this) { + setActive(false); + } + } + public void partVisible(IWorkbenchPartReference partRef) { + if (partRef.getPart(false) == DisassemblyPart.this) { + setActive(true); + } + } + public void partInputChanged(IWorkbenchPartReference partRef) { + } + }; + + private boolean fActive = true; + private boolean fDoPendingPosted; + private boolean fUpdateBeforeFocus; + + private boolean fRefreshAll; + private IMarker fGotoMarkerPending; + private boolean fUpdateTitlePending; + private boolean fRefreshViewPending; + private boolean fUpdateSourcePending; + + private ArrayList fHandlerActivations; + private IContextActivation fContextActivation; + + private DsfServicesTracker fServicesTracker; + private IFrameDMContext fTargetFrameContext; + protected IFrameDMData fTargetFrameData; + + + private final class ActionRefreshView extends AbstractDisassemblyAction { + public ActionRefreshView() { + super(DisassemblyPart.this); + setText(DisassemblyMessages.Disassembly_action_RefreshView_label); + setImageDescriptor(DisassemblyImageRegistry.getImageDescriptor(DisassemblyImageRegistry.ICON_Refresh_enabled)); + setDisabledImageDescriptor(DisassemblyImageRegistry.getImageDescriptor(DisassemblyImageRegistry.ICON_Refresh_disabled)); + } + @Override + public void run() { + refreshView(10); + } + } + + private final class ActionToggleAddressColumn extends AbstractDisassemblyAction { + ActionToggleAddressColumn () { + super(DisassemblyPart.this); + setText(DisassemblyMessages.Disassembly_action_ShowAddresses_label); + } + @Override + public void run() { + IPreferenceStore store = DsfDebugUIPlugin.getDefault().getPreferenceStore(); + store.setValue(DisassemblyPreferenceConstants.SHOW_ADDRESS_RULER, !isAddressRulerVisible()); + } + @Override + public void update() { + setChecked(isAddressRulerVisible()); + } + } + + private final class ActionToggleFunctionColumn extends AbstractDisassemblyAction { + ActionToggleFunctionColumn() { + super(DisassemblyPart.this); + setText(DisassemblyMessages.Disassembly_action_ShowFunctionOffsets_label); + } + @Override + public void run() { + IPreferenceStore store = DsfDebugUIPlugin.getDefault().getPreferenceStore(); + store.setValue(DisassemblyPreferenceConstants.SHOW_FUNCTION_OFFSETS, !isOpcodeRulerVisible()); + } + @Override + public void update() { + setChecked(isOpcodeRulerVisible()); + } + } + + private final class ActionToggleBreakpoint extends AbstractDisassemblyAction { + private IBreakpoint fBreakpoint; + private int fLine; + public ActionToggleBreakpoint() { + super(DisassemblyPart.this); + setText(DisassemblyMessages.Disassembly_action_AddBreakpoint_label); + setImageDescriptor(DisassemblyImageRegistry.getImageDescriptor(DisassemblyImageRegistry.ICON_ToggleBreakpoint)); + } + @Override + public void run() { + try { + if (fBreakpoint != null) { + fBreakpoint.delete(); + } else { + insertBreakpoint(fLine, false); + } + } catch (CoreException e) { + DsfDebugUIPlugin.getDefault().getLog().log(e.getStatus()); + } + } + @Override + public void update() { + super.update(); + if (isEnabled()) { + fLine = fVerticalRuler.getLineOfLastMouseButtonActivity(); + IBreakpoint[] bps = getBreakpointsAtLine(fLine); + if (bps == null) { + fBreakpoint = null; + setText(DisassemblyMessages.Disassembly_action_AddBreakpoint_label); + } else { + fBreakpoint = bps[0]; + setText(DisassemblyMessages.Disassembly_action_RemoveBreakpoint_label); + } + } + } + } + + private final class ActionToggleBreakpointEnablement extends AbstractDisassemblyAction { + private IBreakpoint fBreakpoint; + public ActionToggleBreakpointEnablement() { + super(DisassemblyPart.this); + setText(DisassemblyMessages.Disassembly_action_EnableBreakpoint_label); + } + @Override + public void run() { + try { + fBreakpoint.setEnabled(!fBreakpoint.isEnabled()); + } catch (CoreException e) { + internalError(e); + } + } + @Override + public void update() { + super.update(); + if (isEnabled()) { + int line = fVerticalRuler.getLineOfLastMouseButtonActivity(); + IBreakpoint[] bps = getBreakpointsAtLine(line); + if (bps == null || bps.length == 0) { + setEnabled(false); + } else { + fBreakpoint = bps[0]; + try { + if (fBreakpoint.isEnabled()) { + setText(DisassemblyMessages.Disassembly_action_DisableBreakpoint_label); + } else { + setText(DisassemblyMessages.Disassembly_action_EnableBreakpoint_label); + } + } catch (CoreException e) { + setEnabled(false); + } + } + } + } + } + + private final class ActionToggleSource extends AbstractDisassemblyAction { + public ActionToggleSource() { + super(DisassemblyPart.this); + setText(DisassemblyMessages.Disassembly_action_ShowSource_label); + } + @Override + public void run() { + IPreferenceStore store = DsfDebugUIPlugin.getDefault().getPreferenceStore(); + boolean showSourceEnabled = store.getBoolean(DisassemblyPreferenceConstants.SHOW_SOURCE); + if (showSourceEnabled == fShowSource) { + store.setValue(DisassemblyPreferenceConstants.SHOW_SOURCE, !fShowSource); + } else { + sourceModeChanged(!fShowSource); + } + } + @Override + public void update() { + super.update(); + if (isEnabled()) { + setEnabled(fShowDisassembly); + } + setChecked(fShowSource); + } + } + + private final class ActionToggleSymbols extends AbstractDisassemblyAction { + public ActionToggleSymbols() { + super(DisassemblyPart.this); + setText(DisassemblyMessages.Disassembly_action_ShowSymbols_label); + } + @Override + public void run() { + IPreferenceStore store = DsfDebugUIPlugin.getDefault().getPreferenceStore(); + store.setValue(DisassemblyPreferenceConstants.SHOW_SYMBOLS, !fShowSymbols); + } + @Override + public void update() { + super.update(); + setChecked(fShowSymbols); + } + } + + /** + * Internal property change listener for handling changes in the + * preferences. + */ + class PropertyChangeListener implements IPropertyChangeListener { + /* + * @see IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent) + */ + public void propertyChange(PropertyChangeEvent event) { + handlePreferenceStoreChanged(event); + } + } + + + /** + * The constructor. + */ + public DisassemblyPart() { + fAnnotationPreferences = new MarkerAnnotationPreferences(); + setPreferenceStore(new ChainedPreferenceStore(new IPreferenceStore[] { + DsfDebugUIPlugin.getDefault().getPreferenceStore(), EditorsUI.getPreferenceStore() })); + fPCAddress = fFrameAddress = PC_RUNNING; + fTargetFrame = -1; + fBufferZone = 32; + fPCAnnotation = new DisassemblyIPAnnotation(true, 0); + fSecondaryPCAnnotation = new DisassemblyIPAnnotation(false, 0); + IPreferenceStore prefs = getPreferenceStore(); + fStartAddress = new BigInteger(prefs.getString(DisassemblyPreferenceConstants.START_ADDRESS)); + String endAddressString = prefs.getString(DisassemblyPreferenceConstants.END_ADDRESS); + if(endAddressString.startsWith("0x")) //$NON-NLS-1$ + fEndAddress = new BigInteger(endAddressString.substring(2), 16); + else + fEndAddress = new BigInteger(endAddressString, 16); + // TLETODO [disassembly[ source only mode + fSourceOnlyMode = false; //prefs.getBoolean(DisassemblyPreferenceConstants.USE_SOURCE_ONLY_MODE); + fShowSource = fSourceOnlyMode || prefs.getBoolean(DisassemblyPreferenceConstants.SHOW_SOURCE); + fShowDisassembly = !fSourceOnlyMode || !fShowSource; + fShowOpcodes = prefs.getBoolean(DisassemblyPreferenceConstants.SHOW_FUNCTION_OFFSETS); + fShowSymbols = prefs.getBoolean(DisassemblyPreferenceConstants.SHOW_SYMBOLS); + fUpdateBeforeFocus = !prefs.getBoolean(DisassemblyPreferenceConstants.AVOID_READ_BEFORE_PC); + fPCHistorySizeMax = prefs.getInt(DisassemblyPreferenceConstants.PC_HISTORY_SIZE); + } + + public void logWarning(String message, Throwable error) { + DsfDebugUIPlugin.getDefault().getLog().log(new Status(IStatus.WARNING, DsfDebugUIPlugin.PLUGIN_ID, message, error)); + } + + /* + * @see IAdaptable#getAdapter(java.lang.Class) + */ + @Override + public Object getAdapter(Class required) { + if (IVerticalRulerInfo.class.equals(required)) { + if (fVerticalRuler != null) { + return fVerticalRuler; + } + } else if (IDisassemblyPart.class.equals(required)) { + return this; + } else if (IFindReplaceTarget.class.equals(required)) { + if (fFindReplaceTarget == null) { + fFindReplaceTarget = (fViewer == null ? null : fViewer.getFindReplaceTarget()); + } + return fFindReplaceTarget; + } else if (ITextOperationTarget.class.equals(required)) { + return (fViewer == null ? null : fViewer.getTextOperationTarget()); + } else if (Control.class.equals(required)) { + return fViewer != null ? fViewer.getTextWidget() : null; + } else if (IGotoMarker.class.equals(required)) { + return new IGotoMarker() { + public void gotoMarker(IMarker marker) { + DisassemblyPart.this.gotoMarker(marker); + }}; + } else if (IToggleBreakpointsTarget.class.equals(required)) { + return new IToggleBreakpointsTarget() { + public void toggleLineBreakpoints(IWorkbenchPart part, ISelection selection) throws CoreException { + ITextSelection textSelection = (ITextSelection)selection; + int line = textSelection.getStartLine(); + IBreakpoint[] bp = getBreakpointsAtLine(line); + if (bp == null || bp.length == 0) { + insertBreakpoint(line, false); + } else { + for (int i = 0; i < bp.length; i++) { + bp[i].delete(); + } + } + } + public boolean canToggleLineBreakpoints(IWorkbenchPart part, ISelection selection) { + return fDebugSessionId != null; + } + public void toggleMethodBreakpoints(IWorkbenchPart part, ISelection selection) throws CoreException { + } + public boolean canToggleMethodBreakpoints(IWorkbenchPart part, ISelection selection) { + return false; + } + public void toggleWatchpoints(IWorkbenchPart part, ISelection selection) throws CoreException { + } + public boolean canToggleWatchpoints(IWorkbenchPart part, ISelection selection) { + return false; + }}; + } else if (IRunToLineTarget.class.equals(required)) { + return new IRunToLineTarget() { + public void runToLine(IWorkbenchPart part, ISelection selection, ISuspendResume target) throws CoreException { + ITextSelection textSelection = (ITextSelection)selection; + int line = textSelection.getStartLine(); + BigInteger address = getAddressOfLine(line); + // TLETODO [disassembly] run to line +// getRunControl().runUntil(...); + } + public boolean canRunToLine(IWorkbenchPart part, ISelection selection, ISuspendResume target) { + return fTargetContext != null && isSuspended(fTargetContext) ; + }}; + } + return super.getAdapter(required); + } + + private void setPreferenceStore(IPreferenceStore store) { + if (fPreferenceStore != null) { + fPreferenceStore.removePropertyChangeListener(fPropertyChangeListener); + } + + fPreferenceStore = store; + + if (fPreferenceStore != null) { + fPreferenceStore.addPropertyChangeListener(fPropertyChangeListener); + } + } + + /** + * Handles a property change event describing a change of the editor's + * preference store and updates the preference related editor properties. + *

              + * Subclasses may extend. + *

              + * + * @param event + * the property change event + */ + protected void handlePreferenceStoreChanged(PropertyChangeEvent event) { + + if (fViewer == null) + return; + + String property = event.getProperty(); + IPreferenceStore store = getPreferenceStore(); + + if (getFontPropertyPreferenceKey().equals(property)) { + initializeViewerFont(fViewer); + } else if (property.equals(DisassemblyPreferenceConstants.SHOW_ADDRESS_RULER)) { + fActionToggleAddressColumn.update(); + if (isAddressRulerVisible()) { + showAddressRuler(); + } else { + hideAddressRuler(); + } + } else if (property.equals(DisassemblyPreferenceConstants.ADDRESS_RADIX)) { + if (fAddressRulerColumn != null) { + hideAddressRuler(); + showAddressRuler(); + } + } else if (property.equals(DisassemblyPreferenceConstants.SHOW_ADDRESS_RADIX)) { + if (fAddressRulerColumn != null) { + hideAddressRuler(); + showAddressRuler(); + } + } else if (property.equals(DisassemblyPreferenceConstants.SHOW_SOURCE)) { + sourceModeChanged(store.getBoolean(property)); + } else if (property.equals(DisassemblyPreferenceConstants.INSTRUCTION_RADIX)) { + Runnable doit = new Runnable() { + public void run() { + fDocument.invalidateAddressRange(fStartAddress, fEndAddress, true); + if (!fShowDisassembly) { + fDocument.invalidateDisassemblyWithSource(true); + } + fDocument.setMaxOpcodeLength(0); + fGotoFramePending = true; + }}; + doScrollLocked(doit); + } else if (property.equals(DisassemblyPreferenceConstants.SHOW_SYMBOLS)) { + boolean showSymbols = store.getBoolean(property); + if (fShowSymbols == showSymbols) { + return; + } + fShowSymbols = showSymbols; + Runnable doit = new Runnable() { + public void run() { + fDocument.invalidateAddressRange(fStartAddress, fEndAddress, true); + if (!fShowDisassembly) { + fDocument.invalidateDisassemblyWithSource(true); + } + fGotoFramePending = true; + }}; + doScrollLocked(doit); + } else if (property.equals(DisassemblyPreferenceConstants.USE_SOURCE_ONLY_MODE)) { + fSourceOnlyMode = store.getBoolean(property); + if (fDebugSessionId != null) { + disassemblyModeChanged(isDissemblyMixedModeOn()); + } + } else if (property.equals(DisassemblyPreferenceConstants.SHOW_FUNCTION_OFFSETS)) { + fShowOpcodes = store.getBoolean(property); + fActionToggleFunctionColumn.update(); + if (isOpcodeRulerVisible()) { + showOpcodeRuler(); + } else { + hideOpcodeRuler(); + } + } else if (property.equals(DisassemblyPreferenceConstants.AVOID_READ_BEFORE_PC)) { + fUpdateBeforeFocus = !store.getBoolean(property); + updateVisibleArea(); + } else if (property.equals(fPCAnnotationColorKey)) { + fPCAnnotationRGB = PreferenceConverter.getColor(store, fPCAnnotationColorKey); + // redraw + for (Iterator it=fPCHistory.iterator(); it.hasNext();) { + AddressRangePosition pos = it.next(); + fViewer.invalidateTextPresentation(pos.offset, pos.length); + } + } else if (property.equals(DisassemblyPreferenceConstants.PC_HISTORY_SIZE)) { + fPCHistorySizeMax = store.getInt(property); + } + } + + /** + * This is a callback that will allow us to create the viewer and initialize + * it. + */ + @Override + public void createPartControl(Composite parent) { + fComposite = parent; + FillLayout layout = new FillLayout(); + layout.marginHeight = 2; + parent.setLayout(layout); + fVerticalRuler = createVerticalRuler(); + int styles = SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION; + fViewer = new DisassemblyViewer(parent, fVerticalRuler, getOverviewRuler(), true, styles); + SourceViewerConfiguration sourceViewerConfig = new DisassemblyViewerConfiguration(this); + fViewer.addTextPresentationListener(this); + fViewer.configure(sourceViewerConfig); + fDecorationSupport = new SourceViewerDecorationSupport(fViewer, getOverviewRuler(), getAnnotationAccess(), + getSharedColors()); + configureSourceViewerDecorationSupport(fDecorationSupport); + fDecorationSupport.install(getPreferenceStore()); + if (fPCAnnotationColorKey != null) { + fPCAnnotationRGB = PreferenceConverter.getColor(getPreferenceStore(), fPCAnnotationColorKey); + } else { + fPCAnnotationRGB = parent.getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION).getRGB(); + } + + initializeViewerFont(fViewer); + createActions(); + hookRulerContextMenu(); + hookContextMenu(); + contributeToActionBars(); + + fViewer.addSelectionChangedListener(new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent event) { + updateSelectionDependentActions(); + } + }); + + fDocument = createDocument(); + fViewer.setDocument(fDocument, new AnnotationModel()); + JFaceResources.getFontRegistry().addListener(fPropertyChangeListener); + + fErrorColor = getSharedColors().getColor(new RGB(96, 0, 0)); + fInstructionColor = getSharedColors().getColor(new RGB(0, 0, 96)); + fSourceColor = getSharedColors().getColor(new RGB(64, 0, 80)); + fLabelColor = getSharedColors().getColor(new RGB(0, 0, 96)); + + if (isAddressRulerVisible()) { + showAddressRuler(); + } + if (isOpcodeRulerVisible()) { + showOpcodeRuler(); + } + initDragAndDrop(); + PlatformUI.getWorkbench().getHelpSystem().setHelp(fViewer.getControl(), IDisassemblyHelpContextIds.DISASSEMBLY_VIEW); + updateTitle(); + updateStateDependentActions(); + + if (fDebugSessionId != null) { + debugContextChanged(); + } else { + updateDebugContext(); + } + } + + /* + * @see org.eclipse.ui.part.WorkbenchPart#setSite(org.eclipse.ui.IWorkbenchPartSite) + */ + @Override + protected void setSite(IWorkbenchPartSite site) { + super.setSite(site); + site.getPage().addPartListener(fPartListener); + } + + private DisassemblyDocument createDocument() { + DisassemblyDocument doc = new DisassemblyDocument(); + return doc; + } + + /* + * @see org.eclipse.ui.IWorkbenchPart#dispose() + */ + @Override + public void dispose() { + IWorkbenchPartSite site = getSite(); + site.setSelectionProvider(null); + site.getPage().removePartListener(fPartListener); + if (fHandlerActivations != null) { + IHandlerService handlerService = (IHandlerService)site.getService(IHandlerService.class); + handlerService.deactivateHandlers(fHandlerActivations); + fHandlerActivations = null; + } + if (fContextActivation != null) { + IContextService ctxService = (IContextService)site.getService(IContextService.class); + ctxService.deactivateContext(fContextActivation); + } + fViewer = null; + fDebugSessionId = null; + fTargetContext= null; + if (fServicesTracker != null) { + fServicesTracker.dispose(); + fServicesTracker= null; + } + fAnnotationAccess = null; + fAnnotationPreferences = null; + fAnnotationRulerColumn = null; + fComposite = null; + if (fDecorationSupport != null) { + fDecorationSupport.uninstall(); + fDecorationSupport = null; + } + if (fFont != null) { + fFont.dispose(); + fFont = null; + } + if (fDropTarget != null) { + fDropTarget.dispose(); + fDropTarget = null; + fDragSource.dispose(); + fDragSource = null; + } + if (fPropertyChangeListener != null) { + if (fPreferenceStore != null) { + fPreferenceStore.removePropertyChangeListener(fPropertyChangeListener); + fPreferenceStore = null; + } + fPropertyChangeListener = null; + } + + fDocument.dispose(); + fDocument = null; + super.dispose(); + } + + private void initDragAndDrop() { + if (fDropTarget == null) { + Transfer[] dropTypes = new Transfer[] { FileTransfer.getInstance(), TextTransfer.getInstance() }; + Transfer[] dragTypes = new Transfer[] { TextTransfer.getInstance() }; + Control dropControl = getSourceViewer().getTextWidget(); + Control dragControl = dropControl; + int dropOps = DND.DROP_COPY | DND.DROP_DEFAULT; + int dragOps = DND.DROP_COPY | DND.DROP_DEFAULT; + + fDropTarget = new DropTarget(dropControl, dropOps); + fDropTarget.setTransfer(dropTypes); + fDropTargetAdapter = new DisassemblyDropAdapter(this); + fDropTarget.addDropListener(fDropTargetAdapter); + + fDragSource = new DragSource(dragControl, dragOps); + fDragSource.setTransfer(dragTypes); + fDragSourceAdapter = new TextViewerDragAdapter(getSourceViewer()); + fDragSource.addDragListener(fDragSourceAdapter); + } + } + + private ISourceViewer getSourceViewer() { + return fViewer; + } + + protected void configureSourceViewerDecorationSupport(SourceViewerDecorationSupport support) { + Iterator e = fAnnotationPreferences.getAnnotationPreferences().iterator(); + while (e.hasNext()) { + AnnotationPreference pref = (AnnotationPreference)e.next(); + support.setAnnotationPreference(pref); + if (pref.getAnnotationType().equals(fPCAnnotation.getType())) { + fPCAnnotationColorKey = pref.getColorPreferenceKey(); + } + } + support.setCursorLinePainterPreferenceKeys(CURRENT_LINE, CURRENT_LINE_COLOR); + support.setSymbolicFontName(getFontPropertyPreferenceKey()); + } + + /** + * Returns the symbolic font name for this view as defined in XML. + * + * @return a String with the symbolic font name or null if + * none is defined + */ + private String getSymbolicFontName() { + if (getConfigurationElement() != null) + return getConfigurationElement().getAttribute("symbolicFontName"); //$NON-NLS-1$ + else + return null; + } + + protected final String getFontPropertyPreferenceKey() { + String symbolicFontName = getSymbolicFontName(); + + if (symbolicFontName != null) + return symbolicFontName; + else + return JFaceResources.TEXT_FONT; + } + + /** + * Initializes the given viewer's font. + * + * @param viewer + * the viewer + */ + private void initializeViewerFont(ISourceViewer viewer) { + + boolean isSharedFont = true; + Font font = null; + String symbolicFontName = getSymbolicFontName(); + + if (symbolicFontName != null) + font = JFaceResources.getFont(symbolicFontName); + else if (fPreferenceStore != null) { + // Backward compatibility + if (fPreferenceStore.contains(JFaceResources.TEXT_FONT) + && !fPreferenceStore.isDefault(JFaceResources.TEXT_FONT)) { + FontData data = PreferenceConverter.getFontData(fPreferenceStore, JFaceResources.TEXT_FONT); + + if (data != null) { + isSharedFont = false; + font = new Font(viewer.getTextWidget().getDisplay(), data); + } + } + } + if (font == null) + font = JFaceResources.getTextFont(); + + setFont(viewer, font); + + if (fFont != null) { + fFont.dispose(); + fFont = null; + } + + if (!isSharedFont) + fFont = font; + } + + /** + * Sets the font for the given viewer sustaining selection and scroll + * position. + * + * @param sourceViewer + * the source viewer + * @param font + * the font + */ + private void setFont(ISourceViewer sourceViewer, Font font) { + if (sourceViewer.getDocument() != null) { + + Point selection = sourceViewer.getSelectedRange(); + int topIndex = sourceViewer.getTopIndex(); + + StyledText styledText = sourceViewer.getTextWidget(); + Control parent = styledText; + if (sourceViewer instanceof ITextViewerExtension) { + ITextViewerExtension extension = (ITextViewerExtension) sourceViewer; + parent = extension.getControl(); + } + + parent.setRedraw(false); + + styledText.setFont(font); + + if (fVerticalRuler instanceof IVerticalRulerExtension) { + IVerticalRulerExtension e = (IVerticalRulerExtension) fVerticalRuler; + e.setFont(font); + } + + sourceViewer.setSelectedRange(selection.x, selection.y); + sourceViewer.setTopIndex(topIndex); + + if (parent instanceof Composite) { + Composite composite = (Composite) parent; + composite.layout(true); + } + + parent.setRedraw(true); + + } else { + + StyledText styledText = sourceViewer.getTextWidget(); + styledText.setFont(font); + + if (fVerticalRuler instanceof IVerticalRulerExtension) { + IVerticalRulerExtension e = (IVerticalRulerExtension) fVerticalRuler; + e.setFont(font); + } + } + } + + protected IVerticalRuler createVerticalRuler() { + CompositeRuler ruler = createCompositeRuler(); + IPreferenceStore store = getPreferenceStore(); + if (ruler != null && store != null) { + for (Iterator iter = ruler.getDecoratorIterator(); iter.hasNext();) { + IVerticalRulerColumn column = (IVerticalRulerColumn) iter.next(); + if (column instanceof AnnotationRulerColumn) { + fAnnotationRulerColumn = (AnnotationRulerColumn) column; + for (Iterator iter2 = fAnnotationPreferences.getAnnotationPreferences().iterator(); iter2.hasNext();) { + AnnotationPreference preference = (AnnotationPreference) iter2.next(); + String key = preference.getVerticalRulerPreferenceKey(); + boolean showAnnotation = true; + if (key != null && store.contains(key)) + showAnnotation = store.getBoolean(key); + if (showAnnotation) + fAnnotationRulerColumn.addAnnotationType(preference.getAnnotationType()); + } + fAnnotationRulerColumn.addAnnotationType(Annotation.TYPE_UNKNOWN); + break; + } + } + } + return ruler; + } + + /** + * Returns the vertical ruler. + * + * @return the vertical ruler + */ + protected IVerticalRuler getVerticalRuler() { + return fVerticalRuler; + } + + /** + * Returns the overview ruler. + * + * @return the overview ruler + */ + protected IOverviewRuler getOverviewRuler() { + if (fOverviewRuler == null) + fOverviewRuler = createOverviewRuler(getSharedColors()); + return fOverviewRuler; + } + + protected ISharedTextColors getSharedColors() { + return EditorsUI.getSharedTextColors(); + } + + protected IOverviewRuler createOverviewRuler(ISharedTextColors sharedColors) { + IOverviewRuler ruler = new OverviewRuler(getAnnotationAccess(), VERTICAL_RULER_WIDTH, sharedColors); + Iterator e = fAnnotationPreferences.getAnnotationPreferences().iterator(); + while (e.hasNext()) { + AnnotationPreference preference = (AnnotationPreference) e.next(); + if (preference.contributesToHeader()) + ruler.addHeaderAnnotationType(preference.getAnnotationType()); + } + return ruler; + } + + /** + * Creates a new address ruler column that is appropriately initialized. + * + * @return the created line number column + */ + protected IVerticalRulerColumn createAddressRulerColumn() { + fAddressRulerColumn= new AddressRulerColumn(); + initializeRulerColumn(fAddressRulerColumn, DisassemblyPreferenceConstants.ADDRESS_COLOR); + IPreferenceStore prefs = getPreferenceStore(); + fAddressRulerColumn.setRadix(prefs.getInt(DisassemblyPreferenceConstants.ADDRESS_RADIX)); + fAddressRulerColumn.setShowRadixPrefix(prefs.getBoolean(DisassemblyPreferenceConstants.SHOW_ADDRESS_RADIX)); + return fAddressRulerColumn; + } + + /** + * Creates a new ruler column that is appropriately initialized. + * + * @return the created line number column + */ + protected IVerticalRulerColumn createOpcodeRulerColumn() { + fOpcodeRulerColumn= new FunctionOffsetRulerColumn(); + initializeRulerColumn(fOpcodeRulerColumn, DisassemblyPreferenceConstants.OPCODE_COLOR); + return fOpcodeRulerColumn; + } + + /** + * Initializes the given address ruler column from the preference store. + * + * @param rulerColumn the ruler column to be initialized + */ + protected void initializeRulerColumn(DisassemblyRulerColumn rulerColumn, String colorPrefKey) { + ISharedTextColors sharedColors= getSharedColors(); + IPreferenceStore store= getPreferenceStore(); + if (store != null) { + + RGB rgb= null; + // foreground color + if (store.contains(colorPrefKey)) { + if (store.isDefault(colorPrefKey)) + rgb= PreferenceConverter.getDefaultColor(store, colorPrefKey); + else + rgb= PreferenceConverter.getColor(store, colorPrefKey); + } + if (rgb == null) + rgb= new RGB(0, 0, 0); + rulerColumn.setForeground(sharedColors.getColor(rgb)); + + rgb= null; + + rulerColumn.redraw(); + } + } + + + /** + * @return the preference store + */ + private IPreferenceStore getPreferenceStore() { + return fPreferenceStore; + } + + /** + * Creates a composite ruler to be used as the vertical ruler by this + * editor. Subclasses may re-implement this method. + * + * @return the vertical ruler + */ + protected CompositeRuler createCompositeRuler() { + CompositeRuler ruler = new CompositeRuler(); + ruler.addDecorator(0, new AnnotationRulerColumn(VERTICAL_RULER_WIDTH, getAnnotationAccess())); + return ruler; + } + + private boolean isAddressRulerVisible() { + return getPreferenceStore().getBoolean(DisassemblyPreferenceConstants.SHOW_ADDRESS_RULER); + } + + /** + * Shows the address ruler column. + */ + private void showAddressRuler() { + if (fAddressRulerColumn == null) { + IVerticalRuler v= getVerticalRuler(); + if (v instanceof CompositeRuler) { + CompositeRuler c= (CompositeRuler) v; + c.addDecorator(1, createAddressRulerColumn()); + } + } + } + + /** + * Hides the address ruler column. + */ + private void hideAddressRuler() { + if (fAddressRulerColumn != null) { + IVerticalRuler v= getVerticalRuler(); + if (v instanceof CompositeRuler) { + CompositeRuler c= (CompositeRuler) v; + c.removeDecorator(fAddressRulerColumn); + } + fAddressRulerColumn = null; + } + } + + private boolean isOpcodeRulerVisible() { + return fShowOpcodes; + } + + /** + * Shows the opcode ruler column. + */ + private void showOpcodeRuler() { + if (fOpcodeRulerColumn == null) { + IVerticalRuler v= getVerticalRuler(); + if (v instanceof CompositeRuler) { + CompositeRuler c= (CompositeRuler) v; + c.addDecorator(2, createOpcodeRulerColumn()); + } + } + } + + /** + * Hides the opcode ruler column. + */ + private void hideOpcodeRuler() { + if (fOpcodeRulerColumn != null) { + IVerticalRuler v= getVerticalRuler(); + if (v instanceof CompositeRuler) { + CompositeRuler c= (CompositeRuler) v; + c.removeDecorator(fOpcodeRulerColumn); + } + fOpcodeRulerColumn = null; + } + } + + /** + * Returns the annotation access. + * + * @return the annotation access + */ + protected IAnnotationAccess getAnnotationAccess() { + if (fAnnotationAccess == null) + fAnnotationAccess = createAnnotationAccess(); + return fAnnotationAccess; + } + + /** + * Creates the annotation access for this editor. + * + * @return the created annotation access + */ + protected IAnnotationAccess createAnnotationAccess() { + return new DefaultMarkerAnnotationAccess(); + } + + private void hookContextMenu() { + String id = "#DisassemblyPartContext"; //$NON-NLS-1$ + MenuManager menuMgr = new MenuManager(id, id); + menuMgr.setRemoveAllWhenShown(true); + menuMgr.addMenuListener(new IMenuListener() { + public void menuAboutToShow(IMenuManager manager) { + DisassemblyPart.this.fillContextMenu(manager); + } + }); + Menu menu = menuMgr.createContextMenu(fViewer.getTextWidget()); + fViewer.getTextWidget().setMenu(menu); + getSite().registerContextMenu(id, menuMgr, fViewer); + } + + private void hookRulerContextMenu() { + String id = "#DisassemblyPartRulerContext"; //$NON-NLS-1$ + MenuManager menuMgr = new MenuManager(id, id); + menuMgr.setRemoveAllWhenShown(true); + menuMgr.addMenuListener(new IMenuListener() { + public void menuAboutToShow(IMenuManager manager) { + DisassemblyPart.this.fillRulerContextMenu(manager); + } + }); + Menu menu = menuMgr.createContextMenu(fVerticalRuler.getControl()); + fVerticalRuler.getControl().setMenu(menu); + getSite().registerContextMenu(id, menuMgr, fViewer); + } + + private void contributeToActionBars() { + IWorkbenchPartSite site = getSite(); + site.setSelectionProvider(fViewer); + IContextService ctxService = (IContextService)site.getService(IContextService.class); + fContextActivation = ctxService.activateContext(KEY_BINDING_CONTEXT_DISASSEMBLY); + contributeToActionBars(getActionBars()); + } + + protected abstract IActionBars getActionBars(); + + protected void contributeToActionBars(IActionBars bars) { + for (Iterator iter = fGlobalActions.keySet().iterator(); iter.hasNext();) { + String key = iter.next(); + IAction action = fGlobalActions.get(key); + bars.setGlobalActionHandler(key, action); + } + IMenuManager menu = bars.getMenuManager(); + IMenuManager navigateMenu= menu.findMenuUsingPath(IWorkbenchActionConstants.M_NAVIGATE); + if (navigateMenu != null) { + navigateMenu.appendToGroup(IWorkbenchActionConstants.MB_ADDITIONS, fActionGotoPC); + navigateMenu.appendToGroup(IWorkbenchActionConstants.MB_ADDITIONS, fActionGotoAddress); + navigateMenu.appendToGroup(IWorkbenchActionConstants.MB_ADDITIONS, fActionGotoSymbol); + } + bars.updateActionBars(); + } + + protected void fillContextMenu(IMenuManager manager) { + Point cursorLoc = getSite().getShell().getDisplay().getCursorLocation(); + fContextClickLocation = fViewer.getTextWidget().toControl(cursorLoc); + fActionToggleSource.update(); + fActionToggleSymbols.update(); + manager.add(new GroupMarker("group.top")); // ICommonMenuConstants.GROUP_TOP //$NON-NLS-1$ + manager.add(new Separator("group.breakpoints")); //$NON-NLS-1$ + manager.add(new Separator(IWorkbenchActionConstants.GO_TO)); + manager.add(fActionGotoPC); + manager.add(fActionGotoAddress); + manager.add(fActionGotoSymbol); + manager.add(new Separator("group.debug")); //$NON-NLS-1$ + manager.add(new Separator(ITextEditorActionConstants.GROUP_EDIT)); + manager.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, fGlobalActions.get(ITextEditorActionConstants.COPY)); + manager.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, fGlobalActions.get(ITextEditorActionConstants.SELECT_ALL)); + manager.add(new Separator(ITextEditorActionConstants.GROUP_SETTINGS)); + manager.add(fActionToggleSource); + manager.add(fActionToggleSymbols); + manager.add(fActionOpenPreferences); + manager.add(new Separator()); + manager.add(fActionRefreshView); + // Other plug-ins can contribute their actions here + manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); + } + + protected void fillRulerContextMenu(IMenuManager manager) { + fActionToggleBreakpoint.update(); + fActionToggleBreakpointEnablement.update(); + fActionToggleAddressColumn.update(); + fActionToggleFunctionColumn.update(); + + manager.add(new GroupMarker("group.top")); // ICommonMenuConstants.GROUP_TOP //$NON-NLS-1$ + manager.add(new Separator("group.breakpoints")); //$NON-NLS-1$ + manager.add(fActionToggleBreakpoint); + manager.add(fActionToggleBreakpointEnablement); + manager.add(new GroupMarker("debug")); //$NON-NLS-1$ + manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); + manager.add(new GroupMarker(ITextEditorActionConstants.GROUP_RESTORE)); + manager.add(new Separator("add")); //$NON-NLS-1$ + manager.add(new Separator(ITextEditorActionConstants.GROUP_RULERS)); + manager.add(fActionToggleAddressColumn); + manager.add(fActionToggleFunctionColumn); + manager.add(new Separator(ITextEditorActionConstants.GROUP_REST)); + + for (Object listener : fRulerContextMenuListeners.getListeners()) + ((IMenuListener) listener).menuAboutToShow(manager); + + manager.add(new Separator(ITextEditorActionConstants.GROUP_EDIT)); + manager.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, fGlobalActions.get(ITextEditorActionConstants.COPY)); + } + + protected void fillLocalToolBar(IToolBarManager manager) { + manager.add(fActionGotoPC); + manager.add(fActionGotoAddress); + } + + protected void updateSelectionDependentActions() { + Iterator iterator= fSelectionActions.iterator(); + while (iterator.hasNext()) { + IUpdate action = (IUpdate)iterator.next(); + action.update(); + } + } + + protected void updateStateDependentActions() { + Iterator iterator= fStateDependentActions.iterator(); + while (iterator.hasNext()) { + IUpdate action = iterator.next(); + action.update(); + } + } + + protected void createActions() { + Action action; + action= new TextOperationAction(fViewer, ITextOperationTarget.COPY); + action.setText(DisassemblyMessages.Disassembly_action_Copy_label); + action.setImageDescriptor(DisassemblyImageRegistry.getImageDescriptor(DisassemblyImageRegistry.ICON_Copy_enabled)); + action.setDisabledImageDescriptor(DisassemblyImageRegistry.getImageDescriptor(DisassemblyImageRegistry.ICON_Copy_disabled)); + action.setActionDefinitionId(IWorkbenchActionDefinitionIds.COPY); + fGlobalActions.put(ITextEditorActionConstants.COPY, action); + fSelectionActions.add(action); + + action= new TextOperationAction(fViewer, ITextOperationTarget.SELECT_ALL); + action.setText(DisassemblyMessages.Disassembly_action_SelectAll_label); + action.setActionDefinitionId(IWorkbenchActionDefinitionIds.SELECT_ALL); + fGlobalActions.put(ITextEditorActionConstants.SELECT_ALL, action); + + action= new TextOperationAction(fViewer, ITextOperationTarget.PRINT); + action.setActionDefinitionId(IWorkbenchActionDefinitionIds.PRINT); + fGlobalActions.put(ITextEditorActionConstants.PRINT, action); + + fActionGotoPC = new ActionGotoProgramCounter(this); + fActionGotoPC.setActionDefinitionId(COMMAND_ID_GOTO_PC); + fStateDependentActions.add(fActionGotoPC); + registerWithHandlerService(fActionGotoPC); + + fActionGotoAddress = new ActionGotoAddress(this); + fActionGotoAddress.setActionDefinitionId(COMMAND_ID_GOTO_ADDRESS); + fStateDependentActions.add(fActionGotoAddress); + registerWithHandlerService(fActionGotoAddress); + + fActionGotoSymbol = new ActionGotoSymbol(this); + fActionGotoSymbol.setActionDefinitionId(COMMAND_ID_GOTO_SYMBOL); + fStateDependentActions.add(fActionGotoSymbol); + registerWithHandlerService(fActionGotoSymbol); + + fActionToggleSource = new ActionToggleSource(); + fStateDependentActions.add(fActionToggleSource); + fActionToggleBreakpoint = new ActionToggleBreakpoint(); +// fActionToggleBreakpoint.setActionDefinitionId(COMMAND_ID_TOGGLE_BREAKPOINT); +// registerWithHandlerService(fActionToggleBreakpoint); + fVerticalRuler.getControl().addMouseListener(new MouseAdapter() { + @Override + public void mouseDoubleClick(MouseEvent e) { + fActionToggleBreakpoint.update(); + if (fActionToggleBreakpoint.isEnabled()) { + fActionToggleBreakpoint.run(); + } + } + }); + fActionToggleBreakpointEnablement = new ActionToggleBreakpointEnablement(); + fActionToggleAddressColumn = new ActionToggleAddressColumn(); + fActionToggleFunctionColumn = new ActionToggleFunctionColumn(); + fActionToggleSymbols = new ActionToggleSymbols(); +// fActionSourceSteppingMode.setActionDefinitionId(COMMAND_ID_TOGGLE_STEPPING_MODE); +// registerWithHandlerService(fActionSourceSteppingMode); + fActionRefreshView = new ActionRefreshView(); + fStateDependentActions.add(fActionRefreshView); + fGlobalActions.put(ActionFactory.REFRESH.getId(), fActionRefreshView); + fActionOpenPreferences = new ActionOpenPreferences(getSite().getShell()); + } + + /** + * Register given action with the handler service for key bindings. + * + * @param action + */ + private void registerWithHandlerService(IAction action) { + if (fHandlerActivations == null) { + fHandlerActivations = new ArrayList(5); + } + IHandlerService handlerService = (IHandlerService)getSite().getService(IHandlerService.class); + fHandlerActivations.add(handlerService.activateHandler(action.getActionDefinitionId(), new ActionHandler(action))); + } + + private void gotoFrame(IFrameDMContext frame) { + if (fActive) { + gotoFrame(frame.getLevel(), PC_UNKNOWN); + } + } + + private void gotoFrame(int frame) { + if (fActive) { + gotoFrame(frame, PC_UNKNOWN); + } + } + + /* + * @see org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart#gotoProgramCounter() + */ + public final void gotoProgramCounter() { + if (fPCAddress != PC_RUNNING) { + updatePC(fPCAddress); + } + } + + /* + * @see org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart#gotoAddress(java.math.BigInteger) + */ + public final void gotoAddress(BigInteger address) { + fFocusAddress = address; + if (fDebugSessionId == null) { + return; + } + if (DEBUG) System.out.println("gotoAddress " + getAddressText(address)); //$NON-NLS-1$ + if (fGotoAddressPending == PC_UNKNOWN) { + fGotoAddressPending = address; + } + if (fUpdatePending) { + return; + } + AddressRangePosition pos = getPositionOfAddress(address); + if (pos != null) { + if (pos.fValid) { + AddressRangePosition previousPos = /* fUpdateBeforeFocus ? getPositionOfAddress(pos.fAddressOffset-1): */ null; + if (previousPos == null || previousPos.fValid) { + if (fGotoAddressPending.equals(address)) { + fGotoAddressPending = PC_UNKNOWN; + } + gotoPosition(pos, false); + } else { + int lines = fBufferZone+3; + BigInteger endAddress = pos.fAddressOffset; + BigInteger startAddress = previousPos.fAddressOffset.max( + endAddress.subtract(BigInteger.valueOf(lines * fDocument.getMeanSizeOfInstructions()))); + retrieveDisassembly(startAddress, endAddress, lines); + } + } else { + int lines = fBufferZone+3; + BigInteger endAddress = pos.fAddressOffset.add(pos.fAddressLength).min( + address.add(BigInteger.valueOf(lines * fDocument.getMeanSizeOfInstructions()))); + retrieveDisassembly(address, endAddress, lines); + } + } + } + + /* + * @see org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart#gotoSymbol(java.lang.String) + */ + public final void gotoSymbol(final String symbol) { + if (!fActive || !isSuspended() || fTargetFrameContext == null) { + return; + } + final IExpressions expressions= getService(IExpressions.class); + if (expressions == null) { + return; + } + IExpressionDMContext exprDmc= expressions.createExpression(fTargetContext, '&'+symbol); + final FormattedValueDMContext valueDmc= expressions.getFormattedValueContext(exprDmc, IFormattedValues.HEX_FORMAT); + final DsfExecutor executor= getSession().getExecutor(); + executor.submit(new Runnable() { + public void run() { + expressions.getFormattedExpressionValue(valueDmc, new DataRequestMonitor(executor, null) { + @Override + protected void handleSuccess() { + FormattedValueDMData data= getData(); + final String value= data.getFormattedValue(); + final BigInteger address= decodeAddress(value); + if (address != null) { + asyncExec(new Runnable() { + public void run() { + gotoAddress(address); + }}); + } + } + @Override + protected void handleError() { + asyncExec(new Runnable() { + public void run() { + ErrorDialog.openError(getSite().getShell(), "Error", null, getStatus()); //$NON-NLS-1$ + }}); + } + }); + }}); + } + + private void gotoPosition(Position pos, boolean select) { + if (fViewer == null) { + return; + } + setFocusPosition(pos); + fViewer.setSelectedRange(pos.offset, select ? Math.max(pos.length-1, 0) : 0); + int revealOffset = pos.offset; + boolean onTop = false; + if (/* !fUpdateBeforeFocus && */ pos.offset > 0) { + try { + AddressRangePosition previousPos = fDocument.getModelPosition(pos.offset - 1); + if (previousPos instanceof LabelPosition) { + revealOffset = previousPos.offset; + onTop = true; + } else if (!previousPos.fValid) { + onTop = true; + } + } catch (BadLocationException e) { + // cannot happen + } + } + fViewer.revealOffset(revealOffset, onTop); + } + + private void gotoMarker(final IMarker marker) { + if (marker == null) { + return; + } + if (fDebugSessionId == null || fUpdatePending) { + fGotoMarkerPending = marker; + return; + } + fGotoMarkerPending = null; + + //TLETODO [disassembly] goto (breakpoint) marker + } + + /* + * @see org.eclipse.jface.text.IViewportListener#viewportChanged(int) + */ + public void viewportChanged(int verticalOffset) { + if (fDebugSessionId != null && fGotoAddressPending == PC_UNKNOWN && fScrollPos == null && !fUpdatePending && !fRefreshViewPending) { + fUpdatePending = true; + invokeLater(new Runnable() { + public void run() { + assert fUpdatePending; + if (fUpdatePending) { + fUpdatePending = false; + updateVisibleArea(); + } + } + }); + } + } + + /** + * Update lines of currently visible area + one page buffer zone below. + */ + private void updateVisibleArea() { + if (!fActive || fUpdatePending || fViewer == null || fDebugSessionId == null) { + return; + } + if (fTargetContext == null || !isSuspended(fTargetContext) || fFrameAddress == PC_UNKNOWN) { + return; + } + StyledText styledText = fViewer.getTextWidget(); + Rectangle clientArea = styledText.getClientArea(); + fBufferZone = Math.max(8, clientArea.height / styledText.getLineHeight()); + int topIndex = fViewer.getTopIndex(); + int bottomIndex = fViewer.getBottomIndex(); + int focusIndex = -1; + boolean focusVisible = false; + boolean isScrollingUp = fViewer.isUserTriggeredScrolling() && fViewer.getLastTopPixel() >= styledText.getTopPixel(); + if (fFocusPos != null) { + try { + int focusOffset = fFocusPos.offset; + focusIndex = fDocument.getLineOfOffset(focusOffset); + focusVisible = focusIndex >= topIndex && focusIndex <= bottomIndex; + // workaround for: Clicking the IP annotation in the right ruler has no effect. + // we deselect the IP location if it is scrolled outside the visible area + if (!focusVisible) { + Point selection = fViewer.getSelectedRange(); + if (selection.x == focusOffset && selection.y > 0) { + fViewer.setSelectedRange(selection.x, 0); + } + } + } catch (BadLocationException e) { + setFocusPosition(null); + } + } + if (!focusVisible) { + focusIndex = topIndex + fScrollLine; + } + BigInteger focusAddress = getAddressOfLine(focusIndex); + bottomIndex += 2; + AddressRangePosition bestPosition = null; + int bestLine = -1; + BigInteger bestDistance = null; + Iterator it = fDocument.getInvalidAddressRanges().iterator(); + while (it.hasNext()) { + AddressRangePosition p = it.next(); + try { + int line = fDocument.getLineOfOffset(p.offset); + if (line >= topIndex && line <= bottomIndex) { + if (p instanceof DisassemblyPosition || p.fAddressLength.compareTo( + BigInteger.valueOf(fBufferZone * 2)) <= 0) { + // small areas and known areas are OK to update + } else if (!isScrollingUp && !fUpdateBeforeFocus + && p.fAddressOffset.compareTo(focusAddress) < 0) { + continue; + } + BigInteger distance = p.fAddressOffset.subtract(focusAddress).abs(); + if (bestDistance == null || distance.compareTo(bestDistance) < 0) { + bestPosition = p; + bestLine = line; + bestDistance = distance; + if (bestDistance.compareTo(BigInteger.valueOf(fBufferZone * 2)) <= 0) { + break; + } + } + } + } catch (BadLocationException e) { + continue; + } + } + if (bestPosition != null) { + int lines = fBufferZone+3; + BigInteger startAddress = bestPosition.fAddressOffset; + BigInteger endAddress = bestPosition.fAddressOffset.add(bestPosition.fAddressLength); + BigInteger addressRange = BigInteger.valueOf(lines * fDocument.getMeanSizeOfInstructions()); + if (bestLine > focusIndex || bestLine == focusIndex && startAddress.compareTo(focusAddress) >= 0) { + // insert at start of range + if (endAddress.subtract(startAddress).compareTo(addressRange) < 0) { + // try to increase range to reduce number of requests + Iterator iter = fDocument.getModelPositionIterator(endAddress); + while (iter.hasNext()) { + AddressRangePosition p = (AddressRangePosition)iter.next(); + if (p.fValid) { + endAddress = endAddress.add(p.fAddressLength); + if (endAddress.subtract(startAddress).compareTo(addressRange) >= 0) { + break; + } + } else { + break; + } + } + } + } else { + // insert at end of range + startAddress = startAddress.max(endAddress.subtract(addressRange)); + // make sure we get all disassembly lines until endAddress + lines = endAddress.subtract(startAddress).intValue(); + } + retrieveDisassembly(startAddress, endAddress, lines); + } + scheduleDoPending(); + } + + private void asyncExec(Runnable runnable) { + if (fViewer != null) { + fViewer.getControl().getDisplay().asyncExec(runnable); + } + } + private void invokeLater(Runnable runnable) { + invokeLater(10, runnable); + } + private void invokeLater(int delay, Runnable runnable) { + if (fViewer != null) { + fViewer.getControl().getDisplay().timerExec(delay, runnable); + } + } + + /** + * Insert sourcelines if available. + */ + /*default*/ void updateInvalidSource() { + if (fViewer == null) { + return; + } + boolean unlock = false; + try { + if (fScrollPos == null) { + if (fUpdatePending) { + fUpdateSourcePending= true; + return; + } + fUpdateSourcePending= false; + unlock = true; + fUpdatePending = true; + lockScroller(); + } + ArrayList copy = new ArrayList(fDocument.getInvalidSource()); + Iterator it = copy.iterator(); + while (it.hasNext()) { + SourcePosition p = it.next(); + if (!p.fValid) { + insertSource(p); + } else if (DEBUG && fDocument.getInvalidSource().remove(p)) { + System.err.println("!!! valid source position in invalid source list at "+getAddressText(p.fAddressOffset)); //$NON-NLS-1$ + } + } + } finally { + if (unlock) { + fUpdatePending = false; + unlockScroller(); + doPending(); + } + } + } + + /** + * Show disassembly for given (source) file. + * + * @param file + * @param lines + */ + void retrieveDisassembly(final String file, final int lines, final boolean mixed) { + if (fDebugSessionId == null) { + return; + } + if (fUpdatePending) { + invokeLater(new Runnable() { + public void run() { + retrieveDisassembly(file, lines, mixed); + }}); + return; + } + if (DEBUG) System.out.println("retrieveDisassembly "+file); //$NON-NLS-1$ + String debuggerPath= file; + + // try reverse lookup + final ISourceLookup lookup= getService(ISourceLookup.class); + final ISourceLookupDMContext ctx= DMContexts.getAncestorOfType(fTargetContext, ISourceLookupDMContext.class); + final DsfExecutor executor= getSession().getExecutor(); + Query query= new Query() { + @Override + protected void execute(final DataRequestMonitor rm) { + final DataRequestMonitor request= new DataRequestMonitor(executor, rm) { + @Override + protected void handleSuccess() { + rm.setData(getData()); + rm.done(); + } + }; + lookup.getDebuggerPath(ctx, file, request); + } + }; + try { + getSession().getExecutor().execute(query); + debuggerPath= query.get(); + } catch (InterruptedException exc) { + internalError(exc); + } catch (ExecutionException exc) { + internalError(exc); + } + + final IDisassembly disassembly= fServicesTracker.getService(IDisassembly.class); + final IDisassemblyDMContext context= DMContexts.getAncestorOfType(fTargetContext, IDisassemblyDMContext.class); + + final String finalFile= debuggerPath; + final DataRequestMonitor disassemblyRequest= new DataRequestMonitor(executor, null) { + @Override + public void handleCompleted() { + final IMixedInstruction[] data= getData(); + if (!isCanceled() && data != null) { + asyncExec(new Runnable() { + public void run() { + if (!insertDisassembly(null, data)) { + // retry in non-mixed mode + retrieveDisassembly(file, lines, false); + } + }}); + } else { + final IStatus status= getStatus(); + if (status != null && !status.isOK()) { + asyncExec(new Runnable() { + public void run() { + ErrorDialog.openError(getSite().getShell(), "Error", null, getStatus()); //$NON-NLS-1$ + } + }); + } + fUpdatePending= false; + } + } + }; + assert !fUpdatePending; + fUpdatePending = true; + executor.submit(new Runnable() { + public void run() { + disassembly.getMixedInstructions(context, finalFile, 1, lines, disassemblyRequest); + }}); + } + + private void retrieveDisassembly(BigInteger startAddress, BigInteger endAddress, int lines) { + if (fDebugSessionId == null) { + return; + } + if (DEBUG) System.out.println("retrieveDisassembly "+getAddressText(startAddress)+" "+lines+" lines"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + retrieveDisassembly(startAddress, endAddress, lines, true); + } + + private void retrieveDisassembly(final BigInteger startAddress, BigInteger endAddress, final int linesHint, boolean mixed) { + assert !fUpdatePending; + fUpdatePending = true; + final int lines= linesHint + 2; + final BigInteger addressLength= BigInteger.valueOf(lines * 4); + if (endAddress.subtract(startAddress).compareTo(addressLength) > 0) { + endAddress= startAddress.add(addressLength); + } + boolean insideActiveFrame= startAddress.equals(fFrameAddress); + String file= null; + int lineNumber= -1; + if (insideActiveFrame && fTargetFrameData != null) { + file= fTargetFrameData.getFile(); + if (file != null && file.trim().length() == 0) { + file= null; + } + lineNumber= fTargetFrameData.getLine(); + } + final String finalFile= file; + final int finalLineNumber= lineNumber; + final BigInteger finalEndAddress= endAddress; + + final DsfExecutor executor= getSession().getExecutor(); + final IDisassembly disassembly= fServicesTracker.getService(IDisassembly.class); + final IDisassemblyDMContext context= DMContexts.getAncestorOfType(fTargetContext, IDisassemblyDMContext.class); + + if (mixed) { + final DataRequestMonitor disassemblyRequest= new DataRequestMonitor(executor, null) { + @Override + public void handleCompleted() { + final IMixedInstruction[] data= getData(); + if (!isCanceled() && data != null) { + asyncExec(new Runnable() { + public void run() { + if (!insertDisassembly(startAddress, data)) { + // retry in non-mixed mode + retrieveDisassembly(startAddress, finalEndAddress, linesHint, false); + } + }}); + } else { + final IStatus status= getStatus(); + if (status != null && !status.isOK()) { + asyncExec(new Runnable() { + public void run() { + doScrollLocked(new Runnable() { + public void run() { + insertError(startAddress, status.getMessage()); + } + }); + }}); + } + fUpdatePending= false; + } + } + }; + if (file != null) { + executor.submit(new Runnable() { + public void run() { + disassembly.getMixedInstructions(context, finalFile, finalLineNumber, lines*2, disassemblyRequest); + }}); + } else { + executor.submit(new Runnable() { + public void run() { + disassembly.getMixedInstructions(context, startAddress, finalEndAddress, disassemblyRequest); + }}); + } + } else { + final DataRequestMonitor disassemblyRequest= new DataRequestMonitor(executor, null) { + @Override + public void handleCompleted() { + if (!isCanceled() && getData() != null) { + asyncExec(new Runnable() { + public void run() { + insertDisassembly(startAddress, getData()); + }}); + } else { + final IStatus status= getStatus(); + if (status != null && !status.isOK()) { + asyncExec(new Runnable() { + public void run() { + doScrollLocked(new Runnable() { + public void run() { + insertError(startAddress, status.getMessage()); + } + }); + }}); + } + fUpdatePending= false; + } + } + }; + if (file != null) { + executor.submit(new Runnable() { + public void run() { + disassembly.getInstructions(context, finalFile, finalLineNumber, lines, disassemblyRequest); + }}); + } else { + executor.submit(new Runnable() { + public void run() { + disassembly.getInstructions(context, startAddress, finalEndAddress, disassemblyRequest); + }}); + } + } + } + + private void insertError(BigInteger address, String message) { + AddressRangePosition p = null; + p = getPositionOfAddress(address); + if (p.fValid) { + return; + } + try { + fDocument.insertErrorLine(p, address, BigInteger.ONE, message); + } catch (BadLocationException exc) { + internalError(exc); + } + } + + private void insertDisassembly(BigInteger startAddress, IInstruction[] instructions) { + if (fViewer == null || fDebugSessionId == null) { + return; + } + if (DEBUG) System.out.println("insertDisassembly "+getAddressText(startAddress)); //$NON-NLS-1$ + assert fUpdatePending; + if (!fUpdatePending) { + // safe-guard in case something weird is going on + return; + } + try { + lockScroller(); + + AddressRangePosition p= null; + for (int j = 0; j < instructions.length; j++) { + IInstruction instruction = instructions[j]; + BigInteger address= instruction.getAdress(); + if (startAddress == null || startAddress.compareTo(BigInteger.ZERO) < 0) { + fGotoAddressPending = startAddress = address; + } + if (p == null || !p.containsAddress(address)) { + p = getPositionOfAddress(address); + } + if (p instanceof ErrorPosition && p.fValid) { + p.fValid = false; + fDocument.getInvalidAddressRanges().add(p); + } else if (p == null || p.fValid) { + if (DEBUG) System.out.println("Excess disassembly lines at " + getAddressText(address)); //$NON-NLS-1$ + return; + } + boolean hasSource= false; + String compilationPath= null; + // insert symbol label + final String functionName= instruction.getFuntionName(); + if (functionName != null && functionName.length() > 0 && instruction.getOffset() == 0) { + p = fDocument.insertLabel(p, address, functionName, fShowSymbols && (!hasSource || fShowDisassembly)); + } + // determine instruction byte length + BigInteger instrLength= null; + if (j < instructions.length - 1) { + instrLength= instructions[j+1].getAdress().subtract(instruction.getAdress()).abs(); + } else if (instructions.length == 1) { + if (p.fAddressLength.compareTo(BigInteger.valueOf(8)) <= 0) { + instrLength= p.fAddressLength; + } + } + if (instrLength == null) { + // cannot determine length of last instruction + break; + } + final String opCode; + // insert function name+offset instead of opcode bytes + if (functionName != null && functionName.length() > 0) { + opCode= functionName + '+' + instruction.getOffset(); + } else { + opCode= ""; //$NON-NLS-1$ + } + p = fDocument.insertDisassemblyLine(p, address, instrLength.intValue(), opCode, instruction.getInstruction(), compilationPath, -1); + if (p == null) { + break; + } + } + + } catch (BadLocationException e) { + // should not happen + internalError(e); + } finally { + fUpdatePending = false; + updateInvalidSource(); + unlockScroller(); + doPending(); + updateVisibleArea(); + } + } + + private boolean insertDisassembly(BigInteger startAddress, IMixedInstruction[] mixedInstructions) { + if (fViewer == null || fDebugSessionId == null) { + return true; + } + if (DEBUG) System.out.println("insertDisassembly "+getAddressText(startAddress)); //$NON-NLS-1$ + assert fUpdatePending; + if (!fUpdatePending) { + // safe-guard in case something weird is going on + return true; + } + // indicates whether disassembly for the start address was inserted + boolean success= false; + try { + lockScroller(); + + AddressRangePosition p= null; + for (int i = 0; i < mixedInstructions.length; ++i) { + IMixedInstruction mixedInstruction= mixedInstructions[i]; + final String file= mixedInstruction.getFileName(); + final int lineNumber= mixedInstruction.getLineNumber() - 1; + IInstruction[] instructions= mixedInstruction.getInstructions(); + for (int j = 0; j < instructions.length; ++j) { + IInstruction instruction = instructions[j]; + BigInteger address= instruction.getAdress(); + if (startAddress == null || startAddress.compareTo(BigInteger.ZERO) < 0) { + fGotoAddressPending = startAddress = address; + } + if (p == null || !p.containsAddress(address)) { + p = getPositionOfAddress(address); + } + if (p instanceof ErrorPosition && p.fValid) { + p.fValid = false; + fDocument.getInvalidAddressRanges().add(p); + } else if (p == null) { + if (DEBUG) System.out.println("Excess disassembly lines at " + getAddressText(address)); //$NON-NLS-1$ + return success; + } else if (p.fValid) { + if (DEBUG) System.out.println("Excess disassembly lines at " + getAddressText(address)); //$NON-NLS-1$ + if (file != null && lineNumber >= 0 || p.fAddressLength == BigInteger.ONE) { + // override probably unaligned disassembly + p.fValid = false; + fDocument.getInvalidAddressRanges().add(p); + } else { + return success; + } + } + boolean hasSource= false; + if (file != null && lineNumber >= 0) { + p = insertSource(p, address, file, lineNumber); + hasSource = fFile2Storage.get(file) != null; + } + // insert symbol label + final String functionName= instruction.getFuntionName(); + if (functionName != null && functionName.length() > 0 && instruction.getOffset() == 0) { + p = fDocument.insertLabel(p, address, functionName, fShowSymbols && (!hasSource || fShowDisassembly)); + } + // determine instruction byte length + BigInteger instrLength= null; + if (j < instructions.length - 1) { + instrLength= instructions[j+1].getAdress().subtract(instruction.getAdress()).abs(); + } else if (i < mixedInstructions.length - 1) { + int nextSrcLineIdx= i+1; + while (nextSrcLineIdx < mixedInstructions.length) { + IInstruction[] nextInstrs= mixedInstructions[nextSrcLineIdx].getInstructions(); + if (nextInstrs.length > 0) { + instrLength= nextInstrs[0].getAdress().subtract(instruction.getAdress()).abs(); + break; + } + ++nextSrcLineIdx; + } + if (nextSrcLineIdx >= mixedInstructions.length) { + break; + } + } else if (instructions.length == 1) { + if (p.fAddressLength.compareTo(BigInteger.valueOf(8)) <= 0) { + instrLength= p.fAddressLength; + } + } + if (instrLength == null) { + // cannot determine length of last instruction + break; + } + final String opCode; + // insert function name+offset instead of opcode bytes + if (functionName != null && functionName.length() > 0) { + opCode= functionName + '+' + instruction.getOffset(); + } else { + opCode= ""; //$NON-NLS-1$ + } + success= success || address.compareTo(startAddress) == 0; + p = fDocument.insertDisassemblyLine(p, address, instrLength.intValue(), opCode, instruction.getInstruction(), file, lineNumber); + if (p == null && success) { + break; + } + } + } + + } catch (BadLocationException e) { + // should not happen + internalError(e); + } finally { + fUpdatePending = false; + if (success) { + updateInvalidSource(); + unlockScroller(); + doPending(); + updateVisibleArea(); + } else { + unlockScroller(); + } + } + return success; + } + + private void retrieveFrameAddress(final IExecutionDMContext targetContext, final int frame) { + if (targetContext != null && isSuspended(targetContext)) { + if (fUpdatePending) { + gotoFrame(frame); + return; + } + if (DEBUG) System.out.println("retrieveFrameAddress "+frame); //$NON-NLS-1$ + fUpdatePending = true; + final IStack stack= fServicesTracker.getService(IStack.class); + final DsfExecutor executor= getSession().getExecutor(); + if (fTargetFrameContext == null) { + if (frame == 0) { + final DataRequestMonitor request= new DataRequestMonitor(executor, null) { + @Override + protected void handleCompleted() { + fUpdatePending= false; + fTargetFrameContext= getData(); + if (fTargetFrameContext != null) { + retrieveFrameAddress(targetContext, frame); + } + } + }; + executor.submit(new Runnable() { + public void run() { + stack.getTopFrame(targetContext, request); + }}); + } else { + // TODO retrieve other stack frame + } + return; + } + final DataRequestMonitor request= new DataRequestMonitor(executor, null) { + @Override + protected void handleCompleted() { + if (!isCanceled()) { + fUpdatePending= false; + final IFrameDMData frameData= getData(); + fTargetFrameData= frameData; + final IAddress address= frameData.getAddress(); + final BigInteger addressValue= address.getValue(); + if (DEBUG) System.out.println("retrieveFrameAddress done "+getAddressText(addressValue)); //$NON-NLS-1$ + asyncExec(new Runnable() { + public void run() { + if (address.getSize() * 4 > fAddressSize) { + addressSizeChanged(address.getSize() * 4); + } + if (frame == 0) { + updatePC(addressValue); + } else { + gotoFrame(frame, addressValue); + } + } + + }); + } + } + }; + executor.submit(new Runnable() { + public void run() { + stack.getFrameData(fTargetFrameContext, request); + }}); + } + } + + private void addressSizeChanged(int addressSize) { + BigInteger oldEndAddress= fEndAddress; + fEndAddress= BigInteger.ONE.shiftLeft(addressSize); + int oldAddressSize= fAddressSize; + fAddressSize= addressSize; + if (addressSize < oldAddressSize) { + fDocument.deleteDisassemblyRange(fEndAddress, oldEndAddress, true, true); + List positions= fDocument.getInvalidAddressRanges(); + List toRemove= new ArrayList(); + for (AddressRangePosition position : positions) { + if (position.fAddressOffset.compareTo(fEndAddress) >= 0) { + try { + fDocument.replace(position, position.length, ""); //$NON-NLS-1$ + fDocument.removeModelPosition(position); + toRemove.add(position); + } catch (BadLocationException exc) { + internalError(exc); + } + } else if (position.containsAddress(fEndAddress)){ + position.fAddressLength= fEndAddress.subtract(position.fAddressOffset); + } + } + positions.removeAll(toRemove); + } else if (addressSize > oldAddressSize) { + fDocument.insertInvalidAddressRange(fDocument.getLength(), 0, oldEndAddress, fEndAddress); + } else { + return; + } + if (fAddressRulerColumn != null) { + fAddressRulerColumn.setAddressSize(addressSize); + if (fComposite != null) { + fComposite.layout(true); + } + } + } + + private AddressRangePosition getPositionOfAddress(BigInteger address) { + if (address == null || address.compareTo(BigInteger.ZERO) < 0) { + return null; + } + AddressRangePosition pos = fDocument.getPositionOfAddress(address); + assert !(pos instanceof SourcePosition); + assert pos != null || address.compareTo(fStartAddress) < 0|| address.compareTo(fEndAddress) >= 0; + return pos; + } + + private BigInteger getAddressOfLine(int line) { + return fDocument.getAddressOfLine(line); + } + + private BigInteger getAddressOfOffset(int offset) { + return fDocument.getAddressOfOffset(offset); + } + + private BigInteger getAddressOfPoint(Point location) { + int offset = getOffsetOfPoint(location); + if (offset < 0) { + return PC_UNKNOWN; + } + return getAddressOfOffset(offset); + } + + private int getOffsetOfPoint(Point location) { + if (location == null) { + return -1; + } + StyledText text= fViewer.getTextWidget(); + int line= ((location.y + text.getTopPixel()) / text.getLineHeight()); + try { + return fDocument.getLineOffset(line); + } catch (BadLocationException e) { + internalError(e); + return -1; + } + } + + /** + * Passing the focus request to the viewer's control. + */ + @Override + public void setFocus() { + fViewer.getControl().setFocus(); + } + + protected void setActive(boolean active) { + if (DEBUG) System.out.println("setActive("+ active +")"); //$NON-NLS-1$ //$NON-NLS-2$ + fActive = active; + if (fActive) { + if (fRefreshAll) { + fRefreshAll = false; + refreshView(0); + } else { + doPendingPCUpdates(); + if (fTargetContext != null) { + int frame = getActiveStackFrame(); + if (frame < 0 && isSuspended(fTargetContext)) { + frame= 0; + } + if (frame != fTargetFrame) { + gotoFrame(frame); + } + } + } + } else { + fGotoAddressPending= fFocusAddress= PC_UNKNOWN; + } + firePropertyChange(PROP_ACTIVE); + } + + private int getActiveStackFrame() { + if (fTargetFrameContext != null) { + return fTargetFrameContext.getLevel(); + } + return -1; + } + + /** + * + */ + protected void updateDebugContext() { + IAdaptable debugContext= DebugUITools.getDebugContext(); + if (debugContext instanceof IDMVMContext) { + setDebugContext((IDMVMContext)debugContext); + } + } + + protected void setDebugContext(IDMVMContext vmContext) { + if (vmContext != null) { + IDMContext dmContext= vmContext.getDMContext(); + String sessionId= dmContext.getSessionId(); + if (!sessionId.equals(fDebugSessionId)) { + // switch to different session or initiate session + if (DEBUG) System.out.println("DisassemblyPart.setDebugContext() " + sessionId); //$NON-NLS-1$ + fTargetContext= null; + if (dmContext instanceof IFrameDMContext) { + IFrameDMContext frame= (IFrameDMContext) dmContext; + IExecutionDMContext executionContext= DMContexts.getAncestorOfType(frame, IExecutionDMContext.class); + if (executionContext != null) { + fTargetContext= executionContext; + fTargetFrameContext= frame; + fTargetFrame= frame.getLevel(); + } + } + if (fTargetContext != null) { + fDebugSessionId= sessionId; + if (fServicesTracker != null) { + fServicesTracker.dispose(); + } + fServicesTracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), sessionId); + if (fViewer != null) { + debugContextChanged(); + } + } + } else if (dmContext instanceof IFrameDMContext) { + // switch to different frame + IFrameDMContext frame= (IFrameDMContext) dmContext; + final IDMContext[] parents= frame.getParents(); + for (IDMContext context : parents) { + if (context instanceof IExecutionDMContext) { + fTargetContext= (IExecutionDMContext) context; + fTargetFrameContext= frame; + gotoFrame(frame); + break; + } + } + } + } else if (fDebugSessionId != null) { + if (getSession() != null) { + getSession().removeServiceEventListener(this); + } + fDebugSessionId= null; + fTargetContext= null; + if (fViewer != null) { + debugContextChanged(); + } + } + } + + private void debugContextChanged() { + if (DEBUG) System.out.println("DisassemblyPart.debugContextChanged()"); //$NON-NLS-1$ + fRunnableQueue.clear(); + fUpdatePending = false; + resetViewer(); + if (fDebugSessionId != null) { + final DsfSession session= getSession(); + session.addServiceEventListener(this, null); + DsfSession.addSessionEndedListener(new SessionEndedListener() { + public void sessionEnded(DsfSession endedSsession) { + if (session == endedSsession) { + DsfSession.removeSessionEndedListener(this); + asyncExec(new Runnable() { + public void run() { + setDebugContext(null); + }}); + } + }}); + + updatePC(PC_UNKNOWN); + + if (fGotoAddressPending != PC_UNKNOWN) { + gotoAddress(fGotoAddressPending); + } + if (fGotoMarkerPending != null) { + gotoMarker(fGotoMarkerPending); + } + fViewer.addViewportListener(this); + } else { + fViewer.removeViewportListener(this); + fGotoMarkerPending = null; +// invokeLater(new Runnable() { +// public void run() { +// closePart(); +// }}); + } + updateTitle(); + updateStateDependentActions(); + firePropertyChange(PROP_CONNECTED); + firePropertyChange(PROP_SUSPENDED); + } + + @DsfServiceEventHandler + public void handleEvent(IExitedDMEvent event) { + if (event.getDMContext().equals(fTargetContext) + || DMContexts.isAncestorOf(event.getDMContext(), fTargetContext)) { + setDebugContext(null); + } + } + + @DsfServiceEventHandler + public void handleEvent(ISuspendedDMEvent event) { + if (event.getDMContext().equals(fTargetContext) + || DMContexts.isAncestorOf(event.getDMContext(), fTargetContext)) { + updatePC(PC_UNKNOWN); + firePropertyChange(PROP_SUSPENDED); + } + } + + @DsfServiceEventHandler + public void handleEvent(IResumedDMEvent event) { + if (event.getDMContext().equals(fTargetContext) + || DMContexts.isAncestorOf(event.getDMContext(), fTargetContext)) { + updatePC(PC_RUNNING); + firePropertyChange(PROP_SUSPENDED); + } + } + + private void attachBreakpointsAnnotationModel() { + IAnnotationModel annotationModel = fViewer.getAnnotationModel(); + if (annotationModel instanceof IAnnotationModelExtension) { + IAnnotationModelExtension ame= (IAnnotationModelExtension) annotationModel; + ame.addAnnotationModel(BREAKPOINT_ANNOTATIONS, new BreakpointsAnnotationModel()); + } + } + + private void refreshView(int delay) { + if (fViewer == null || fRefreshViewPending || fRefreshAll) { + return; + } + fRunnableQueue.clear(); + fRefreshViewPending = true; + final long refreshViewScheduled = System.currentTimeMillis() + delay; + final Runnable refresh = new Runnable() { + public void run() { + fRefreshViewPending = false; + long now = System.currentTimeMillis(); + if (now >= refreshViewScheduled) { + if (DEBUG) System.err.println("*** refreshing view ***"); //$NON-NLS-1$ + fFocusAddress = PC_UNKNOWN; + int targetFrame= fTargetFrame; + resetViewer(); + if (fScrollPos != null) { + fScrollPos.isDeleted = true; + } + gotoFrame(targetFrame); + } else { + refreshView((int)(refreshViewScheduled - now)); + } + }}; + if (delay > 0) { + invokeLater(delay, new Runnable() { + public void run() { + doScrollLocked(refresh); + }}); + } else { + doScrollLocked(refresh); + } + } + + private void resetViewer() { + // clear all state and cache + fPCAnnotationUpdatePending = false; + fGotoFramePending = false; + fPCAddress = fFrameAddress = PC_RUNNING; + fTargetFrame = -1; + fGotoAddressPending = fFocusAddress; + fFocusAddress = PC_UNKNOWN; + setFocusPosition(null); + fPCHistory.clear(); + fPendingPCUpdates.clear(); + fFile2Storage.clear(); + DisassemblyDocument doc= fDocument; + fDocument = createDocument(); + fViewer.setDocument(fDocument, new AnnotationModel()); + doc.dispose(); + if (fDebugSessionId != null) { + attachBreakpointsAnnotationModel(); + fDocument.insertInvalidAddressRange(0, 0, fStartAddress, fEndAddress); + } + } + + private AddressRangePosition getPCPosition(BigInteger address) { + if (address.compareTo(BigInteger.ZERO) < 0) { + // invalid address + return null; + } + AddressRangePosition pos = getPositionOfAddress(address); + if (pos == null || !pos.fValid) { + // invalid disassembly line + return null; + } + if (pos.length > 0) { + // valid disassembly line + return pos; + } + // hidden disassembly + if (!(pos instanceof DisassemblyPosition)) { + return pos; + } + String srcFile = ((DisassemblyPosition)pos).getFile(); + if (srcFile == null) { + return pos; + } + SourceFileInfo fi = fDocument.getSourceInfo(srcFile); + if (fi == null) { + return pos; + } + if (fi.fSource == null) { + if (fi.fError != null) { + // could not read source + return pos; + } + return null; + } +// if (!fi.fValid) { +// // need line info first +// return null; +// } + // determine stmt line of source range + try { + int stmtLine = ((DisassemblyPosition)pos).getLine(); + if (stmtLine < 0) { + return pos; + } + BigInteger stmtAddress = fi.fLine2Addr[stmtLine]; + if (stmtAddress.compareTo(BigInteger.ZERO) < 0) { + return pos; + } + SourcePosition srcPos = fDocument.getSourcePosition(stmtAddress); + if (srcPos == null) { + return pos; + } else if (!srcPos.fValid) { + return null; + } + assert stmtLine >= srcPos.fLine; + int baseOffset = fi.fSource.getLineOffset(srcPos.fLine); + IRegion stmtLineRegion = fi.fSource.getLineInformation(stmtLine); + int lineOffset = stmtLineRegion.getOffset(); + int offset = srcPos.offset + lineOffset - baseOffset; + int length = stmtLineRegion.getLength() + 1; + if (offset >= srcPos.offset && offset < srcPos.offset + srcPos.length) { + return new AddressRangePosition(offset, length, address, BigInteger.ZERO); + } + } catch (BadLocationException e) { + internalError(e); + } + return pos; + } + + /** + * Update the annotation indicating the given address. + * @return a position which denotes the documents position + */ + private AddressRangePosition updateAddressAnnotation(Annotation annotation, BigInteger address) { + IAnnotationModel annotationModel = fViewer.getAnnotationModel(); + annotationModel.removeAnnotation(annotation); + AddressRangePosition pos = getPCPosition(address); + if (pos != null) { + annotationModel.addAnnotation(annotation, new Position(pos.offset, Math.max(0, pos.length-1))); + } + return pos; + } + + public IBreakpoint[] getBreakpointsAtLine(int line) { + BreakpointsAnnotationModel bpModel= null; + IAnnotationModel am= fViewer.getAnnotationModel(); + if (am instanceof IAnnotationModelExtension) { + IAnnotationModelExtension ame= (IAnnotationModelExtension) am; + bpModel= (BreakpointsAnnotationModel) ame.getAnnotationModel(BREAKPOINT_ANNOTATIONS); + if (bpModel != null) { + IRegion lineRegion; + try { + lineRegion= fDocument.getLineInformation(line); + } catch (BadLocationException exc) { + return null; + } + int offset= lineRegion.getOffset(); + int length= lineRegion.getLength(); + @SuppressWarnings("unchecked") + Iterator it= bpModel.getAnnotationIterator(offset, length, true, true); + List bpList= new ArrayList(5); + final IBreakpointManager bpMgr= DebugPlugin.getDefault().getBreakpointManager(); + while (it.hasNext()) { + final SimpleMarkerAnnotation annotation= it.next(); + IBreakpoint bp= bpMgr.getBreakpoint(annotation.getMarker()); + if (bp != null) { + bpList.add(bp); + } + } + if (bpList.size() > 0) { + return bpList.toArray(new IBreakpoint[bpList.size()]); + } + } + } + return null; + } + + private void gotoFrame(int frame, BigInteger address) { + if (DEBUG) System.out.println("gotoFrame " + frame + " " + getAddressText(address)); //$NON-NLS-1$ //$NON-NLS-2$ + fTargetFrame = frame; + fFrameAddress = address; + if (fTargetFrame == -1) { + fTargetFrame = getActiveStackFrame(); + if (fTargetFrame < 0 && isSuspended(fTargetContext)) { + fTargetFrame= 0; + } + if (fTargetFrame == -1) { + fGotoFramePending = false; + return; + } + } + fGotoFramePending = true; + if (frame == 0) { + fPCAddress = fFrameAddress; + } + if (fFrameAddress.compareTo(PC_UNKNOWN) == 0) { + if (!fUpdatePending) { + fGotoFramePending = false; + retrieveFrameAddress(fTargetContext, fTargetFrame); + } + return; + } + AddressRangePosition pcPos = updatePCAnnotation(); + if (pcPos == null && fFrameAddress.compareTo(BigInteger.ZERO) >= 0) { + pcPos = getPCPosition(fFrameAddress); + if (pcPos == null) { + gotoAddress(fFrameAddress); + return; + } + } + if (pcPos != null) { + if (frame == 0) { + addToPCHistory(pcPos); + } + fGotoFramePending = false; + if (fGotoAddressPending == fFrameAddress) { + fGotoAddressPending = PC_UNKNOWN; + } +// if (DEBUG) System.out.println("pc updated "+getAddressText(address)); //$NON-NLS-1$ + gotoPosition(pcPos, false); + updateVisibleArea(); + } else { + // give up + fGotoFramePending = false; + fGotoAddressPending = PC_UNKNOWN; + } + doPendingPCUpdates(); + } + + /* + * @see org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart#isActive() + */ + public final boolean isActive() { + return fActive; + } + + /* + * @see org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart#isConnected() + */ + public final boolean isConnected() { + return fDebugSessionId != null && fTargetContext != null; + } + + /* + * @see org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart#isSuspended() + */ + public final boolean isSuspended() { + return isConnected() && isSuspended(fTargetContext); + } + + /* + * @see org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart#getTextViewer() + */ + public final ISourceViewer getTextViewer() { + return fViewer; + } + + /* + * @see org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart#addRulerContextMenuListener(org.eclipse.jface.action.IMenuListener) + */ + public final void addRulerContextMenuListener(IMenuListener listener) { + fRulerContextMenuListeners.add(listener); + } + + /* + * @see org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart#removeRulerContextMenuListener(org.eclipse.jface.action.IMenuListener) + */ + public final void removeRulerContextMenuListener(IMenuListener listener) { + fRulerContextMenuListeners.remove(listener); + } + + private boolean isSuspended(IExecutionDMContext targetContext) { + return getRunControl().isSuspended(targetContext); + } + + private IRunControl getRunControl() { + return getService(IRunControl.class); + } + + /*default*/ DsfSession getSession() { + return DsfSession.getSession(fDebugSessionId); + } + + /*default*/ V getService(Class serviceClass) { + if (fServicesTracker != null) { + return fServicesTracker.getService(serviceClass); + } + return null; + } + + /*default*/ IFrameDMContext getTargetFrameContext() { + return fTargetFrameContext; + } + + /** + * Schedule the retrieval of a module time stamp for the given address. + * Should return a Long object in case the value was computed, + * another object to be waited on if the retrieval is in progress, null + * if no time stamp could be retrieved. + * + * @param address + * @return Long, Object or null + */ + synchronized Object retrieveModuleTimestamp(BigInteger address) { + // TLETODO [disassembly] retrieve and cache module time stamp + return null; + } + + private void setFocusPosition(Position pcPos) { + if (fFocusPos != null) { + fDocument.removePosition(fFocusPos); + fFocusPos = null; + } + if (pcPos != null) { + fFocusPos = new Position(pcPos.offset, pcPos.length); + try { + fDocument.addPosition(fFocusPos); + } catch (BadLocationException e) { + internalError(e); + } + } else { + fFocusAddress = PC_UNKNOWN; + } + } + + private void doPendingPCUpdates() { + if (fPendingPCUpdates.isEmpty()) { + return; + } + BigInteger pc; + do { + pc = fPendingPCUpdates.remove(0); + if (pc.compareTo(BigInteger.ZERO) >= 0) { + break; + } + } while (!fPendingPCUpdates.isEmpty()); + gotoFrame(0, pc); + } + + private void addToPCHistory(AddressRangePosition pcPos) { + if (DEBUG) System.out.println("addToPCHistory "+getAddressText(pcPos.fAddressOffset)); //$NON-NLS-1$ + if (fPCHistorySizeMax <= 1) { + return; + } + AddressRangePosition first = null; + if (fPCHistory.size() > 0) { + first = fPCHistory.getFirst(); + if (first.fAddressOffset == pcPos.fAddressOffset) { + if (first.offset != pcPos.offset || first.length != pcPos.length) { + fPCHistory.removeFirst(); + fViewer.invalidateTextPresentation(first.offset, first.length); + } else { + return; + } + } + } + // clone and add + pcPos = new AddressRangePosition(pcPos.offset, pcPos.length, pcPos.fAddressOffset, BigInteger.ZERO); + fPCHistory.addFirst(pcPos); + try { + fDocument.addPosition(pcPos); + } catch (BadLocationException e) { + internalError(e); + } + // limit to max size + if (fPCHistory.size() > fPCHistorySizeMax) { + AddressRangePosition last = fPCHistory.removeLast(); + fDocument.removePosition(last); + fViewer.invalidateTextPresentation(last.offset, last.length); + } + // redraw + for (Iterator it=fPCHistory.iterator(); it.hasNext();) { + AddressRangePosition pos = it.next(); + fViewer.invalidateTextPresentation(pos.offset, pos.length); + } + } + + /** + * Update current pc. If a pc update is currently under way, adds this + * address to a list of pending pc updates. + * + * @param pc Current pc address. -1 means retrieve pc from top frame, -2 + * means target resumed + */ + private void updatePC(BigInteger pc) { + if (!fPendingPCUpdates.isEmpty()) { + BigInteger last = fPendingPCUpdates.get(fPendingPCUpdates.size()-1); + if (last.compareTo(BigInteger.ZERO) < 0) { + fPendingPCUpdates.remove(fPendingPCUpdates.size()-1); + } + } + fPendingPCUpdates.add(pc); + if (fPendingPCUpdates.size() > fPCHistorySizeMax) { + if (!fActive) { + // if not active, we can savely remove + // the pc updates before the history range + fPendingPCUpdates.remove(0); + } + // we ignore the current goto frame request + // and continue with the pending updates + fGotoFramePending = false; + } + if (fActive) { + if (fGotoFramePending) { + if (!fUpdatePending) { + gotoFrame(0, fFrameAddress); + } + } else { + doPendingPCUpdates(); + } + } + } + + private AddressRangePosition updatePCAnnotation() { + if (fUpdatePending) { + fPCAnnotationUpdatePending = true; + return null; + } + AddressRangePosition pos; + if (fTargetFrame == 0) { + // clear secondary + updateAddressAnnotation(fSecondaryPCAnnotation, PC_UNKNOWN); + // set primary + pos = updateAddressAnnotation(fPCAnnotation, fPCAddress); + } else { + // clear primary + updateAddressAnnotation(fPCAnnotation, PC_UNKNOWN); + // set secondary + pos = updateAddressAnnotation(fSecondaryPCAnnotation, fFrameAddress); + } + fPCAnnotationUpdatePending = pos == null && fFrameAddress.compareTo(BigInteger.ZERO) >= 0; + return pos; + } + + private void scheduleDoPending() { + if (!fUpdatePending && !fDoPendingPosted) { + fDoPendingPosted = true; + invokeLater(new Runnable() { + public void run() { + doPending(); + fDoPendingPosted = false; + } + }); + } + } + + private void doPending() { + if (fViewer == null || fDocument == null) { + return; + } + if (fUpdateSourcePending) { + updateInvalidSource(); + } + boolean sourceValid= fDocument.getInvalidSource().isEmpty(); + if (sourceValid || fShowDisassembly) { + if (fGotoFramePending) { + gotoFrame(fTargetFrame, fFrameAddress); + } + } + if (sourceValid) { + if (fGotoAddressPending != PC_UNKNOWN) { + gotoAddress(fGotoAddressPending); + } else if (fGotoMarkerPending != null) { + gotoMarker(fGotoMarkerPending); + } + if (fPCAnnotationUpdatePending && !fGotoFramePending) { + updatePCAnnotation(); + } + if (fUpdateTitlePending) { + updateTitle(); + } + } + } + + /** + * Safely run given runnable in a state when no update is pending. + * Delays execution by 10 ms if update is currently pending. + * @param doit + */ + private void doScrollLocked(final Runnable doit) { + if (fViewer == null || fDebugSessionId == null) { + // disposed + return; + } + if (!fActive) { + // refresh all when becoming active again + fRefreshViewPending= false; + fRefreshAll = true; + return; + } + if (doit != null) { + fRunnableQueue.add(doit); + } + if (fUpdatePending) { + if (fRunnableQueue.size() == 1) { + Runnable doitlater = new Runnable() { + public void run() { + doScrollLocked(null); + }}; + invokeLater(doitlater); + } + } else { + fUpdatePending = true; + lockScroller(); + try { + ArrayList copy = new ArrayList(fRunnableQueue); + fRunnableQueue.clear(); + for (Iterator iter = copy.iterator(); iter.hasNext();) { + Runnable doitnow = iter.next(); + try { + doitnow.run(); + } catch(Exception e) { + internalError(e); + } + } + } finally { + fUpdatePending = false; + unlockScroller(); + doPending(); + updateVisibleArea(); + } + } + } + + private void lockScroller() { + assert fScrollPos == null; + if (isOpcodeRulerVisible()) { + fRedrawControl = fViewer.getControl(); + } else { + fRedrawControl = fViewer.getTextWidget(); + } + fRedrawControl.setRedraw(false); + try { + int topOffset = fViewer.getTopIndexStartOffset(); + int topIndex = fViewer.getTopIndex(); + int bottomIndex = fViewer.getBottomIndex(); + int bottomOffset = fViewer.getBottomIndexEndOffset(); + int focusLine; + int focusOffset; + if (fFocusPos != null && fFocusPos.isDeleted) { + fFocusPos = null; + } + if (fFocusPos != null && fFocusPos.offset >= topOffset && fFocusPos.offset <= bottomOffset) { + focusOffset = fFocusPos.offset; + focusLine = fDocument.getLineOfOffset(focusOffset); + } else { + focusLine = Math.max(0, (topIndex + bottomIndex) / 2); + focusOffset = fDocument.getLineOffset(focusLine); + AddressRangePosition pos = fDocument.getDisassemblyPosition(focusOffset); + if (pos != null && !pos.fValid) { + // don't lock position of invalid range + focusOffset = pos.offset+pos.length; + focusLine = fDocument.getLineOfOffset(focusOffset); + } + } + fScrollPos = new Position(focusOffset); + fScrollLine = focusLine - topIndex; + fDocument.addPosition(fScrollPos); + } catch (BadLocationException e) { + // should not happen + internalError(e); + } + } + + private void unlockScroller() { + try { + if (fScrollPos == null) { + return; + } + if (fScrollPos.isDeleted) { + fScrollPos.isDeleted = false; + if (fScrollPos.offset >= fDocument.getLength()) { + fScrollPos.offset = 0; + fScrollLine = 0; + } + } + if (fFocusPos != null && (fFocusPos.isDeleted || fFocusPos.length == 0)) { + if (fFocusAddress.compareTo(BigInteger.ZERO) >= 0) { + fGotoAddressPending = fFocusAddress; + setFocusPosition(getPositionOfAddress(fFocusAddress)); + } + } + int topLine = fDocument.getLineOfOffset(fScrollPos.offset) - fScrollLine; + // limit text size + int lineCount = fDocument.getNumberOfLines(); + if (lineCount > fgHighWaterMark*fBufferZone) { + int startLine = Math.max(0, topLine-fgLowWaterMark/2*fBufferZone); + int endLine = Math.min(lineCount-1, topLine+fgLowWaterMark/2*fBufferZone); + fDocument.deleteLineRange(endLine, lineCount-1); + fDocument.deleteLineRange(0, startLine); + } + int lineHeight = fViewer.getTextWidget().getLineHeight(); + int topPixel = topLine * lineHeight; + if (Math.abs(fViewer.getTextWidget().getTopPixel() - topPixel) >= lineHeight) { + fViewer.setTopIndex(topLine); + } + } catch (BadLocationException e) { + // should not happen + internalError(e); + } finally { + if (fScrollPos != null && fDocument != null) { + fDocument.removePosition(fScrollPos); + fScrollPos = null; + } + if (fViewer != null) { + fRedrawControl.setRedraw(true); + getVerticalRuler().update(); + getOverviewRuler().update(); + } + } + } + + private void insertSource(SourcePosition pos) { + if (!fShowSource) { + fDocument.insertSource(pos, "", pos.fLine, true); //$NON-NLS-1$ + return; + } + SourceFileInfo fi = pos.fFileInfo; + BigInteger address = pos.fAddressOffset; + int lineNr = pos.fLine; + if (fi.fError != null) { + // handled below + } else if (fi.fValid) { +// assert fi.fLinesNode.isValid(); + Addr2Line a2l = fi.fAddr2Line[Addr2Line.hash(address, fi.fAddr2Line.length)]; + while (a2l != null && !a2l.addr.equals(address)) + a2l = a2l.next; + if (a2l != null) { + int first = a2l.first; + int line; + for (line = first; line <= a2l.last; ++line) { + if (!fi.fLine2Addr[line].equals(address)) { + if (line > first) { + String source = fi.getLines(first, line-1); + pos = fDocument.insertSource(pos, source, first, false); + } + first = line+1; + } + } + if (line > first) { + String source = fi.getLines(first, line-1); + fDocument.insertSource(pos, source, first, true); + if (source.length() == 0) { + fDocument.removeSourcePosition(pos); + } + } else if (first > a2l.first) { + fDocument.insertSource(pos, "", first, true); //$NON-NLS-1$ + fDocument.removeSourcePosition(pos); + } + } else { + // no source at all + fDocument.insertSource(pos, "", lineNr, true); //$NON-NLS-1$ + fDocument.removeSourcePosition(pos); + } + } else if (fi.fLinesNode == null) { + // TLETODO [disassembly] asynchronous line info + if (fi.fSource != null) { + fi.fError= new Error(); + } + } + if (fi.fError != null && !pos.fValid) { + if (fi.fSource != null) { + if (fi.fSource != null && lineNr >= 0 && lineNr < fi.fSource.getNumberOfLines()) { + fi.fStartAddress = fi.fStartAddress.min(pos.fAddressOffset); + fi.fEndAddress = fi.fEndAddress.max(pos.fAddressOffset.add(pos.fAddressLength)); + if (fi.fLine2Addr[lineNr] == null || fi.fLine2Addr[lineNr].compareTo(BigInteger.ZERO) < 0) { + fi.fLine2Addr[lineNr] = pos.fAddressOffset; + String sourceLine = fi.getLine(lineNr); + fDocument.insertSource(pos, sourceLine, lineNr, true); + } else if (fi.fLine2Addr[lineNr].compareTo(pos.fAddressOffset) > 0) { + SourcePosition oldPos = fDocument.getSourcePosition(fi.fLine2Addr[lineNr]); + if (oldPos != null) { + try { + fDocument.replace(oldPos, oldPos.length, null); + } catch (BadLocationException e) { + internalError(e); + } + fDocument.removeSourcePosition(oldPos); + } + fi.fLine2Addr[lineNr] = pos.fAddressOffset; + String sourceLine = fi.getLine(lineNr); + fDocument.insertSource(pos, sourceLine, lineNr, true); + } else if (fi.fLine2Addr[lineNr].equals(pos.fAddressOffset)) { + String sourceLine = fi.getLine(lineNr); + fDocument.insertSource(pos, sourceLine, lineNr, true); + } else { + fDocument.insertSource(pos, "", lineNr, true); //$NON-NLS-1$ + fDocument.removeSourcePosition(pos); + } + } + } else { + // no source at all + fDocument.insertSource(pos, "", lineNr, true); //$NON-NLS-1$ + fDocument.removeSourcePosition(pos); + } + } + } + + private void updateTitle() { + if (fDebugSessionId == null) { + String descr = DisassemblyMessages.Disassembly_message_notConnected; + String title = getConfigurationElement().getAttribute("name"); //$NON-NLS-1$ + setPartName(title); + setContentDescription(descr); + setTitleToolTip(title); + } else { + // TLETODO Proper content description + setContentDescription(""); //$NON-NLS-1$ + } + } + + private boolean isDissemblyMixedModeOn() { + // TLETODO [disassembly] mixed mode on/off + return true; + } + + /** + * Close this part + */ + protected abstract void closePart(); + + /* + * @see org.eclipse.jface.text.ITextPresentationListener#applyTextPresentation(org.eclipse.jface.text.TextPresentation) + */ + public void applyTextPresentation(TextPresentation textPresentation) { + IRegion coverage = textPresentation.getExtent(); + if (coverage == null) { + coverage= new Region(0, fDocument.getLength()); + } + int startOffset = coverage.getOffset(); + int length = coverage.getLength(); + int endOffset = startOffset + length; + Iterator it; + try { + // make sure we start with first overlapping position + AddressRangePosition pos = fDocument.getModelPosition(startOffset); + assert pos != null; + if (pos == null) { + return; + } + it = fDocument.getPositionIterator(DisassemblyDocument.CATEGORY_MODEL, pos.offset); + } catch (BadPositionCategoryException e) { + return; + } catch (BadLocationException e) { + return; + } + ArrayList styleRanges = new ArrayList(); + while(it.hasNext()) { + AddressRangePosition pos = (AddressRangePosition)it.next(); + if (pos.offset >= endOffset) { + break; + } + if (pos.offset+pos.length <= startOffset) { + continue; + } + if (pos.fValid && pos.length > 0) { + if (pos instanceof DisassemblyPosition) { + DisassemblyPosition disPos = (DisassemblyPosition)pos; + styleRanges.add(new StyleRange(pos.offset, disPos.length, fInstructionColor, null, SWT.NULL)); + } else if (pos instanceof ErrorPosition) { + styleRanges.add(new StyleRange(pos.offset, pos.length, fErrorColor, null, SWT.NULL)); + } else if (pos instanceof LabelPosition) { + styleRanges.add(new StyleRange(pos.offset, pos.length, fLabelColor, null, SWT.BOLD)); + } else if (pos instanceof SourcePosition) { + SourcePosition srcPos = (SourcePosition)pos; + TextPresentation presentation = null; + if (srcPos.fFileInfo.fSource != null) { + presentation = srcPos.fFileInfo.getPresentation(srcPos.fFileInfo.getRegion(srcPos.fLine, pos.length)); + } + if (presentation != null) { + // clip result window to coverage + int start = Math.max(startOffset, srcPos.offset); + int end = Math.min(endOffset, srcPos.offset + srcPos.length); + int srcOffset = srcPos.fFileInfo.getLineOffset(srcPos.fLine); + int clipOffset = start - srcPos.offset; + presentation.setResultWindow(new Region(srcOffset + clipOffset, end-start)); + for (Iterator iter = presentation.getNonDefaultStyleRangeIterator(); iter.hasNext();) { + StyleRange styleRange = iter.next(); + styleRange.start += srcPos.offset + clipOffset; + styleRanges.add(styleRange); + } + } else { + styleRanges.add(new StyleRange(pos.offset, pos.length, fSourceColor, null, SWT.NULL)); + } + } + } + } + if (styleRanges.size() > 0) { + for (Iterator iter = styleRanges.iterator(); iter.hasNext();) { + textPresentation.addStyleRange(iter.next()); + } + } + // update pc history trail + if (fPCHistory.size() > 1) { + HSL hsv = new HSL(fPCAnnotationRGB); + double luminanceStep = (1-hsv.luminance)/(fPCHistorySizeMax+1); + hsv.luminance = 1 - luminanceStep * (fPCHistorySizeMax - fPCHistory.size()); + for (ListIterator listIt = fPCHistory.listIterator(fPCHistory.size()); listIt.hasPrevious();) { + AddressRangePosition pcPos = listIt.previous(); + hsv.luminance -= luminanceStep; + if (pcPos.isDeleted) { + listIt.remove(); + continue; + } + if (!pcPos.fValid) { + continue; + } + if (pcPos.overlapsWith(startOffset, length)) { + RGB rgb = hsv.toRGB(); + Color pcColor = getSharedColors().getColor(rgb); + Color textColor = null; + // experimental: if color is dark, use white (background) as text color +// Color textColor = hsv.luminance < 0.7 ? fViewer.getTextWidget().getBackground() : null; + textPresentation.mergeStyleRange(new StyleRange(pcPos.offset, pcPos.length, textColor, pcColor)); + } + } + } + } + + + private IBreakpoint insertBreakpoint(int line, boolean edit) throws CoreException { + SourcePosition srcPos = null; + try { + int lineOffset = fDocument.getLineOffset(line); + srcPos = fDocument.getSourcePosition(lineOffset); + } catch (BadLocationException e) { + // should not happen, but its safe to ignore anyway + } + boolean lineBreakpoint = srcPos != null && srcPos.length > 0; + + IResource resource; + ICBreakpoint bp; + + if (lineBreakpoint) { + SourceFileInfo srcInfo = srcPos.fFileInfo; + String filePath = null; + resource = (IResource)srcInfo.fFile.getAdapter(IResource.class); + if (resource != null) { + final IPath location= resource.getLocation(); + if (location == null) { + return null; + } + filePath = location.toOSString(); + } else { + resource = ResourcesPlugin.getWorkspace().getRoot(); + filePath = srcInfo.fFile.getFullPath().toOSString(); + } + BigInteger address = srcPos.fAddressOffset; + AddressRangePosition pos = fDocument.getDisassemblyPosition(address); + int srcLine = -1; + if (pos instanceof DisassemblyPosition) { + srcLine = ((DisassemblyPosition)pos).getLine(); + } + bp= CDIDebugModel.createLineBreakpoint(filePath, resource, srcLine + 1, true, 0, "", true); //$NON-NLS-1$ + } else { + resource = ResourcesPlugin.getWorkspace().getRoot(); + BigInteger address = getAddressOfLine(line); + bp= CDIDebugModel.createAddressBreakpoint(null, null, resource, new Addr64(address), true, 0, "", true); //$NON-NLS-1$ + } + + return bp; + } + + private AddressRangePosition insertSource(AddressRangePosition pos, BigInteger address, final String file, int lineNr) { + Object sourceElement = null; + if (fFile2Storage.containsKey(file)) { + sourceElement = fFile2Storage.get(file); + } else { + final ISourceLookup lookup= getService(ISourceLookup.class); + final ISourceLookupDMContext ctx= DMContexts.getAncestorOfType(fTargetContext, ISourceLookupDMContext.class); + final DsfExecutor executor= getSession().getExecutor(); + Query query= new Query() { + @Override + protected void execute(final DataRequestMonitor rm) { + final DataRequestMonitor request= new DataRequestMonitor(executor, rm) { + @Override + protected void handleSuccess() { + rm.setData(getData()); + rm.done(); + } + }; + lookup.getSource(ctx, file, request); + } + }; + try { + getSession().getExecutor().execute(query); + sourceElement= query.get(); + } catch (InterruptedException exc) { + internalError(exc); + } catch (ExecutionException exc) { + internalError(exc); + } + if (sourceElement instanceof File) { + sourceElement = new LocalFileStorage((File)sourceElement); + } + if (sourceElement instanceof IStorage) { + fFile2Storage.put(file, sourceElement); + } else { + fFile2Storage.put(file, null); + logWarning(DisassemblyMessages.Disassembly_log_error_locateFile+file, null); + } + } + if (sourceElement instanceof IStorage) { + SourceFileInfo fi = fDocument.getSourceInfo((IStorage)sourceElement); + if (fi == null) { + IStorage storage = (IStorage)sourceElement; + Display display = getSite().getShell().getDisplay(); + Runnable done = new SourceColorerJob(display, storage, this); + fi = fDocument.createSourceInfo(file, storage, done); + EditionFinderJob editionJob = null; + if (storage instanceof IFile) { + editionJob = new EditionFinderJob(fi, address, this); + editionJob.schedule(); + } + fi.fReadingJob.schedule(); + } + pos = fDocument.insertInvalidSource(pos, address, fi, lineNr); + } + return pos; + } + + private void disassemblyModeChanged(boolean isDisassemblyOn) { + if (fShowDisassembly == isDisassemblyOn) { + return; + } + if (fShowDisassembly && !fSourceOnlyMode) { + // if not in source-only mode, do not update if disassembly mode is disabled + return; + } + fShowDisassembly = isDisassemblyOn; + if (!fShowDisassembly) { + sourceModeChanged(true); + } + fActionToggleSource.update(); + Runnable doit = new Runnable() { + public void run() { + fDocument.invalidateDisassemblyWithSource(!fShowDisassembly); + fGotoFramePending = true; + }}; + doScrollLocked(doit); + } + + /** + * Turn on/off source mode. + * @param isSourceModeOn + */ + private void sourceModeChanged(boolean isSourceModeOn) { + if (fShowSource == isSourceModeOn) { + return; + } + fShowSource = isSourceModeOn; + fActionToggleSource.update(); + fDocument.invalidateSource(); + if (!fShowSource && !fShowDisassembly) { + disassemblyModeChanged(true); + } else { + fPCAnnotationUpdatePending = true; + updateInvalidSource(); + } + } + + public static BigInteger decodeAddress(String string) { + if (string.startsWith("0x")) { //$NON-NLS-1$ + return new BigInteger(string.substring(2), 16); + } + return new BigInteger(string); + } + + private static String getAddressText(BigInteger address) { + if (address == null) { + return ""; //$NON-NLS-1$ + } + if (address.compareTo(BigInteger.ZERO) < 0) { + return address.toString(); + } + String hex = address.toString(16); + return "0x" + "0000000000000000".substring(hex.length() + (address.bitLength() <= 32 ? 8 : 0)) + hex; //$NON-NLS-1$ //$NON-NLS-2$ + } + + static void internalError(Throwable e) { + if (DEBUG) { + System.err.println("Disassembly: Internal error"); //$NON-NLS-1$ + e.printStackTrace(); + } + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyRulerColumn.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyRulerColumn.java new file mode 100644 index 00000000000..5645a394360 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyRulerColumn.java @@ -0,0 +1,985 @@ +/******************************************************************************* + * Copyright (c) 2000, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Anton Leherbauer (Wind River Systems) + *******************************************************************************/ + +package org.eclipse.dd.dsf.debug.internal.ui.disassembly; + +import java.util.Arrays; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextListener; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.ITextViewerExtension; +import org.eclipse.jface.text.ITextViewerExtension5; +import org.eclipse.jface.text.IViewportListener; +import org.eclipse.jface.text.TextEvent; +import org.eclipse.jface.text.source.CompositeRuler; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.jface.text.source.IVerticalRulerColumn; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyleRange; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.MouseTrackListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontMetrics; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; + +/** + * Vertical ruler column for use with disassembly parts. + *

              + * Derived from {@link org.eclipse.jface.text.source.LineNumberRulerColumn}. + *

              + */ +public class DisassemblyRulerColumn implements IVerticalRulerColumn { + protected final static String DOTS = "......................................................................"; //$NON-NLS-1$ + protected final static String SPACES = " "; //$NON-NLS-1$ + + /** + * Internal listener class. + */ + class InternalListener implements IViewportListener, ITextListener, ISelectionChangedListener { + + /* + * @see IViewportListener#viewportChanged(int) + */ + public void viewportChanged(int verticalPosition) { + if (verticalPosition != fScrollPos) + redraw(); + } + + /* + * @see ITextListener#textChanged(TextEvent) + */ + public void textChanged(TextEvent event) { + + if (updateNumberOfDigits()) { + computeIndentations(); + layout(event.getViewerRedrawState()); + return; + } + + if (!event.getViewerRedrawState()) + return; + + if (fSensitiveToTextChanges || event.getDocumentEvent() == null) + postRedraw(); + + } + + /* + * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent) + */ + public void selectionChanged(SelectionChangedEvent event) { + postRedraw(); + } + } + + /** + * Handles all the mouse interaction in this line number ruler column. + */ + class MouseHandler implements MouseListener, MouseMoveListener, MouseTrackListener { + + /** The cached view port size */ + private int fCachedViewportSize; + /** The area of the line at which line selection started */ + private IRegion fStartLine; + /** The number of the line at which line selection started */ + private int fStartLineNumber; + /** The auto scroll direction */ + private int fAutoScrollDirection; + + /* + * @see org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent) + */ + public void mouseUp(MouseEvent event) { + // see bug 45700 + if (event.button == 1) { + stopSelecting(); + stopAutoScroll(); + postRedraw(); + } + } + + /* + * @see org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent) + */ + public void mouseDown(MouseEvent event) { + fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y); + // see bug 45700 + if (event.button == 1) { + startSelecting(); + } + } + + /* + * @see org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent) + */ + public void mouseDoubleClick(MouseEvent event) { + fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y); + stopSelecting(); + stopAutoScroll(); + } + + /* + * @see org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events.MouseEvent) + */ + public void mouseMove(MouseEvent event) { + if (!autoScroll(event)) { + int newLine = fParentRuler.toDocumentLineNumber(event.y); + expandSelection(newLine); + } + } + + /* + * @see org.eclipse.swt.events.MouseTrackListener#mouseEnter(org.eclipse.swt.events.MouseEvent) + */ + public void mouseEnter(MouseEvent event) { + } + + /* + * @see org.eclipse.swt.events.MouseTrackListener#mouseExit(org.eclipse.swt.events.MouseEvent) + */ + public void mouseExit(MouseEvent event) { + } + + /* + * @see org.eclipse.swt.events.MouseTrackListener#mouseHover(org.eclipse.swt.events.MouseEvent) + */ + public void mouseHover(MouseEvent event) { + } + + /** + * Called when line drag selection started. Adds mouse move and track + * listeners to this column's control. + */ + private void startSelecting() { + try { + + // select line + IDocument document = fCachedTextViewer.getDocument(); + fStartLineNumber = fParentRuler.getLineOfLastMouseButtonActivity(); + fStartLine = document.getLineInformation(fStartLineNumber); + fCachedTextViewer.setSelectedRange(fStartLine.getOffset(), fStartLine.getLength()); + fCachedViewportSize = getVisibleLinesInViewport(); + + // prepare for drag selection + fCanvas.addMouseMoveListener(this); + fCanvas.addMouseTrackListener(this); + + } catch (BadLocationException x) { + } + } + + /** + * Called when line drag selection stopped. Removes all previously + * installed listeners from this column's control. + */ + private void stopSelecting() { + // drag selection stopped + fCanvas.removeMouseMoveListener(this); + fCanvas.removeMouseTrackListener(this); + } + + /** + * Expands the line selection from the remembered start line to the + * given line. + * + * @param lineNumber + * the line to which to expand the selection + */ + private void expandSelection(int lineNumber) { + try { + + IDocument document = fCachedTextViewer.getDocument(); + IRegion lineInfo = document.getLineInformation(lineNumber); + + int start = Math.min(fStartLine.getOffset(), lineInfo.getOffset()); + int end = Math.max(fStartLine.getOffset() + fStartLine.getLength(), lineInfo.getOffset() + + lineInfo.getLength()); + + if (lineNumber < fStartLineNumber) + fCachedTextViewer.setSelectedRange(end, start - end); + else + fCachedTextViewer.setSelectedRange(start, end - start); + + } catch (BadLocationException x) { + } + } + + /** + * Called when auto scrolling stopped. Clears the auto scroll direction. + */ + private void stopAutoScroll() { + fAutoScrollDirection = SWT.NULL; + } + + /** + * Called on drag selection. + * + * @param event + * the mouse event caught by the mouse move listener + * @return true if scrolling happened, false + * otherwise + */ + private boolean autoScroll(MouseEvent event) { + Rectangle area = fCanvas.getClientArea(); + + if (event.y > area.height) { + autoScroll(SWT.DOWN); + return true; + } + + if (event.y < 0) { + autoScroll(SWT.UP); + return true; + } + + stopAutoScroll(); + return false; + } + + /** + * Scrolls the viewer into the given direction. + * + * @param direction + * the scroll direction + */ + private void autoScroll(int direction) { + + if (fAutoScrollDirection == direction) + return; + + final int TIMER_INTERVAL = 5; + final Display display = fCanvas.getDisplay(); + Runnable timer = null; + switch (direction) { + case SWT.UP: + timer = new Runnable() { + public void run() { + if (fAutoScrollDirection == SWT.UP) { + int top = getInclusiveTopIndex(); + if (top > 0) { + fCachedTextViewer.setTopIndex(top - 1); + expandSelection(top - 1); + display.timerExec(TIMER_INTERVAL, this); + } + } + } + }; + break; + case SWT.DOWN: + timer = new Runnable() { + public void run() { + if (fAutoScrollDirection == SWT.DOWN) { + int top = getInclusiveTopIndex(); + fCachedTextViewer.setTopIndex(top + 1); + expandSelection(top + 1 + fCachedViewportSize); + display.timerExec(TIMER_INTERVAL, this); + } + } + }; + break; + } + + if (timer != null) { + fAutoScrollDirection = direction; + display.timerExec(TIMER_INTERVAL, timer); + } + } + + /** + * Returns the viewer's first visible line, even if only partially + * visible. + * + * @return the viewer's first visible line + */ + private int getInclusiveTopIndex() { + if (fCachedTextWidget != null && !fCachedTextWidget.isDisposed()) { + int top = fCachedTextViewer.getTopIndex(); + if ((fCachedTextWidget.getTopPixel() % fCachedTextWidget.getLineHeight()) != 0) + --top; + return top; + } + return -1; + } + } + + /** This column's parent ruler */ + private CompositeRuler fParentRuler; + /** Cached text viewer */ + private ITextViewer fCachedTextViewer; + /** Cached text widget */ + private StyledText fCachedTextWidget; + /** The columns canvas */ + private Canvas fCanvas; + /** Cache for the actual scroll position in pixels */ + private int fScrollPos; + /** The drawable for double buffering */ + private Image fBuffer; + /** The internal listener */ + private InternalListener fInternalListener = new InternalListener(); + /** The font of this column */ + private Font fFont; + /** The indentation cache */ + private int[] fIndentation; + /** Indicates whether this column reacts on text change events */ + private boolean fSensitiveToTextChanges = false; + /** The foreground color */ + private Color fForeground; + /** The background color */ + private Color fBackground; + /** Cached number of displayed digits */ + private int fCachedNumberOfDigits = -1; + /** Flag indicating whether a relayout is required */ + private boolean fRelayoutRequired = false; + /** + * Redraw runnable lock + */ + private Object fRunnableLock = new Object(); + /** + * Redraw runnable state + */ + private boolean fIsRunnablePosted = false; + /** + * Redraw runnable + */ + private Runnable fRunnable = new Runnable() { + public void run() { + synchronized (fRunnableLock) { + fIsRunnablePosted = false; + } + redraw(); + } + }; + private boolean fAlignRight; + private boolean fPaintStyleBackground; + private boolean fPaintSelectionBackground; + + /** + * Constructs a new vertical ruler column. + * + */ + public DisassemblyRulerColumn() { + this(SWT.LEFT); + // default constructor + } + + public DisassemblyRulerColumn(int align) { + this(align, true, false); + } + + public DisassemblyRulerColumn(int align, boolean paintSelection, boolean paintStyle) { + fAlignRight = (align & SWT.RIGHT) != 0; + fPaintSelectionBackground = paintSelection; + fPaintStyleBackground = paintStyle; + } + + /** + * Sets the foreground color of this column. + * + * @param foreground + * the foreground color + */ + public void setForeground(Color foreground) { + fForeground = foreground; + } + + /** + * Returns the foreground color being used to print the line numbers. + * + * @return the configured foreground color + */ + protected Color getForeground() { + return fForeground; + } + + /** + * Sets the background color of this column. + * + * @param background + * the background color + */ + public void setBackground(Color background) { + fBackground = background; + if (fCanvas != null && !fCanvas.isDisposed()) + fCanvas.setBackground(getBackground(fCanvas.getDisplay())); + } + + /** + * Returns the System background color for list widgets. + * + * @param display + * the display + * @return the System background color for list widgets + */ + protected Color getBackground(Display display) { + if (fBackground == null) + return display.getSystemColor(SWT.COLOR_LIST_BACKGROUND); + return fBackground; + } + + /* + * @see IVerticalRulerColumn#getControl() + */ + public Control getControl() { + return fCanvas; + } + + /* + * @see IVerticalRuleColumnr#getWidth + */ + public int getWidth() { + return fIndentation[0]; + } + + /** + * Computes the number of digits to be displayed. Returns true + * if the number of digits changed compared to the previous call of this + * method. If the method is called for the first time, the return value is + * also true. + * + * @return whether the number of digits has been changed + */ + protected boolean updateNumberOfDigits() { + if (fCachedTextViewer == null) + return false; + + int digits = computeNumberOfCharacters(); + + if (fCachedNumberOfDigits != digits) { + fCachedNumberOfDigits = digits; + return true; + } + + return false; + } + + /** + * Does the real computation of the number of characters. The default + * implementation computes the number of digits for the line number. + * Subclasses may override this method if they need extra space on the ruler. + * + * @return the number of characters to be displayed on the ruler. + */ + protected int computeNumberOfCharacters() { + IDocument document = fCachedTextViewer.getDocument(); + int lines= document == null ? 0 : document.getNumberOfLines(); + + int digits= 2; + while (lines > Math.pow(10, digits) - 1) { + ++digits; + } + return digits; + } + + /** + * Layouts the enclosing viewer to adapt the layout to changes of the size + * of the individual components. + * + * @param redraw + * true if this column can be redrawn + */ + protected void layout(boolean redraw) { + if (!redraw) { + fRelayoutRequired= true; + return; + } + + fRelayoutRequired= false; + if (fCachedTextViewer instanceof ITextViewerExtension) { + ITextViewerExtension extension= (ITextViewerExtension) fCachedTextViewer; + Control control= extension.getControl(); + if (control instanceof Composite && !control.isDisposed()) { + Composite composite= (Composite) control; + composite.layout(true); + } + } + } + + /** + * Computes the indentations for the given font and stores them in + * fIndentation. + */ + protected void computeIndentations() { + if (fCanvas == null) + return; + + GC gc= new GC(fCanvas); + try { + + gc.setFont(fCanvas.getFont()); + + fIndentation= new int[fCachedNumberOfDigits + 1]; + char[] digitStr= new char[fCachedNumberOfDigits + 1]; + Arrays.fill(digitStr, '9'); + Point p= gc.stringExtent(new String(digitStr, 0, fCachedNumberOfDigits + 1)); + fIndentation[0]= p.x; + + for (int i= 1; i <= fCachedNumberOfDigits; i++) { + p= gc.stringExtent(new String(digitStr, 0, i)); + fIndentation[i]= fIndentation[0] - p.x; + } + + } finally { + gc.dispose(); + } + } + + /* + * @see IVerticalRulerColumn#createControl(CompositeRuler, Composite) + */ + public Control createControl(CompositeRuler parentRuler, Composite parentControl) { + + fParentRuler= parentRuler; + fCachedTextViewer= parentRuler.getTextViewer(); + fCachedTextWidget= fCachedTextViewer.getTextWidget(); + + fCanvas= new Canvas(parentControl, SWT.NONE); + fCanvas.setBackground(getBackground(fCanvas.getDisplay())); + fCanvas.setForeground(fForeground); + + fCanvas.addPaintListener(new PaintListener() { + public void paintControl(PaintEvent event) { + if (fCachedTextViewer != null) + doubleBufferPaint(event.gc); + } + }); + + fCanvas.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + handleDispose(); + fCachedTextViewer= null; + fCachedTextWidget= null; + } + }); + + fCanvas.addMouseListener(new MouseHandler()); + + if (fCachedTextViewer != null) { + + fCachedTextViewer.addViewportListener(fInternalListener); + fCachedTextViewer.addTextListener(fInternalListener); + fCachedTextViewer.getSelectionProvider().addSelectionChangedListener(fInternalListener); + + if (fFont == null) { + if (fCachedTextWidget != null && !fCachedTextWidget.isDisposed()) + fFont= fCachedTextWidget.getFont(); + } + } + + if (fFont != null) + fCanvas.setFont(fFont); + + updateNumberOfDigits(); + computeIndentations(); + return fCanvas; + } + + /** + * Disposes the column's resources. + */ + protected void handleDispose() { + + if (fCachedTextViewer != null) { + fCachedTextViewer.removeViewportListener(fInternalListener); + fCachedTextViewer.removeTextListener(fInternalListener); + fCachedTextViewer.getSelectionProvider().removeSelectionChangedListener(fInternalListener); + } + + if (fBuffer != null) { + fBuffer.dispose(); + fBuffer= null; + } + } + + /** + * Double buffer drawing. + * + * @param dest + * the gc to draw into + */ + private void doubleBufferPaint(GC dest) { + + Point size= fCanvas.getSize(); + + if (size.x <= 0 || size.y <= 0) + return; + + if (fBuffer != null) { + Rectangle r= fBuffer.getBounds(); + if (r.width != size.x || r.height != size.y) { + fBuffer.dispose(); + fBuffer= null; + } + } + if (fBuffer == null) + fBuffer= new Image(fCanvas.getDisplay(), size.x, size.y); + + GC gc= new GC(fBuffer); + gc.setFont(fCanvas.getFont()); + if (fForeground != null) + gc.setForeground(fForeground); + + try { + gc.setBackground(getBackground(fCanvas.getDisplay())); + gc.fillRectangle(0, 0, size.x, size.y); + + if (fCachedTextViewer instanceof ITextViewerExtension5) + doPaint1(gc); + else + doPaint(gc); + + } finally { + gc.dispose(); + } + + dest.drawImage(fBuffer, 0, 0); + } + + /** + * Returns the viewport height in lines. + * + * @return the viewport height in lines + */ + protected int getVisibleLinesInViewport() { + Rectangle clArea= fCachedTextWidget.getClientArea(); + return clArea.height / fCachedTextWidget.getLineHeight(); + } + + /** + * Draws the ruler column. + * + * @param gc + * the gc to draw into + */ + private void doPaint(GC gc) { + + if (fCachedTextViewer == null) + return; + + if (fCachedTextWidget == null) + return; + + int firstLine= 0; + + int topLine= fCachedTextWidget.getTopIndex(); + fScrollPos= fCachedTextWidget.getTopPixel(); + int lineheight= fCachedTextWidget.getLineHeight(); + int partialLineHidden= fScrollPos % lineheight; + + if (partialLineHidden > 0 && topLine > 0) // widgetTopLine shows the + // first fully visible line + --topLine; + + int bottomLine; + + try { + + IRegion region= fCachedTextViewer.getVisibleRegion(); + IDocument doc= fCachedTextViewer.getDocument(); + + if (doc == null) + return; + + firstLine= doc.getLineOfOffset(region.getOffset()); + if (firstLine > topLine) + topLine= firstLine; + + bottomLine= doc.getLineOfOffset(region.getOffset() + region.getLength()); + + } catch (BadLocationException x) { + return; + } + + fSensitiveToTextChanges= bottomLine - topLine < getVisibleLinesInViewport(); + + int baselineBias= getBaselineBias(gc); + + int topInset= fCachedTextViewer.getTopInset(); + int y= topInset - partialLineHidden; + Point canvasSize= fCanvas.getSize(); + Point selection= fCachedTextWidget.getSelection(); + boolean selectedLine= false; + Color defaultForeground= gc.getForeground(); + Color defaultBackground= gc.getBackground(); + + for (int line= topLine; y < canvasSize.y && line <= bottomLine; line++, y += lineheight) { + int widgetOffset= fCachedTextWidget.getOffsetAtLine(line); + if (fPaintSelectionBackground && widgetOffset >= selection.x && widgetOffset < selection.y) { + if (!selectedLine) { + selectedLine= true; + gc.setForeground(fCachedTextWidget.getSelectionForeground()); + gc.setBackground(fCachedTextWidget.getSelectionBackground()); + } + } else if (selectedLine) { + selectedLine= false; + gc.setForeground(defaultForeground); + gc.setBackground(defaultBackground); + } + if (selectedLine) { + gc.fillRectangle(0, y, canvasSize.x, lineheight); + } else if (fPaintStyleBackground && widgetOffset >= 0 && widgetOffset < fCachedTextWidget.getCharCount()) { + StyleRange style= fCachedTextWidget.getStyleRangeAtOffset(widgetOffset); + if (style != null && style.background != null) { + gc.setBackground(style.background); + gc.fillRectangle(0, y + baselineBias, canvasSize.x, lineheight - baselineBias); + gc.setBackground(defaultBackground); + } + } + paintLine(line, y, lineheight, gc, fCachedTextWidget.getDisplay()); + String s= createDisplayString(line); + int indentation= fAlignRight ? fIndentation[s.length()] : 0; + gc.drawString(s, indentation, y + baselineBias, true); + } + } + + /** + * Computes the string to be printed for line. The default + * implementation returns Integer.toString(line + 1). + * + * @param line + * the line number for which the string is generated + * @return the string to be printed on the ruler column for line + */ + String createDisplayString(int line) { + return Integer.toString(line + 1); + } + + /** + * Draws the ruler column. Uses ITextViewerExtension5 for the + * implementation. Will replace doPinat(GC). + * + * @param gc + * the gc to draw into + */ + private void doPaint1(GC gc) { + + if (fCachedTextViewer == null) + return; + + ITextViewerExtension5 extension= (ITextViewerExtension5) fCachedTextViewer; + + int widgetTopLine= fCachedTextWidget.getTopIndex(); + fScrollPos= fCachedTextWidget.getTopPixel(); + int lineheight= fCachedTextWidget.getLineHeight(); + int partialLineHidden= fScrollPos % lineheight; + + if (partialLineHidden > 0 && widgetTopLine > 0) // widgetTopLine shows + // the first fully + // visible line + --widgetTopLine; + + int modelTopLine= extension.widgetLine2ModelLine(widgetTopLine); + int modelBottomLine= fCachedTextViewer.getBottomIndex(); + if (modelBottomLine >= 0) + ++modelBottomLine; + + try { + + IRegion region= extension.getModelCoverage(); + IDocument doc= fCachedTextViewer.getDocument(); + + if (doc == null) + return; + + int coverageTopLine= doc.getLineOfOffset(region.getOffset()); + if (coverageTopLine > modelTopLine || modelTopLine == -1) + modelTopLine= coverageTopLine; + + int coverageBottomLine= doc.getLineOfOffset(region.getOffset() + region.getLength()); + if (coverageBottomLine < modelBottomLine || modelBottomLine == -1) + modelBottomLine= coverageBottomLine; + + } catch (BadLocationException x) { + return; + } + + fSensitiveToTextChanges= modelBottomLine - modelTopLine < getVisibleLinesInViewport(); + + int baselineBias= getBaselineBias(gc); + + int topInset= fCachedTextViewer.getTopInset(); + int y= topInset - partialLineHidden; + Point canvasSize= fCanvas.getSize(); + Point selection= fCachedTextWidget.getSelection(); + boolean selectedLine= false; + Color defaultForeground= gc.getForeground(); + Color defaultBackground= gc.getBackground(); + + for (int modelLine= modelTopLine; y < canvasSize.y && modelLine <= modelBottomLine; modelLine++) { + + // don't draw hidden (e.g. folded) lines + int widgetLine= extension.modelLine2WidgetLine(modelLine); + if (widgetLine == -1) + continue; + int widgetOffset= fCachedTextWidget.getOffsetAtLine(widgetLine); + if (fPaintSelectionBackground && widgetOffset >= selection.x && widgetOffset < selection.y) { + if (!selectedLine) { + selectedLine= true; + gc.setForeground(fCachedTextWidget.getSelectionForeground()); + gc.setBackground(fCachedTextWidget.getSelectionBackground()); + } + } else if (selectedLine) { + selectedLine= false; + gc.setForeground(defaultForeground); + gc.setBackground(defaultBackground); + } + if (selectedLine) { + gc.fillRectangle(0, y, canvasSize.x, lineheight); + } else if (fPaintStyleBackground && widgetOffset >= 0 && widgetOffset < fCachedTextWidget.getCharCount()) { + StyleRange style= fCachedTextWidget.getStyleRangeAtOffset(widgetOffset); + if (style != null && style.background != null) { + gc.setBackground(style.background); + gc.fillRectangle(0, y + baselineBias, canvasSize.x, lineheight - baselineBias); + gc.setBackground(defaultBackground); + } + } + + paintLine(modelLine, y, lineheight, gc, fCachedTextWidget.getDisplay()); + + String s= createDisplayString(modelLine); + int indentation= fAlignRight ? fIndentation[s.length()] : 0; + gc.drawString(s, indentation, y + baselineBias, true); + y += lineheight; + } + } + + /** + * Returns the difference between the baseline of the widget and the + * baseline as specified by the font for gc. When drawing + * text, the returned bias should be added to obtain text line up on + * the correct base line of the text widget. + * + * @param gc + * the GC to get the font metrics from + * @return the baseline bias to use when drawing text that is line up with + * fCachedTextWidget + */ + private int getBaselineBias(GC gc) { + /* + * https://bugs.eclipse.org/bugs/show_bug.cgi?id=62951 widget line + * height may be more than the font height used for the text, + * since font styles (bold, italics...) can have larger font metrics + * than the simple font used for the numbers. + */ + int widgetBaseline= fCachedTextWidget.getBaseline(); + FontMetrics fm= gc.getFontMetrics(); + int fontBaseline= fm.getAscent() + fm.getLeading(); + Assert.isTrue(widgetBaseline >= fontBaseline); + int baselineBias= widgetBaseline - fontBaseline; + return baselineBias; + } + + /** + * Paints the line. After this method is called the text is painted + * on top of the result of this method. + *

              + * This default implementation does nothing. + *

              + * + * @param line + * the line of the document which the ruler is painted for + * @param y + * the y-coordinate of the box being painted for + * line, relative to gc + * @param lineheight + * the height of one line (and therefore of the box being + * painted) + * @param gc + * the drawing context the client may choose to draw on. + * @param display + * the display the drawing occurs on + */ + protected void paintLine(int line, int y, int lineheight, GC gc, Display display) { + } + + /** + * Triggers a redraw in the display thread. + */ + protected final void postRedraw() { + if (fCanvas != null && !fCanvas.isDisposed()) { + Display d= fCanvas.getDisplay(); + if (d != null) { + synchronized (fRunnableLock) { + if (fIsRunnablePosted) + return; + fIsRunnablePosted= true; + } + d.asyncExec(fRunnable); + } + } + } + + /* + * @see IVerticalRulerColumn#redraw() + */ + public void redraw() { + + if (fRelayoutRequired) { + layout(true); + return; + } + + if (fCanvas != null && !fCanvas.isDisposed()) { + GC gc= new GC(fCanvas); + doubleBufferPaint(gc); + gc.dispose(); + } + } + + /* + * @see IVerticalRulerColumn#setModel(IAnnotationModel) + */ + public void setModel(IAnnotationModel model) { + } + + /* + * @see IVerticalRulerColumn#setFont(Font) + */ + public void setFont(Font font) { + fFont= font; + if (fCanvas != null && !fCanvas.isDisposed()) { + fCanvas.setFont(fFont); + updateNumberOfDigits(); + computeIndentations(); + } + } + + /** + * Returns the parent (composite) ruler of this ruler column. + * + * @return the parent ruler + */ + protected CompositeRuler getParentRuler() { + return fParentRuler; + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyTextHover.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyTextHover.java new file mode 100644 index 00000000000..171ee7804e5 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyTextHover.java @@ -0,0 +1,148 @@ +/******************************************************************************* + * Copyright (c) 2007, 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly; + +import java.util.concurrent.ExecutionException; + +import org.eclipse.cdt.internal.ui.text.CWordFinder; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfExecutor; +import org.eclipse.dd.dsf.concurrent.Query; +import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.AddressRangePosition; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.DisassemblyDocument; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.DisassemblyPosition; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.LabelPosition; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.SourcePosition; +import org.eclipse.dd.dsf.debug.service.IExpressions; +import org.eclipse.dd.dsf.debug.service.IFormattedValues; +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData; +import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextHover; +import org.eclipse.jface.text.ITextViewer; + +/** + * A text hover to evaluate registers and variables under the cursor. + */ +public class DisassemblyTextHover implements ITextHover { + + private final DisassemblyPart fDisassemblyPart; + + /** + * Create a new disassembly text hover. + */ + public DisassemblyTextHover(DisassemblyPart part) { + fDisassemblyPart= part; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.ITextHover#getHoverRegion(org.eclipse.jface.text.ITextViewer, int) + */ + public IRegion getHoverRegion(ITextViewer textViewer, int offset) { + IDocument doc = textViewer.getDocument(); + return CWordFinder.findWord(doc, offset); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.ITextHover#getHoverInfo(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion) + */ + public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) { + DisassemblyDocument doc = (DisassemblyDocument)textViewer.getDocument(); + int offset = hoverRegion.getOffset(); + AddressRangePosition pos; + try { + String ident = doc.get(offset, hoverRegion.getLength()); + String value = null; + pos = doc.getModelPosition(offset); + if (pos instanceof SourcePosition) { + value = evaluateExpression(ident); + } else if (pos instanceof LabelPosition) { + value = evaluateExpression(ident); + } else if (pos instanceof DisassemblyPosition) { + // first, try to evaluate as register + value = evaluateRegister(ident); + if (value == null) { + // if this fails, try expression + value = evaluateExpression(ident); + } + } + if (value != null) { + return ident + " = " + value; //$NON-NLS-1$ + } + } catch (BadLocationException e) { + if (DsfDebugUIPlugin.getDefault().isDebugging()) { + DsfDebugUIPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, "Internal Error", e)); //$NON-NLS-1$ + } + } + return null; + } + + /** + * Evaluate the given register. + * @param register + * @return register value or null + */ + private String evaluateRegister(String register) { + // TLETODO [disassembly] evaluate register + return null; + } + + /** + * Evaluate the given expression. + * @param expr + * @return expression value or null + */ + private String evaluateExpression(String expr) { + final IExpressions expressions= fDisassemblyPart.getService(IExpressions.class); + if (expressions == null) { + return null; + } + final IFrameDMContext frameDmc= fDisassemblyPart.getTargetFrameContext(); + if (frameDmc == null || !fDisassemblyPart.isSuspended()) { + return null; + } + IExpressionDMContext exprDmc= expressions.createExpression(frameDmc, expr); + final FormattedValueDMContext valueDmc= expressions.getFormattedValueContext(exprDmc, IFormattedValues.NATURAL_FORMAT); + final DsfExecutor executor= fDisassemblyPart.getSession().getExecutor(); + Query query= new Query() { + @Override + protected void execute(final DataRequestMonitor rm) { + expressions.getFormattedExpressionValue(valueDmc, new DataRequestMonitor(executor, rm) { + @Override + protected void handleSuccess() { + FormattedValueDMData data= getData(); + rm.setData(data); + rm.done(); + } + }); + }}; + + executor.execute(query); + FormattedValueDMData data= null; + try { + data= query.get(); + } catch (InterruptedException exc) { + } catch (ExecutionException exc) { + } + if (data != null) { + return data.getFormattedValue(); + } + return null; + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyView.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyView.java new file mode 100644 index 00000000000..a85b6db47e1 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyView.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * Copyright (c) 2007, 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly; + +import org.eclipse.debug.ui.IDebugUIConstants; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IMemento; +import org.eclipse.ui.ISelectionListener; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IViewSite; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.PartInitException; + +/** + * DisassemblyView + */ +public class DisassemblyView extends DisassemblyPart implements IViewPart { + + private ISelectionListener fDebugViewListener; + + /** + * + */ + public DisassemblyView() { + super(); + } + + /* + * @see com.windriver.ide.disassembly.views.DisassemblyPart#getActionBars() + */ + @Override + protected IActionBars getActionBars() { + return getViewSite().getActionBars(); + } + + /* + * @see org.eclipse.ui.IViewPart#getViewSite() + */ + public IViewSite getViewSite() { + return (IViewSite)getSite(); + } + + /* + * @see org.eclipse.ui.IViewPart#init(org.eclipse.ui.IViewSite) + */ + public void init(IViewSite site) throws PartInitException { + setSite(site); + } + + /* + * @see org.eclipse.ui.IViewPart#init(org.eclipse.ui.IViewSite, org.eclipse.ui.IMemento) + */ + public void init(IViewSite site, IMemento memento) throws PartInitException { + setSite(site); + site.getPage().addSelectionListener(IDebugUIConstants.ID_DEBUG_VIEW, fDebugViewListener= new ISelectionListener() { + public void selectionChanged(IWorkbenchPart part, ISelection selection) { + updateDebugContext(); + }}); + } + + /* + * @see org.eclipse.ui.IViewPart#saveState(org.eclipse.ui.IMemento) + */ + public void saveState(IMemento memento) { + } + + /* + * @see com.windriver.ide.disassembly.views.DisassemblyPart#contributeToActionBars() + */ + @Override + protected void contributeToActionBars(IActionBars bars) { + super.contributeToActionBars(bars); + fillLocalPullDown(bars.getMenuManager()); + } + + protected void fillLocalPullDown(IMenuManager manager) { + manager.add(fActionGotoPC); + manager.add(fActionGotoAddress); + manager.add(fActionToggleSource); + manager.add(new Separator()); + } + + /* + * @see com.windriver.ide.disassembly.views.DisassemblyPart#closePart() + */ + @Override + protected void closePart() { + getViewSite().getPage().hideView(this); + } + + /* + * @see com.windriver.ide.disassembly.views.DisassemblyPart#dispose() + */ + @Override + public void dispose() { + getSite().getPage().removeSelectionListener(fDebugViewListener); + super.dispose(); + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyViewer.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyViewer.java new file mode 100644 index 00000000000..467ae30c0f7 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyViewer.java @@ -0,0 +1,283 @@ +/******************************************************************************* + * Copyright (c) 2007, 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly; + +import java.util.Iterator; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.DisassemblyDocument; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.source.CompositeRuler; +import org.eclipse.jface.text.source.IOverviewRuler; +import org.eclipse.jface.text.source.IVerticalRuler; +import org.eclipse.jface.text.source.IVerticalRulerColumn; +import org.eclipse.jface.text.source.SourceViewer; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.dnd.Clipboard; +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.ControlListener; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Composite; + +/** + * DisassemblyViewer + */ +public class DisassemblyViewer extends SourceViewer { + + class ResizeListener implements ControlListener { + /* + * @see ControlListener#controlResized(ControlEvent) + */ + public void controlResized(ControlEvent e) { + updateViewportListeners(RESIZE); + } + /* + * @see ControlListener#controlMoved(ControlEvent) + */ + public void controlMoved(ControlEvent e) { + } + } + + private boolean fUserTriggeredScrolling; + private int fCachedLastTopPixel; + + // extra resize listener to workaround bug 171018 + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=171018 + private ResizeListener fResizeListener; + + /** + * Create a new DisassemblyViewer. + * @param parent + * @param ruler + * @param overviewRuler + * @param showsAnnotationOverview + * @param styles + */ + public DisassemblyViewer(Composite parent, IVerticalRuler ruler, IOverviewRuler overviewRuler, boolean showsAnnotationOverview, int styles) { + super(parent, ruler, overviewRuler, showsAnnotationOverview, styles); + // always readonly + setEditable(false); + } + + /* + * @see org.eclipse.jface.text.source.SourceViewer#createControl(org.eclipse.swt.widgets.Composite, int) + */ + @Override + protected void createControl(Composite parent, int styles) { + super.createControl(parent, styles); + // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=171018 + getTextWidget().addControlListener(fResizeListener= new ResizeListener()); + } + + /* + * @see org.eclipse.jface.text.source.SourceViewer#handleDispose() + */ + @Override + protected void handleDispose() { + if (fResizeListener != null) { + getTextWidget().removeControlListener(fResizeListener); + } + super.handleDispose(); + } + + /* + * @see org.eclipse.jface.text.source.SourceViewer#doOperation(int) + */ + @Override + public void doOperation(int operation) { + switch (operation) { + case COPY: + StyledText textWidget = getTextWidget(); + if (textWidget == null || !redraws()) { + return; + } + if (textWidget.getSelectionCount() == 0) { + return; + } + String selectedText; + try { + selectedText = getSelectedText(); + } catch (BadLocationException e) { + // should not happend + DsfDebugUIPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, e.getLocalizedMessage(), e)); + return; + } + Clipboard clipboard = new Clipboard(textWidget.getDisplay()); + clipboard.setContents(new Object[] { selectedText }, new Transfer[] { TextTransfer.getInstance() }); + clipboard.dispose(); + break; + default: + super.doOperation(operation); + } + } + + /** + * Get the selected text together with text displayed in visible + * ruler columns. + * @return the selected text + * @throws BadLocationException + */ + public String getSelectedText() throws BadLocationException { + StringBuffer text = new StringBuffer(200); + String lineSeparator = System.getProperty("line.separator"); //$NON-NLS-1$ + DisassemblyDocument doc = (DisassemblyDocument)getDocument(); + Point selection = getSelectedRange(); + int startOffset = selection.x; + int length = selection.y; + int endOffset = startOffset + length; + int startLine = doc.getLineOfOffset(startOffset); + int endLine = doc.getLineOfOffset(endOffset); + int firstLineOffset = startOffset - doc.getLineOffset(startLine); + if (firstLineOffset > 0) { + // partial first line + int lineLength = doc.getLineInformation(startLine).getLength(); + text.append(doc.get(startOffset, Math.min(lineLength - firstLineOffset, length))); + ++startLine; + if (startLine <= endLine) { + text.append(lineSeparator); + } + } + for (int line = startLine; line < endLine; ++line) { + String lineText = getLineText(line); + text.append(lineText); + text.append(lineSeparator); + } + if (doc.getLineOffset(endLine) < endOffset) { + // partial last line + if (startLine <= endLine) { + int lineStart = doc.getLineOffset(endLine); + text.append(getLinePrefix(endLine)); + text.append(doc.get(lineStart, endOffset - lineStart)); + } + } + return text.toString(); + } + + /** + * Return the content of the given line, excluding line separator. + * @param line the line number + * @return the line content + * @throws BadLocationException + */ + public String getLineText(int line) throws BadLocationException { + IDocument doc = getDocument(); + IRegion lineRegion = doc.getLineInformation(line); + return getLinePrefix(line) + doc.get(lineRegion.getOffset(), lineRegion.getLength()); + } + + /** + * Get the line prefix by concatenating the text displayed by + * the visible ruler columns. + * @param line the line number + * @return the prefix string with trailing blank or the empty string + */ + public String getLinePrefix(int line) { + StringBuffer prefix = new StringBuffer(10); + IVerticalRuler ruler = getVerticalRuler(); + if (ruler instanceof CompositeRuler) { + for (Iterator iter = ((CompositeRuler)ruler).getDecoratorIterator(); iter.hasNext();) { + IVerticalRulerColumn column = (IVerticalRulerColumn) iter.next(); + if (column instanceof DisassemblyRulerColumn) { + DisassemblyRulerColumn disassColumn = (DisassemblyRulerColumn)column; + String columnText = disassColumn.createDisplayString(line); + prefix.append(columnText); + int columnWidth = disassColumn.computeNumberOfCharacters(); + columnWidth -= columnText.length(); + while(columnWidth-- > 0) + prefix.append(' '); + prefix.append(' '); + } + } + } + return prefix.toString(); + } + + /** + * Scroll the given position into the visible area if it is not yet visible. + * @param offset + * @see org.eclipse.jface.text.TextViewer#revealRange(int, int) + */ + public void revealOffset(int offset, boolean onTop) { + try { + IDocument doc = getVisibleDocument(); + + int focusLine = doc.getLineOfOffset(offset); + + StyledText textWidget = getTextWidget(); + int top = textWidget.getTopIndex(); + if (top > -1) { + + // scroll vertically + int lines = getEstimatedVisibleLinesInViewport(); + int bottom = top + lines; + + int bottomBuffer = Math.max(1, lines / 3); + + if (!onTop && focusLine >= top && focusLine <= bottom - bottomBuffer) { + // do not scroll at all as it is already visible + } else { + if (focusLine > bottom - bottomBuffer && focusLine <= bottom) { + // focusLine is already in bottom bufferZone + // scroll to top of bottom bufferzone - for smooth down-scrolling + int scrollDelta = focusLine - (bottom - bottomBuffer); + textWidget.setTopIndex(top + scrollDelta); + } else { + // scroll to top of visible area minus buffer zone + int topBuffer = onTop ? 0 : lines / 3; + textWidget.setTopIndex(Math.max(0, focusLine - topBuffer)); + } + updateViewportListeners(INTERNAL); + } + } + } catch (BadLocationException ble) { + throw new IllegalArgumentException(ble.getLocalizedMessage()); + } + } + + /** + * @return the number of visible lines in the viewport assuming a constant + * line height. + */ + private int getEstimatedVisibleLinesInViewport() { + StyledText textWidget = getTextWidget(); + if (textWidget != null) { + Rectangle clArea= textWidget.getClientArea(); + if (!clArea.isEmpty()) + return clArea.height / textWidget.getLineHeight(); + } + return -1; + } + + int getLastTopPixel() { + return fCachedLastTopPixel; + } + boolean isUserTriggeredScrolling() { + return fUserTriggeredScrolling; + } + + /* + * @see org.eclipse.jface.text.TextViewer#updateViewportListeners(int) + */ + @Override + protected void updateViewportListeners(int origin) { + fCachedLastTopPixel = fLastTopPixel; + fUserTriggeredScrolling = origin != INTERNAL && origin != RESIZE; + super.updateViewportListeners(origin); + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyViewerConfiguration.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyViewerConfiguration.java new file mode 100644 index 00000000000..9092894f209 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyViewerConfiguration.java @@ -0,0 +1,131 @@ +/******************************************************************************* + * Copyright (c) 2007, 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly; + +import org.eclipse.jface.text.DocumentEvent; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextHover; +import org.eclipse.jface.text.ITypedRegion; +import org.eclipse.jface.text.IUndoManager; +import org.eclipse.jface.text.Region; +import org.eclipse.jface.text.TextPresentation; +import org.eclipse.jface.text.hyperlink.IHyperlinkDetector; +import org.eclipse.jface.text.presentation.IPresentationDamager; +import org.eclipse.jface.text.presentation.IPresentationReconciler; +import org.eclipse.jface.text.presentation.IPresentationRepairer; +import org.eclipse.jface.text.presentation.PresentationReconciler; +import org.eclipse.jface.text.reconciler.IReconciler; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.ui.editors.text.EditorsUI; +import org.eclipse.ui.editors.text.TextSourceViewerConfiguration; + +/** + * DisassemblyViewerConfiguration + */ +public class DisassemblyViewerConfiguration extends TextSourceViewerConfiguration { + + private DisassemblyPart fPart; + + /** + * SimpleDamagerRepairer + */ + public class SimpleDamagerRepairer implements IPresentationDamager, IPresentationRepairer { + + /* + * @see org.eclipse.jface.text.presentation.IPresentationDamager#setDocument(org.eclipse.jface.text.IDocument) + */ + public void setDocument(IDocument document) { + } + + /* + * @see org.eclipse.jface.text.presentation.IPresentationDamager#getDamageRegion(org.eclipse.jface.text.ITypedRegion, org.eclipse.jface.text.DocumentEvent, boolean) + */ + public IRegion getDamageRegion(ITypedRegion partition, DocumentEvent e, boolean documentPartitioningChanged) { + int start= e.fOffset; + int end= e.getOffset() + (e.getText() == null ? 0 : e.getText().length()); + return new Region(start, end - start); + } + + /* + * @see org.eclipse.jface.text.presentation.IPresentationRepairer#createPresentation(org.eclipse.jface.text.TextPresentation, org.eclipse.jface.text.ITypedRegion) + */ + public void createPresentation(TextPresentation presentation, ITypedRegion damage) { + // do nothing + } + + } + + /** + * + */ + public DisassemblyViewerConfiguration(DisassemblyPart part) { + super(EditorsUI.getPreferenceStore()); + fPart = part; + } + + /* + * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getPresentationReconciler(org.eclipse.jface.text.source.ISourceViewer) + */ + @Override + public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) { + PresentationReconciler reconciler = new PresentationReconciler(); + SimpleDamagerRepairer dr = new SimpleDamagerRepairer(); + reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE); + reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE); + return reconciler; + } + /* + * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getUndoManager(org.eclipse.jface.text.source.ISourceViewer) + */ + @Override + public IUndoManager getUndoManager(ISourceViewer sourceViewer) { + // no undo/redo + return null; + } + + /* + * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getTextHover(org.eclipse.jface.text.source.ISourceViewer, java.lang.String) + */ + @Override + public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) { + return new DisassemblyTextHover(fPart); + } + + /* + * @see org.eclipse.ui.editors.text.TextSourceViewerConfiguration#getHyperlinkDetectors(org.eclipse.jface.text.source.ISourceViewer) + */ + @Override + public IHyperlinkDetector[] getHyperlinkDetectors(ISourceViewer sourceViewer) { + IHyperlinkDetector[] inheritedDetectors= super.getHyperlinkDetectors(sourceViewer); + + if (fPart == null) + return inheritedDetectors; + + int inheritedDetectorsLength= inheritedDetectors != null ? inheritedDetectors.length : 0; + IHyperlinkDetector[] detectors= new IHyperlinkDetector[inheritedDetectorsLength + 1]; + detectors[0]= new DisassemblyHyperlinkDetector(fPart); + for (int i= 0; i < inheritedDetectorsLength; i++) { + detectors[i+1]= inheritedDetectors[i]; + } + + return detectors; + } + + /* + * @see org.eclipse.ui.editors.text.TextSourceViewerConfiguration#getReconciler(org.eclipse.jface.text.source.ISourceViewer) + */ + @Override + public IReconciler getReconciler(ISourceViewer sourceViewer) { + // disable spell checking + return null; + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/EditionFinderJob.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/EditionFinderJob.java new file mode 100644 index 00000000000..1d3241481eb --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/EditionFinderJob.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly; + +import java.math.BigInteger; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFileState; +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.SourceFileInfo; + +/** + * A job to find a suitable edition from the local history + * based on a file and the timestamp of the code module. + */ +class EditionFinderJob extends Job { + + private final IFile fFile; + private final BigInteger fAddress; + private final DisassemblyPart fDisassemblyPart; + private final SourceFileInfo fSourceInfo; + + /** + * Create a new edition finder for a file resource and address. + * + * @param sourceInfo the file info containing the file resource for which to find an edition + * @param address address inside the module + * @param disassemblyPart the disassembly part where this job originated from + */ + public EditionFinderJob(SourceFileInfo sourceInfo, BigInteger address, DisassemblyPart disassemblyPart) { + super(DisassemblyMessages.EditionFinderJob_name); + Assert.isNotNull(sourceInfo); + Assert.isLegal(sourceInfo.fFile instanceof IFile); + fSourceInfo= sourceInfo; + fFile = (IFile)sourceInfo.fFile; + fAddress = address; + fDisassemblyPart= disassemblyPart; + setRule(fFile); + setSystem(true); + sourceInfo.fEditionJob= this; + } + + /* + * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + protected IStatus run(IProgressMonitor monitor) { + monitor.beginTask(DisassemblyMessages.EditionFinderJob_name, 2); + monitor.subTask(DisassemblyMessages.EditionFinderJob_task_get_timestamp); + long moduleTime; + Object token = fDisassemblyPart.retrieveModuleTimestamp(fAddress); + if (token != null && !(token instanceof Long) && !monitor.isCanceled()) { + try { + synchronized (token) { + token.wait(1000); + } + } catch (InterruptedException e) { + DisassemblyPart.internalError(e); + } + token = fDisassemblyPart.retrieveModuleTimestamp(fAddress); + } + monitor.worked(1); + if (token instanceof Long && !monitor.isCanceled()) { + moduleTime = ((Long)token).longValue(); + long buildTime = moduleTime * 1000; + if (fFile.getLocalTimeStamp() > buildTime) { + monitor.subTask(DisassemblyMessages.EditionFinderJob_task_search_history); + // get history - recent states first + IFileState[] states; + try { + states = fFile.getHistory(new SubProgressMonitor(monitor, 1)); + } catch (CoreException e) { + states = new IFileState[0]; + } + for (int i = 0; i < states.length; i++) { + IFileState state = states[i]; + long saveTime = state.getModificationTime(); + if (saveTime <= buildTime) { + fSourceInfo.fEdition = state; + break; + } + } + } + } + fSourceInfo.fEditionJob = null; + monitor.worked(1); + monitor.done(); + return Status.OK_STATUS; + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/FunctionOffsetRulerColumn.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/FunctionOffsetRulerColumn.java new file mode 100644 index 00000000000..0cc653eba03 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/FunctionOffsetRulerColumn.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2007, 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly; + +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.AddressRangePosition; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.DisassemblyDocument; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.DisassemblyPosition; +import org.eclipse.jface.text.BadLocationException; + +/** + * A vertical ruler column to display the function + offset of instructions. + */ +public class FunctionOffsetRulerColumn extends DisassemblyRulerColumn { + + /** + * Default constructor. + */ + public FunctionOffsetRulerColumn() { + super(); + } + + /* + * @see org.eclipse.jface.text.source.LineNumberRulerColumn#createDisplayString(int) + */ + @Override + protected String createDisplayString(int line) { + DisassemblyDocument doc = (DisassemblyDocument)getParentRuler().getTextViewer().getDocument(); + int offset; + try { + offset = doc.getLineOffset(line); + AddressRangePosition pos = doc.getDisassemblyPosition(offset); + if (pos instanceof DisassemblyPosition && pos.length > 0 && pos.offset == offset && pos.fValid) { + DisassemblyPosition disassPos = (DisassemblyPosition)pos; + return new String(disassPos.fFunction); + } else if (pos != null && !pos.fValid) { + return DOTS.substring(0, doc.getMaxFunctionLength()); + } + } catch (BadLocationException e) { + // silently ignored + } + return ""; //$NON-NLS-1$ + } + + /* + * @see com.windriver.ide.disassembly.views.DisassemblyRulerColumn#computeNumberOfCharacters() + */ + @Override + protected int computeNumberOfCharacters() { + DisassemblyDocument doc = (DisassemblyDocument)getParentRuler().getTextViewer().getDocument(); + return doc.getMaxFunctionLength(); + } + + /* + * @see org.eclipse.jface.text.source.IVerticalRulerColumn#getWidth() + */ + @Override + public int getWidth() { + return super.getWidth(); + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/IDisassemblyHelpContextIds.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/IDisassemblyHelpContextIds.java new file mode 100644 index 00000000000..72d3754577d --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/IDisassemblyHelpContextIds.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2007, 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly; + +import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; + +/** + * IDisassemblyHelpContextIds + */ +public interface IDisassemblyHelpContextIds { + + public final static String PREFIX = DsfDebugUIPlugin.PLUGIN_ID + '.'; + public final static String DISASSEMBLY_PREFERENCE_PAGE = PREFIX + "disassembly_preference_page"; //$NON-NLS-1$ + public final static String DISASSEMBLY_VIEW = PREFIX + "disassembly_view"; //$NON-NLS-1$ + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/IDisassemblyPart.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/IDisassemblyPart.java new file mode 100644 index 00000000000..392de20c3c3 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/IDisassemblyPart.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Anton Leherbauer (Wind River Systems) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.dsf.debug.internal.ui.disassembly; + +import java.math.BigInteger; + +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.ui.IWorkbenchPart; + +/** + * Interface which the disassembly view and editor implement. + */ +public interface IDisassemblyPart extends IWorkbenchPart { + + /** + * Property id for the active state of the part. + */ + public final int PROP_ACTIVE= 0x505; + + /** + * Property id for the connected state of the part. + */ + public final int PROP_CONNECTED= 0x506; + + /** + * Property id for the suspended state of the underlying execution context. + */ + public final int PROP_SUSPENDED= 0x507; + + /** + * Test whether this part is connected to a debug session and execution context. + * + * @return true if the part is connected to a debug session and execution context + */ + boolean isConnected(); + + /** + * Test whether this part is active. A part is active if it is visible and connected. + * + * @return true if the part is active + */ + boolean isActive(); + + /** + * Test whether the underlying execution context is currently suspended. + * Implies connected state. + * + * @return true if the execution context is currently suspended + */ + boolean isSuspended(); + + /** + * Get access to the text viewer. + * + * @return the text viewer + */ + ISourceViewer getTextViewer(); + + /** + * Navigate to the given address. + * + * @param address + */ + void gotoAddress(BigInteger address); + + /** + * Navigate to current program counter. + */ + void gotoProgramCounter(); + + /** + * Navigate to the address the given expression evaluates to. + * + * @param expression a symbolic address expression + */ + void gotoSymbol(String expression); + + /** + * Adds a ruler context menu listener to the disassembly part. + * + * @param listener the listener + */ + void addRulerContextMenuListener(IMenuListener listener); + + /** + * Removes a ruler context menu listener from the disassembly part. + * + * @param listener the listener + */ + void removeRulerContextMenuListener(IMenuListener listener); + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/SourceColorerJob.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/SourceColorerJob.java new file mode 100644 index 00000000000..6a8b339184e --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/SourceColorerJob.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly; + +import org.eclipse.core.resources.IStorage; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.DisassemblyDocument; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.SourceFileInfo; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.progress.IWorkbenchSiteProgressService; +import org.eclipse.ui.progress.UIJob; + +/** + * UI job to color source code. + */ +class SourceColorerJob extends UIJob implements Runnable { + + private final DisassemblyPart fDisassemblyPart; + private final ISourceViewer fViewer; + private final DisassemblyDocument fDocument; + private final IStorage fStorage; + + public SourceColorerJob(Display jobDisplay, IStorage storage, DisassemblyPart disassemblyPart) { + super(DisassemblyMessages.SourceColorerJob_name); + fDisassemblyPart= disassemblyPart; + fViewer= disassemblyPart.getTextViewer(); + fDocument= (DisassemblyDocument) fViewer.getDocument(); + fStorage = storage; + setDisplay(fDisassemblyPart.getSite().getShell().getDisplay()); + setSystem(true); + setPriority(INTERACTIVE); + } + + /* + * @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public IStatus runInUIThread(IProgressMonitor monitor) { + if (fViewer != null && !monitor.isCanceled()) { + monitor.beginTask(DisassemblyMessages.SourceColorerJob_name, IProgressMonitor.UNKNOWN); + SourceFileInfo fi = fDocument.getSourceInfo(fStorage); + if (fi != null) { + fi.initPresentationCreator(fViewer); + if (fi.fError != null) { + String message= DisassemblyMessages.Disassembly_log_error_readFile + fi.fFileKey; + fDisassemblyPart.logWarning(message, fi.fError); + } + } + fDisassemblyPart.updateInvalidSource(); + monitor.done(); + } + return Status.OK_STATUS; + } + + /* + * @see java.lang.Runnable#run() + */ + public void run() { + IWorkbenchSiteProgressService progressService = (IWorkbenchSiteProgressService)fDisassemblyPart.getSite().getAdapter(IWorkbenchSiteProgressService.class); + if(progressService != null) { + progressService.schedule(this, 0, true); + } else { + schedule(); + } + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/AbstractDisassemblyAction.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/AbstractDisassemblyAction.java new file mode 100644 index 00000000000..7ce85f57210 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/AbstractDisassemblyAction.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart; +import org.eclipse.jface.action.Action; +import org.eclipse.ui.IPropertyListener; +import org.eclipse.ui.texteditor.IUpdate; + +public abstract class AbstractDisassemblyAction extends Action implements IUpdate, IPropertyListener { + + protected IDisassemblyPart fDisassemblyPart; + + AbstractDisassemblyAction() { + } + + /** + * Create a disassembly action. + * + * @param disassemblyPart + */ + public AbstractDisassemblyAction(IDisassemblyPart disassemblyPart) { + Assert.isLegal(disassemblyPart != null); + fDisassemblyPart= disassemblyPart; + fDisassemblyPart.addPropertyListener(this); + } + + /** + * @return the disassembly part + */ + public final IDisassemblyPart getDisassemblyPart() { + return fDisassemblyPart; + } + + /* + * @see org.eclipse.jface.action.Action#run() + */ + @Override + public abstract void run(); + + public void update() { + boolean enabled= fDisassemblyPart == null || fDisassemblyPart.isConnected(); + setEnabled(enabled); + } + + /* + * @see org.eclipse.ui.IPropertyListener#propertyChanged(java.lang.Object, int) + */ + public void propertyChanged(Object source, int propId) { + if (source == fDisassemblyPart && (propId & 0x500) != 0) { + update(); + } + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/AbstractDisassemblyBreakpointRulerAction.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/AbstractDisassemblyBreakpointRulerAction.java new file mode 100644 index 00000000000..118abcc286e --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/AbstractDisassemblyBreakpointRulerAction.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions; + +import java.util.Iterator; + +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.model.IBreakpoint; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.jface.text.source.IVerticalRulerInfo; +import org.eclipse.ui.texteditor.SimpleMarkerAnnotation; + +/** + * Abstract implementation of a breakpoint ruler action. + */ +public abstract class AbstractDisassemblyBreakpointRulerAction extends AbstractDisassemblyRulerAction { + + /** + * Create breakpoint ruler action. + * + * @param disassemblyPart + * @param rulerInfo + */ + protected AbstractDisassemblyBreakpointRulerAction(IDisassemblyPart disassemblyPart, IVerticalRulerInfo rulerInfo) { + super(disassemblyPart, rulerInfo); + } + + /** + * Returns the breakpoint at the last line of mouse activity in the ruler + * or null if none. + * + * @return breakpoint associated with activity in the ruler or null + */ + protected IBreakpoint getBreakpoint() { + IAnnotationModel annotationModel = getAnnotationModel(); + IDocument document = getDocument(); + if (annotationModel != null) { + Iterator iterator = annotationModel.getAnnotationIterator(); + while (iterator.hasNext()) { + Object object = iterator.next(); + if (object instanceof SimpleMarkerAnnotation) { + SimpleMarkerAnnotation markerAnnotation = (SimpleMarkerAnnotation) object; + IMarker marker = markerAnnotation.getMarker(); + try { + if (marker.isSubtypeOf(IBreakpoint.BREAKPOINT_MARKER)) { + Position position = annotationModel.getPosition(markerAnnotation); + int line = document.getLineOfOffset(position.getOffset()); + if (line == getRulerInfo().getLineOfLastMouseButtonActivity()) { + IBreakpoint breakpoint = DebugPlugin.getDefault().getBreakpointManager().getBreakpoint(marker); + if (breakpoint != null) { + return breakpoint; + } + } + } + } catch (CoreException e) { + } catch (BadLocationException e) { + } + } + } + } + return null; + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/AbstractDisassemblyRulerAction.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/AbstractDisassemblyRulerAction.java new file mode 100644 index 00000000000..248801fba39 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/AbstractDisassemblyRulerAction.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions; + +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.jface.text.source.IVerticalRulerInfo; + +/** + * Abstract implementation for disassembly vertical ruler actions. + */ +public abstract class AbstractDisassemblyRulerAction extends AbstractDisassemblyAction { + + private final IVerticalRulerInfo fRulerInfo; + + protected AbstractDisassemblyRulerAction(IDisassemblyPart disassemblyPart, IVerticalRulerInfo rulerInfo) { + fDisassemblyPart= disassemblyPart; + fRulerInfo= rulerInfo; + } + + public final IVerticalRulerInfo getRulerInfo() { + return fRulerInfo; + } + + public final IDocument getDocument() { + return getDisassemblyPart().getTextViewer().getDocument(); + } + + public final IAnnotationModel getAnnotationModel() { + return getDisassemblyPart().getTextViewer().getAnnotationModel(); + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/AbstractDisassemblyRulerActionDelegate.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/AbstractDisassemblyRulerActionDelegate.java new file mode 100644 index 00000000000..eda11b1d47d --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/AbstractDisassemblyRulerActionDelegate.java @@ -0,0 +1,167 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions; + +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.text.source.IVerticalRulerInfo; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.ui.IEditorActionDelegate; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IViewActionDelegate; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.actions.ActionDelegate; +import org.eclipse.ui.texteditor.IUpdate; + +/** + * This class serves as an adapter for actions contributed to the vertical ruler's + * context menu. This adapter provides the contributed actions access to their disassembly part + * and the disassembly part's vertical ruler. These actions gain only limited access to the vertical + * ruler as defined by IVerticalRulerInfo. The adapter updates the + * adapter (inner) action on menu and mouse action on the vertical ruler.

              + * Extending classes must implement the factory method + * createAction(IDisassemblyPart, IVerticalRulerInfo). + * + * @see org.eclipse.ui.texteditor.AbstractRulerActionDelegate + */ +public abstract class AbstractDisassemblyRulerActionDelegate extends ActionDelegate implements IEditorActionDelegate, IViewActionDelegate, MouseListener, IMenuListener { + + /** The disassembly part. */ + private IDisassemblyPart fDisassemblyPart; + /** The action calling the action delegate. */ + private IAction fCallerAction; + /** The underlying action. */ + private IAction fAction; + + /** + * The factory method creating the underlying action. + * + * @param disassemblyPart the disassembly part the action to be created will work on + * @param rulerInfo the vertical ruler the action to be created will work on + * @return the created action + */ + protected abstract IAction createAction(IDisassemblyPart disassemblyPart, IVerticalRulerInfo rulerInfo); + + /* + * @see IEditorActionDelegate#setActiveEditor(org.eclipse.jface.action.IAction, org.eclipse.ui.IEditorPart) + */ + public void setActiveEditor(IAction callerAction, IEditorPart targetEditor) { + setTargetPart(callerAction, targetEditor); + } + + /* + * @see org.eclipse.ui.IViewActionDelegate#init(org.eclipse.ui.IViewPart) + */ + public void init(IViewPart view) { + setTargetPart(fCallerAction, view); + } + + @Override + public void init(IAction action) { + fCallerAction= action; + } + + private void setTargetPart(IAction callerAction, IWorkbenchPart targetPart) { + if (fDisassemblyPart != null) { + IVerticalRulerInfo rulerInfo= (IVerticalRulerInfo) fDisassemblyPart.getAdapter(IVerticalRulerInfo.class); + if (rulerInfo != null) { + Control control= rulerInfo.getControl(); + if (control != null && !control.isDisposed()) + control.removeMouseListener(this); + } + + fDisassemblyPart.removeRulerContextMenuListener(this); + } + + fDisassemblyPart= (IDisassemblyPart)(targetPart == null ? null : targetPart.getAdapter(IDisassemblyPart.class)); + fCallerAction= callerAction; + fAction= null; + + if (fDisassemblyPart != null) { + fDisassemblyPart.addRulerContextMenuListener(this); + + IVerticalRulerInfo rulerInfo= (IVerticalRulerInfo) fDisassemblyPart.getAdapter(IVerticalRulerInfo.class); + if (rulerInfo != null) { + fAction= createAction(fDisassemblyPart, rulerInfo); + update(); + + Control control= rulerInfo.getControl(); + if (control != null && !control.isDisposed()) + control.addMouseListener(this); + } + } + } + + @Override + public void run(IAction callerAction) { + if (fAction != null) + fAction.run(); + } + + @Override + public void runWithEvent(IAction action, Event event) { + if (fAction != null) + fAction.runWithEvent(event); + } + + @Override + public void selectionChanged(IAction action, ISelection selection) { + /* + * This is a ruler action - don't update on selection. + */ + } + + /** + * Updates to the current state. + */ + private void update() { + if (fAction instanceof IUpdate) { + ((IUpdate) fAction).update(); + if (fCallerAction != null) { + fCallerAction.setText(fAction.getText()); + fCallerAction.setEnabled(fAction.isEnabled()); + } + } + } + + /* + * @see IMenuListener#menuAboutToShow(org.eclipse.jface.action.IMenuManager) + */ + public void menuAboutToShow(IMenuManager manager) { + update(); + } + + /* + * @see MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent) + */ + public void mouseDoubleClick(MouseEvent e) { + } + + /* + * @see MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent) + */ + public void mouseDown(MouseEvent e) { + update(); + } + + /* + * @see MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent) + */ + public void mouseUp(MouseEvent e) { + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/ActionGotoAddress.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/ActionGotoAddress.java new file mode 100644 index 00000000000..99c9525dd7b --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/ActionGotoAddress.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions; + +import java.math.BigInteger; + +import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.DisassemblyMessages; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.DisassemblyPart; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.IInputValidator; +import org.eclipse.jface.dialogs.InputDialog; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.swt.widgets.Shell; + +public final class ActionGotoAddress extends AbstractDisassemblyAction { + public ActionGotoAddress(IDisassemblyPart disassemblyPart) { + super(disassemblyPart); + setText(DisassemblyMessages.Disassembly_action_GotoAddress_label); + } + @Override + public void run() { + IInputValidator validator = new IInputValidator() { + public String isValid(String input) { + if (input == null || input.length() == 0) + return " "; //$NON-NLS-1$ + try { + BigInteger address= DisassemblyPart.decodeAddress(input); + if (address.compareTo(BigInteger.ZERO) < 0) { + return DisassemblyMessages.Disassembly_GotoAddressDialog_error_invalid_address; + } + } catch (NumberFormatException x) { + return DisassemblyMessages.Disassembly_GotoAddressDialog_error_not_a_number; //; + } + return null; + } + }; + String defaultValue = ((ITextSelection)getDisassemblyPart().getSite().getSelectionProvider().getSelection()).getText(); + if (validator.isValid(defaultValue) != null) { + defaultValue = DsfDebugUIPlugin.getDefault().getDialogSettings().get("gotoAddress"); //$NON-NLS-1$ + if (validator.isValid(defaultValue) != null) { + defaultValue = ""; //$NON-NLS-1$ + } + } + String dlgTitle = DisassemblyMessages.Disassembly_GotoAddressDialog_title; + String dlgLabel = DisassemblyMessages.Disassembly_GotoAddressDialog_label; + final Shell shell= getDisassemblyPart().getSite().getShell(); + InputDialog dlg = new InputDialog(shell, dlgTitle, dlgLabel, defaultValue, validator); + if (dlg.open() == IDialogConstants.OK_ID) { + String value = dlg.getValue(); + BigInteger address= DisassemblyPart.decodeAddress(value); + DsfDebugUIPlugin.getDefault().getDialogSettings().put("gotoAddress", value); //$NON-NLS-1$ + getDisassemblyPart().gotoAddress(address); + } + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/ActionGotoProgramCounter.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/ActionGotoProgramCounter.java new file mode 100644 index 00000000000..d5729b29f76 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/ActionGotoProgramCounter.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions; + +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.DisassemblyMessages; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart; + +public final class ActionGotoProgramCounter extends AbstractDisassemblyAction { + public ActionGotoProgramCounter(IDisassemblyPart disassemblyPart) { + super(disassemblyPart); + setText(DisassemblyMessages.Disassembly_action_GotoPC_label); + setToolTipText(DisassemblyMessages.Disassembly_action_GotoPC_tooltip); + } + @Override + public void run() { + getDisassemblyPart().gotoProgramCounter(); + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/ActionGotoSymbol.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/ActionGotoSymbol.java new file mode 100644 index 00000000000..4849a8bd5d3 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/ActionGotoSymbol.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions; + +import org.eclipse.cdt.internal.ui.text.CWordFinder; +import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.DisassemblyMessages; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.InputDialog; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.swt.widgets.Shell; + +public final class ActionGotoSymbol extends AbstractDisassemblyAction { + public ActionGotoSymbol(IDisassemblyPart disassemblyPart) { + super(disassemblyPart); + setText(DisassemblyMessages.Disassembly_action_GotoSymbol_label); + } + @Override + public void run() { + ITextViewer viewer = getDisassemblyPart().getTextViewer(); + IDocument document= viewer.getDocument(); + IRegion wordRegion = CWordFinder.findWord(document, viewer.getSelectedRange().x); + String defaultValue = null; + if (wordRegion != null) { + try { + defaultValue = document.get(wordRegion.getOffset(), wordRegion.getLength()); + } catch (BadLocationException e) { + // safely ignored + } + } + if (defaultValue == null) { + defaultValue = DsfDebugUIPlugin.getDefault().getDialogSettings().get("gotoSymbol"); //$NON-NLS-1$ + if (defaultValue == null) { + defaultValue = ""; //$NON-NLS-1$ + } + } + String dlgTitle = DisassemblyMessages.Disassembly_GotoSymbolDialog_title; + String dlgLabel = DisassemblyMessages.Disassembly_GotoSymbolDialog_label; + final Shell shell= getDisassemblyPart().getSite().getShell(); + InputDialog dlg = new InputDialog(shell, dlgTitle, dlgLabel, defaultValue, null); + if (dlg.open() == IDialogConstants.OK_ID) { + String value = dlg.getValue(); + DsfDebugUIPlugin.getDefault().getDialogSettings().put("gotoSymbol", value); //$NON-NLS-1$ + getDisassemblyPart().gotoSymbol(value); + } + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/ActionOpenPreferences.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/ActionOpenPreferences.java new file mode 100644 index 00000000000..7be4676c79f --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/ActionOpenPreferences.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions; + +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.DisassemblyMessages; +import org.eclipse.jface.action.Action; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.dialogs.PreferencesUtil; + +public final class ActionOpenPreferences extends Action { + private final static String PREF_PAGE_ID = "org.eclipse.dd.dsf.debug.ui.disassembly.preferencePage"; //$NON-NLS-1$ + private final Shell fShell; + public ActionOpenPreferences(Shell shell) { + fShell= shell; + setText(DisassemblyMessages.Disassembly_action_OpenPreferences_label); + } + @Override + public void run() { + PreferencesUtil.createPreferenceDialogOn(fShell, PREF_PAGE_ID, new String[] { PREF_PAGE_ID }, null).open(); + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/BreakpointPropertiesRulerAction.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/BreakpointPropertiesRulerAction.java new file mode 100644 index 00000000000..17aa90acbb9 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/BreakpointPropertiesRulerAction.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions; + +import org.eclipse.cdt.debug.core.model.ICBreakpoint; +import org.eclipse.cdt.debug.internal.ui.CBreakpointContext; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.DisassemblyMessages; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart; +import org.eclipse.debug.core.model.IBreakpoint; +import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.jface.text.source.IVerticalRulerInfo; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.ui.dialogs.PropertyDialogAction; + +/** + * Ruler action to display breakpoint properties. + */ +public class BreakpointPropertiesRulerAction extends AbstractDisassemblyBreakpointRulerAction { + + private Object fContext; + + protected BreakpointPropertiesRulerAction(IDisassemblyPart disassemblyPart, IVerticalRulerInfo rulerInfo) { + super(disassemblyPart, rulerInfo); + setText(DisassemblyMessages.Disassembly_action_BreakpointProperties_label); + } + + /* + * @see org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions.AbstractDisassemblyAction#run() + */ + @Override + public void run() { + if ( fContext != null ) { + PropertyDialogAction action = new PropertyDialogAction( getDisassemblyPart().getSite(), new ISelectionProvider() { + + public void addSelectionChangedListener( ISelectionChangedListener listener ) { + } + + public ISelection getSelection() { + return new StructuredSelection( fContext ); + } + + public void removeSelectionChangedListener( ISelectionChangedListener listener ) { + } + + public void setSelection( ISelection selection ) { + } + } ); + action.run(); + action.dispose(); + } + } + + /* + * @see IUpdate#update() + */ + @Override + public void update() { + IBreakpoint breakpoint= getBreakpoint(); + if (breakpoint instanceof ICBreakpoint) { + fContext = new CBreakpointContext((ICBreakpoint)breakpoint, getDebugContext()); + } else { + fContext = breakpoint; + } + setEnabled( fContext != null ); + } + + private ISelection getDebugContext() { + return DebugUITools.getDebugContextManager().getContextService(getDisassemblyPart().getSite().getWorkbenchWindow()).getActiveContext(); + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/BreakpointPropertiesRulerActionDelegate.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/BreakpointPropertiesRulerActionDelegate.java new file mode 100644 index 00000000000..c34f3b78ea9 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/BreakpointPropertiesRulerActionDelegate.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions; + +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.text.source.IVerticalRulerInfo; + +/** + * Ruler action delegate for the breakpoint properties action. + */ +public class BreakpointPropertiesRulerActionDelegate extends AbstractDisassemblyRulerActionDelegate { + + /* + * @see org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions.AbstractDisassemblyRulerActionDelegate#createAction(org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart, org.eclipse.jface.text.source.IVerticalRulerInfo) + */ + @Override + protected IAction createAction(IDisassemblyPart disassemblyPart, IVerticalRulerInfo rulerInfo) { + return new BreakpointPropertiesRulerAction(disassemblyPart, rulerInfo); + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/TextOperationAction.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/TextOperationAction.java new file mode 100644 index 00000000000..765d96027d6 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/TextOperationAction.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2007, 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.text.ITextOperationTarget; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.ui.texteditor.IUpdate; + +/** + * TextOperationAction + */ +public class TextOperationAction extends Action implements IUpdate { + + private int fOperationCode= -1; + private ITextOperationTarget fOperationTarget; + + public TextOperationAction(ITextViewer viewer, int operationCode) { + fOperationCode= operationCode; + fOperationTarget= viewer.getTextOperationTarget(); + update(); + } + + /** + * Updates the enabled state of the action. + * Fires a property change if the enabled state changes. + * + * @see Action#firePropertyChange(String, Object, Object) + */ + public void update() { + + boolean wasEnabled= isEnabled(); + boolean isEnabled= (fOperationTarget != null && fOperationTarget.canDoOperation(fOperationCode)); + setEnabled(isEnabled); + + if (wasEnabled != isEnabled) { + firePropertyChange(ENABLED, wasEnabled ? Boolean.TRUE : Boolean.FALSE, isEnabled ? Boolean.TRUE : Boolean.FALSE); + } + } + + /** + * @see Action#run() + */ + @Override + public void run() { + if (fOperationCode != -1 && fOperationTarget != null) { + fOperationTarget.doOperation(fOperationCode); + } + } + } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/Addr2Line.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/Addr2Line.java new file mode 100644 index 00000000000..0e171abb8a2 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/Addr2Line.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2007, 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model; + +import java.math.BigInteger; + + +public class Addr2Line { + public BigInteger addr; + public Addr2Line next; + public int first; + public int last; + + public static int hash(BigInteger addr, int size) { + return (int)((addr.shiftRight(2).longValue()) % size); + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/AddressRangePosition.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/AddressRangePosition.java new file mode 100644 index 00000000000..4740a8f7335 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/AddressRangePosition.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model; + +import java.math.BigInteger; + +import org.eclipse.jface.text.Position; + +/** + * AddressRangePosition + */ +public class AddressRangePosition extends Position { + + public BigInteger fAddressOffset; + public BigInteger fAddressLength; + public boolean fValid; + + /** + * @param offset + * @param length + */ + public AddressRangePosition(int offset, int length, BigInteger addressOffset, BigInteger addressLength) { + super(offset, length); + fAddressOffset = addressOffset; + fAddressLength = addressLength; + fValid = true; + } + + /** + * @param offset + * @param length + * @param valid + */ + public AddressRangePosition(int offset, int length, BigInteger addressOffset, BigInteger addressLength, boolean valid) { + super(offset, length); + fAddressOffset = addressOffset; + fAddressLength = addressLength; + fValid = valid; + } + + /** + * @param address + * @return + */ + public boolean containsAddress(BigInteger address) { + return address.compareTo(fAddressOffset) >= 0 + && address.compareTo(fAddressOffset.add(fAddressLength)) < 0; + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object other) { + // identity comparison + return this == other; + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/BreakpointsAnnotationModel.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/BreakpointsAnnotationModel.java new file mode 100644 index 00000000000..ff9c7ba36cf --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/BreakpointsAnnotationModel.java @@ -0,0 +1,229 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Anton Leherbauer (Wind River Systems) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model; + +import java.math.BigInteger; +import java.util.Iterator; + +import org.eclipse.cdt.debug.core.model.ICAddressBreakpoint; +import org.eclipse.cdt.debug.core.model.ICLineBreakpoint; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IMarkerDelta; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.IBreakpointListener; +import org.eclipse.debug.core.IBreakpointManager; +import org.eclipse.debug.core.model.IBreakpoint; +import org.eclipse.debug.core.model.ILineBreakpoint; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.DocumentEvent; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IDocumentListener; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.source.Annotation; +import org.eclipse.jface.text.source.AnnotationModel; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.texteditor.MarkerAnnotation; +import org.eclipse.ui.texteditor.SimpleMarkerAnnotation; + +/** + * Annotation model for breakpoints in the disassembly. + * Works only with {@link DisassemblyDocument}. + */ +public class BreakpointsAnnotationModel extends AnnotationModel implements IBreakpointListener, IDocumentListener { + + private Runnable fCatchup; + + @Override + public void connect(IDocument document) { + super.connect(document); + if (document instanceof DisassemblyDocument) { + final IBreakpointManager bpMgr= DebugPlugin.getDefault().getBreakpointManager(); + addBreakpoints(bpMgr.getBreakpoints()); + bpMgr.addBreakpointListener(this); + document.addDocumentListener(this); + } + } + + @Override + public void disconnect(IDocument document) { + if (document instanceof DisassemblyDocument) { + final IBreakpointManager bpMgr= DebugPlugin.getDefault().getBreakpointManager(); + bpMgr.removeBreakpointListener(this); + document.removeDocumentListener(this); + fCatchup= null; + } + super.disconnect(document); + } + + private void catchupWithBreakpoints() { + removeAllAnnotations(false); + final IBreakpointManager bpMgr= DebugPlugin.getDefault().getBreakpointManager(); + addBreakpoints(bpMgr.getBreakpoints()); + } + + private void addBreakpoints(IBreakpoint[] breakpoints) { + for (IBreakpoint breakpoint : breakpoints) { + addBreakpointAnnotation(breakpoint, false); + } + fireModelChanged(); + } + + /* + * @see org.eclipse.debug.core.IBreakpointListener#breakpointAdded(org.eclipse.debug.core.model.IBreakpoint) + */ + public void breakpointAdded(IBreakpoint breakpoint) { + addBreakpointAnnotation(breakpoint, true); + } + + /* + * @see org.eclipse.debug.core.IBreakpointListener#breakpointChanged(org.eclipse.debug.core.model.IBreakpoint, org.eclipse.core.resources.IMarkerDelta) + */ + public void breakpointChanged(IBreakpoint breakpoint, IMarkerDelta delta) { + Annotation a= findAnnotation(breakpoint.getMarker()); + if (a != null) { + if (a instanceof SimpleMarkerAnnotation) { + ((SimpleMarkerAnnotation)a).update(); + } + synchronized (getLockObject()) { + getAnnotationModelEvent().annotationChanged(a); + } + fireModelChanged(); + } + } + + /* + * @see org.eclipse.debug.core.IBreakpointListener#breakpointRemoved(org.eclipse.debug.core.model.IBreakpoint, org.eclipse.core.resources.IMarkerDelta) + */ + public void breakpointRemoved(IBreakpoint breakpoint, IMarkerDelta delta) { + Annotation a= findAnnotation(breakpoint.getMarker()); + if (a != null) { + removeAnnotation(a, true); + } + } + + @SuppressWarnings("unchecked") + private Annotation findAnnotation(IMarker marker) { + for (Iterator it= getAnnotationIterator(false); it.hasNext();) { + SimpleMarkerAnnotation a= it.next(); + if (a.getMarker().equals(marker)) { + return a; + } + } + return null; + } + + private void addBreakpointAnnotation(IBreakpoint breakpoint, boolean fireEvent) { + final IMarker marker= breakpoint.getMarker(); + if (marker == null) { + return; + } + try { + Position position= createPositionFromBreakpoint(breakpoint); + if (position != null) { + addAnnotation(new MarkerAnnotation(marker), position, fireEvent); + } + } catch (CoreException exc) { + // ignore problems accessing attributes + } catch (BadLocationException exc) { + // ignore wrong positions + } + } + + private Position createPositionFromBreakpoint(IBreakpoint breakpoint) throws CoreException { + if (breakpoint instanceof ICAddressBreakpoint) { + ICAddressBreakpoint addressBreakpoint= (ICAddressBreakpoint) breakpoint; + return createPositionFromAddress(decodeAddress(addressBreakpoint.getAddress())); + } else if (breakpoint instanceof ILineBreakpoint) { + ILineBreakpoint lineBreakpoint= (ILineBreakpoint) breakpoint; + Position position= null; + final int lineNumber= lineBreakpoint.getLineNumber() - 1; + final IMarker marker= breakpoint.getMarker(); + if (marker.getResource().getType() == IResource.FILE) { + position= createPositionFromSourceLine((IFile) marker.getResource(), lineNumber); + } else if (breakpoint instanceof ICLineBreakpoint) { + ICLineBreakpoint cBreakpoint= (ICLineBreakpoint) breakpoint; + position= createPositionFromSourceLine(cBreakpoint.getFileName(), lineNumber); + if (position == null) { + position= createPositionFromAddress(decodeAddress(cBreakpoint.getAddress())); + } + } else { + String fileName= marker.getAttribute(ICLineBreakpoint.SOURCE_HANDLE, null); + if (fileName != null) { + position= createPositionFromSourceLine(fileName, lineNumber); + } + } + return position; + } + return null; + } + + private Position createPositionFromSourceLine(String fileName, int lineNumber) { + return getDisassemblyDocument().getSourcePosition(fileName, lineNumber); + } + + private Position createPositionFromSourceLine(IFile file, int lineNumber) { + return getDisassemblyDocument().getSourcePosition(file, lineNumber); + } + + private Position createPositionFromAddress(BigInteger address) { + AddressRangePosition p= getDisassemblyDocument().getDisassemblyPosition(address); + if (p != null && p.fValid) { + return new Position(p.offset, p.length); + } + return null; + } + + private DisassemblyDocument getDisassemblyDocument() { + return (DisassemblyDocument) fDocument; + } + + /** + * Decode given string representation of a non-negative integer. A + * hexadecimal encoded integer is expected to start with 0x. + * + * @param string + * decimal or hexadecimal representation of an non-negative integer + * @return address value as BigInteger + */ + private static BigInteger decodeAddress(String string) { + if (string.startsWith("0x")) { //$NON-NLS-1$ + return new BigInteger(string.substring(2), 16); + } + return new BigInteger(string); + } + + /* + * @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent) + */ + public void documentAboutToBeChanged(DocumentEvent event) { + } + + /* + * @see org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.jface.text.DocumentEvent) + */ + public void documentChanged(DocumentEvent event) { + if (fCatchup == null && event.fText != null && event.fText.length() > 0) { + fCatchup= new Runnable() { + public void run() { + if (fCatchup == this) { + catchupWithBreakpoints(); + fCatchup= null; + } + }}; + Display.getCurrent().timerExec(50, fCatchup); + } + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/DisassemblyDocument.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/DisassemblyDocument.java new file mode 100644 index 00000000000..e6bc008e426 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/DisassemblyDocument.java @@ -0,0 +1,1423 @@ +/******************************************************************************* + * Copyright (c) 2007, 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model; + +import java.io.File; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.resources.IStorage; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.text.REDDocument; +import org.eclipse.debug.core.sourcelookup.containers.LocalFileStorage; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.BadPositionCategoryException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.Position; + +/** + * DisassemblyDocument + */ +public class DisassemblyDocument extends REDDocument { + + public final static String CATEGORY_MODEL = "category_model"; //$NON-NLS-1$ + public final static String CATEGORY_DISASSEMBLY = "category_disassembly"; //$NON-NLS-1$ + public final static String CATEGORY_SOURCE = "category_source"; //$NON-NLS-1$ + public final static String CATEGORY_LABELS = "category_labels"; //$NON-NLS-1$ + + private final static boolean DEBUG = false; + + public ArrayList fInvalidAddressRanges = new ArrayList(); + public ArrayList fInvalidSource = new ArrayList(); + private Map fFileInfoMap = new HashMap(); + + private int fMaxFunctionLength = 0; + + private boolean fShowAddresses = false; + private int fRadix = 16; + private boolean fShowRadixPrefix = false; + private String fRadixPrefix; + private int fNumberOfDigits; + private boolean fShowCodeBytes = false; + + private int fNumberOfInstructions; + private double fMeanSizeOfInstructions = 4; + + public DisassemblyDocument() { + super(); + } + + /* + * @see org.eclipse.jface.text.AbstractDocument#completeInitialization() + */ + @Override + protected void completeInitialization() { + super.completeInitialization(); + addPositionCategory(CATEGORY_MODEL); + addPositionCategory(CATEGORY_DISASSEMBLY); + addPositionCategory(CATEGORY_SOURCE); + addPositionCategory(CATEGORY_LABELS); + setRadix(16); + setShowRadixPrefix(false); + } + + /** + * Cleanup. + */ + @Override + public void dispose() { + super.dispose(); + if (fFileInfoMap != null) { + // cleanup source info + for (Iterator iter = fFileInfoMap.values().iterator(); iter.hasNext();) { + SourceFileInfo fi = iter.next(); + fi.dispose(); + } + fFileInfoMap = null; + } + } + + public List getInvalidAddressRanges() { + return fInvalidAddressRanges; + } + + public List getInvalidSource() { + return fInvalidSource; + } + + public void setMaxOpcodeLength(int opcodeLength) { + fMaxFunctionLength = opcodeLength; + } + + public int getMaxFunctionLength() { + return fMaxFunctionLength; + } + + public int getAddressLength() { + return fNumberOfDigits+2; + } + + public int getMeanSizeOfInstructions() { + return (int)(fMeanSizeOfInstructions+.9); + } + + public Iterator getModelPositionIterator(BigInteger address) { + try { + return getPositionIterator(CATEGORY_MODEL, address); + } catch (BadPositionCategoryException e) { + // cannot happen + } + return null; + } + + public Iterator getPositionIterator(String category, int offset) throws BadPositionCategoryException { + @SuppressWarnings("unchecked") + List positions = (List) getDocumentManagedPositions().get(category); + if (positions == null) { + throw new BadPositionCategoryException(); + } + int idx = computeIndexInPositionList(positions, offset, true); + return positions.listIterator(idx); + } + + public Iterator getPositionIterator(String category, BigInteger address) throws BadPositionCategoryException { + @SuppressWarnings("unchecked") + List positions = (List) getDocumentManagedPositions().get(category); + if (positions == null) { + throw new BadPositionCategoryException(); + } + int idx = computeIndexInPositionListFirst(positions, address); + return positions.listIterator(idx); + } + + public int computeIndexInCategory(String category, BigInteger address) throws BadPositionCategoryException { + @SuppressWarnings("unchecked") + List c = (List) getDocumentManagedPositions().get(category); + if (c == null) { + throw new BadPositionCategoryException(); + } + return computeIndexInPositionListFirst(c, address); + } + + /** + * Computes the index in the list of positions at which a position with the + * given address would be inserted. The position is supposed to become the + * first in this list of all positions with the same offset. + * + * @param positions + * the list in which the index is computed + * @param address + * the address for which the index is computed + * @return the computed index + * + */ + protected int computeIndexInPositionListFirst(List positions, BigInteger address) { + int size = positions.size(); + if (size == 0) { + return 0; + } + int left = 0; + int right = size - 1; + int mid = 0; + while (left <= right) { + mid = (left + right) / 2; + AddressRangePosition range = positions.get(mid); + if (address.compareTo(range.fAddressOffset) < 0) { + right = mid - 1; + } else if (address.compareTo(range.fAddressOffset) == 0) { + break; + } else if (address.compareTo(range.fAddressOffset.add(range.fAddressLength)) >= 0) { + left = mid + 1; + } else { + break; + } + } + int idx = mid; + AddressRangePosition p = positions.get(idx); + if (address.compareTo(p.fAddressOffset.add(p.fAddressLength)) > 0) { + ++idx; + } else if (address.compareTo(p.fAddressOffset) == 0) { + do { + --idx; + if (idx < 0) { + break; + } + p = positions.get(idx); + } while (address.compareTo(p.fAddressOffset) == 0); + ++idx; + } + return idx; + } + + /** + * Computes the index in the list of positions at which a position with the + * given address would be inserted. The position is supposed to become the + * last but one in this list of all positions with the same address. + * + * @param positions + * the list in which the index is computed + * @param address + * the address for which the index is computed + * @return the computed index + * + */ + protected int computeIndexInPositionListLast(List positions, BigInteger address) { + int size = positions.size(); + if (size == 0) { + return 0; + } + int left = 0; + int right = size - 1; + int mid = 0; + while (left <= right) { + mid = (left + right) / 2; + AddressRangePosition range = positions.get(mid); + if (address.compareTo(range.fAddressOffset) < 0) { + right = mid - 1; + } else if (address.compareTo(range.fAddressOffset) == 0) { + break; + } else if (address.compareTo(range.fAddressOffset.add(range.fAddressLength)) >= 0) { + left = mid + 1; + } else { + break; + } + } + int idx = mid; + AddressRangePosition p = positions.get(idx); + if (address.compareTo(p.fAddressOffset) > 0) { + ++idx; + } else if (address.compareTo(p.fAddressOffset) == 0 && p.fAddressLength.compareTo(BigInteger.ZERO) == 0) { + do { + ++idx; + if (idx == size) { + break; + } + p = positions.get(idx); + } while (address.compareTo(p.fAddressOffset) == 0 && p.fAddressLength.compareTo(BigInteger.ZERO) == 0); + // --idx; + } + return idx; + } + + /** + * Computes the index in the list of positions at which a position with the + * given offset would be inserted. The position is supposed to become the + * last in this list of all positions with the same offset. + * + * @param positions + * the list in which the index is computed + * @param offset + * the offset for which the index is computed + * @return the computed index + * + * @see IDocument#computeIndexInCategory(String, int) + */ + protected int computeIndexInPositionListLast(List positions, int offset) { + + if (positions.size() == 0) + return 0; + + int left = 0; + int right = positions.size() - 1; + int mid = 0; + Position p = null; + + while (left < right) { + + mid = (left + right) / 2; + + p = positions.get(mid); + if (offset < p.getOffset()) { + if (left == mid) + right = left; + else + right = mid - 1; + } else if (offset > p.getOffset()) { + if (right == mid) + left = right; + else + left = mid + 1; + } else if (offset == p.getOffset()) { + left = right = mid; + } + + } + + int pos = left; + p = positions.get(pos); + while (offset >= p.getOffset()) { + // entry will become the last of all entries with the same offset + ++pos; + if (pos == positions.size()) { + break; + } + p = positions.get(pos); + } + + assert 0 <= pos && pos <= positions.size(); + + return pos; + } + + /** + * Get the position for the supplied category and index. + * + * @param category + * @param index + * @return a Position matching the category and index, or null. + */ + public Position getPositionOfIndex(String category, int index) throws BadPositionCategoryException { + if (index >= 0) { + @SuppressWarnings("unchecked") + List positions = (List) getDocumentManagedPositions().get(category); + if (positions == null) { + throw new BadPositionCategoryException(); + } + if (index < positions.size()) { + return positions.get(index); + } + } + return null; + } + + /** + * @param address + * @return + */ + public AddressRangePosition getPositionOfAddress(BigInteger address) { + AddressRangePosition pos = getPositionOfAddress(CATEGORY_DISASSEMBLY, address); + return pos; + } + + /** + * @param category + * @param address + * @return + */ + public AddressRangePosition getPositionOfAddress(String category, BigInteger address) { + @SuppressWarnings("unchecked") + List positions = (List) getDocumentManagedPositions().get(category); + if (positions == null) { + return null; + } + int index = computeIndexInPositionListFirst(positions, address); + if (index < positions.size()) { + AddressRangePosition p = positions.get(index); + if (address.compareTo(p.fAddressOffset) == 0 || p.containsAddress(address)) { + return p; + } + } + return null; + } + + /** + * @param category + * @param range + * @return + */ + public AddressRangePosition getPositionInAddressRange(String category, AddressRangePosition range) { + @SuppressWarnings("unchecked") + List positions = (List) getDocumentManagedPositions().get(category); + if (positions == null) { + return null; + } + BigInteger endAddress = range.fAddressOffset.add(range.fAddressLength); + int index = computeIndexInPositionListFirst(positions, range.fAddressOffset); + if (index < positions.size()) { + do { + AddressRangePosition p = positions.get(index); + if (p.fAddressOffset.compareTo(endAddress) >= 0) { + --index; + } else { + return p; + } + } while (index >= 0); + } + return null; + } + + /** + * Compute the address of the given document line number. + * + * @param line + * @return the address of the given document line number, -1 if no valid + * address can be computed + */ + public BigInteger getAddressOfLine(int line) { + try { + int offset = getLineOffset(line); + return getAddressOfOffset(offset); + } catch (BadLocationException e) { + // intentionally ignored + } + return BigInteger.valueOf(-1); + } + + /** + * Compute the address off the given document offset. + * + * @param offset + * @return the address of the given document offset, -1 if no valid address + * can be computed + */ + public BigInteger getAddressOfOffset(int offset) { + AddressRangePosition pos; + try { + pos = getModelPosition(offset); + } catch (BadLocationException e) { + internalError(e); + return BigInteger.valueOf(-1); + } + if (pos == null) { + return BigInteger.valueOf(-1); + } + return pos.fAddressOffset; + } + + /** + * @param offset + * @return + */ + public AddressRangePosition getDisassemblyPosition(int offset) throws BadLocationException { + Position p = null; + try { + p = getPosition(CATEGORY_DISASSEMBLY, offset, false); + } catch (BadPositionCategoryException e) { + // cannot happen + } + return (AddressRangePosition) p; + } + + /** + * @param address + * @return + */ + public AddressRangePosition getDisassemblyPosition(BigInteger address) { + return getPositionOfAddress(CATEGORY_DISASSEMBLY, address); + } + + + /** + * @param offset + * @return + * @throws BadLocationException + */ + public AddressRangePosition getModelPosition(int offset) throws BadLocationException { + Position p = null; + try { + p = getPosition(CATEGORY_MODEL, offset, false); + } catch (BadPositionCategoryException e) { + // cannot happen + } + return (AddressRangePosition) p; + } + + /** + * @param offset + * @return + * @throws BadLocationException + */ + public SourcePosition getSourcePosition(int offset) throws BadLocationException { + Position p = null; + try { + p = getPosition(CATEGORY_SOURCE, offset, true); + } catch (BadPositionCategoryException e) { + // cannot happen + } + return (SourcePosition) p; + } + + /** + * @param address + * @return + */ + public SourcePosition getSourcePosition(BigInteger address) { + return (SourcePosition) getPositionOfAddress(CATEGORY_SOURCE, address); + } + + /** + * @param address + * @return + */ + public LabelPosition getLabelPosition(BigInteger address) { + return (LabelPosition) getPositionOfAddress(CATEGORY_LABELS, address); + } + + /** + * @param range + * @return + */ + public SourcePosition getSourcePositionInAddressRange(AddressRangePosition range) { + return (SourcePosition) getPositionInAddressRange(CATEGORY_SOURCE, range); + } + + /** + * Compute document position of the given source line. + * + * @param file the file as an IStorage + * @param lineNumber the 0-based line number + * @return the document position or null + */ + public Position getSourcePosition(IStorage file, int lineNumber) { + SourceFileInfo info= getSourceInfo(file); + return getSourcePosition(info, lineNumber); + } + + /** + * Compute document position of the given source line. + * + * @param fileName the file name, may be a raw debugger path or the path to an external file + * @param lineNumber the 0-based line number + * @return the document position or null + */ + public Position getSourcePosition(String fileName, int lineNumber) { + SourceFileInfo info= getSourceInfo(fileName); + if (info == null) { + info= getSourceInfo(new LocalFileStorage(new File(fileName))); + } + return getSourcePosition(info, lineNumber); + } + + /** + * Compute document position of the given source line. + * + * @param info + * @param lineNumber the 0-based line number + * @return the document position or null + */ + protected Position getSourcePosition(SourceFileInfo info, int lineNumber) { + if (info == null) { + return null; + } + try { + SourcePosition srcPos= null; + IRegion stmtLineRegion= info.fSource.getLineInformation(lineNumber); + final int lineOffset = stmtLineRegion.getOffset(); + final int lineLength = stmtLineRegion.getLength() + 1; + BigInteger stmtAddress = info.fLine2Addr[lineNumber]; + if (stmtAddress != null && stmtAddress.compareTo(BigInteger.ZERO) > 0) { + srcPos = getSourcePosition(stmtAddress); + } + if (srcPos == null) { + for (Iterator iterator = getPositionIterator(CATEGORY_SOURCE, 0); iterator.hasNext(); ) { + SourcePosition pos= (SourcePosition) iterator.next(); + if (pos.fFileInfo == info && pos.fValid && lineNumber >= pos.fLine) { + int baseOffset= info.fSource.getLineOffset(srcPos.fLine); + if (lineOffset + lineLength - baseOffset <= srcPos.length) { + srcPos= pos; + break; + } + } + } + if (srcPos == null) { + return null; + } + } else if (!srcPos.fValid) { + return null; + } + assert lineNumber >= srcPos.fLine; + int baseOffset = info.fSource.getLineOffset(srcPos.fLine); + int offset = srcPos.offset + lineOffset - baseOffset; + if (offset >= srcPos.offset && offset < srcPos.offset + srcPos.length) { + return new Position(offset, lineLength); + } + } catch (BadLocationException exc) { + // TLETODO Auto-generated catch block + exc.printStackTrace(); + } catch (BadPositionCategoryException exc) { + // TLETODO Auto-generated catch block + exc.printStackTrace(); + } + return null; + } + + + /** + * @param category + * @param offset + * @return + * @throws BadPositionCategoryException + * @throws BadLocationException + */ + public Position getPosition(String category, int offset, boolean allowZeroLength) throws BadLocationException, BadPositionCategoryException { + @SuppressWarnings("unchecked") + List list = (List) getDocumentManagedPositions().get(category); + int idx; + idx = computeIndexInPositionList(list, offset, true); + if (idx > 0) { + --idx; + } + while (idx < list.size()) { + Position pos = list.get(idx); + if (pos.offset > offset) { + break; + } + if (pos.includes(offset)) { + return pos; + } + if (allowZeroLength && pos.offset == offset) { + return pos; + } + ++idx; + } + return null; + } + + /** + * @param pos + */ + public void addModelPosition(AddressRangePosition pos) { + try { + addPositionLast(CATEGORY_MODEL, pos); + } catch (BadPositionCategoryException e) { + // cannot happen + } + } + + /** + * @param pos + */ + public void addModelPositionFirst(AddressRangePosition pos) { + @SuppressWarnings("unchecked") + List list = (List) getDocumentManagedPositions().get(CATEGORY_MODEL); + int idx; + idx = computeIndexInPositionListFirst(list, pos.fAddressOffset.add(pos.fAddressLength)); + if (idx < list.size()) { + AddressRangePosition nextPos = list.get(idx); + assert nextPos.fAddressOffset.compareTo(pos.fAddressOffset.add(pos.fAddressLength)) == 0; + } + list.add(idx, pos); + } + + /** + * @param pos + * @throws BadLocationException + */ + public void addDisassemblyPosition(AddressRangePosition pos) throws BadLocationException { + try { + addPositionLast(CATEGORY_DISASSEMBLY, pos); + } catch (BadPositionCategoryException e) { + // cannot happen + } + if (pos instanceof DisassemblyPosition) { + int functionLength = ((DisassemblyPosition)pos).fFunction.length; + if (functionLength > fMaxFunctionLength) { + fMaxFunctionLength = functionLength; + } + if (fNumberOfInstructions < 100) { + fMeanSizeOfInstructions = (fMeanSizeOfInstructions * fNumberOfInstructions + pos.fAddressLength.floatValue()) / (++fNumberOfInstructions); + } + } + } + + /** + * @param pos + * @throws BadPositionCategoryException + */ + public void addPositionLast(String category, AddressRangePosition pos) throws BadPositionCategoryException { + @SuppressWarnings("unchecked") + List list = (List) getDocumentManagedPositions().get(category); + if (list == null) { + throw new BadPositionCategoryException(); + } + int idx; + idx = computeIndexInPositionListLast(list, pos.fAddressOffset); + list.add(idx, pos); + } + + /** + * @param pos + * @throws BadLocationException + */ + public void addLabelPosition(AddressRangePosition pos) throws BadLocationException { + try { + addPositionLast(CATEGORY_LABELS, pos); + } catch (BadPositionCategoryException e) { + // cannot happen + } + } + + /** + * @param pos + */ + public void addSourcePosition(AddressRangePosition pos) throws BadLocationException { + try { + addPositionLast(CATEGORY_SOURCE, pos); + } catch (BadPositionCategoryException e) { + // cannot happen + } + } + + /** + * @param pos + */ + public void removeDisassemblyPosition(AddressRangePosition pos) { + try { + removePosition(CATEGORY_DISASSEMBLY, pos); + } catch (BadPositionCategoryException e) { + // cannot happen + } + } + + /** + * @param pos + */ + public void removeSourcePosition(AddressRangePosition pos) { + try { + removePosition(CATEGORY_SOURCE, pos); + } catch (BadPositionCategoryException e) { + // cannot happen + } + } + + /** + * @param pos + */ + public void removeModelPosition(AddressRangePosition pos) { + try { + removePosition(getCategory(pos), pos); + } catch (BadPositionCategoryException e) { + // cannot happen + } + } + + /** + * @param pos + * @return + */ + private static String getCategory(AddressRangePosition pos) { + if (pos instanceof LabelPosition) { + return CATEGORY_LABELS; + } else if (pos instanceof SourcePosition) { + return CATEGORY_SOURCE; + } + return CATEGORY_DISASSEMBLY; + } + + /* + * @see org.eclipse.jface.text.IDocument#removePosition(java.lang.String, + * org.eclipse.jface.text.Position) + */ + @Override + public void removePosition(String category, Position position) throws BadPositionCategoryException { + super.removePosition(category, position); + if (category != CATEGORY_MODEL && position instanceof AddressRangePosition) { + super.removePosition(CATEGORY_MODEL, position); + } + } + + @SuppressWarnings("unchecked") + public void removePositions(String category, List toRemove) { + if (toRemove.isEmpty()) { + return; + } + List positions = (List) getDocumentManagedPositions().get(category); + if (positions != null) { + positions.removeAll(toRemove); + } + if (category != CATEGORY_MODEL) { + positions = (List) getDocumentManagedPositions().get(CATEGORY_MODEL); + if (positions != null) { + positions.removeAll(toRemove); + } + } + } + + public void addPositionLast(String category, Position position) throws BadLocationException, + BadPositionCategoryException { + + if ((0 > position.offset) || (0 > position.length) || (position.offset + position.length > getLength())) + throw new BadLocationException(); + + if (category == null) + throw new BadPositionCategoryException(); + + @SuppressWarnings("unchecked") + List list = (List) getDocumentManagedPositions().get(category); + if (list == null) + throw new BadPositionCategoryException(); + + list.add(computeIndexInPositionListLast(list, position.offset), position); + } + + public void checkConsistency() { + AddressRangePosition last = null; + try { + for (Iterator it = getPositionIterator(CATEGORY_MODEL, 0); it.hasNext();) { + AddressRangePosition pos = (AddressRangePosition) it.next(); + if (last != null) { + assert last.fAddressOffset.compareTo(pos.fAddressOffset) <= 0; + assert last.fAddressOffset.add(last.fAddressLength).compareTo(pos.fAddressOffset) == 0; + assert last.offset <= pos.offset; + assert last.offset + last.length == pos.offset; + } + last = pos; + } + } catch (BadPositionCategoryException e) { + assert false; + } + } + + /** + * @param insertPos + * @param replaceLength + * @param text + * @throws BadLocationException + */ + public void replace(AddressRangePosition insertPos, int replaceLength, String text) throws BadLocationException { + int delta = (text != null ? text.length() : 0) - replaceLength; + if (delta != 0) { + BigInteger address = insertPos.fAddressOffset; + Iterator it = getModelPositionIterator(address); + while (it.hasNext()) { + AddressRangePosition pos = it.next(); + assert pos.fAddressOffset.compareTo(address) >= 0; + if (pos.fAddressOffset.compareTo(address) > 0) { + break; + } + if (pos.offset > insertPos.offset) { + break; + } + if (pos == insertPos) { + break; + } + } + while (it.hasNext()) { + AddressRangePosition pos = it.next(); + pos.offset += delta; + } + } + super.replace(insertPos.offset, replaceLength, text); + } + + /** + * @param pos + * @param insertPos + * @param line + * @throws BadPositionCategoryException + * @throws BadLocationException + */ + public AddressRangePosition insertAddressRange(AddressRangePosition pos, AddressRangePosition insertPos, String line, boolean addToModel) + throws BadLocationException { + final BigInteger address = insertPos.fAddressOffset; + BigInteger length = insertPos.fAddressLength; + if (pos == null) { + pos = getPositionOfAddress(address); + } + assert !pos.isDeleted && !pos.fValid && (length.compareTo(BigInteger.ZERO) == 0 || pos.containsAddress(address)); + int insertOffset; + int replaceLength = 0; + if (length.compareTo(BigInteger.ONE) > 0 && !pos.containsAddress(address.add(length.subtract(BigInteger.ONE)))) { + // merge with successor positions + Iterator it = getModelPositionIterator(pos.fAddressOffset.add(pos.fAddressLength)); + assert it.hasNext(); + do { + AddressRangePosition overlap = it.next(); + BigInteger posEndAddress= pos.fAddressOffset.add(pos.fAddressLength); + assert pos.offset <= overlap.offset && overlap.fAddressOffset.compareTo(posEndAddress) == 0; + if (overlap instanceof LabelPosition || overlap instanceof SourcePosition) { + // don't override label or source positions, instead fix + // length of disassembly line to insert + length = insertPos.fAddressLength = posEndAddress.subtract(address.max(pos.fAddressOffset)); + break; + } + pos.fAddressLength = pos.fAddressLength.add(overlap.fAddressLength); + replaceLength = overlap.offset + overlap.length - pos.offset - pos.length; + it.remove(); + removeModelPosition(overlap); + if (!overlap.fValid) { + fInvalidAddressRanges.remove(overlap); + } + } while(!pos.containsAddress(address.add(length.subtract(BigInteger.ONE)))); + } + BigInteger newEndAddress = pos.fAddressOffset.add(pos.fAddressLength); + BigInteger newStartAddress = address.add(length); + assert newEndAddress.compareTo(newStartAddress) >= 0; + if (address.compareTo(pos.fAddressOffset) == 0) { + // insert at start of range + insertOffset = pos.offset; + if (replaceLength == 0 && newEndAddress.compareTo(newStartAddress) > 0) { + // optimization: shrink position in place + pos.fAddressOffset = newStartAddress; + pos.fAddressLength = pos.fAddressLength.subtract(length); + // don't insert new pos + newEndAddress = newStartAddress; + } else { + replaceLength += pos.length; + fInvalidAddressRanges.remove(pos); + removeDisassemblyPosition(pos); + pos = null; + } + } else { + // insert in mid/end of range + insertOffset = pos.offset + pos.length; + pos.fAddressLength = address.subtract(pos.fAddressOffset); + assert pos.fAddressLength.compareTo(BigInteger.ZERO) > 0; + pos = null; + } + if (newEndAddress.compareTo(newStartAddress) > 0) { + pos = insertInvalidAddressRange(insertOffset+replaceLength, 0, newStartAddress, newEndAddress); + } + assert pos == null || pos.fAddressLength.compareTo(BigInteger.ZERO) > 0 && pos.containsAddress(address.add(length)); + assert insertOffset + replaceLength <= getLength(); + + insertPos.offset = insertOffset; + if (addToModel) { + addModelPosition(insertPos); + } + replace(insertPos, replaceLength, line); + if (DEBUG) checkConsistency(); + return pos; + } + + /** + * @param pos + * @param address + * @param length + * @param instruction + * @throws BadPositionCategoryException + * @throws BadLocationException + */ + public AddressRangePosition insertDisassemblyLine(AddressRangePosition pos, BigInteger address, int length, String opcode, String instruction, String file, int lineNr) + throws BadLocationException { + String disassLine = null; + if (instruction == null || instruction.length() == 0) { + disassLine = ""; //$NON-NLS-1$ + } else { + disassLine = buildDisassemblyLine(address, opcode, instruction); + } + AddressRangePosition disassPos; + if (lineNr < 0) { + disassPos = new DisassemblyPosition(0, disassLine.length(), address, BigInteger.valueOf(length), opcode); + } else { + disassPos = new DisassemblyWithSourcePosition(0, disassLine.length(), address, BigInteger.valueOf(length), + opcode, file, lineNr); + } + pos = insertAddressRange(pos, disassPos, disassLine, true); + addDisassemblyPosition(disassPos); + return pos; + } + /** + * @param address + * @param opcode + * @param instruction + */ + private String buildDisassemblyLine(BigInteger address, String opcode, String instruction) { + StringBuffer buf = new StringBuffer(40); + if (fShowAddresses) { + if (fRadixPrefix != null) { + buf.append(fRadixPrefix); + } + String str = address.toString(fRadix); + for (int i=str.length(); i 0) { + buf.append(opcode); + int tab = 16; + if (opcode.length() >= 16) { + tab = (opcode.length() + 8) & ~7; + } + int diff = tab - opcode.length(); + while (diff-- > 0) { + buf.append(' '); + } + } else if (!fShowAddresses) { + buf.append(' '); + buf.append(' '); + } + int n = instruction.length(); + int prefixLen = buf.length(); + for (int j = 0; j < n; j++) { + char ch = instruction.charAt(j); + if (ch == '\t') { + int tab = (buf.length()-prefixLen + 8) & ~0x7; + do + buf.append(' '); + while (buf.length()-prefixLen < tab); + } else { + buf.append(ch); + } + } + buf.append('\n'); + return buf.toString(); + } + + public void setRadix(int radix) { + fRadix = radix; + fNumberOfDigits = (int)(Math.log(1L<<32)/Math.log(radix)+0.9); + setShowRadixPrefix(fShowRadixPrefix); + } + + public void setShowRadixPrefix(boolean showRadixPrefix) { + fShowRadixPrefix = showRadixPrefix; + if (!fShowRadixPrefix) { + fRadixPrefix = null; + } else if (fRadix == 16) { + fRadixPrefix = "0x"; //$NON-NLS-1$ + } else if (fRadix == 8) { + fRadixPrefix = "0"; //$NON-NLS-1$ + } else { + fRadixPrefix = null; + } + } + + public AddressRangePosition insertErrorLine(AddressRangePosition pos, BigInteger address, BigInteger length, String line) + throws BadLocationException { + int hashCode = line.hashCode(); + final long alignment = 0x1L; + if (alignment > 1 && !(pos instanceof ErrorPosition)) { + AddressRangePosition before = getPositionOfAddress(address.subtract(BigInteger.ONE)); + if (before instanceof ErrorPosition && before.hashCode() == hashCode && before.offset + before.length == pos.offset) { + assert before.fAddressOffset.add(before.fAddressLength).compareTo(address) == 0; + assert pos.fAddressOffset.compareTo(address) == 0; + // merge with previous error position + BigInteger pageOffset = before.fAddressOffset.and(BigInteger.valueOf(~(alignment-1))); + BigInteger mergeLen = pageOffset.add(BigInteger.valueOf(alignment)) + .subtract((before.fAddressOffset.add(before.fAddressLength))).min(length); + if (mergeLen.compareTo(BigInteger.ZERO) > 0) { + pos.fAddressLength = pos.fAddressLength.subtract(mergeLen); + if (pos.fAddressLength.compareTo(BigInteger.ZERO) == 0) { + replace(pos, pos.length, null); + removeModelPosition(pos); + fInvalidAddressRanges.remove(pos); + pos = null; + } else { + pos.fAddressOffset = pos.fAddressOffset.add(mergeLen); + } + before.fAddressLength = before.fAddressLength.add(mergeLen); + address = address.add(mergeLen); + length = length.subtract(mergeLen); + if (DEBUG) checkConsistency(); + if (length.compareTo(BigInteger.ZERO) == 0) { + return pos; + } + } + } + AddressRangePosition after = getPositionOfAddress(address.add(length)); + if (after instanceof ErrorPosition && after.hashCode() == hashCode && pos.offset + pos.length == after.offset) { + assert after.fAddressOffset == address.add(length); + assert pos.fAddressOffset.add(pos.fAddressLength).compareTo(after.fAddressOffset) == 0; + // merge with next error position + BigInteger pageOffset = after.fAddressOffset.add(BigInteger.valueOf(~(alignment-1))); + BigInteger mergeLen = after.fAddressOffset.subtract(pageOffset).min(length); + if (mergeLen.compareTo(BigInteger.ZERO) > 0) { + after.fAddressOffset = after.fAddressOffset.subtract(mergeLen); + after.fAddressLength = after.fAddressLength.add(mergeLen); + pos.fAddressLength = pos.fAddressLength.subtract(mergeLen); + if (pos.fAddressLength.compareTo(BigInteger.ZERO) == 0) { + replace(pos, pos.length, null); + removeModelPosition(pos); + fInvalidAddressRanges.remove(pos); + pos = null; + } + if (DEBUG) checkConsistency(); + length = length.subtract(mergeLen); + if (length.compareTo(BigInteger.ZERO) == 0) { + return pos; + } + } + } + } + BigInteger pageOffset = address.and(BigInteger.valueOf(~(alignment-1))); + BigInteger posLen = pageOffset.add(BigInteger.valueOf(alignment)).subtract(address).min(length); + while (length.compareTo(BigInteger.ZERO) > 0) { + AddressRangePosition errorPos = new ErrorPosition(0, 0, address, posLen, hashCode); + String errorLine = buildDisassemblyLine(address, null, line); + // TLEHACK: check for error messages, which occur only temporarily: + // "Target is busy. Try again later" + // "Cannot Perform requested Operation" + if (line.startsWith("Target is busy") || line.startsWith("Cannot perform")) { //$NON-NLS-1$ //$NON-NLS-2$ + // try again only once... + if (!(pos instanceof ErrorPosition)) { + errorLine = "...\n"; //$NON-NLS-1$ + errorPos.fValid = false; + } + } + errorPos.length = errorLine.length(); + pos = insertAddressRange(pos, errorPos, errorLine, true); + addDisassemblyPosition(errorPos); + if (!errorPos.fValid) { + fInvalidAddressRanges.add(errorPos); + } + length = length.subtract(posLen); + address = address.add(posLen); + posLen = BigInteger.valueOf(alignment).min(length); + } + return pos; + } + + /** + * @param pos + * @param address + * @param label + * @throws BadLocationException + * @throws BadPositionCategoryException + */ + public AddressRangePosition insertLabel(AddressRangePosition pos, BigInteger address, String label, boolean showLabels) + throws BadLocationException { + String labelLine = showLabels ? label + ":\n" : ""; //$NON-NLS-1$ //$NON-NLS-2$ + LabelPosition labelPos = getLabelPosition(address); + if (labelPos != null) { + assert labelPos.fAddressOffset.compareTo(address) == 0; + if (labelPos.length != labelLine.length()) { + int oldLength = labelPos.length; + labelPos.length = labelLine.length(); + replace(labelPos, oldLength, labelLine); + } + return pos; + } + labelPos = new LabelPosition(0, labelLine.length(), address, null); + pos = insertAddressRange(pos, labelPos, labelLine, true); + addLabelPosition(labelPos); + return pos; + } + + /** + * @param pos + * @param address + * @param source + * @param line + * @param endOfSource + * @throws BadLocationException + * @throws BadPositionCategoryException + */ + public SourcePosition insertSource(SourcePosition pos, String source, int line, boolean endOfSource) { +// System.out.println("insertSource at "+getAddressText(pos.fAddressOffset)); +// System.out.println(source); + String sourceLines = source; + if (source.length() > 0 && sourceLines.charAt(source.length() - 1) != '\n') { + sourceLines += "\n"; //$NON-NLS-1$ + } + try { + assert !pos.fValid; + int oldLength = pos.length; + pos.length = sourceLines.length(); + pos.fLine = line; + pos.fValid = true; + fInvalidSource.remove(pos); + replace(pos, oldLength, sourceLines); + if (!endOfSource) { + if (pos.length > 0) { + SourcePosition oldPos = getSourcePosition(pos.offset+pos.length); + if (oldPos == null || oldPos.fAddressOffset.compareTo(pos.fAddressOffset) != 0) { + pos = new SourcePosition(pos.offset+pos.length, 0, pos.fAddressOffset, pos.fFileInfo, line, false); + addSourcePosition(pos); + addModelPosition(pos); + fInvalidSource.add(pos); + } else { + //TLETODO need more checks for correct source pos + pos = oldPos; + } + } + } + } catch (BadLocationException e) { + internalError(e); + } + return pos; + } + + /** + * @param pos + * @param address + * @param fi + * @param lineNr + * @return + */ + public AddressRangePosition insertInvalidSource(AddressRangePosition pos, BigInteger address, SourceFileInfo fi, int lineNr) { + SourcePosition sourcePos = getSourcePosition(address); + if (sourcePos != null) { + return pos; + } + String sourceLine = ""; //$NON-NLS-1$ + sourcePos = new SourcePosition(0, sourceLine.length(), address, fi, lineNr, false); + try { + pos = insertAddressRange(pos, sourcePos, sourceLine, true); + addSourcePosition(sourcePos); + assert !fInvalidSource.contains(sourcePos); + fInvalidSource.add(sourcePos); + } catch (BadLocationException e) { + internalError(e); + } + return pos; + } + + /** + * @param offset + * @param replaceLength + * @param startAddress + * @param endAddress + * @return + */ + public AddressRangePosition insertInvalidAddressRange(int offset, int replaceLength, BigInteger startAddress, BigInteger endAddress) { + String periods = "...\n"; //$NON-NLS-1$ + AddressRangePosition newPos = new AddressRangePosition(offset, periods.length(), startAddress, endAddress + .subtract(startAddress), false); + try { + addModelPositionFirst(newPos); + replace(newPos, replaceLength, periods); + addDisassemblyPosition(newPos); + fInvalidAddressRanges.add(newPos); + } catch (BadLocationException e) { + internalError(e); + } + return newPos; + } + + public void invalidateAddressRange(BigInteger startAddress, BigInteger endAddress, boolean collapse) { + deleteDisassemblyRange(startAddress, endAddress, true, collapse); + } + + public void deleteDisassemblyRange(BigInteger startAddress, BigInteger endAddress, boolean invalidate, boolean collapse) { + String replacement = invalidate ? "...\n" : null; //$NON-NLS-1$ + int replaceLen = replacement != null ? replacement.length() : 0; + AddressRangePosition lastPos = null; + ArrayList toRemove = new ArrayList(); + Iterator it = getModelPositionIterator(startAddress); + while (it.hasNext()) { + AddressRangePosition pos = it.next(); + BigInteger posEndAddress = pos.fAddressOffset.add(pos.fAddressLength); + if (pos instanceof LabelPosition) { + if (!invalidate && pos.length > 0 && posEndAddress.compareTo(endAddress) > 0) { + try { + int oldLength = pos.length; + pos.length = 0; + replace(pos, oldLength, null); + } catch (BadLocationException e) { + internalError(e); + } + } + pos = null; + } else if (pos instanceof SourcePosition) { + pos = null; + } else if (pos instanceof ErrorPosition) { + pos = null; + } else if (pos instanceof DisassemblyPosition) { + // optimization: join adjacent positions + if (collapse && lastPos != null + && (invalidate || lastPos.fValid == pos.fValid) + && lastPos.offset+lastPos.length == pos.offset) { + assert lastPos.fAddressOffset.add(lastPos.fAddressLength).compareTo(pos.fAddressOffset) == 0; + lastPos.length += pos.length; + lastPos.fAddressLength = lastPos.fAddressLength.add(pos.fAddressLength); + toRemove.add(pos); + if (!pos.fValid) { + fInvalidAddressRanges.remove(pos); + } + pos = null; + if (posEndAddress.compareTo(endAddress) < 0) { + continue; + } + } + } + if (lastPos != null) { + try { + if (lastPos.length > 0 || replaceLen > 0) { + int oldLength = lastPos.length; + lastPos.length = replaceLen; + replace(lastPos, oldLength, replacement); + } + } catch (BadLocationException e) { + internalError(e); + } + } + if (pos == null && posEndAddress.compareTo(endAddress) >= 0) { + break; + } + lastPos = null; + if (pos != null) { + if (pos.fValid && invalidate) { + pos.fValid = false; + fInvalidAddressRanges.add(pos); + } + lastPos = pos; + } + } + removePositions(CATEGORY_DISASSEMBLY, toRemove); + if (DEBUG) checkConsistency(); + } + + public void invalidateSource() { + Iterator it; + try { + it = getPositionIterator(CATEGORY_SOURCE, 0); + } catch (BadPositionCategoryException e) { + internalError(e); + return; + } + while (it.hasNext()) { + SourcePosition srcPos = (SourcePosition)it.next(); + if (srcPos != null && srcPos.fValid) { + srcPos.fValid = false; + assert !getInvalidSource().contains(srcPos); + getInvalidSource().add(srcPos); + } + } + } + + public void invalidateDisassemblyWithSource(boolean removeDisassembly) { + for (Iterator it = fFileInfoMap.values().iterator(); it.hasNext();) { + SourceFileInfo info = it.next(); + if (info.fLine2Addr != null) { + deleteDisassemblyRange(info.fStartAddress, info.fEndAddress.add(BigInteger.ONE), !removeDisassembly, !removeDisassembly); + } + } + } + + /** + * @param start + * @param end + * @throws BadLocationException + */ + public void deleteLineRange(int start, int end) throws BadLocationException { + if (start >= end) { + return; + } + int startOffset = getLineOffset(start); + int endOffset = getLineOffset(end); + int replaceLength = 0; + AddressRangePosition startPos = getDisassemblyPosition(startOffset); + if (startPos == null) { + return; + } + startOffset = startPos.offset; + AddressRangePosition endPos = getDisassemblyPosition(endOffset); + if (endPos == null) { + return; + } + BigInteger startAddress = BigInteger.ZERO; + BigInteger addressLength = BigInteger.ZERO; + ArrayList toRemove = new ArrayList(); + try { + Iterator it = getPositionIterator(DisassemblyDocument.CATEGORY_MODEL, startAddress); + while (it.hasNext()) { + AddressRangePosition p = it.next(); + addressLength = addressLength.add(p.fAddressLength); + replaceLength += p.length; + toRemove.add(p); + if (!p.fValid) { + if (p instanceof SourcePosition) { + getInvalidSource().remove(p); + } else { + getInvalidAddressRanges().remove(p); + } + } + if (addressLength.compareTo(BigInteger.ZERO) > 0 && p.fAddressOffset.compareTo(endPos.fAddressOffset) >= 0) { + break; + } + } + } catch (BadPositionCategoryException e) { + // cannot happen + } + for (Iterator iter = toRemove.iterator(); iter.hasNext();) { + AddressRangePosition pos = iter.next(); + removeModelPosition(pos); + } + if (addressLength.compareTo(BigInteger.ZERO) > 0) { + insertInvalidAddressRange(startOffset, replaceLength, startAddress, startAddress.add(addressLength)); + } + } + + public SourceFileInfo getSourceInfo(BigInteger address) { + AddressRangePosition pos = getDisassemblyPosition(address); + if (pos instanceof DisassemblyPosition) { + DisassemblyPosition disassPos = (DisassemblyPosition)pos; + return getSourceInfo(disassPos.getFile()); + } + return null; + } + + public SourceFileInfo getSourceInfo(String file) { + if (fFileInfoMap == null || file == null) { + return null; + } + for (Iterator iter = fFileInfoMap.values().iterator(); iter.hasNext();) { + SourceFileInfo info = iter.next(); + if (file.equals(info.fFileKey)) { + return info; + } + } + return null; + } + + public SourceFileInfo getSourceInfo(IStorage sourceElement) { + if (fFileInfoMap == null) { + return null; + } + SourceFileInfo fi = fFileInfoMap.get(sourceElement); + return fi; + } + + public SourceFileInfo createSourceInfo(String fileKey, IStorage sourceElement, Runnable done) { + SourceFileInfo fi = new SourceFileInfo(fileKey, sourceElement); + assert fFileInfoMap != null; + if (fFileInfoMap != null) { + fFileInfoMap.put(sourceElement, fi); + new SourceReadingJob(fi, done); + } + return fi; + } + + private void internalError(Throwable e) { + if (DEBUG) { + System.err.println("Disassembly: Internal error"); //$NON-NLS-1$ + e.printStackTrace(); + } + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/DisassemblyPosition.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/DisassemblyPosition.java new file mode 100644 index 00000000000..8b2010cd515 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/DisassemblyPosition.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2007, 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model; + +import java.math.BigInteger; + +/** + * DisassemblyPosition + */ +public class DisassemblyPosition extends AddressRangePosition { + + public char[] fFunction; + + /** + * + * @param offset + * @param length + * @param addressOffset + * @param addressLength + * @param opcodes + */ + public DisassemblyPosition(int offset, int length, BigInteger addressOffset, BigInteger addressLength, String opcodes) { + super(offset, length, addressOffset, addressLength); + fFunction = opcodes.toCharArray(); + } + + /** + * @return source file + */ + public String getFile() { + return null; + } + + /** + * @return source line number + */ + public int getLine() { + return -1; + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/DisassemblyWithSourcePosition.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/DisassemblyWithSourcePosition.java new file mode 100644 index 00000000000..55e537e5935 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/DisassemblyWithSourcePosition.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2007, 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model; + +import java.math.BigInteger; + +/** + * DisassemblyWithSourcePosition + */ +public class DisassemblyWithSourcePosition extends DisassemblyPosition { + + private String fFile; + private int fLine; + + /** + * @param offset + * @param length + * @param addressOffset + * @param addressLength + * @param opcodes + */ + public DisassemblyWithSourcePosition(int offset, int length, BigInteger addressOffset, BigInteger addressLength, String opcodes, String file, int lineNr) { + super(offset, length, addressOffset, addressLength, opcodes); + fFile = file; + fLine = lineNr; + } + + /* (non-Javadoc) + * @see com.windriver.ide.disassembly.model.DisassemblyPosition#getFile() + */ + @Override + public String getFile() { + return fFile; + } + + /* (non-Javadoc) + * @see com.windriver.ide.disassembly.model.DisassemblyPosition#getLine() + */ + @Override + public int getLine() { + return fLine; + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/ErrorPosition.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/ErrorPosition.java new file mode 100644 index 00000000000..93be42f3f7a --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/ErrorPosition.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2007, 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model; + +import java.math.BigInteger; + +/** + * ErrorPosition + */ +public class ErrorPosition extends AddressRangePosition { + + public int fHashCode; + + /** + * @param offset + * @param length + * @param addressOffset + * @param addressLength + */ + public ErrorPosition(int offset, int length, BigInteger addressOffset, BigInteger addressLength, int hashCode) { + super(offset, length, addressOffset, addressLength); + fHashCode = hashCode; + } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return fHashCode; + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/LabelPosition.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/LabelPosition.java new file mode 100644 index 00000000000..88157414d89 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/LabelPosition.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2007, 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model; + +import java.math.BigInteger; + +/** + * LabelPosition + */ +public class LabelPosition extends AddressRangePosition { + + public String fLabel; + + /** + * @param offset + * @param length + * @param addressOffset + */ + public LabelPosition(int offset, int length, BigInteger addressOffset, String label) { + super(offset, length, addressOffset, BigInteger.ZERO); + fLabel = label; + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/SourceDocumentProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/SourceDocumentProvider.java new file mode 100644 index 00000000000..c9a1dfb8233 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/SourceDocumentProvider.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright (c) 2007, 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model; + +import java.util.Iterator; + +import org.eclipse.cdt.internal.ui.editor.CDocumentSetupParticipant; +import org.eclipse.core.filesystem.EFS; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFileState; +import org.eclipse.core.resources.IStorage; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.text.REDDocument; +import org.eclipse.debug.core.sourcelookup.containers.LocalFileStorage; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.ui.IStorageEditorInput; +import org.eclipse.ui.IURIEditorInput; +import org.eclipse.ui.editors.text.StorageDocumentProvider; + +/** + * SourceDocumentProvider + */ +public class SourceDocumentProvider extends StorageDocumentProvider { + + public SourceDocumentProvider() { + super(); + } + + /** + * Dispose all connected documents. + */ + public void dispose() { + Iterator it = getConnectedElements(); + while(it.hasNext()) { + Object element = it.next(); + ElementInfo info = getElementInfo(element); + // force refcount to 1 + info.fCount = 1; + disconnect(element); + } + } + + /* + * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#createDocument(java.lang.Object) + */ + @Override + protected IDocument createEmptyDocument() { + IDocument doc = new REDDocument(); + return doc; + } + + /* + * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#createAnnotationModel(java.lang.Object) + */ + @Override + protected IAnnotationModel createAnnotationModel(Object element) throws CoreException { + return null; + } + + /* + * @see org.eclipse.ui.editors.text.StorageDocumentProvider#setupDocument(java.lang.Object, org.eclipse.jface.text.IDocument) + */ + @Override + protected void setupDocument(Object element, IDocument document) { + super.setupDocument(element, document); + if (element instanceof IStorageEditorInput) { + new CDocumentSetupParticipant().setup(document); + } + } + + /* + * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#disposeElementInfo(java.lang.Object, org.eclipse.ui.texteditor.AbstractDocumentProvider.ElementInfo) + */ + @Override + protected void disposeElementInfo(Object element, ElementInfo info) { + super.disposeElementInfo(element, info); + IDocument doc = info.fDocument; + if (doc instanceof REDDocument) { + ((REDDocument)doc).dispose(); + } + } + + /* + * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#getModificationStamp(java.lang.Object) + */ + @Override + public long getModificationStamp(Object element) { + try { + if (element instanceof IStorageEditorInput) { + IStorage file= ((IStorageEditorInput)element).getStorage(); + if (file instanceof IFile) { + return ((IFile)file).getLocalTimeStamp(); + } else if (file instanceof IFileState) { + return ((IFileState)file).getModificationTime(); + } else if (file instanceof LocalFileStorage) { + return ((LocalFileStorage)file).getFile().lastModified(); + } + } else if (element instanceof IURIEditorInput) { + return EFS.getStore(((IURIEditorInput)element).getURI()).fetchInfo().getLastModified(); + } + } catch (CoreException e) { + // ignore + } + return 0; + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/SourceEditorInput.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/SourceEditorInput.java new file mode 100644 index 00000000000..df7ebc592f1 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/SourceEditorInput.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2007, 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model; + +import org.eclipse.core.resources.IStorage; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.util.StorageEditorInput; + +/** + * SourceEditorInput + */ +public class SourceEditorInput extends StorageEditorInput { + + /** + * @param storage + */ + public SourceEditorInput(IStorage storage) { + super(storage); + } + + /* + * @see org.eclipse.ui.IEditorInput#exists() + */ + public boolean exists() { + return false; + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/SourceFileInfo.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/SourceFileInfo.java new file mode 100644 index 00000000000..97522e9031c --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/SourceFileInfo.java @@ -0,0 +1,187 @@ +/******************************************************************************* + * Copyright (c) 2007, 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model; + +import java.math.BigInteger; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.model.ILanguage; +import org.eclipse.cdt.core.model.LanguageManager; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IStorage; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.content.IContentType; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.presentation.ISourcePresentationCreator; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.presentation.SourcePresentationCreatorFactory; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.Region; +import org.eclipse.jface.text.TextPresentation; +import org.eclipse.ui.IEditorInput; + +/** + * Holds information about a source file. + */ +public class SourceFileInfo { + public final String fFileKey; + public final IStorage fFile; + public IStorage fEdition; + public BigInteger[] fLine2Addr; + public Addr2Line[] fAddr2Line; + public volatile IDocument fSource; + public volatile boolean fValid; + public Object fLinesNode; + public Throwable fError; + public volatile SourceReadingJob fReadingJob; + public volatile Job fEditionJob; + public ISourcePresentationCreator fPresentationCreator; + public BigInteger fStartAddress = BigInteger.ONE.shiftLeft(64).subtract(BigInteger.ONE); + public BigInteger fEndAddress= BigInteger.ZERO; + + public SourceFileInfo(String fileKey, IStorage file) { + fFileKey = fileKey; + fFile = fEdition = file; + } + + /** + * Initialize source document. + * @throws CoreException + */ + public void initSource() throws CoreException { + SourceDocumentProvider provider = DsfDebugUIPlugin.getSourceDocumentProvider(); + IEditorInput input = new SourceEditorInput(fEdition); + synchronized (provider) { + provider.connect(input); + } + IStatus status = provider.getStatus(input); + if (status != null && !status.isOK()) { + throw new CoreException(status); + } + } + + /** + * Initialize presentation creator. + * @param viewer + */ + public void initPresentationCreator(ITextViewer viewer) { + SourceDocumentProvider provider = DsfDebugUIPlugin.getSourceDocumentProvider(); + IEditorInput input = new SourceEditorInput(fEdition); + IDocument doc = provider.getDocument(input); + if (doc != null) { + IContentType contentType= null; + if (fEdition instanceof IFile) { + IFile file= (IFile)fEdition; + contentType= CCorePlugin.getContentType(file.getProject(), file.getName()); + } else { + contentType= CCorePlugin.getContentType(fEdition.getName()); + } + ILanguage language= null; + if (contentType != null) { + language= LanguageManager.getInstance().getLanguage(contentType); + } + if (language != null) { + fPresentationCreator= SourcePresentationCreatorFactory.create(language, fEdition, viewer); + } + int lines = doc.getNumberOfLines(); + fLine2Addr = new BigInteger[lines]; + fAddr2Line = new Addr2Line[lines / 10 + 1]; + // assign fSource last, triggering source update + fSource = doc; + } + } + + /** + * Dispose this object. + */ + public void dispose() { + if (fReadingJob != null) { + if (!fReadingJob.cancel()) { + fReadingJob.dispose(); + } + fReadingJob = null; + } + if (fPresentationCreator != null) { + fPresentationCreator.dispose(); + fPresentationCreator = null; + } + SourceDocumentProvider provider = DsfDebugUIPlugin.getSourceDocumentProvider(); + synchronized (provider) { + provider.disconnect(new SourceEditorInput(fEdition)); + } + fSource = null; + fValid = false; +// fLinesNode = null; + } + + public String getLine(int lineNr) { + return getLines(lineNr, lineNr); + } + + public String getLines(int first, int last) { + try { + int startOffset = fSource.getLineOffset(first); + int endOffset; + if (last < fSource.getNumberOfLines()-1) { + IRegion lastRegion = fSource.getLineInformation(last+1); + endOffset = lastRegion.getOffset(); + } else { + // last line + IRegion lastRegion = fSource.getLineInformation(last); + endOffset = lastRegion.getOffset() + lastRegion.getLength(); + } + return fSource.get(startOffset, endOffset - startOffset); + } catch (BadLocationException e) { + return null; + } + } + + public IRegion getRegion(int line, int length) { + try { + IRegion lineRegion = fSource.getLineInformation(line); + return new Region(lineRegion.getOffset(), length); + } catch (BadLocationException e) { + return null; + } + } + + /** + * Get or create text presentation for the given region. + * Must be called in display thread. + * @param region + * @return text presentation + */ + public TextPresentation getPresentation(IRegion region) { + if (fSource != null && fPresentationCreator != null) { + return fPresentationCreator.getPresentation(region, fSource); + } + return null; + } + + /** + * @return offset of given line + */ + public int getLineOffset(int line) { + if (fSource != null) { + try { + return fSource.getLineOffset(line); + } catch (BadLocationException e) { + // ignored + } + } + return -1; + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/SourcePosition.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/SourcePosition.java new file mode 100644 index 00000000000..e03699948e2 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/SourcePosition.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2007, 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model; + +import java.math.BigInteger; + +/** + * SourcePosition + */ +public class SourcePosition extends AddressRangePosition { + + public SourceFileInfo fFileInfo; + public int fLine; + + /** + * + * @param offset + * @param length + * @param addressOffset + * @param fileInfo + * @param line + */ + public SourcePosition(int offset, int length, BigInteger addressOffset, SourceFileInfo fileInfo, int line) { + this(offset, length, addressOffset, fileInfo, line, true); + } + + /** + * + * @param offset + * @param length + * @param addressOffset + * @param fileInfo + * @param line + * @param valid + */ + public SourcePosition(int offset, int length, BigInteger addressOffset, SourceFileInfo fileInfo, int line, boolean valid) { + super(offset, length, addressOffset, BigInteger.ZERO, valid); + fFileInfo = fileInfo; + fLine = line; + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/SourceReadingJob.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/SourceReadingJob.java new file mode 100644 index 00000000000..54e87a68596 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/SourceReadingJob.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (c) 2007, 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly.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.debug.internal.ui.disassembly.DisassemblyMessages; + + +/** + * Low-level job to read source files in the background. + */ +public class SourceReadingJob extends Job { + + private final static String NAME = DisassemblyMessages.SourceReadingJob_name; + + private SourceFileInfo fFileInfo; + private Runnable fDone; + + public SourceReadingJob(SourceFileInfo fi, Runnable done) { + super(NAME); + fFileInfo = fi; + fFileInfo.fReadingJob = this; + fDone = done; + if (fi.fFile instanceof ISchedulingRule) { + setRule((ISchedulingRule)fi.fFile); + } + setSystem(true); + // usually short lived job + setPriority(SHORT); + if (fi.fFile.getFullPath() != null) { + String fileName = fi.fFile.getFullPath().lastSegment(); + setName(NAME + " (" + fileName + ')'); //$NON-NLS-1$ + } + } + + public synchronized void dispose() { + fDone = null; + Thread thread = getThread(); + if (thread != null && thread.isAlive()) { + thread.interrupt(); + } + } + + @Override + public IStatus run(IProgressMonitor monitor) { + if (fFileInfo.fEditionJob != null) { + try { + fFileInfo.fEditionJob.join(); + } catch (InterruptedException e) { + // ignore + } + } + try { + fFileInfo.initSource(); + } catch (Throwable e) { + fFileInfo.fError = e; + } finally { + fFileInfo.fReadingJob = null; + synchronized (this) { + if (fDone != null && !getThread().isInterrupted()) { + fDone.run(); + } + } + } + // errors are handled elsewhere + return Status.OK_STATUS; + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/preferences/DisassemblyPreferenceConstants.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/preferences/DisassemblyPreferenceConstants.java new file mode 100644 index 00000000000..1b6415dc400 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/preferences/DisassemblyPreferenceConstants.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2007, 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly.preferences; + +import java.math.BigInteger; + +import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer; +import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.PreferenceConverter; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.ui.editors.text.EditorsUI; +import org.eclipse.ui.editors.text.TextEditorPreferenceConstants; + +/** + * DisassemblyPreferenceConstants + */ +public class DisassemblyPreferenceConstants { + + public static final String START_ADDRESS = "startAddress"; //$NON-NLS-1$ + public static final String END_ADDRESS = "endAddress"; //$NON-NLS-1$ + public static final String PC_HISTORY_SIZE = "pcHistorySize"; //$NON-NLS-1$ + public static final String SHOW_SOURCE = "showSource"; //$NON-NLS-1$ + public static final String SHOW_LABELS = "showLabels"; //$NON-NLS-1$ + public static final String SHOW_SYMBOLS = "showSymbols"; //$NON-NLS-1$ + public static final String SIMPLIFIED = "simplified"; //$NON-NLS-1$ + public static final String INSTRUCTION_RADIX = "instructionRadix"; //$NON-NLS-1$ + public static final String ADDRESS_RADIX = "addressRadix"; //$NON-NLS-1$ + public static final String SHOW_ADDRESS_RADIX = "showAddressRadix"; //$NON-NLS-1$ + public static final String SHOW_ADDRESS_RULER = "showAddressRuler"; //$NON-NLS-1$ + public static final String ADDRESS_COLOR = "addressColor"; //$NON-NLS-1$ + public static final String SHOW_FUNCTION_OFFSETS = "showOpcodeRuler"; //$NON-NLS-1$ + public static final String OPCODE_COLOR = "opcodeColor"; //$NON-NLS-1$ + public static final String USE_SOURCE_ONLY_MODE = "useSourceOnlyMode"; //$NON-NLS-1$ + public static final String AVOID_READ_BEFORE_PC = "avoidReadBeforePC"; //$NON-NLS-1$ + + /** + * + */ + private DisassemblyPreferenceConstants() { + // not intended to be subclassed or instatiated + } + + /** + * Initialize preference default values. + * @param store + */ + public static void initializeDefaults(IPreferenceStore store) { + TextEditorPreferenceConstants.initializeDefaultValues(store); + store.setDefault(START_ADDRESS, 0x0L); + store.setDefault(END_ADDRESS, "0x" + BigInteger.ONE.shiftLeft(64).toString(16)); //$NON-NLS-1$ + store.setDefault(PC_HISTORY_SIZE, 4); + store.setDefault(SHOW_SOURCE, true); + store.setDefault(SHOW_FUNCTION_OFFSETS, false); + store.setDefault(SHOW_LABELS, true); + store.setDefault(SHOW_SYMBOLS, true); + store.setDefault(SIMPLIFIED, true); + store.setDefault(INSTRUCTION_RADIX, 16); + store.setDefault(ADDRESS_RADIX, 16); + store.setDefault(SHOW_ADDRESS_RADIX, false); + store.setDefault(SHOW_ADDRESS_RULER, true); + store.setDefault(AVOID_READ_BEFORE_PC, false); + store.setDefault(USE_SOURCE_ONLY_MODE, false); + PreferenceConverter.setDefault(store, ADDRESS_COLOR, new RGB(0, 96, 0)); + PreferenceConverter.setDefault(store, OPCODE_COLOR, new RGB(96, 0, 0)); + } + + public static class Initializer extends AbstractPreferenceInitializer { + @Override + public void initializeDefaultPreferences() { + IPreferenceStore store = DsfDebugUIPlugin.getDefault().getPreferenceStore(); + initializeDefaults(store); + EditorsUI.useAnnotationsPreferencePage(store); + } + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/preferences/DisassemblyPreferencePage.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/preferences/DisassemblyPreferencePage.java new file mode 100644 index 00000000000..372eaab2cbb --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/preferences/DisassemblyPreferencePage.java @@ -0,0 +1,313 @@ +/******************************************************************************* + * Copyright (c) 2007, 2008 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.debug.internal.ui.disassembly.preferences; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.DisassemblyMessages; +import org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyHelpContextIds; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.eclipse.ui.PlatformUI; + +/** + * DisassemblyPreferencePage + */ +public class DisassemblyPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { + + private List